From 5c1dcd57ee642a2462d50e7fa45d97ecac5af580 Mon Sep 17 00:00:00 2001 From: Jonathan Zhang Date: Fri, 21 Oct 2022 18:55:38 -0700 Subject: [PATCH] drivers/ipmi/ocp: add functions to get board configuration These functions are added for ramstage: * add IPMI OEM command to get board configuration. * add function to get blade index in the sled. Signed-off-by: Jingle Hsu Signed-off-by: Jonathan Zhang Change-Id: I85ec7ba68d580c13e368e7d656dba47ea043d33e Reviewed-on: https://review.coreboot.org/c/coreboot/+/68779 Reviewed-by: Angel Pons Reviewed-by: Christian Walter Tested-by: build bot (Jenkins) --- src/drivers/ipmi/ocp/Makefile.inc | 2 +- src/drivers/ipmi/ocp/ipmi_ocp.h | 11 +++++++++++ src/drivers/ipmi/ocp/ipmi_sel.c | 32 +++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/drivers/ipmi/ocp/Makefile.inc b/src/drivers/ipmi/ocp/Makefile.inc index fc56364170..2b492e124d 100644 --- a/src/drivers/ipmi/ocp/Makefile.inc +++ b/src/drivers/ipmi/ocp/Makefile.inc @@ -1,4 +1,4 @@ -ramstage-$(CONFIG_IPMI_OCP) += ipmi_ocp.c +ramstage-$(CONFIG_IPMI_OCP) += ipmi_ocp.c ipmi_sel.c ifeq ($(CONFIG_IPMI_OCP),y) romstage-$(CONFIG_IPMI_KCS_ROMSTAGE) += ipmi_ocp_romstage.c smm-$(CONFIG_IPMI_BMC_SEL) += ipmi_sel.c diff --git a/src/drivers/ipmi/ocp/ipmi_ocp.h b/src/drivers/ipmi/ocp/ipmi_ocp.h index c479e520a4..571eafc731 100644 --- a/src/drivers/ipmi/ocp/ipmi_ocp.h +++ b/src/drivers/ipmi/ocp/ipmi_ocp.h @@ -11,6 +11,7 @@ #define IPMI_BMC_SET_POST_START 0x73 #define IPMI_OEM_SET_BIOS_BOOT_ORDER 0x52 #define IPMI_OEM_GET_BIOS_BOOT_ORDER 0x53 +#define IPMI_OEM_GET_BOARD_ID 0x37 #define CMOS_BIT (1 << 1) #define VALID_BIT (1 << 7) @@ -101,6 +102,13 @@ struct ipmi_sel_pcie_dev_fail { uint8_t rsvd2; } __packed; +struct ipmi_config_rsp { + uint8_t board_sku_id; + uint8_t board_rev_id; + uint8_t slot_id; + uint8_t slot_config_id; +} __packed; + #define SEL_RECORD_ID 0x01 #define SEL_PCIE_DEV_ERR 0x20 #define SEL_PCIE_IIO_ERR 0x23 @@ -167,4 +175,7 @@ void ipmi_send_sel_pcie_dev_err(pci_devfn_t bdf, uint16_t prmry_cnt, uint8_t sec uint8_t prmry_id); void ipmi_send_sel_pcie_dev_fail(uint16_t sts_reg, uint16_t src_id, enum fail_type code); void ipmi_send_sel_iio_err(uint8_t iio_stack_num, uint8_t err_id); + +enum cb_err ipmi_get_board_config(const int port, struct ipmi_config_rsp *config); +uint8_t get_blade_id(void); #endif diff --git a/src/drivers/ipmi/ocp/ipmi_sel.c b/src/drivers/ipmi/ocp/ipmi_sel.c index 55c0c3e3d9..b10755fd97 100644 --- a/src/drivers/ipmi/ocp/ipmi_sel.c +++ b/src/drivers/ipmi/ocp/ipmi_sel.c @@ -79,3 +79,35 @@ void ipmi_send_sel_pcie_dev_fail(uint16_t sts_reg, uint16_t src_id, enum fail_ty printk(BIOS_DEBUG, "\terror_code = %x, src_id = %x\n", ubslp.type, ubslp.failure_details2); } + +enum cb_err ipmi_get_board_config(const int port, struct ipmi_config_rsp *config) +{ + int ret; + struct ipmi_oem_rsp { + struct ipmi_rsp resp; + struct ipmi_config_rsp data; + } __packed; + + struct ipmi_oem_rsp rsp; + + ret = ipmi_message(port, IPMI_NETFN_OEM, 0x0, IPMI_OEM_GET_BOARD_ID, NULL, 0, + (unsigned char *)&rsp, sizeof(rsp)); + if (ret < sizeof(struct ipmi_rsp) || rsp.resp.completion_code) { + printk(BIOS_ERR, "IPMI: %s command failed (ret=%d resp=0x%x)\n", + __func__, ret, rsp.resp.completion_code); + return CB_ERR; + } + *config = rsp.data; + return CB_SUCCESS; +} + +__weak uint8_t get_blade_id(void) +{ + struct ipmi_config_rsp rsp = {.slot_id = UINT8_MAX}; + + if (CONFIG(IPMI_KCS) && CONFIG_BMC_KCS_BASE) { + if (ipmi_get_board_config(CONFIG_BMC_KCS_BASE, &rsp) != CB_SUCCESS) + return UINT8_MAX; + } + return rsp.slot_id; +}