From 5f43a95bd032279440196a1c9802e1dec5d24a65 Mon Sep 17 00:00:00 2001 From: "Jason M. Bills" Date: Wed, 4 Apr 2018 13:52:39 -0700 Subject: [PATCH] Add support for new PECI commands Signed-off-by: Jason M. Bills Signed-off-by: Jae Hyun Yoo Signed-off-by: Zhu, Yunge --- drivers/peci/peci-core.c | 430 ++++++++++++++++++++++++++++++++++++++++ include/uapi/linux/peci-ioctl.h | 179 +++++++++++++++++ 2 files changed, 609 insertions(+) diff --git a/drivers/peci/peci-core.c b/drivers/peci/peci-core.c index 2a6be04..43a86a0 100644 --- a/drivers/peci/peci-core.c +++ b/drivers/peci/peci-core.c @@ -318,6 +318,13 @@ static int peci_scan_cmd_mask(struct peci_adapter *adapter) * See PECI Spec Table 3-1. */ revision = FIELD_GET(REVISION_NUM_MASK, dib); + if (revision >= 0x40) { /* Rev. 4.0 */ + adapter->cmd_mask |= BIT(PECI_CMD_RD_IA_MSREX); + adapter->cmd_mask |= BIT(PECI_CMD_RD_END_PT_CFG); + adapter->cmd_mask |= BIT(PECI_CMD_WR_END_PT_CFG); + adapter->cmd_mask |= BIT(PECI_CMD_CRASHDUMP_DISC); + adapter->cmd_mask |= BIT(PECI_CMD_CRASHDUMP_GET_FRAME); + } if (revision >= 0x36) /* Rev. 3.6 */ adapter->cmd_mask |= BIT(PECI_CMD_WR_IA_MSR); if (revision >= 0x35) /* Rev. 3.5 */ @@ -375,14 +382,18 @@ static int peci_cmd_xfer(struct peci_adapter *adapter, void *vmsg) switch (msg->tx_buf[0]) { case PECI_RDPKGCFG_CMD: case PECI_RDIAMSR_CMD: + case PECI_RDIAMSREX_CMD: case PECI_RDPCICFG_CMD: case PECI_RDPCICFGLOCAL_CMD: + case PECI_RDENDPTCFG_CMD: + case PECI_CRASHDUMP_CMD: ret = peci_xfer_with_retries(adapter, msg, false); break; case PECI_WRPKGCFG_CMD: case PECI_WRIAMSR_CMD: case PECI_WRPCICFG_CMD: case PECI_WRPCICFGLOCAL_CMD: + case PECI_WRENDPTCFG_CMD: /* Check if the AW FCS byte is already provided */ ret = peci_aw_fcs(msg, 2 + msg->tx_len, &aw_fcs); if (ret) @@ -590,6 +601,34 @@ static int peci_cmd_rd_ia_msr(struct peci_adapter *adapter, void *vmsg) return ret; } +static int peci_cmd_rd_ia_msrex(struct peci_adapter *adapter, void *vmsg) +{ + struct peci_rd_ia_msrex_msg *umsg = vmsg; + struct peci_xfer_msg *msg; + int ret; + + msg = peci_get_xfer_msg(PECI_RDIAMSREX_WRITE_LEN, PECI_RDIAMSREX_READ_LEN); + if (!msg) + return -ENOMEM; + + msg->addr = umsg->addr; + msg->tx_buf[0] = PECI_RDIAMSREX_CMD; + msg->tx_buf[1] = 0; + msg->tx_buf[2] = (u8)umsg->thread_id; + msg->tx_buf[3] = (u8)(umsg->thread_id >> 8); + msg->tx_buf[4] = (u8)umsg->address; + msg->tx_buf[5] = (u8)(umsg->address >> 8); + + ret = peci_xfer_with_retries(adapter, msg, false); + if (!ret) + memcpy(&umsg->value, &msg->rx_buf[1], sizeof(uint64_t)); + + umsg->cc = msg->rx_buf[0]; + peci_put_xfer_msg(msg); + + return ret; +} + static int peci_cmd_wr_ia_msr(struct peci_adapter *adapter, void *vmsg) { return -ENOSYS; /* Not implemented yet */ @@ -730,6 +769,392 @@ static int peci_cmd_wr_pci_cfg_local(struct peci_adapter *adapter, void *vmsg) return ret; } +static int peci_cmd_rd_end_pt_cfg(struct peci_adapter *adapter, void *vmsg) +{ + struct peci_rd_end_pt_cfg_msg *umsg = vmsg; + struct peci_xfer_msg *msg = NULL; + u32 address; + u8 tx_size; + int ret; + + switch (umsg->msg_type) { + case PECI_ENDPTCFG_TYPE_LOCAL_PCI: + case PECI_ENDPTCFG_TYPE_PCI: + /* + * Per the PECI spec, the read length must be a byte, word, + * or dword + */ + if (umsg->rx_len != 1 && umsg->rx_len != 2 && + umsg->rx_len != 4) { + dev_dbg(&adapter->dev, + "Invalid read length, rx_len: %d\n", + umsg->rx_len); + return -EINVAL; + } + + msg = peci_get_xfer_msg(PECI_RDENDPTCFG_PCI_WRITE_LEN, + PECI_RDENDPTCFG_READ_LEN_BASE + + umsg->rx_len); + if (!msg) + return -ENOMEM; + + address = umsg->params.pci_cfg.reg; /* [11:0] - Register */ + address |= (u32)umsg->params.pci_cfg.function + << 12; /* [14:12] - Function */ + address |= (u32)umsg->params.pci_cfg.device + << 15; /* [19:15] - Device */ + address |= (u32)umsg->params.pci_cfg.bus + << 20; /* [27:20] - Bus */ + /* [31:28] - Reserved */ + msg->addr = umsg->addr; + msg->tx_buf[0] = PECI_RDENDPTCFG_CMD; + msg->tx_buf[1] = 0x00; /* request byte for Host ID|Retry bit */ + msg->tx_buf[2] = umsg->msg_type; /* Message Type */ + msg->tx_buf[3] = 0x00; /* Endpoint ID */ + msg->tx_buf[4] = 0x00; /* Reserved */ + msg->tx_buf[5] = 0x00; /* Reserved */ + msg->tx_buf[6] = PECI_ENDPTCFG_ADDR_TYPE_PCI; /* Addr Type */ + msg->tx_buf[7] = umsg->params.pci_cfg.seg; /* PCI Segment */ + msg->tx_buf[8] = (u8)address; /* LSB - PCI Config Address */ + msg->tx_buf[9] = (u8)(address >> 8); /* PCI Config Address */ + msg->tx_buf[10] = (u8)(address >> 16); /* PCI Config Address */ + msg->tx_buf[11] = + (u8)(address >> 24); /* MSB - PCI Config Address */ + break; + + case PECI_ENDPTCFG_TYPE_MMIO: + /* + * Per the PECI spec, the read length must be a byte, word, + * dword, or qword + */ + if (umsg->rx_len != 1 && umsg->rx_len != 2 && + umsg->rx_len != 4 && umsg->rx_len != 8) { + dev_dbg(&adapter->dev, + "Invalid read length, rx_len: %d\n", + umsg->rx_len); + return -EINVAL; + } + /* + * Per the PECI spec, the address type must specify either DWORD + * or QWORD + */ + if (umsg->params.mmio.addr_type != + PECI_ENDPTCFG_ADDR_TYPE_MMIO_D && + umsg->params.mmio.addr_type != + PECI_ENDPTCFG_ADDR_TYPE_MMIO_Q) { + dev_dbg(&adapter->dev, + "Invalid address type, addr_type: %d\n", + umsg->params.mmio.addr_type); + return -EINVAL; + } + + if (umsg->params.mmio.addr_type == + PECI_ENDPTCFG_ADDR_TYPE_MMIO_D) + tx_size = PECI_RDENDPTCFG_MMIO_D_WRITE_LEN; + else + tx_size = PECI_RDENDPTCFG_MMIO_Q_WRITE_LEN; + msg = peci_get_xfer_msg(tx_size, + PECI_RDENDPTCFG_READ_LEN_BASE + + umsg->rx_len); + if (!msg) + return -ENOMEM; + + address = umsg->params.mmio.function; /* [2:0] - Function */ + address |= (u32)umsg->params.mmio.device + << 3; /* [7:3] - Device */ + + msg->addr = umsg->addr; + msg->tx_buf[0] = PECI_RDENDPTCFG_CMD; + msg->tx_buf[1] = 0x00; /* request byte for Host ID|Retry bit */ + msg->tx_buf[2] = umsg->msg_type; /* Message Type */ + msg->tx_buf[3] = 0x00; /* Endpoint ID */ + msg->tx_buf[4] = 0x00; /* Reserved */ + msg->tx_buf[5] = umsg->params.mmio.bar; /* BAR # */ + msg->tx_buf[6] = umsg->params.mmio.addr_type; /* Address Type */ + msg->tx_buf[7] = umsg->params.mmio.seg; /* PCI Segment */ + msg->tx_buf[8] = (u8)address; /* Function/Device */ + msg->tx_buf[9] = umsg->params.mmio.bus; /* PCI Bus */ + msg->tx_buf[10] = (u8)umsg->params.mmio + .offset; /* LSB - Register Offset */ + msg->tx_buf[11] = (u8)(umsg->params.mmio.offset + >> 8); /* Register Offset */ + msg->tx_buf[12] = (u8)(umsg->params.mmio.offset + >> 16); /* Register Offset */ + msg->tx_buf[13] = (u8)(umsg->params.mmio.offset + >> 24); /* MSB - DWORD Register Offset */ + if (umsg->params.mmio.addr_type == + PECI_ENDPTCFG_ADDR_TYPE_MMIO_Q) { + msg->tx_buf[14] = (u8)(umsg->params.mmio.offset + >> 32); /* Register Offset */ + msg->tx_buf[15] = (u8)(umsg->params.mmio.offset + >> 40); /* Register Offset */ + msg->tx_buf[16] = (u8)(umsg->params.mmio.offset + >> 48); /* Register Offset */ + msg->tx_buf[17] = + (u8)(umsg->params.mmio.offset + >> 56); /* MSB - QWORD Register Offset */ + } + break; + + default: + return -EINVAL; + } + + ret = peci_xfer_with_retries(adapter, msg, false); + if (!ret) + memcpy(umsg->data, &msg->rx_buf[1], umsg->rx_len); + + umsg->cc = msg->rx_buf[0]; + peci_put_xfer_msg(msg); + + return ret; +} + +static int peci_cmd_wr_end_pt_cfg(struct peci_adapter *adapter, void *vmsg) +{ + struct peci_wr_end_pt_cfg_msg *umsg = vmsg; + struct peci_xfer_msg *msg = NULL; + u8 tx_size, aw_fcs; + int ret, i, idx; + u32 address; + + switch (umsg->msg_type) { + case PECI_ENDPTCFG_TYPE_LOCAL_PCI: + case PECI_ENDPTCFG_TYPE_PCI: + /* + * Per the PECI spec, the write length must be a byte, word, + * or dword + */ + if (umsg->tx_len != 1 && umsg->tx_len != 2 && + umsg->tx_len != 4) { + dev_dbg(&adapter->dev, + "Invalid write length, tx_len: %d\n", + umsg->tx_len); + return -EINVAL; + } + + msg = peci_get_xfer_msg(PECI_WRENDPTCFG_PCI_WRITE_LEN_BASE + + umsg->tx_len, PECI_WRENDPTCFG_READ_LEN); + if (!msg) + return -ENOMEM; + + address = umsg->params.pci_cfg.reg; /* [11:0] - Register */ + address |= (u32)umsg->params.pci_cfg.function + << 12; /* [14:12] - Function */ + address |= (u32)umsg->params.pci_cfg.device + << 15; /* [19:15] - Device */ + address |= (u32)umsg->params.pci_cfg.bus + << 20; /* [27:20] - Bus */ + /* [31:28] - Reserved */ + msg->addr = umsg->addr; + msg->tx_buf[0] = PECI_WRENDPTCFG_CMD; + msg->tx_buf[1] = 0x00; /* request byte for Host ID|Retry bit */ + msg->tx_buf[2] = umsg->msg_type; /* Message Type */ + msg->tx_buf[3] = 0x00; /* Endpoint ID */ + msg->tx_buf[4] = 0x00; /* Reserved */ + msg->tx_buf[5] = 0x00; /* Reserved */ + msg->tx_buf[6] = PECI_ENDPTCFG_ADDR_TYPE_PCI; /* Addr Type */ + msg->tx_buf[7] = umsg->params.pci_cfg.seg; /* PCI Segment */ + msg->tx_buf[8] = (u8)address; /* LSB - PCI Config Address */ + msg->tx_buf[9] = (u8)(address >> 8); /* PCI Config Address */ + msg->tx_buf[10] = (u8)(address >> 16); /* PCI Config Address */ + msg->tx_buf[11] = + (u8)(address >> 24); /* MSB - PCI Config Address */ + for (i = 0; i < umsg->tx_len; i++) + msg->tx_buf[12 + i] = (u8)(umsg->value >> (i << 3)); + + /* Add an Assured Write Frame Check Sequence byte */ + ret = peci_aw_fcs(msg, 15 + umsg->tx_len, &aw_fcs); + if (ret) + goto out; + + msg->tx_buf[12 + i] = 0x80 ^ aw_fcs; + break; + + case PECI_ENDPTCFG_TYPE_MMIO: + /* + * Per the PECI spec, the write length must be a byte, word, + * dword, or qword + */ + if (umsg->tx_len != 1 && umsg->tx_len != 2 && + umsg->tx_len != 4 && umsg->tx_len != 8) { + dev_dbg(&adapter->dev, + "Invalid write length, tx_len: %d\n", + umsg->tx_len); + return -EINVAL; + } + /* + * Per the PECI spec, the address type must specify either DWORD + * or QWORD + */ + if (umsg->params.mmio.addr_type != + PECI_ENDPTCFG_ADDR_TYPE_MMIO_D && + umsg->params.mmio.addr_type != + PECI_ENDPTCFG_ADDR_TYPE_MMIO_Q) { + dev_dbg(&adapter->dev, + "Invalid address type, addr_type: %d\n", + umsg->params.mmio.addr_type); + return -EINVAL; + } + + if (umsg->params.mmio.addr_type == + PECI_ENDPTCFG_ADDR_TYPE_MMIO_D) + tx_size = PECI_WRENDPTCFG_MMIO_D_WRITE_LEN_BASE + + umsg->tx_len; + else + tx_size = PECI_WRENDPTCFG_MMIO_Q_WRITE_LEN_BASE + + umsg->tx_len; + msg = peci_get_xfer_msg(tx_size, PECI_WRENDPTCFG_READ_LEN); + if (!msg) + return -ENOMEM; + + address = umsg->params.mmio.function; /* [2:0] - Function */ + address |= (u32)umsg->params.mmio.device + << 3; /* [7:3] - Device */ + + msg->addr = umsg->addr; + msg->tx_buf[0] = PECI_WRENDPTCFG_CMD; + msg->tx_buf[1] = 0x00; /* request byte for Host ID|Retry bit */ + msg->tx_buf[2] = umsg->msg_type; /* Message Type */ + msg->tx_buf[3] = 0x00; /* Endpoint ID */ + msg->tx_buf[4] = 0x00; /* Reserved */ + msg->tx_buf[5] = umsg->params.mmio.bar; /* BAR # */ + msg->tx_buf[6] = umsg->params.mmio.addr_type; /* Address Type */ + msg->tx_buf[7] = umsg->params.mmio.seg; /* PCI Segment */ + msg->tx_buf[8] = (u8)address; /* Function/Device */ + msg->tx_buf[9] = umsg->params.mmio.bus; /* PCI Bus */ + msg->tx_buf[10] = (u8)umsg->params.mmio + .offset; /* LSB - Register Offset */ + msg->tx_buf[11] = (u8)(umsg->params.mmio.offset + >> 8); /* Register Offset */ + msg->tx_buf[12] = (u8)(umsg->params.mmio.offset + >> 16); /* Register Offset */ + msg->tx_buf[13] = (u8)(umsg->params.mmio.offset + >> 24); /* MSB - DWORD Register Offset */ + if (umsg->params.mmio.addr_type == + PECI_ENDPTCFG_ADDR_TYPE_MMIO_Q) { + msg->tx_len = PECI_WRENDPTCFG_MMIO_Q_WRITE_LEN_BASE; + msg->tx_buf[14] = (u8)(umsg->params.mmio.offset + >> 32); /* Register Offset */ + msg->tx_buf[15] = (u8)(umsg->params.mmio.offset + >> 40); /* Register Offset */ + msg->tx_buf[16] = (u8)(umsg->params.mmio.offset + >> 48); /* Register Offset */ + msg->tx_buf[17] = + (u8)(umsg->params.mmio.offset + >> 56); /* MSB - QWORD Register Offset */ + idx = 18; + } else { + idx = 14; + } + for (i = 0; i < umsg->tx_len; i++) + msg->tx_buf[idx + i] = (u8)(umsg->value >> (i << 3)); + + /* Add an Assured Write Frame Check Sequence byte */ + ret = peci_aw_fcs(msg, idx + 3 + umsg->tx_len, &aw_fcs); + if (ret) + goto out; + + msg->tx_buf[idx + i] = 0x80 ^ aw_fcs; + break; + + default: + return -EINVAL; + } + + ret = peci_xfer_with_retries(adapter, msg, false); + +out: + umsg->cc = msg->rx_buf[0]; + peci_put_xfer_msg(msg); + + return ret; +} + +static int peci_cmd_crashdump_disc(struct peci_adapter *adapter, void *vmsg) +{ + struct peci_crashdump_disc_msg *umsg = vmsg; + struct peci_xfer_msg *msg; + int ret; + + /* Per the EDS, the read length must be a byte, word, or qword */ + if (umsg->rx_len != 1 && umsg->rx_len != 2 && umsg->rx_len != 8) { + dev_dbg(&adapter->dev, "Invalid read length, rx_len: %d\n", + umsg->rx_len); + return -EINVAL; + } + + msg = peci_get_xfer_msg(PECI_CRASHDUMP_DISC_WRITE_LEN, + PECI_CRASHDUMP_DISC_READ_LEN_BASE + + umsg->rx_len); + if (!msg) + return -ENOMEM; + + msg->addr = umsg->addr; + msg->tx_buf[0] = PECI_CRASHDUMP_CMD; + msg->tx_buf[1] = 0x00; /* request byte for Host ID | Retry bit */ + /* Host ID is 0 for PECI 3.0 */ + msg->tx_buf[2] = PECI_CRASHDUMP_DISC_VERSION; + msg->tx_buf[3] = PECI_CRASHDUMP_DISC_OPCODE; + msg->tx_buf[4] = umsg->subopcode; + msg->tx_buf[5] = umsg->param0; + msg->tx_buf[6] = (u8)umsg->param1; + msg->tx_buf[7] = (u8)(umsg->param1 >> 8); + msg->tx_buf[8] = umsg->param2; + + ret = peci_xfer_with_retries(adapter, msg, false); + if (!ret) + memcpy(umsg->data, &msg->rx_buf[1], umsg->rx_len); + + umsg->cc = msg->rx_buf[0]; + peci_put_xfer_msg(msg); + + return ret; +} + +static int peci_cmd_crashdump_get_frame(struct peci_adapter *adapter, + void *vmsg) +{ + struct peci_crashdump_get_frame_msg *umsg = vmsg; + struct peci_xfer_msg *msg; + int ret; + + /* Per the EDS, the read length must be a qword or dqword */ + if (umsg->rx_len != 8 && umsg->rx_len != 16) { + dev_dbg(&adapter->dev, "Invalid read length, rx_len: %d\n", + umsg->rx_len); + return -EINVAL; + } + + msg = peci_get_xfer_msg(PECI_CRASHDUMP_GET_FRAME_WRITE_LEN, + PECI_CRASHDUMP_GET_FRAME_READ_LEN_BASE + + umsg->rx_len); + if (!msg) + return -ENOMEM; + + msg->addr = umsg->addr; + msg->tx_buf[0] = PECI_CRASHDUMP_CMD; + msg->tx_buf[1] = 0x00; /* request byte for Host ID | Retry bit */ + /* Host ID is 0 for PECI 3.0 */ + msg->tx_buf[2] = PECI_CRASHDUMP_GET_FRAME_VERSION; + msg->tx_buf[3] = PECI_CRASHDUMP_GET_FRAME_OPCODE; + msg->tx_buf[4] = (u8)umsg->param0; + msg->tx_buf[5] = (u8)(umsg->param0 >> 8); + msg->tx_buf[6] = (u8)umsg->param1; + msg->tx_buf[7] = (u8)(umsg->param1 >> 8); + msg->tx_buf[8] = (u8)umsg->param2; + msg->tx_buf[8] = (u8)(umsg->param2 >> 8); + + ret = peci_xfer_with_retries(adapter, msg, false); + if (!ret) + memcpy(umsg->data, &msg->rx_buf[1], umsg->rx_len); + + umsg->cc = msg->rx_buf[0]; + peci_put_xfer_msg(msg); + + return ret; +} + typedef int (*peci_cmd_fn_type)(struct peci_adapter *, void *); static const peci_cmd_fn_type peci_cmd_fn[PECI_CMD_MAX] = { @@ -741,10 +1166,15 @@ static const peci_cmd_fn_type peci_cmd_fn[PECI_CMD_MAX] = { 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, }; /** diff --git a/include/uapi/linux/peci-ioctl.h b/include/uapi/linux/peci-ioctl.h index 253fb42..1158254 100644 --- a/include/uapi/linux/peci-ioctl.h +++ b/include/uapi/linux/peci-ioctl.h @@ -47,6 +47,7 @@ * @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 @@ -67,10 +68,15 @@ enum peci_cmd { 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 }; @@ -312,6 +318,34 @@ struct peci_wr_ia_msr_msg { } __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 @@ -438,6 +472,132 @@ struct peci_wr_pci_cfg_local_msg { __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 \ @@ -464,6 +624,9 @@ struct peci_wr_pci_cfg_local_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) @@ -478,4 +641,20 @@ struct peci_wr_pci_cfg_local_msg { _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 */ -- 2.7.4