diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/dt-bindings/clock/aspeed-clock.h | 2 | ||||
-rw-r--r-- | include/dt-bindings/clock/ast2600-clock.h | 4 | ||||
-rw-r--r-- | include/dt-bindings/interrupt-controller/aspeed-scu-ic.h | 23 | ||||
-rw-r--r-- | include/keys/trusted.h | 12 | ||||
-rw-r--r-- | include/linux/mfd/intel-peci-client.h | 119 | ||||
-rw-r--r-- | include/linux/peci.h | 150 | ||||
-rw-r--r-- | include/linux/tpm.h | 213 | ||||
-rw-r--r-- | include/trace/events/fsi.h | 6 | ||||
-rw-r--r-- | include/trace/events/fsi_master_aspeed.h | 77 | ||||
-rw-r--r-- | include/uapi/linux/aspeed-xdma.h | 42 | ||||
-rw-r--r-- | include/uapi/linux/peci-ioctl.h | 661 |
11 files changed, 1300 insertions, 9 deletions
diff --git a/include/dt-bindings/clock/aspeed-clock.h b/include/dt-bindings/clock/aspeed-clock.h index f43738607d77..9ff4f6e4558c 100644 --- a/include/dt-bindings/clock/aspeed-clock.h +++ b/include/dt-bindings/clock/aspeed-clock.h @@ -39,6 +39,8 @@ #define ASPEED_CLK_BCLK 33 #define ASPEED_CLK_MPLL 34 #define ASPEED_CLK_24M 35 +#define ASPEED_CLK_MAC1RCLK 36 +#define ASPEED_CLK_MAC2RCLK 37 #define ASPEED_RESET_XDMA 0 #define ASPEED_RESET_MCTP 1 diff --git a/include/dt-bindings/clock/ast2600-clock.h b/include/dt-bindings/clock/ast2600-clock.h index 38074a5f7296..62b9520a00fd 100644 --- a/include/dt-bindings/clock/ast2600-clock.h +++ b/include/dt-bindings/clock/ast2600-clock.h @@ -83,6 +83,10 @@ #define ASPEED_CLK_MAC12 64 #define ASPEED_CLK_MAC34 65 #define ASPEED_CLK_USBPHY_40M 66 +#define ASPEED_CLK_MAC1RCLK 67 +#define ASPEED_CLK_MAC2RCLK 68 +#define ASPEED_CLK_MAC3RCLK 69 +#define ASPEED_CLK_MAC4RCLK 70 /* Only list resets here that are not part of a gate */ #define ASPEED_RESET_ADC 55 diff --git a/include/dt-bindings/interrupt-controller/aspeed-scu-ic.h b/include/dt-bindings/interrupt-controller/aspeed-scu-ic.h new file mode 100644 index 000000000000..f315d5a7f5ee --- /dev/null +++ b/include/dt-bindings/interrupt-controller/aspeed-scu-ic.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_ASPEED_SCU_IC_H_ +#define _DT_BINDINGS_INTERRUPT_CONTROLLER_ASPEED_SCU_IC_H_ + +#define ASPEED_SCU_IC_VGA_CURSOR_CHANGE 0 +#define ASPEED_SCU_IC_VGA_SCRATCH_REG_CHANGE 1 + +#define ASPEED_AST2500_SCU_IC_PCIE_RESET_LO_TO_HI 2 +#define ASPEED_AST2500_SCU_IC_PCIE_RESET_HI_TO_LO 3 +#define ASPEED_AST2500_SCU_IC_LPC_RESET_LO_TO_HI 4 +#define ASPEED_AST2500_SCU_IC_LPC_RESET_HI_TO_LO 5 +#define ASPEED_AST2500_SCU_IC_ISSUE_MSI 6 + +#define ASPEED_AST2600_SCU_IC0_PCIE_PERST_LO_TO_HI 2 +#define ASPEED_AST2600_SCU_IC0_PCIE_PERST_HI_TO_LO 3 +#define ASPEED_AST2600_SCU_IC0_PCIE_RCRST_LO_TO_HI 4 +#define ASPEED_AST2600_SCU_IC0_PCIE_RCRST_HI_TO_LO 5 + +#define ASPEED_AST2600_SCU_IC1_LPC_RESET_LO_TO_HI 0 +#define ASPEED_AST2600_SCU_IC1_LPC_RESET_HI_TO_LO 1 + +#endif /* _DT_BINDINGS_INTERRUPT_CONTROLLER_ASPEED_SCU_IC_H_ */ diff --git a/include/keys/trusted.h b/include/keys/trusted.h index 0071298b9b28..841ae111c976 100644 --- a/include/keys/trusted.h +++ b/include/keys/trusted.h @@ -17,7 +17,7 @@ #define LOAD32N(buffer, offset) (*(uint32_t *)&buffer[offset]) #define LOAD16(buffer, offset) (ntohs(*(uint16_t *)&buffer[offset])) -struct tpm_buf { +struct tpm1_buf { int len; unsigned char data[MAX_BUF_SIZE]; }; @@ -46,7 +46,7 @@ int TSS_checkhmac1(unsigned char *buffer, unsigned int keylen, ...); int trusted_tpm_send(unsigned char *cmd, size_t buflen); -int oiap(struct tpm_buf *tb, uint32_t *handle, unsigned char *nonce); +int oiap(struct tpm1_buf *tb, uint32_t *handle, unsigned char *nonce); #define TPM_DEBUG 0 @@ -110,24 +110,24 @@ static inline void dump_tpm_buf(unsigned char *buf) } #endif -static inline void store8(struct tpm_buf *buf, const unsigned char value) +static inline void store8(struct tpm1_buf *buf, const unsigned char value) { buf->data[buf->len++] = value; } -static inline void store16(struct tpm_buf *buf, const uint16_t value) +static inline void store16(struct tpm1_buf *buf, const uint16_t value) { *(uint16_t *) & buf->data[buf->len] = htons(value); buf->len += sizeof value; } -static inline void store32(struct tpm_buf *buf, const uint32_t value) +static inline void store32(struct tpm1_buf *buf, const uint32_t value) { *(uint32_t *) & buf->data[buf->len] = htonl(value); buf->len += sizeof value; } -static inline void storebytes(struct tpm_buf *buf, const unsigned char *in, +static inline void storebytes(struct tpm1_buf *buf, const unsigned char *in, const int len) { memcpy(buf->data + buf->len, in, len); diff --git a/include/linux/mfd/intel-peci-client.h b/include/linux/mfd/intel-peci-client.h new file mode 100644 index 000000000000..7668d0cfa843 --- /dev/null +++ b/include/linux/mfd/intel-peci-client.h @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2018-2019 Intel Corporation */ + +#ifndef __LINUX_MFD_INTEL_PECI_CLIENT_H +#define __LINUX_MFD_INTEL_PECI_CLIENT_H + +#include <linux/peci.h> + +#if IS_ENABLED(CONFIG_X86) +#include <asm/intel-family.h> +#else +/* + * Architectures other than x86 cannot include the header file so define these + * at here. These are needed for detecting type of client x86 CPUs behind a PECI + * connection. + */ +#define INTEL_FAM6_HASWELL_X 0x3F +#define INTEL_FAM6_BROADWELL_X 0x4F +#define INTEL_FAM6_SKYLAKE_X 0x55 +#define INTEL_FAM6_SKYLAKE_XD 0x56 +#endif + +#define INTEL_FAM6 6 /* P6 (Pentium Pro and later) */ + +#define CORE_MAX_ON_HSX 18 /* Max number of cores on Haswell */ +#define CHAN_RANK_MAX_ON_HSX 8 /* Max number of channel ranks on Haswell */ +#define DIMM_IDX_MAX_ON_HSX 3 /* Max DIMM index per channel on Haswell */ + +#define CORE_MAX_ON_BDX 24 /* Max number of cores on Broadwell */ +#define CHAN_RANK_MAX_ON_BDX 4 /* Max number of channel ranks on Broadwell */ +#define DIMM_IDX_MAX_ON_BDX 3 /* Max DIMM index per channel on Broadwell */ + +#define CORE_MAX_ON_SKX 28 /* Max number of cores on Skylake */ +#define CHAN_RANK_MAX_ON_SKX 6 /* Max number of channel ranks on Skylake */ +#define DIMM_IDX_MAX_ON_SKX 2 /* Max DIMM index per channel on Skylake */ + +#define CORE_MAX_ON_SKXD 16 /* Max number of cores on Skylake D */ +#define CHAN_RANK_MAX_ON_SKXD 2 /* Max number of channel ranks on Skylake D */ +#define DIMM_IDX_MAX_ON_SKXD 2 /* Max DIMM index per channel on Skylake D */ + +#define CORE_NUMS_MAX CORE_MAX_ON_SKX +#define CHAN_RANK_MAX CHAN_RANK_MAX_ON_HSX +#define DIMM_IDX_MAX DIMM_IDX_MAX_ON_HSX +#define DIMM_NUMS_MAX (CHAN_RANK_MAX * DIMM_IDX_MAX) + +/** + * struct cpu_gen_info - CPU generation specific information + * @family: CPU family ID + * @model: CPU model + * @core_max: max number of cores + * @chan_rank_max: max number of channel ranks + * @dimm_idx_max: max number of DIMM indices + * + * CPU generation specific information to identify maximum number of cores and + * DIMM slots. + */ +struct cpu_gen_info { + u16 family; + u8 model; + uint core_max; + uint chan_rank_max; + uint dimm_idx_max; +}; + +/** + * struct peci_client_manager - PECI client manager information + * @client; pointer to the PECI client + * @name: PECI client manager name + * @gen_info: CPU generation info of the detected CPU + * + * PECI client manager information for managing PECI sideband functions on a CPU + * client. + */ +struct peci_client_manager { + struct peci_client *client; + char name[PECI_NAME_SIZE]; + const struct cpu_gen_info *gen_info; +}; + +/** + * peci_client_read_package_config - read from the Package Configuration Space + * @priv: driver private data structure + * @index: encoding index for the requested service + * @param: parameter to specify the exact data being requested + * @data: data buffer to store the result + * Context: can sleep + * + * A generic PECI command that provides read access to the + * "Package Configuration Space" that is maintained by the PCU, including + * various power and thermal management functions. Typical PCS read services + * supported by the processor may include access to temperature data, energy + * status, run time information, DIMM temperatures and so on. + * + * Return: zero on success, else a negative error code. + */ +static inline int +peci_client_read_package_config(struct peci_client_manager *priv, + u8 index, u16 param, u8 *data) +{ + struct peci_rd_pkg_cfg_msg msg; + int ret; + + msg.addr = priv->client->addr; + msg.index = index; + msg.param = param; + msg.rx_len = 4; + + ret = peci_command(priv->client->adapter, PECI_CMD_RD_PKG_CFG, &msg); + if (msg.cc != PECI_DEV_CC_SUCCESS) + ret = -EAGAIN; + if (ret) + return ret; + + memcpy(data, msg.pkg_config, 4); + + return 0; +} + +#endif /* __LINUX_MFD_INTEL_PECI_CLIENT_H */ diff --git a/include/linux/peci.h b/include/linux/peci.h new file mode 100644 index 000000000000..4bc4595c797d --- /dev/null +++ b/include/linux/peci.h @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2018-2019 Intel Corporation */ + +#ifndef __LINUX_PECI_H +#define __LINUX_PECI_H + +#include <linux/device.h> +#include <linux/mutex.h> +#include <linux/peci-ioctl.h> + +#define PECI_NAME_SIZE 32 + +struct peci_board_info { + char type[PECI_NAME_SIZE]; + u8 addr; /* CPU client address */ + struct device_node *of_node; +}; + +/** + * struct peci_adapter - represent a PECI adapter + * @owner: owner module of the PECI adpater + * @bus_lock: mutex for exclusion of multiple callers + * @dev: device interface to this driver + * @nr: the bus number to map + * @name: name of the adapter + * @userspace_clients_lock: mutex for exclusion of clients handling + * @userspace_clients: list of registered clients + * @xfer: low-level transfer function pointer of the adapter + * @cmd_mask: mask for supportable PECI commands + * @use_dma: flag for indicating that adapter uses DMA + * + * Each PECI adapter can communicate with one or more PECI client children. + * These make a small bus, sharing a single wired PECI connection. + */ +struct peci_adapter { + struct module *owner; + struct mutex bus_lock; /* mutex for bus locking */ + struct device dev; + int nr; + char name[PECI_NAME_SIZE]; + struct mutex userspace_clients_lock; /* clients list mutex */ + struct list_head userspace_clients; + int (*xfer)(struct peci_adapter *adapter, + struct peci_xfer_msg *msg); + u32 cmd_mask; + bool use_dma; +}; + +static inline struct peci_adapter *to_peci_adapter(void *d) +{ + return container_of(d, struct peci_adapter, dev); +} + +static inline void *peci_get_adapdata(const struct peci_adapter *adapter) +{ + return dev_get_drvdata(&adapter->dev); +} + +static inline void peci_set_adapdata(struct peci_adapter *adapter, void *data) +{ + dev_set_drvdata(&adapter->dev, data); +} + +/** + * struct peci_client - represent a PECI client device + * @dev: driver model device node for the client + * @adapter: manages the bus segment hosting this PECI device + * @addr: address used on the PECI bus connected to the parent adapter + * @name: indicates the type of the device + * @detected: detected PECI clients list + * + * A peci_client identifies a single device (i.e. CPU) connected to a peci bus. + * The behaviour exposed to Linux is defined by the driver managing the device. + */ +struct peci_client { + struct device dev; + struct peci_adapter *adapter; + u8 addr; + char name[PECI_NAME_SIZE]; + struct list_head detected; +}; + +static inline struct peci_client *to_peci_client(void *d) +{ + return container_of(d, struct peci_client, dev); +} + +struct peci_device_id { + char name[PECI_NAME_SIZE]; + ulong driver_data; /* Data private to the driver */ +}; + +/** + * struct peci_driver - represent a PECI device driver + * @probe: callback for device binding + * @remove: callback for device unbinding + * @shutdown: callback for device shutdown + * @driver: device driver model driver + * @id_table: list of PECI devices supported by this driver + * + * The driver.owner field should be set to the module owner of this driver. + * The driver.name field should be set to the name of this driver. + */ +struct peci_driver { + int (*probe)(struct peci_client *client); + int (*remove)(struct peci_client *client); + void (*shutdown)(struct peci_client *client); + struct device_driver driver; + const struct peci_device_id *id_table; +}; + +static inline struct peci_driver *to_peci_driver(void *d) +{ + return container_of(d, struct peci_driver, driver); +} + +/** + * module_peci_driver - Helper macro for registering a modular PECI driver + * @__peci_driver: peci_driver struct + * + * Helper macro for PECI drivers which do not do anything special in module + * init/exit. This eliminates a lot of boilerplate. Each module may only + * use this macro once, and calling it replaces module_init() and module_exit() + */ +#define module_peci_driver(__peci_driver) \ + module_driver(__peci_driver, peci_add_driver, peci_del_driver) + +/* use a define to avoid include chaining to get THIS_MODULE */ +#define peci_add_driver(driver) peci_register_driver(THIS_MODULE, driver) + +extern struct bus_type peci_bus_type; +extern struct device_type peci_adapter_type; +extern struct device_type peci_client_type; + +int peci_register_driver(struct module *owner, struct peci_driver *drv); +void peci_del_driver(struct peci_driver *driver); +struct peci_client *peci_verify_client(struct device *dev); +struct peci_adapter *peci_alloc_adapter(struct device *dev, uint size); +struct peci_adapter *peci_get_adapter(int nr); +void peci_put_adapter(struct peci_adapter *adapter); +int peci_add_adapter(struct peci_adapter *adapter); +void peci_del_adapter(struct peci_adapter *adapter); +struct peci_adapter *peci_verify_adapter(struct device *dev); +int peci_for_each_dev(void *data, int (*fn)(struct device *, void *)); +struct peci_xfer_msg *peci_get_xfer_msg(u8 tx_len, u8 rx_len); +void peci_put_xfer_msg(struct peci_xfer_msg *msg); +int peci_command(struct peci_adapter *adpater, enum peci_cmd cmd, void *vmsg); +int peci_get_cpu_id(struct peci_adapter *adapter, u8 addr, u32 *cpu_id); + +#endif /* __LINUX_PECI_H */ diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 53c0ea9ec9df..1ce90b121fa5 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -21,6 +21,7 @@ #include <linux/acpi.h> #include <linux/cdev.h> #include <linux/fs.h> +#include <linux/highmem.h> #include <crypto/hash_info.h> #define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */ @@ -161,6 +162,218 @@ struct tpm_chip { int locality; }; +#define TPM_HEADER_SIZE 10 + +enum tpm2_const { + TPM2_PLATFORM_PCR = 24, + TPM2_PCR_SELECT_MIN = ((TPM2_PLATFORM_PCR + 7) / 8), +}; + +enum tpm2_timeouts { + TPM2_TIMEOUT_A = 750, + TPM2_TIMEOUT_B = 2000, + TPM2_TIMEOUT_C = 200, + TPM2_TIMEOUT_D = 30, + TPM2_DURATION_SHORT = 20, + TPM2_DURATION_MEDIUM = 750, + TPM2_DURATION_LONG = 2000, + TPM2_DURATION_LONG_LONG = 300000, + TPM2_DURATION_DEFAULT = 120000, +}; + +enum tpm2_structures { + TPM2_ST_NO_SESSIONS = 0x8001, + TPM2_ST_SESSIONS = 0x8002, +}; + +/* Indicates from what layer of the software stack the error comes from */ +#define TSS2_RC_LAYER_SHIFT 16 +#define TSS2_RESMGR_TPM_RC_LAYER (11 << TSS2_RC_LAYER_SHIFT) + +enum tpm2_return_codes { + TPM2_RC_SUCCESS = 0x0000, + TPM2_RC_HASH = 0x0083, /* RC_FMT1 */ + TPM2_RC_HANDLE = 0x008B, + TPM2_RC_INITIALIZE = 0x0100, /* RC_VER1 */ + TPM2_RC_FAILURE = 0x0101, + TPM2_RC_DISABLED = 0x0120, + TPM2_RC_UPGRADE = 0x012D, + TPM2_RC_COMMAND_CODE = 0x0143, + TPM2_RC_TESTING = 0x090A, /* RC_WARN */ + TPM2_RC_REFERENCE_H0 = 0x0910, + TPM2_RC_RETRY = 0x0922, +}; + +enum tpm2_command_codes { + TPM2_CC_FIRST = 0x011F, + TPM2_CC_HIERARCHY_CONTROL = 0x0121, + TPM2_CC_HIERARCHY_CHANGE_AUTH = 0x0129, + TPM2_CC_CREATE_PRIMARY = 0x0131, + TPM2_CC_SEQUENCE_COMPLETE = 0x013E, + TPM2_CC_SELF_TEST = 0x0143, + TPM2_CC_STARTUP = 0x0144, + TPM2_CC_SHUTDOWN = 0x0145, + TPM2_CC_NV_READ = 0x014E, + TPM2_CC_CREATE = 0x0153, + TPM2_CC_LOAD = 0x0157, + TPM2_CC_SEQUENCE_UPDATE = 0x015C, + TPM2_CC_UNSEAL = 0x015E, + TPM2_CC_CONTEXT_LOAD = 0x0161, + TPM2_CC_CONTEXT_SAVE = 0x0162, + TPM2_CC_FLUSH_CONTEXT = 0x0165, + TPM2_CC_VERIFY_SIGNATURE = 0x0177, + TPM2_CC_GET_CAPABILITY = 0x017A, + TPM2_CC_GET_RANDOM = 0x017B, + TPM2_CC_PCR_READ = 0x017E, + TPM2_CC_PCR_EXTEND = 0x0182, + TPM2_CC_EVENT_SEQUENCE_COMPLETE = 0x0185, + TPM2_CC_HASH_SEQUENCE_START = 0x0186, + TPM2_CC_CREATE_LOADED = 0x0191, + TPM2_CC_LAST = 0x0193, /* Spec 1.36 */ +}; + +enum tpm2_permanent_handles { + TPM2_RS_PW = 0x40000009, +}; + +enum tpm2_capabilities { + TPM2_CAP_HANDLES = 1, + TPM2_CAP_COMMANDS = 2, + TPM2_CAP_PCRS = 5, + TPM2_CAP_TPM_PROPERTIES = 6, +}; + +enum tpm2_properties { + TPM_PT_TOTAL_COMMANDS = 0x0129, +}; + +enum tpm2_startup_types { + TPM2_SU_CLEAR = 0x0000, + TPM2_SU_STATE = 0x0001, +}; + +enum tpm2_cc_attrs { + TPM2_CC_ATTR_CHANDLES = 25, + TPM2_CC_ATTR_RHANDLE = 28, +}; + +#define TPM_VID_INTEL 0x8086 +#define TPM_VID_WINBOND 0x1050 +#define TPM_VID_STM 0x104A + +enum tpm_chip_flags { + TPM_CHIP_FLAG_TPM2 = BIT(1), + TPM_CHIP_FLAG_IRQ = BIT(2), + TPM_CHIP_FLAG_VIRTUAL = BIT(3), + TPM_CHIP_FLAG_HAVE_TIMEOUTS = BIT(4), + TPM_CHIP_FLAG_ALWAYS_POWERED = BIT(5), + TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED = BIT(6), +}; + +#define to_tpm_chip(d) container_of(d, struct tpm_chip, dev) + +struct tpm_header { + __be16 tag; + __be32 length; + union { + __be32 ordinal; + __be32 return_code; + }; +} __packed; + +/* A string buffer type for constructing TPM commands. This is based on the + * ideas of string buffer code in security/keys/trusted.h but is heap based + * in order to keep the stack usage minimal. + */ + +enum tpm_buf_flags { + TPM_BUF_OVERFLOW = BIT(0), +}; + +struct tpm_buf { + unsigned int flags; + u8 *data; +}; + +static inline void tpm_buf_reset(struct tpm_buf *buf, u16 tag, u32 ordinal) +{ + struct tpm_header *head = (struct tpm_header *)buf->data; + + head->tag = cpu_to_be16(tag); + head->length = cpu_to_be32(sizeof(*head)); + head->ordinal = cpu_to_be32(ordinal); +} + +static inline int tpm_buf_init(struct tpm_buf *buf, u16 tag, u32 ordinal) +{ + buf->data = (u8 *)__get_free_page(GFP_KERNEL); + if (!buf->data) + return -ENOMEM; + + buf->flags = 0; + tpm_buf_reset(buf, tag, ordinal); + return 0; +} + +static inline void tpm_buf_destroy(struct tpm_buf *buf) +{ + free_page((unsigned long)buf->data); +} + +static inline u32 tpm_buf_length(struct tpm_buf *buf) +{ + struct tpm_header *head = (struct tpm_header *)buf->data; + + return be32_to_cpu(head->length); +} + +static inline u16 tpm_buf_tag(struct tpm_buf *buf) +{ + struct tpm_header *head = (struct tpm_header *)buf->data; + + return be16_to_cpu(head->tag); +} + +static inline void tpm_buf_append(struct tpm_buf *buf, + const unsigned char *new_data, + unsigned int new_len) +{ + struct tpm_header *head = (struct tpm_header *)buf->data; + u32 len = tpm_buf_length(buf); + + /* Return silently if overflow has already happened. */ + if (buf->flags & TPM_BUF_OVERFLOW) + return; + + if ((len + new_len) > PAGE_SIZE) { + WARN(1, "tpm_buf: overflow\n"); + buf->flags |= TPM_BUF_OVERFLOW; + return; + } + + memcpy(&buf->data[len], new_data, new_len); + head->length = cpu_to_be32(len + new_len); +} + +static inline void tpm_buf_append_u8(struct tpm_buf *buf, const u8 value) +{ + tpm_buf_append(buf, &value, 1); +} + +static inline void tpm_buf_append_u16(struct tpm_buf *buf, const u16 value) +{ + __be16 value2 = cpu_to_be16(value); + + tpm_buf_append(buf, (u8 *) &value2, 2); +} + +static inline void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value) +{ + __be32 value2 = cpu_to_be32(value); + + tpm_buf_append(buf, (u8 *) &value2, 4); +} + #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE) extern int tpm_is_tpm2(struct tpm_chip *chip); diff --git a/include/trace/events/fsi.h b/include/trace/events/fsi.h index 92e5e89e52ed..9832cb8e0eb0 100644 --- a/include/trace/events/fsi.h +++ b/include/trace/events/fsi.h @@ -26,7 +26,7 @@ TRACE_EVENT(fsi_master_read, __entry->addr = addr; __entry->size = size; ), - TP_printk("fsi%d:%02d:%02d %08x[%zd]", + TP_printk("fsi%d:%02d:%02d %08x[%zu]", __entry->master_idx, __entry->link, __entry->id, @@ -56,7 +56,7 @@ TRACE_EVENT(fsi_master_write, __entry->data = 0; memcpy(&__entry->data, data, size); ), - TP_printk("fsi%d:%02d:%02d %08x[%zd] <= {%*ph}", + TP_printk("fsi%d:%02d:%02d %08x[%zu] <= {%*ph}", __entry->master_idx, __entry->link, __entry->id, @@ -93,7 +93,7 @@ TRACE_EVENT(fsi_master_rw_result, if (__entry->write || !__entry->ret) memcpy(&__entry->data, data, size); ), - TP_printk("fsi%d:%02d:%02d %08x[%zd] %s {%*ph} ret %d", + TP_printk("fsi%d:%02d:%02d %08x[%zu] %s {%*ph} ret %d", __entry->master_idx, __entry->link, __entry->id, diff --git a/include/trace/events/fsi_master_aspeed.h b/include/trace/events/fsi_master_aspeed.h new file mode 100644 index 000000000000..a355ceacc33f --- /dev/null +++ b/include/trace/events/fsi_master_aspeed.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM fsi_master_aspeed + +#if !defined(_TRACE_FSI_MASTER_ASPEED_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_FSI_MASTER_ASPEED_H + +#include <linux/tracepoint.h> + +TRACE_EVENT(fsi_master_aspeed_opb_read, + TP_PROTO(uint32_t addr, size_t size, uint32_t result, uint32_t status, uint32_t irq_status), + TP_ARGS(addr, size, result, status, irq_status), + TP_STRUCT__entry( + __field(uint32_t, addr) + __field(size_t, size) + __field(uint32_t, result) + __field(uint32_t, status) + __field(uint32_t, irq_status) + ), + TP_fast_assign( + __entry->addr = addr; + __entry->size = size; + __entry->result = result; + __entry->status = status; + __entry->irq_status = irq_status; + ), + TP_printk("addr %08x size %zu: result %08x sts: %08x irq_sts: %08x", + __entry->addr, __entry->size, __entry->result, + __entry->status, __entry->irq_status + ) +); + +TRACE_EVENT(fsi_master_aspeed_opb_write, + TP_PROTO(uint32_t addr, uint32_t val, size_t size, uint32_t status, uint32_t irq_status), + TP_ARGS(addr, val, size, status, irq_status), + TP_STRUCT__entry( + __field(uint32_t, addr) + __field(uint32_t, val) + __field(size_t, size) + __field(uint32_t, status) + __field(uint32_t, irq_status) + ), + TP_fast_assign( + __entry->addr = addr; + __entry->val = val; + __entry->size = size; + __entry->status = status; + __entry->irq_status = irq_status; + ), + TP_printk("addr %08x val %08x size %zu status: %08x irq_sts: %08x", + __entry->addr, __entry->val, __entry->size, + __entry->status, __entry->irq_status + ) + ); + +TRACE_EVENT(fsi_master_aspeed_opb_error, + TP_PROTO(uint32_t mresp0, uint32_t mstap0, uint32_t mesrb0), + TP_ARGS(mresp0, mstap0, mesrb0), + TP_STRUCT__entry( + __field(uint32_t, mresp0) + __field(uint32_t, mstap0) + __field(uint32_t, mesrb0) + ), + TP_fast_assign( + __entry->mresp0 = mresp0; + __entry->mstap0 = mstap0; + __entry->mesrb0 = mesrb0; + ), + TP_printk("mresp0 %08x mstap0 %08x mesrb0 %08x", + __entry->mresp0, __entry->mstap0, __entry->mesrb0 + ) + ); + +#endif + +#include <trace/define_trace.h> diff --git a/include/uapi/linux/aspeed-xdma.h b/include/uapi/linux/aspeed-xdma.h new file mode 100644 index 000000000000..3a3646fd1e9e --- /dev/null +++ b/include/uapi/linux/aspeed-xdma.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* Copyright IBM Corp 2019 */ + +#ifndef _UAPI_LINUX_ASPEED_XDMA_H_ +#define _UAPI_LINUX_ASPEED_XDMA_H_ + +#include <linux/ioctl.h> +#include <linux/types.h> + +#define __ASPEED_XDMA_IOCTL_MAGIC 0xb7 +#define ASPEED_XDMA_IOCTL_RESET _IO(__ASPEED_XDMA_IOCTL_MAGIC, 0) + +/* + * aspeed_xdma_direction + * + * ASPEED_XDMA_DIRECTION_DOWNSTREAM: transfers data from the host to the BMC + * + * ASPEED_XDMA_DIRECTION_UPSTREAM: transfers data from the BMC to the host + */ +enum aspeed_xdma_direction { + ASPEED_XDMA_DIRECTION_DOWNSTREAM = 0, + ASPEED_XDMA_DIRECTION_UPSTREAM, +}; + +/* + * aspeed_xdma_op + * + * host_addr: the DMA address on the host side, typically configured by PCI + * subsystem + * + * len: the size of the transfer in bytes + * + * direction: an enumerator indicating the direction of the DMA operation; see + * enum aspeed_xdma_direction + */ +struct aspeed_xdma_op { + __u64 host_addr; + __u32 len; + __u32 direction; +}; + +#endif /* _UAPI_LINUX_ASPEED_XDMA_H_ */ diff --git a/include/uapi/linux/peci-ioctl.h b/include/uapi/linux/peci-ioctl.h new file mode 100644 index 000000000000..c74b3cde52e8 --- /dev/null +++ b/include/uapi/linux/peci-ioctl.h @@ -0,0 +1,661 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* Copyright (c) 2018-2020 Intel Corporation */ + +#ifndef __PECI_IOCTL_H +#define __PECI_IOCTL_H + +#include <linux/ioctl.h> +#include <linux/types.h> + +/* The PECI client's default address of 0x30 */ +#define PECI_BASE_ADDR 0x30 + +/* Max number of CPU clients */ +#define PECI_OFFSET_MAX 8 + +/* PECI read/write data buffer size max */ +#define PECI_BUFFER_SIZE 255 + +/* Device Specific Completion Code (CC) Definition */ +#define PECI_DEV_CC_SUCCESS 0x40 +#define PECI_DEV_CC_NEED_RETRY 0x80 +#define PECI_DEV_CC_OUT_OF_RESOURCE 0x81 +#define PECI_DEV_CC_UNAVAIL_RESOURCE 0x82 +#define PECI_DEV_CC_INVALID_REQ 0x90 +#define PECI_DEV_CC_MCA_ERROR 0x91 +#define PECI_DEV_CC_CATASTROPHIC_MCA_ERROR 0x93 +#define PECI_DEV_CC_FATAL_MCA_DETECTED 0x94 +#define PECI_DEV_CC_PARITY_ERROR_ON_GPSB_OR_PMSB 0x98 +#define PECI_DEV_CC_PARITY_ERROR_ON_GPSB_OR_PMSB_IERR 0x9B +#define PECI_DEV_CC_PARITY_ERROR_ON_GPSB_OR_PMSB_MCA 0x9C + +/* Completion Code mask to check retry needs */ +#define PECI_DEV_CC_RETRY_CHECK_MASK 0xf0 + +#define PECI_DEV_RETRY_TIMEOUT msecs_to_jiffies(700) +#define PECI_DEV_RETRY_INTERVAL_MIN_MSEC 1 +#define PECI_DEV_RETRY_INTERVAL_MAX_MSEC 128 +#define PECI_DEV_RETRY_BIT 0x01 + +/** + * enum peci_cmd - PECI client commands + * @PECI_CMD_XFER: raw PECI transfer + * @PECI_CMD_PING: ping, a required message for all PECI devices + * @PECI_CMD_GET_DIB: get DIB (Device Info Byte) + * @PECI_CMD_GET_TEMP: get maximum die temperature + * @PECI_CMD_RD_PKG_CFG: read access to the PCS (Package Configuration Space) + * @PECI_CMD_WR_PKG_CFG: write access to the PCS (Package Configuration Space) + * @PECI_CMD_RD_IA_MSR: read access to MSRs (Model Specific Registers) + * @PECI_CMD_WR_IA_MSR: write access to MSRs (Model Specific Registers) + * @PECI_CMD_RD_IA_MSREX: read access to MSRs (Model Specific Registers) + * @PECI_CMD_RD_PCI_CFG: sideband read access to the PCI configuration space + * maintained in downstream devices external to the processor + * @PECI_CMD_WR_PCI_CFG: sideband write access to the PCI configuration space + * maintained in downstream devices external to the processor + * @PECI_CMD_RD_PCI_CFG_LOCAL: sideband read access to the PCI configuration + * space that resides within the processor + * @PECI_CMD_WR_PCI_CFG_LOCAL: sideband write access to the PCI configuration + * space that resides within the processor + * + * Available commands depend on client's PECI revision. + */ +enum peci_cmd { + PECI_CMD_XFER = 0, + PECI_CMD_PING, + PECI_CMD_GET_DIB, + PECI_CMD_GET_TEMP, + PECI_CMD_RD_PKG_CFG, + PECI_CMD_WR_PKG_CFG, + PECI_CMD_RD_IA_MSR, + PECI_CMD_WR_IA_MSR, + PECI_CMD_RD_IA_MSREX, + PECI_CMD_RD_PCI_CFG, + PECI_CMD_WR_PCI_CFG, + PECI_CMD_RD_PCI_CFG_LOCAL, + PECI_CMD_WR_PCI_CFG_LOCAL, + PECI_CMD_RD_END_PT_CFG, + PECI_CMD_WR_END_PT_CFG, + PECI_CMD_CRASHDUMP_DISC, + PECI_CMD_CRASHDUMP_GET_FRAME, + PECI_CMD_MAX +}; + +/** + * struct peci_xfer_msg - raw PECI transfer command + * @addr; address of the client + * @tx_len: number of data to be written in bytes + * @rx_len: number of data to be read in bytes + * @tx_buf: data to be written, or NULL + * @rx_buf: data to be read, or NULL + * + * raw PECI transfer + */ +struct peci_xfer_msg { + __u8 addr; + __u8 tx_len; + __u8 rx_len; + __u8 padding; + __u8 *tx_buf; + __u8 *rx_buf; +} __attribute__((__packed__)); + +/** + * struct peci_ping_msg - ping command + * @addr: address of the client + * + * Ping() is a required message for all PECI devices. This message is used to + * enumerate devices or determine if a device has been removed, been + * powered-off, etc. + */ +struct peci_ping_msg { + __u8 addr; + __u8 padding[3]; +} __attribute__((__packed__)); + +/** + * struct peci_get_dib_msg - GetDIB command + * @addr: address of the client + * @dib: DIB data to be read + * + * The processor PECI client implementation of GetDIB() includes an 8-byte + * response and provides information regarding client revision number and the + * number of supported domains. All processor PECI clients support the GetDIB() + * command. + */ +struct peci_get_dib_msg { +#define PECI_GET_DIB_WR_LEN 1 +#define PECI_GET_DIB_RD_LEN 8 +#define PECI_GET_DIB_CMD 0xf7 + + __u8 addr; + __u8 padding[3]; + __u64 dib; +} __attribute__((__packed__)); + +/** + * struct peci_get_temp_msg - GetTemp command + * @addr: address of the client + * @temp_raw: raw temperature data to be read + * + * The GetTemp() command is used to retrieve the maximum die temperature from a + * target PECI address. The temperature is used by the external thermal + * management system to regulate the temperature on the die. The data is + * returned as a negative value representing the number of degrees centigrade + * below the maximum processor junction temperature. + */ +struct peci_get_temp_msg { +#define PECI_GET_TEMP_WR_LEN 1 +#define PECI_GET_TEMP_RD_LEN 2 +#define PECI_GET_TEMP_CMD 0x01 + + __u8 addr; + __u8 padding; + __s16 temp_raw; +} __attribute__((__packed__)); + +/** + * struct peci_rd_pkg_cfg_msg - RdPkgConfig command + * @addr: address of the client + * @index: encoding index for the requested service + * @param: specific data being requested + * @rx_len: number of data to be read in bytes + * @cc: completion code + * @pkg_config: package config data to be read + * + * The RdPkgConfig() command provides read access to the Package Configuration + * Space (PCS) within the processor, including various power and thermal + * management functions. Typical PCS read services supported by the processor + * may include access to temperature data, energy status, run time information, + * DIMM temperatures and so on. + */ +struct peci_rd_pkg_cfg_msg { +#define PECI_RDPKGCFG_WRITE_LEN 5 +#define PECI_RDPKGCFG_READ_LEN_BASE 1 +#define PECI_RDPKGCFG_CMD 0xa1 + + __u8 addr; + __u8 index; +#define PECI_MBX_INDEX_CPU_ID 0 /* Package Identifier Read */ +#define PECI_MBX_INDEX_VR_DEBUG 1 /* VR Debug */ +#define PECI_MBX_INDEX_PKG_TEMP_READ 2 /* Package Temperature Read */ +#define PECI_MBX_INDEX_ENERGY_COUNTER 3 /* Energy counter */ +#define PECI_MBX_INDEX_ENERGY_STATUS 4 /* DDR Energy Status */ +#define PECI_MBX_INDEX_WAKE_MODE_BIT 5 /* "Wake on PECI" Mode bit */ +#define PECI_MBX_INDEX_EPI 6 /* Efficient Performance Indication */ +#define PECI_MBX_INDEX_PKG_RAPL_PERF 8 /* Pkg RAPL Performance Status Read */ +#define PECI_MBX_INDEX_PER_CORE_DTS_TEMP 9 /* Per Core DTS Temperature Read */ +#define PECI_MBX_INDEX_DTS_MARGIN 10 /* DTS thermal margin */ +#define PECI_MBX_INDEX_SKT_PWR_THRTL_DUR 11 /* Socket Power Throttled Duration */ +#define PECI_MBX_INDEX_CFG_TDP_CONTROL 12 /* TDP Config Control */ +#define PECI_MBX_INDEX_CFG_TDP_LEVELS 13 /* TDP Config Levels */ +#define PECI_MBX_INDEX_DDR_DIMM_TEMP 14 /* DDR DIMM Temperature */ +#define PECI_MBX_INDEX_CFG_ICCMAX 15 /* Configurable ICCMAX */ +#define PECI_MBX_INDEX_TEMP_TARGET 16 /* Temperature Target Read */ +#define PECI_MBX_INDEX_CURR_CFG_LIMIT 17 /* Current Config Limit */ +#define PECI_MBX_INDEX_DIMM_TEMP_READ 20 /* Package Thermal Status Read */ +#define PECI_MBX_INDEX_DRAM_IMC_TMP_READ 22 /* DRAM IMC Temperature Read */ +#define PECI_MBX_INDEX_DDR_CH_THERM_STAT 23 /* DDR Channel Thermal Status */ +#define PECI_MBX_INDEX_PKG_POWER_LIMIT1 26 /* Package Power Limit1 */ +#define PECI_MBX_INDEX_PKG_POWER_LIMIT2 27 /* Package Power Limit2 */ +#define PECI_MBX_INDEX_TDP 28 /* Thermal design power minimum */ +#define PECI_MBX_INDEX_TDP_HIGH 29 /* Thermal design power maximum */ +#define PECI_MBX_INDEX_TDP_UNITS 30 /* Units for power/energy registers */ +#define PECI_MBX_INDEX_RUN_TIME 31 /* Accumulated Run Time */ +#define PECI_MBX_INDEX_CONSTRAINED_TIME 32 /* Thermally Constrained Time Read */ +#define PECI_MBX_INDEX_TURBO_RATIO 33 /* Turbo Activation Ratio */ +#define PECI_MBX_INDEX_DDR_RAPL_PL1 34 /* DDR RAPL PL1 */ +#define PECI_MBX_INDEX_DDR_PWR_INFO_HIGH 35 /* DRAM Power Info Read (high) */ +#define PECI_MBX_INDEX_DDR_PWR_INFO_LOW 36 /* DRAM Power Info Read (low) */ +#define PECI_MBX_INDEX_DDR_RAPL_PL2 37 /* DDR RAPL PL2 */ +#define PECI_MBX_INDEX_DDR_RAPL_STATUS 38 /* DDR RAPL Performance Status */ +#define PECI_MBX_INDEX_DDR_HOT_ABSOLUTE 43 /* DDR Hottest Dimm Absolute Temp */ +#define PECI_MBX_INDEX_DDR_HOT_RELATIVE 44 /* DDR Hottest Dimm Relative Temp */ +#define PECI_MBX_INDEX_DDR_THROTTLE_TIME 45 /* DDR Throttle Time */ +#define PECI_MBX_INDEX_DDR_THERM_STATUS 46 /* DDR Thermal Status */ +#define PECI_MBX_INDEX_TIME_AVG_TEMP 47 /* Package time-averaged temperature */ +#define PECI_MBX_INDEX_TURBO_RATIO_LIMIT 49 /* Turbo Ratio Limit Read */ +#define PECI_MBX_INDEX_HWP_AUTO_OOB 53 /* HWP Autonomous Out-of-band */ +#define PECI_MBX_INDEX_DDR_WARM_BUDGET 55 /* DDR Warm Power Budget */ +#define PECI_MBX_INDEX_DDR_HOT_BUDGET 56 /* DDR Hot Power Budget */ +#define PECI_MBX_INDEX_PKG_PSYS_PWR_LIM3 57 /* Package/Psys Power Limit3 */ +#define PECI_MBX_INDEX_PKG_PSYS_PWR_LIM1 58 /* Package/Psys Power Limit1 */ +#define PECI_MBX_INDEX_PKG_PSYS_PWR_LIM2 59 /* Package/Psys Power Limit2 */ +#define PECI_MBX_INDEX_PKG_PSYS_PWR_LIM4 60 /* Package/Psys Power Limit4 */ +#define PECI_MBX_INDEX_PERF_LIMIT_REASON 65 /* Performance Limit Reasons */ + + __u16 param; +/* When index is PECI_MBX_INDEX_CPU_ID */ +#define PECI_PKG_ID_CPU_ID 0x0000 /* CPUID Info */ +#define PECI_PKG_ID_PLATFORM_ID 0x0001 /* Platform ID */ +#define PECI_PKG_ID_UNCORE_ID 0x0002 /* Uncore Device ID */ +#define PECI_PKG_ID_MAX_THREAD_ID 0x0003 /* Max Thread ID */ +#define PECI_PKG_ID_MICROCODE_REV 0x0004 /* CPU Microcode Update Revision */ +#define PECI_PKG_ID_MACHINE_CHECK_STATUS 0x0005 /* Machine Check Status */ + + __u8 rx_len; + __u8 cc; + __u8 padding[2]; + __u8 pkg_config[4]; +} __attribute__((__packed__)); + +/** + * struct peci_wr_pkg_cfg_msg - WrPkgConfig command + * @addr: address of the client + * @index: encoding index for the requested service + * @param: specific data being requested + * @tx_len: number of data to be written in bytes + * @cc: completion code + * @value: package config data to be written + * + * The WrPkgConfig() command provides write access to the Package Configuration + * Space (PCS) within the processor, including various power and thermal + * management functions. Typical PCS write services supported by the processor + * may include power limiting, thermal averaging constant programming and so + * on. + */ +struct peci_wr_pkg_cfg_msg { +#define PECI_WRPKGCFG_WRITE_LEN_BASE 6 +#define PECI_WRPKGCFG_READ_LEN 1 +#define PECI_WRPKGCFG_CMD 0xa5 + + __u8 addr; + __u8 index; +#define PECI_MBX_INDEX_DIMM_AMBIENT 19 +#define PECI_MBX_INDEX_DIMM_TEMP 24 + + __u16 param; + __u8 tx_len; + __u8 cc; + __u8 padding[2]; + __u32 value; +} __attribute__((__packed__)); + +/** + * struct peci_rd_ia_msr_msg - RdIAMSR command + * @addr: address of the client + * @thread_id: ID of the specific logical processor + * @address: address of MSR to read from + * @cc: completion code + * @value: data to be read + * + * The RdIAMSR() PECI command provides read access to Model Specific Registers + * (MSRs) defined in the processor's Intel Architecture (IA). + */ +struct peci_rd_ia_msr_msg { +#define PECI_RDIAMSR_WRITE_LEN 5 +#define PECI_RDIAMSR_READ_LEN 9 +#define PECI_RDIAMSR_CMD 0xb1 + + __u8 addr; + __u8 thread_id; + __u16 address; + __u8 cc; + __u8 padding[3]; + __u64 value; +} __attribute__((__packed__)); + +/** + * struct peci_wr_ia_msr_msg - WrIAMSR command + * @addr: address of the client + * @thread_id: ID of the specific logical processor + * @address: address of MSR to write to + * @tx_len: number of data to be written in bytes + * @cc: completion code + * @value: data to be written + * + * The WrIAMSR() PECI command provides write access to Model Specific Registers + * (MSRs) defined in the processor's Intel Architecture (IA). + */ +struct peci_wr_ia_msr_msg { +#define PECI_WRIAMSR_CMD 0xb5 + + __u8 addr; + __u8 thread_id; + __u16 address; + __u8 tx_len; + __u8 cc; + __u8 padding[2]; + __u64 value; +} __attribute__((__packed__)); + +/** + * struct peci_rd_ia_msrex_msg - RdIAMSREX command + * @addr: address of the client + * @thread_id: ID of the specific logical processor + * @address: address of MSR to read from + * @cc: completion code + * @value: data to be read + * + * The RdIAMSREX() PECI command provides read access to Model Specific + * Registers (MSRs) defined in the processor's Intel Architecture (IA). + * The differences between RdIAMSREX() and RdIAMSR() are that: + * (1)RdIAMSR() can only read MC registers, RdIAMSREX() can read all MSRs + * (2)thread_id of RdIAMSR() is u8, thread_id of RdIAMSREX() is u16 + */ +struct peci_rd_ia_msrex_msg { +#define PECI_RDIAMSREX_WRITE_LEN 6 +#define PECI_RDIAMSREX_READ_LEN 9 +#define PECI_RDIAMSREX_CMD 0xd1 + + __u8 addr; + __u8 padding0; + __u16 thread_id; + __u16 address; + __u8 cc; + __u8 padding1; + __u64 value; +} __attribute__((__packed__)); + +/** + * struct peci_rd_pci_cfg_msg - RdPCIConfig command + * @addr: address of the client + * @bus: PCI bus number + * @device: PCI device number + * @function: specific function to read from + * @reg: specific register to read from + * @cc: completion code + * @pci_config: config data to be read + * + * The RdPCIConfig() command provides sideband read access to the PCI + * configuration space maintained in downstream devices external to the + * processor. + */ +struct peci_rd_pci_cfg_msg { +#define PECI_RDPCICFG_WRITE_LEN 6 +#define PECI_RDPCICFG_READ_LEN 5 +#define PECI_RDPCICFG_READ_LEN_MAX 24 +#define PECI_RDPCICFG_CMD 0x61 + + __u8 addr; + __u8 bus; +#define PECI_PCI_BUS0_CPU0 0x00 +#define PECI_PCI_BUS0_CPU1 0x80 +#define PECI_PCI_CPUBUSNO_BUS 0x00 +#define PECI_PCI_CPUBUSNO_DEV 0x08 +#define PECI_PCI_CPUBUSNO_FUNC 0x02 +#define PECI_PCI_CPUBUSNO 0xcc +#define PECI_PCI_CPUBUSNO_1 0xd0 +#define PECI_PCI_CPUBUSNO_VALID 0xd4 + + __u8 device; + __u8 function; + __u16 reg; + __u8 cc; + __u8 padding[1]; + __u8 pci_config[4]; +} __attribute__((__packed__)); + +/** + * struct peci_wr_pci_cfg_msg - WrPCIConfig command + * @addr: address of the client + * @bus: PCI bus number + * @device: PCI device number + * @function: specific function to write to + * @reg: specific register to write to + * @tx_len: number of data to be written in bytes + * @cc: completion code + * @pci_config: config data to be written + * + * The RdPCIConfig() command provides sideband write access to the PCI + * configuration space maintained in downstream devices external to the + * processor. + */ +struct peci_wr_pci_cfg_msg { +#define PECI_WRPCICFG_CMD 0x65 + + __u8 addr; + __u8 bus; + __u8 device; + __u8 function; + __u16 reg; + __u8 tx_len; + __u8 cc; + __u8 pci_config[4]; +} __attribute__((__packed__)); + +/** + * struct peci_rd_pci_cfg_local_msg - RdPCIConfigLocal command + * @addr: address of the client + * @bus: PCI bus number + * @device: PCI device number + * @function: specific function to read from + * @reg: specific register to read from + * @rx_len: number of data to be read in bytes + * @cc: completion code + * @pci_config: config data to be read + * + * The RdPCIConfigLocal() command provides sideband read access to the PCI + * configuration space that resides within the processor. This includes all + * processor IIO and uncore registers within the PCI configuration space. + */ +struct peci_rd_pci_cfg_local_msg { +#define PECI_RDPCICFGLOCAL_WRITE_LEN 5 +#define PECI_RDPCICFGLOCAL_READ_LEN_BASE 1 +#define PECI_RDPCICFGLOCAL_CMD 0xe1 + + __u8 addr; + __u8 bus; + __u8 device; + __u8 function; + __u16 reg; + __u8 rx_len; + __u8 cc; + __u8 pci_config[4]; +} __attribute__((__packed__)); + +/** + * struct peci_wr_pci_cfg_local_msg - WrPCIConfigLocal command + * @addr: address of the client + * @bus: PCI bus number + * @device: PCI device number + * @function: specific function to read from + * @reg: specific register to read from + * @tx_len: number of data to be written in bytes + * @cc: completion code + * @value: config data to be written + * + * The WrPCIConfigLocal() command provides sideband write access to the PCI + * configuration space that resides within the processor. PECI originators can + * access this space even before BIOS enumeration of the system buses. + */ +struct peci_wr_pci_cfg_local_msg { +#define PECI_WRPCICFGLOCAL_WRITE_LEN_BASE 6 +#define PECI_WRPCICFGLOCAL_READ_LEN 1 +#define PECI_WRPCICFGLOCAL_CMD 0xe5 + + __u8 addr; + __u8 bus; + __u8 device; + __u8 function; + __u16 reg; + __u8 tx_len; + __u8 cc; + __u32 value; +} __attribute__((__packed__)); + +struct peci_rd_end_pt_cfg_msg { +#define PECI_RDENDPTCFG_PCI_WRITE_LEN 12 +#define PECI_RDENDPTCFG_MMIO_D_WRITE_LEN 14 +#define PECI_RDENDPTCFG_MMIO_Q_WRITE_LEN 18 +#define PECI_RDENDPTCFG_READ_LEN_BASE 1 +#define PECI_RDENDPTCFG_CMD 0xc1 + + __u8 addr; + __u8 msg_type; +#define PECI_ENDPTCFG_TYPE_LOCAL_PCI 0x03 +#define PECI_ENDPTCFG_TYPE_PCI 0x04 +#define PECI_ENDPTCFG_TYPE_MMIO 0x05 + + union { + struct { + __u8 seg; + __u8 bus; + __u8 device; + __u8 function; + __u16 reg; + } pci_cfg; + struct { + __u8 seg; + __u8 bus; + __u8 device; + __u8 function; + __u8 bar; + __u8 addr_type; +#define PECI_ENDPTCFG_ADDR_TYPE_PCI 0x04 +#define PECI_ENDPTCFG_ADDR_TYPE_MMIO_D 0x05 +#define PECI_ENDPTCFG_ADDR_TYPE_MMIO_Q 0x06 + + __u64 offset; + } mmio; + } params; + __u8 rx_len; + __u8 cc; + __u8 padding[2]; + __u8 data[8]; +} __attribute__((__packed__)); + +struct peci_wr_end_pt_cfg_msg { +#define PECI_WRENDPTCFG_PCI_WRITE_LEN_BASE 13 +#define PECI_WRENDPTCFG_MMIO_D_WRITE_LEN_BASE 15 +#define PECI_WRENDPTCFG_MMIO_Q_WRITE_LEN_BASE 19 +#define PECI_WRENDPTCFG_READ_LEN 1 +#define PECI_WRENDPTCFG_CMD 0xc5 + + __u8 addr; + __u8 msg_type; + /* See msg_type in struct peci_rd_end_pt_cfg_msg */ + + union { + struct { + __u8 seg; + __u8 bus; + __u8 device; + __u8 function; + __u16 reg; + } pci_cfg; + struct { + __u8 seg; + __u8 bus; + __u8 device; + __u8 function; + __u8 bar; + __u8 addr_type; + /* See addr_type in struct peci_rd_end_pt_cfg_msg */ + + __u64 offset; + } mmio; + } params; + __u8 tx_len; + __u8 cc; + __u8 padding[2]; + __u64 value; +} __attribute__((__packed__)); + +/* Crashdump Agent */ +#define PECI_CRASHDUMP_CORE 0x00 +#define PECI_CRASHDUMP_TOR 0x01 + +/* Crashdump Agent Param */ +#define PECI_CRASHDUMP_PAYLOAD_SIZE 0x00 + +/* Crashdump Agent Data Param */ +#define PECI_CRASHDUMP_AGENT_ID 0x00 +#define PECI_CRASHDUMP_AGENT_PARAM 0x01 + +struct peci_crashdump_disc_msg { + __u8 addr; + __u8 subopcode; +#define PECI_CRASHDUMP_ENABLED 0x00 +#define PECI_CRASHDUMP_NUM_AGENTS 0x01 +#define PECI_CRASHDUMP_AGENT_DATA 0x02 + + __u8 cc; + __u8 param0; + __u16 param1; + __u8 param2; + __u8 rx_len; + __u8 data[8]; +} __attribute__((__packed__)); + +struct peci_crashdump_get_frame_msg { +#define PECI_CRASHDUMP_DISC_WRITE_LEN 9 +#define PECI_CRASHDUMP_DISC_READ_LEN_BASE 1 +#define PECI_CRASHDUMP_DISC_VERSION 0 +#define PECI_CRASHDUMP_DISC_OPCODE 1 +#define PECI_CRASHDUMP_GET_FRAME_WRITE_LEN 10 +#define PECI_CRASHDUMP_GET_FRAME_READ_LEN_BASE 1 +#define PECI_CRASHDUMP_GET_FRAME_VERSION 0 +#define PECI_CRASHDUMP_GET_FRAME_OPCODE 3 +#define PECI_CRASHDUMP_CMD 0x71 + + __u8 addr; + __u8 padding0; + __u16 param0; + __u16 param1; + __u16 param2; + __u8 rx_len; + __u8 cc; + __u8 padding1[2]; + __u8 data[16]; +} __attribute__((__packed__)); + +#define PECI_IOC_BASE 0xb7 + +#define PECI_IOC_XFER \ + _IOWR(PECI_IOC_BASE, PECI_CMD_XFER, struct peci_xfer_msg) + +#define PECI_IOC_PING \ + _IOWR(PECI_IOC_BASE, PECI_CMD_PING, struct peci_ping_msg) + +#define PECI_IOC_GET_DIB \ + _IOWR(PECI_IOC_BASE, PECI_CMD_GET_DIB, struct peci_get_dib_msg) + +#define PECI_IOC_GET_TEMP \ + _IOWR(PECI_IOC_BASE, PECI_CMD_GET_TEMP, struct peci_get_temp_msg) + +#define PECI_IOC_RD_PKG_CFG \ + _IOWR(PECI_IOC_BASE, PECI_CMD_RD_PKG_CFG, struct peci_rd_pkg_cfg_msg) + +#define PECI_IOC_WR_PKG_CFG \ + _IOWR(PECI_IOC_BASE, PECI_CMD_WR_PKG_CFG, struct peci_wr_pkg_cfg_msg) + +#define PECI_IOC_RD_IA_MSR \ + _IOWR(PECI_IOC_BASE, PECI_CMD_RD_IA_MSR, struct peci_rd_ia_msr_msg) + +#define PECI_IOC_WR_IA_MSR \ + _IOWR(PECI_IOC_BASE, PECI_CMD_WR_IA_MSR, struct peci_wr_ia_msr_msg) + +#define PECI_IOC_RD_IA_MSREX \ + _IOWR(PECI_IOC_BASE, PECI_CMD_RD_IA_MSREX, struct peci_rd_ia_msrex_msg) + +#define PECI_IOC_RD_PCI_CFG \ + _IOWR(PECI_IOC_BASE, PECI_CMD_RD_PCI_CFG, struct peci_rd_pci_cfg_msg) + +#define PECI_IOC_WR_PCI_CFG \ + _IOWR(PECI_IOC_BASE, PECI_CMD_WR_PCI_CFG, struct peci_wr_pci_cfg_msg) + +#define PECI_IOC_RD_PCI_CFG_LOCAL \ + _IOWR(PECI_IOC_BASE, PECI_CMD_RD_PCI_CFG_LOCAL, \ + struct peci_rd_pci_cfg_local_msg) + +#define PECI_IOC_WR_PCI_CFG_LOCAL \ + _IOWR(PECI_IOC_BASE, PECI_CMD_WR_PCI_CFG_LOCAL, \ + struct peci_wr_pci_cfg_local_msg) + +#define PECI_IOC_RD_END_PT_CFG \ + _IOWR(PECI_IOC_BASE, PECI_CMD_RD_END_PT_CFG, \ + struct peci_rd_end_pt_cfg_msg) + +#define PECI_IOC_WR_END_PT_CFG \ + _IOWR(PECI_IOC_BASE, PECI_CMD_WR_END_PT_CFG, \ + struct peci_wr_end_pt_cfg_msg) + +#define PECI_IOC_CRASHDUMP_DISC \ + _IOWR(PECI_IOC_BASE, PECI_CMD_CRASHDUMP_DISC, \ + struct peci_crashdump_disc_msg) + +#define PECI_IOC_CRASHDUMP_GET_FRAME \ + _IOWR(PECI_IOC_BASE, PECI_CMD_CRASHDUMP_GET_FRAME, \ + struct peci_crashdump_get_frame_msg) + +#endif /* __PECI_IOCTL_H */ |