diff options
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0026-Add-support-for-new-PECI-commands.patch')
-rw-r--r-- | meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0026-Add-support-for-new-PECI-commands.patch | 724 |
1 files changed, 724 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0026-Add-support-for-new-PECI-commands.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0026-Add-support-for-new-PECI-commands.patch new file mode 100644 index 000000000..223c15fc6 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0026-Add-support-for-new-PECI-commands.patch @@ -0,0 +1,724 @@ +From 5f43a95bd032279440196a1c9802e1dec5d24a65 Mon Sep 17 00:00:00 2001 +From: "Jason M. Bills" <jason.m.bills@intel.com> +Date: Wed, 4 Apr 2018 13:52:39 -0700 +Subject: [PATCH] Add support for new PECI commands + +Signed-off-by: Jason M. Bills <jason.m.bills@intel.com> +Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com> +Signed-off-by: Zhu, Yunge <yunge.zhu@linux.intel.com> +--- + 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[9] = (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 + |