Tim Chu has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/42242 )
Change subject: drivers/ocp/ipmi: Add ipmi set processor information ......................................................................
drivers/ocp/ipmi: Add ipmi set processor information
Implement setting processor information to BMC.
TEST=Use get command in OpenBMC to check. Command and information are shown as below:
root@bmc-oob:~# ipmi-util 1 0xd8 0x11 0x4c 0x1c 0x00 0 1 DC 11 00 47 65 6E 75 69 6E 65 20 49 6E 74 65 6C 28 52 29 20 43 50 55 20 30 30 30 30 25 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 root@bmc-oob:~# ipmi-util 1 0xd8 0x11 0x4c 0x1c 0x00 0 2 DC 11 00 1A 34 00 DC 05 58 58 root@bmc-oob:~#
Signed-off-by: TimChu Tim.Chu@quantatw.com Change-Id: I3d53ac241a11ca962572816283a0c653fcde9f9e --- M src/drivers/ocp/ipmi/Kconfig M src/drivers/ocp/ipmi/ipmi_ocp.c M src/drivers/ocp/ipmi/ipmi_ocp.h 3 files changed, 138 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/42/42242/1
diff --git a/src/drivers/ocp/ipmi/Kconfig b/src/drivers/ocp/ipmi/Kconfig index 95c51c0..d4ebafe 100644 --- a/src/drivers/ocp/ipmi/Kconfig +++ b/src/drivers/ocp/ipmi/Kconfig @@ -1,3 +1,8 @@ config IPMI_OCP bool default n + +config MANU_ID + hex + default 0 + depends on IPMI_OCP diff --git a/src/drivers/ocp/ipmi/ipmi_ocp.c b/src/drivers/ocp/ipmi/ipmi_ocp.c index c1766d9..4ad710d 100644 --- a/src/drivers/ocp/ipmi/ipmi_ocp.c +++ b/src/drivers/ocp/ipmi/ipmi_ocp.c @@ -54,6 +54,108 @@ return 0; }
+static int ipmi_set_processor_information_param1(struct device *dev) +{ + int ret; + struct ipmi_processor_info_param1_req req1 = {0}; + struct ipmi_rsp rsp; + + for (int index = 0; index < sizeof(req1.data.manufacturer_id); index++) { + req1.data.manufacturer_id[index] = (mfid >> (index * 8)) & 0xff; + } + printk(BIOS_DEBUG, "IPMI BMC manufacturer id: %02x%02x%02x\n", + req1.data.manufacturer_id[2], req1.data.manufacturer_id[1], + req1.data.manufacturer_id[0]); + + req1.data.index = 0; + req1.data.parameter_selector = 1; + + /* Get processor name. */ + fill_processor_name(req1.product_name); + printk(BIOS_DEBUG, "IPMI CPU NAME: %s.\n", req1.product_name); + + ret = ipmi_kcs_message(dev->path.pnp.port, IPMI_NETFN_OEM_COMMON, 0, + IPMI_BMC_SET_PROCESSOR_INFORMATION, (u8 *) &req1, + sizeof(req1), (u8 *) &rsp, sizeof(rsp)); + + if (ret < sizeof(struct ipmi_rsp) || rsp.completion_code) { + printk(BIOS_ERR, "IPMI BMC: %s command failed (ret=%d rsp=0x%x)\n", + __func__, ret, rsp.completion_code); + return CB_ERR; + } + return CB_SUCCESS; +} + +static int ipmi_set_processor_information_param2(struct device *dev) +{ + int ret; + struct ipmi_processor_info_param2_req req2 = {0}; + struct ipmi_rsp rsp; + struct cpuid_result regs; + msr_t msr; + uint8_t stepping_id; + + for (int index = 0; index < sizeof(req2.data.manufacturer_id); index++) { + req2.data.manufacturer_id[index] = (mfid >> (index * 8)) & 0xff; + } + printk(BIOS_DEBUG, "IPMI BMC manufacturer id: %02x%02x%02x\n", + req2.data.manufacturer_id[2], req2.data.manufacturer_id[1], + req2.data.manufacturer_id[0]); + + req2.data.index = 0; + req2.data.parameter_selector = 2; + + /* Get core number and thread number. */ + msr = rdmsr(MSR_CORE_THREAD_COUNT); + req2.thread_number = (msr.lo >> 0) & 0xffff; + req2.core_number = (msr.lo >> 16) & 0xffff; + printk(BIOS_DEBUG, "IPMI CPU has %u cores, %u threads enabled.\n", + req2.core_number, req2.thread_number); + + /* Get processor frequency. */ + msr = rdmsr(MSR_PLATFORM_INFO); + req2.processor_freq = 100 * ((msr.lo >> 8) & 0xff); + printk(BIOS_DEBUG, "IPMI CPU frequency is %u MHz.\n", + req2.processor_freq); + + /* Get revision. */ + regs = cpuid(0x01); + stepping_id = (regs.eax & 0xf); + printk(BIOS_DEBUG, "IPMI CPU stepping id is %x.\n", stepping_id); + switch (stepping_id) { + /* TBD */ + case 0xa: + req2.revision[0] = 'X'; + req2.revision[1] = 'X'; + break; + default: + req2.revision[0] = 'X'; + req2.revision[1] = 'X'; + } + + ret = ipmi_kcs_message(dev->path.pnp.port, IPMI_NETFN_OEM_COMMON, 0, + IPMI_BMC_SET_PROCESSOR_INFORMATION, (u8 *) &req2, + sizeof(req2), (u8 *) &rsp, sizeof(rsp)); + + if (ret < sizeof(struct ipmi_rsp) || rsp.completion_code) { + printk(BIOS_ERR, "IPMI: %s command failed (ret=%d rsp=0x%x)\n", + __func__, ret, rsp.completion_code); + return CB_ERR; + } + return CB_SUCCESS; +} + +static void ipmi_set_processor_information(struct device *dev) +{ + if (ipmi_set_processor_information_param1(dev)) { + printk(BIOS_ERR, "IPMI BMC set param 1 processor info failed\n"); + } + + if (ipmi_set_processor_information_param2(dev)) { + printk(BIOS_ERR, "IPMI BMC set param 2 processor info failed\n"); + } +} + static void ipmi_ocp_init(struct device *dev) { struct ipmi_rsp postrsp; @@ -67,6 +169,9 @@ { struct ipmi_rsp postrsp;
+ /* Send processor information */ + ipmi_set_processor_information(dev); + /* Send POST end to BMC. */ if (!ipmi_set_post_end(dev, &postrsp)) printk(BIOS_DEBUG, "IPMI BMC POST is ended\n"); diff --git a/src/drivers/ocp/ipmi/ipmi_ocp.h b/src/drivers/ocp/ipmi/ipmi_ocp.h index 1cdea2f..f04b5ba 100644 --- a/src/drivers/ocp/ipmi/ipmi_ocp.h +++ b/src/drivers/ocp/ipmi/ipmi_ocp.h @@ -3,8 +3,36 @@ #ifndef __IPMI_OCP_H #define __IPMI_OCP_H
+#include <soc/msr.h> +#include <cpu/x86/msr.h> +#include <cpu/x86/name.h> +#include "drivers/ipmi/ipmi_kcs.h" #define IPMI_NETFN_OEM 0x30 #define IPMI_BMC_SET_POST_START 0x73 #define IPMI_BMC_SET_POST_END 0x74 +#define IPMI_NETFN_OEM_COMMON 0x36 +#define IPMI_BMC_SET_PROCESSOR_INFORMATION 0x10 +#define IPMI_BMC_GET_PROCESSOR_INFORMATION 0x11 + +#define mfid CONFIG_MANU_ID + +struct ipmi_processor_info_req { + uint8_t manufacturer_id[3]; + uint8_t index; + uint8_t parameter_selector; +} __packed; + +struct ipmi_processor_info_param1_req { + struct ipmi_processor_info_req data; + char product_name[48]; +} __packed; + +struct ipmi_processor_info_param2_req { + struct ipmi_processor_info_req data; + uint8_t core_number; + uint16_t thread_number; + uint16_t processor_freq; + char revision[2]; +} __packed;
#endif