From ef7dd5d54df9137b8167e86838270a7c812b21f3 Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Fri, 22 Oct 2021 01:02:32 +0300 Subject: [PATCH] drivers/ipmi: prepare for adding more interfaces De-duplicate common initialization code (self-test and device identification) and put it in a new ipmi_if.c unit, which is supposed to work with any underlying IPMI interface. Change-Id: Ia99da6fb63adb7bf556d3d6f7964b34831be8a2f Signed-off-by: Sergii Dmytruk Reviewed-on: https://review.coreboot.org/c/coreboot/+/67056 Tested-by: build bot (Jenkins) Reviewed-by: Krystian Hebel --- Documentation/drivers/ipmi_kcs.md | 9 ++ src/drivers/ipmi/Makefile.inc | 4 +- src/drivers/ipmi/chip.h | 5 +- src/drivers/ipmi/ipmi_fru.c | 3 +- src/drivers/ipmi/ipmi_if.c | 101 ++++++++++++++++++ src/drivers/ipmi/{ipmi_kcs.h => ipmi_if.h} | 41 +++++--- src/drivers/ipmi/ipmi_kcs.c | 8 +- src/drivers/ipmi/ipmi_kcs_ops.c | 78 +------------- src/drivers/ipmi/ipmi_kcs_ops_premem.c | 113 --------------------- src/drivers/ipmi/ipmi_ops.c | 13 +-- src/drivers/ipmi/ipmi_ops.h | 2 +- src/drivers/ipmi/ipmi_ops_premem.c | 53 ++++++++++ src/drivers/ipmi/ocp/ipmi_ocp.c | 7 +- src/drivers/ipmi/ocp/ipmi_ocp_romstage.c | 24 ++--- src/drivers/ipmi/supermicro_oem.c | 14 +-- src/mainboard/ocp/deltalake/ipmi.c | 6 +- src/mainboard/ocp/deltalake/romstage.c | 4 +- src/mainboard/ocp/tiogapass/ipmi.c | 2 +- src/mainboard/ocp/tiogapass/romstage.c | 4 +- 19 files changed, 245 insertions(+), 246 deletions(-) create mode 100644 src/drivers/ipmi/ipmi_if.c rename src/drivers/ipmi/{ipmi_kcs.h => ipmi_if.h} (68%) delete mode 100644 src/drivers/ipmi/ipmi_kcs_ops_premem.c create mode 100644 src/drivers/ipmi/ipmi_ops_premem.c diff --git a/Documentation/drivers/ipmi_kcs.md b/Documentation/drivers/ipmi_kcs.md index f6f0fb986a..c4db492e00 100644 --- a/Documentation/drivers/ipmi_kcs.md +++ b/Documentation/drivers/ipmi_kcs.md @@ -42,6 +42,15 @@ The following registers can be set: * `gpe_interrupt` * Integer * The bit in GPE (SCI) used to notify about a change on the KCS. +* `wait_for_bmc` + * Boolean + * Wait for BMC to boot. This can be used if the BMC takes a long time to boot + after PoR: + - AST2400 on Supermicro X11SSH: 34 s +* `bmc_boot_timeout` + * Integer + * The timeout in seconds to wait for the IPMI service to be loaded. + Will be used if wait_for_bmc is true. [IPMI]: https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/ipmi-second-gen-interface-spec-v2-rev1-1.pdf diff --git a/src/drivers/ipmi/Makefile.inc b/src/drivers/ipmi/Makefile.inc index e4bcf313eb..85f3dde437 100644 --- a/src/drivers/ipmi/Makefile.inc +++ b/src/drivers/ipmi/Makefile.inc @@ -1,8 +1,10 @@ +ramstage-$(CONFIG_IPMI_KCS) += ipmi_if.c ramstage-$(CONFIG_IPMI_KCS) += ipmi_kcs.c ramstage-$(CONFIG_IPMI_KCS) += ipmi_kcs_ops.c ramstage-$(CONFIG_IPMI_KCS) += ipmi_ops.c ramstage-$(CONFIG_IPMI_KCS) += ipmi_fru.c ramstage-$(CONFIG_DRIVERS_IPMI_SUPERMICRO_OEM) += supermicro_oem.c -romstage-$(CONFIG_IPMI_KCS_ROMSTAGE) += ipmi_kcs_ops_premem.c +romstage-$(CONFIG_IPMI_KCS_ROMSTAGE) += ipmi_if.c +romstage-$(CONFIG_IPMI_KCS_ROMSTAGE) += ipmi_ops_premem.c romstage-$(CONFIG_IPMI_KCS_ROMSTAGE) += ipmi_kcs.c romstage-$(CONFIG_IPMI_KCS_ROMSTAGE) += ipmi_ops.c diff --git a/src/drivers/ipmi/chip.h b/src/drivers/ipmi/chip.h index 4e9d9e1985..3b970c9fa4 100644 --- a/src/drivers/ipmi/chip.h +++ b/src/drivers/ipmi/chip.h @@ -8,6 +8,7 @@ #include struct drivers_ipmi_config { +#if CONFIG(IPMI_KCS) u8 bmc_i2c_address; u8 have_nv_storage; u8 nv_storage_device_address; @@ -25,6 +26,9 @@ struct drivers_ipmi_config { /* "POST complete" GPIO and polarity */ u32 post_complete_gpio; bool post_complete_invert; + unsigned int uid; /* Auto-filled by ipmi_ssdt() */ +#endif + /* * Wait for BMC to boot. * This can be used if the BMC takes a long time to boot after PoR: @@ -36,7 +40,6 @@ struct drivers_ipmi_config { * Will be used if wait_for_bmc is true. */ u16 bmc_boot_timeout; - unsigned int uid; /* Auto-filled by ipmi_ssdt() */ }; #endif /* _IMPI_CHIP_H_ */ diff --git a/src/drivers/ipmi/ipmi_fru.c b/src/drivers/ipmi/ipmi_fru.c index 822e5bfa23..f16530705f 100644 --- a/src/drivers/ipmi/ipmi_fru.c +++ b/src/drivers/ipmi/ipmi_fru.c @@ -5,6 +5,7 @@ #include #include +#include "ipmi_if.h" #include "ipmi_ops.h" #define MAX_FRU_BUSY_RETRY 5 @@ -34,7 +35,7 @@ static enum cb_err ipmi_read_fru(const int port, struct ipmi_read_fru_data_req * req->count = CONFIG_IPMI_FRU_SINGLE_RW_SZ; while (retry_count <= MAX_FRU_BUSY_RETRY) { - ret = ipmi_kcs_message(port, IPMI_NETFN_STORAGE, 0x0, + ret = ipmi_message(port, IPMI_NETFN_STORAGE, 0x0, IPMI_READ_FRU_DATA, (const unsigned char *) req, sizeof(*req), (unsigned char *) &rsp, sizeof(rsp)); if (rsp.resp.completion_code == 0x81) { diff --git a/src/drivers/ipmi/ipmi_if.c b/src/drivers/ipmi/ipmi_if.c new file mode 100644 index 0000000000..4ff9004741 --- /dev/null +++ b/src/drivers/ipmi/ipmi_if.c @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include "ipmi_if.h" + +#include +#include + +#include "chip.h" + +int ipmi_get_device_id(const struct device *dev, struct ipmi_devid_rsp *rsp) +{ + int ret; + + ret = ipmi_message(dev->path.pnp.port, IPMI_NETFN_APPLICATION, 0, + IPMI_BMC_GET_DEVICE_ID, NULL, 0, (u8 *)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 1; + } + if (ret != sizeof(*rsp)) { + printk(BIOS_ERR, "IPMI: %s response truncated\n", __func__); + return 1; + } + return 0; +} + +static int ipmi_get_bmc_self_test_result(const struct device *dev, + struct ipmi_selftest_rsp *rsp) +{ + int ret; + + ret = ipmi_message(dev->path.pnp.port, IPMI_NETFN_APPLICATION, 0, + IPMI_BMC_GET_SELFTEST_RESULTS, NULL, 0, (u8 *)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 1; + } + if (ret != sizeof(*rsp)) { + printk(BIOS_ERR, "IPMI: %s response truncated\n", __func__); + return 1; + } + + return 0; +} + +int ipmi_process_self_test_result(const struct device *dev) +{ + int failure = 0; + uint8_t retry_count = 0; + struct ipmi_selftest_rsp selftestrsp = {0}; + + const struct drivers_ipmi_config *conf = dev->chip_info; + uint8_t retry_limit = 0; + + if (conf && conf->wait_for_bmc) + retry_limit = conf->bmc_boot_timeout; + + if (retry_limit == 0) + /* Try to get self-test results at least once */ + retry_limit = 1; + + printk(BIOS_INFO, "Get BMC self test result..."); + for (retry_count = 0; retry_count < retry_limit; retry_count++) { + if (!ipmi_get_bmc_self_test_result(dev, &selftestrsp)) + break; + + mdelay(1000); + } + + switch (selftestrsp.result) { + case IPMI_APP_SELFTEST_NO_ERROR: /* 0x55 */ + printk(BIOS_DEBUG, "No Error\n"); + break; + case IPMI_APP_SELFTEST_NOT_IMPLEMENTED: /* 0x56 */ + printk(BIOS_DEBUG, "Function Not Implemented\n"); + break; + case IPMI_APP_SELFTEST_ERROR: /* 0x57 */ + printk(BIOS_ERR, "BMC: Corrupted or inaccessible data or device\n"); + failure = 1; + break; + case IPMI_APP_SELFTEST_FATAL_HW_ERROR: /* 0x58 */ + printk(BIOS_ERR, "BMC: Fatal Hardware Error\n"); + failure = 1; + break; + case IPMI_APP_SELFTEST_RESERVED: /* 0xFF */ + printk(BIOS_DEBUG, "Reserved\n"); + break; + + default: /* Other Device Specific Hardware Error */ + printk(BIOS_ERR, "BMC: Device Specific Error: 0x%02x\n", selftestrsp.result); + failure = 1; + break; + } + + return failure; +} diff --git a/src/drivers/ipmi/ipmi_kcs.h b/src/drivers/ipmi/ipmi_if.h similarity index 68% rename from src/drivers/ipmi/ipmi_kcs.h rename to src/drivers/ipmi/ipmi_if.h index 33ddd5f016..984b46953b 100644 --- a/src/drivers/ipmi/ipmi_kcs.h +++ b/src/drivers/ipmi/ipmi_if.h @@ -1,7 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef __IPMI_KCS_H -#define __IPMI_KCS_H +#ifndef __IPMI_IF_H +#define __IPMI_IF_H + +/* Common API and code for different IPMI interfaces in different stages */ + +#include #define IPMI_NETFN_CHASSIS 0x00 #define IPMI_NETFN_BRIDGE 0x02 @@ -25,16 +29,6 @@ #define IPMI_CMD_ACPI_POWERON 0x06 -extern int ipmi_kcs_message(int port, int netfn, int lun, int cmd, - const unsigned char *inmsg, int inlen, - unsigned char *outmsg, int outlen); - -/* Run basic IPMI init functions in romstage from the provided PnP device, - * returns CB_SUCCESS on success and CB_ERR if an error occurred. */ -enum cb_err ipmi_kcs_premem_init(const u16 port, const u16 device); - -void ipmi_bmc_version(uint8_t *ipmi_bmc_major_revision, uint8_t *ipmi_bmc_minor_revision); - struct ipmi_rsp { uint8_t lun; uint8_t cmd; @@ -61,4 +55,25 @@ struct ipmi_selftest_rsp { uint8_t param; } __packed; -#endif +struct device; + +/* + * Sends a command and reads its response. Input buffer is for payload, but + * output includes `struct ipmi_rsp` as a header. Returns number of bytes copied + * into the buffer or -1. + */ +int ipmi_message(int port, int netfn, int lun, int cmd, + const unsigned char *inmsg, int inlen, + unsigned char *outmsg, int outlen); + +/* Run basic IPMI init functions in romstage from the provided PnP device, + * returns CB_SUCCESS on success and CB_ERR if an error occurred. */ +enum cb_err ipmi_premem_init(const uint16_t port, const uint16_t device); + +int ipmi_get_device_id(const struct device *dev, struct ipmi_devid_rsp *rsp); + +int ipmi_process_self_test_result(const struct device *dev); + +void ipmi_bmc_version(uint8_t *ipmi_bmc_major_revision, uint8_t *ipmi_bmc_minor_revision); + +#endif /* __IPMI_IF_H */ diff --git a/src/drivers/ipmi/ipmi_kcs.c b/src/drivers/ipmi/ipmi_kcs.c index 12cbe82f14..667827224f 100644 --- a/src/drivers/ipmi/ipmi_kcs.c +++ b/src/drivers/ipmi/ipmi_kcs.c @@ -4,7 +4,7 @@ #include #include #include -#include "ipmi_kcs.h" +#include "ipmi_if.h" #define IPMI_KCS_STATE(_x) ((_x) >> 6) @@ -219,9 +219,9 @@ static int ipmi_kcs_read_message(int port, unsigned char *msg, int len) return ret; } -int ipmi_kcs_message(int port, int netfn, int lun, int cmd, - const unsigned char *inmsg, int inlen, - unsigned char *outmsg, int outlen) +int ipmi_message(int port, int netfn, int lun, int cmd, + const unsigned char *inmsg, int inlen, + unsigned char *outmsg, int outlen) { if (ipmi_kcs_send_message(port, netfn, lun, cmd, inmsg, inlen)) { printk(BIOS_ERR, "ipmi_kcs_send_message failed\n"); diff --git a/src/drivers/ipmi/ipmi_kcs_ops.c b/src/drivers/ipmi/ipmi_kcs_ops.c index 4ffa91fe23..a2ad7abd86 100644 --- a/src/drivers/ipmi/ipmi_kcs_ops.c +++ b/src/drivers/ipmi/ipmi_kcs_ops.c @@ -24,7 +24,7 @@ #include #include #include -#include "ipmi_kcs.h" +#include "ipmi_if.h" #include "ipmi_supermicro_oem.h" #include "chip.h" @@ -37,46 +37,6 @@ static u8 bmc_revision_minor = 0x0; static struct boot_state_callback bscb_post_complete; -static int ipmi_get_device_id(struct device *dev, struct ipmi_devid_rsp *rsp) -{ - int ret; - - ret = ipmi_kcs_message(dev->path.pnp.port, IPMI_NETFN_APPLICATION, 0, - IPMI_BMC_GET_DEVICE_ID, NULL, 0, (u8 *)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 1; - } - if (ret != sizeof(*rsp)) { - printk(BIOS_ERR, "IPMI: %s response truncated\n", __func__); - return 1; - } - return 0; -} - -static int ipmi_get_bmc_self_test_result(struct device *dev, struct ipmi_selftest_rsp *rsp) -{ - int ret; - - ret = ipmi_kcs_message(dev->path.pnp.port, IPMI_NETFN_APPLICATION, 0, - IPMI_BMC_GET_SELFTEST_RESULTS, NULL, 0, (u8 *)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 1; - } - if (ret != sizeof(*rsp)) { - printk(BIOS_ERR, "IPMI: %s response truncated\n", __func__); - return 1; - } - - return 0; -} - static void bmc_set_post_complete_gpio_callback(void *arg) { struct drivers_ipmi_config *conf = arg; @@ -103,8 +63,6 @@ static void ipmi_kcs_init(struct device *dev) uint32_t man_id = 0, prod_id = 0; struct drivers_ipmi_config *conf = dev->chip_info; const struct gpio_operations *gpio_ops; - struct ipmi_selftest_rsp selftestrsp = {0}; - uint8_t retry_count; if (!conf) { printk(BIOS_WARNING, "IPMI: chip_info is missing! Skip init.\n"); @@ -154,41 +112,9 @@ static void ipmi_kcs_init(struct device *dev) } } - printk(BIOS_INFO, "Get BMC self test result..."); - for (retry_count = 0; retry_count < conf->bmc_boot_timeout; retry_count++) { - if (!ipmi_get_bmc_self_test_result(dev, &selftestrsp)) - break; - - mdelay(1000); - } - - switch (selftestrsp.result) { - case IPMI_APP_SELFTEST_NO_ERROR: /* 0x55 */ - printk(BIOS_DEBUG, "No Error\n"); - break; - case IPMI_APP_SELFTEST_NOT_IMPLEMENTED: /* 0x56 */ - printk(BIOS_DEBUG, "Function Not Implemented\n"); - break; - case IPMI_APP_SELFTEST_ERROR: /* 0x57 */ - printk(BIOS_ERR, "BMC: Corrupted or inaccessible data or device\n"); + if (ipmi_process_self_test_result(dev)) /* Don't write tables if communication failed */ dev->enabled = 0; - break; - case IPMI_APP_SELFTEST_FATAL_HW_ERROR: /* 0x58 */ - printk(BIOS_ERR, "BMC: Fatal Hardware Error\n"); - /* Don't write tables if communication failed */ - dev->enabled = 0; - break; - case IPMI_APP_SELFTEST_RESERVED: /* 0xFF */ - printk(BIOS_DEBUG, "Reserved\n"); - break; - - default: /* Other Device Specific Hardware Error */ - printk(BIOS_ERR, "BMC: Device Specific Error\n"); - /* Don't write tables if communication failed */ - dev->enabled = 0; - break; - } if (!ipmi_get_device_id(dev, &rsp)) { /* Queried the IPMI revision from BMC */ diff --git a/src/drivers/ipmi/ipmi_kcs_ops_premem.c b/src/drivers/ipmi/ipmi_kcs_ops_premem.c deleted file mode 100644 index e1ae0dc3e5..0000000000 --- a/src/drivers/ipmi/ipmi_kcs_ops_premem.c +++ /dev/null @@ -1,113 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include - -#include "ipmi_kcs.h" -#include "chip.h" - -static int ipmi_get_bmc_self_test_result(const struct device *dev, - struct ipmi_selftest_rsp *rsp) -{ - int ret; - - ret = ipmi_kcs_message(dev->path.pnp.port, IPMI_NETFN_APPLICATION, 0, - IPMI_BMC_GET_SELFTEST_RESULTS, NULL, 0, (u8 *)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 1; - } - if (ret != sizeof(*rsp)) { - printk(BIOS_ERR, "IPMI: %s response truncated\n", __func__); - return 1; - } - - return 0; -} - -enum cb_err ipmi_kcs_premem_init(const u16 port, const u16 device) -{ - const struct drivers_ipmi_config *conf = NULL; - struct ipmi_selftest_rsp selftestrsp = {0}; - uint8_t retry_count; - const struct device *dev; - - /* Find IPMI PNP device from devicetree in romstage */ - dev = dev_find_slot_pnp(port, device); - - if (!dev) { - printk(BIOS_ERR, "IPMI: Cannot find PNP device port: %x, device %x\n", - port, device); - return CB_ERR; - } - if (!dev->enabled) { - printk(BIOS_ERR, "IPMI: device is not enabled\n"); - return CB_ERR; - } - printk(BIOS_DEBUG, "IPMI: romstage PNP KCS 0x%x\n", dev->path.pnp.port); - if (dev->chip_info) - conf = dev->chip_info; - - if (conf && conf->wait_for_bmc && conf->bmc_boot_timeout) { - struct stopwatch sw; - stopwatch_init_msecs_expire(&sw, conf->bmc_boot_timeout * 1000); - printk(BIOS_DEBUG, "IPMI: Waiting for BMC...\n"); - - while (!stopwatch_expired(&sw)) { - if (inb(dev->path.pnp.port) != 0xff) - break; - mdelay(100); - } - if (stopwatch_expired(&sw)) { - printk(BIOS_INFO, "IPMI: Waiting for BMC timed out\n"); - return CB_ERR; - } - } - - printk(BIOS_INFO, "Get BMC self test result..."); - if (conf && conf->bmc_boot_timeout) { - for (retry_count = 0; retry_count < conf->bmc_boot_timeout; retry_count++) { - if (!ipmi_get_bmc_self_test_result(dev, &selftestrsp)) - break; - - mdelay(1000); - } - } else { - /* At least run once */ - ipmi_get_bmc_self_test_result(dev, &selftestrsp); - } - - int ret = CB_ERR; - switch (selftestrsp.result) { - case IPMI_APP_SELFTEST_NO_ERROR: /* 0x55 */ - printk(BIOS_DEBUG, "No Error\n"); - ret = CB_SUCCESS; - break; - case IPMI_APP_SELFTEST_NOT_IMPLEMENTED: /* 0x56 */ - printk(BIOS_DEBUG, "Function Not Implemented\n"); - ret = CB_SUCCESS; - break; - case IPMI_APP_SELFTEST_ERROR: /* 0x57 */ - printk(BIOS_ERR, "Corrupted or inaccessible data or device\n"); - break; - case IPMI_APP_SELFTEST_FATAL_HW_ERROR: /* 0x58 */ - printk(BIOS_ERR, "Fatal Hardware Error\n"); - break; - case IPMI_APP_SELFTEST_RESERVED: /* 0xFF */ - printk(BIOS_DEBUG, "Reserved\n"); - ret = CB_SUCCESS; - break; - - default: /* Other Device Specific Hardware Error */ - printk(BIOS_ERR, "Device Specific Error 0x%x 0x%x\n", selftestrsp.result, - selftestrsp.param); - break; - } - return ret; -} diff --git a/src/drivers/ipmi/ipmi_ops.c b/src/drivers/ipmi/ipmi_ops.c index 73a02e1f37..d9b3256eec 100644 --- a/src/drivers/ipmi/ipmi_ops.c +++ b/src/drivers/ipmi/ipmi_ops.c @@ -2,6 +2,7 @@ #include #include "ipmi_ops.h" +#include "ipmi_if.h" #include #include @@ -18,7 +19,7 @@ enum cb_err ipmi_init_and_start_bmc_wdt(const int port, uint16_t countdown, /* clear BIOS FRB2 expiration flag */ req.timer_use_expiration_flags_clr = 2; req.initial_countdown_val = countdown; - ret = ipmi_kcs_message(port, IPMI_NETFN_APPLICATION, 0x0, + ret = ipmi_message(port, IPMI_NETFN_APPLICATION, 0x0, IPMI_BMC_SET_WDG_TIMER, (const unsigned char *) &req, sizeof(req), (unsigned char *) &rsp, sizeof(rsp)); @@ -32,7 +33,7 @@ enum cb_err ipmi_init_and_start_bmc_wdt(const int port, uint16_t countdown, } /* Reset command to start timer */ - ret = ipmi_kcs_message(port, IPMI_NETFN_APPLICATION, 0x0, + ret = ipmi_message(port, IPMI_NETFN_APPLICATION, 0x0, IPMI_BMC_RESET_WDG_TIMER, NULL, 0, (unsigned char *) &rsp, sizeof(rsp)); @@ -56,7 +57,7 @@ enum cb_err ipmi_stop_bmc_wdt(const int port) struct ipmi_rsp resp; /* Get current timer first */ - ret = ipmi_kcs_message(port, IPMI_NETFN_APPLICATION, 0x0, + ret = ipmi_message(port, IPMI_NETFN_APPLICATION, 0x0, IPMI_BMC_GET_WDG_TIMER, NULL, 0, (unsigned char *) &rsp, sizeof(rsp)); @@ -76,7 +77,7 @@ enum cb_err ipmi_stop_bmc_wdt(const int port) rsp.data.timer_use &= ~(1 << 6); rsp.data.initial_countdown_val = 0; req = rsp.data; - ret = ipmi_kcs_message(port, IPMI_NETFN_APPLICATION, 0x0, + ret = ipmi_message(port, IPMI_NETFN_APPLICATION, 0x0, IPMI_BMC_SET_WDG_TIMER, (const unsigned char *) &req, sizeof(req), (unsigned char *) &resp, sizeof(resp)); @@ -104,7 +105,7 @@ enum cb_err ipmi_get_system_guid(const int port, uint8_t *uuid) return CB_ERR; } - ret = ipmi_kcs_message(port, IPMI_NETFN_APPLICATION, 0x0, + ret = ipmi_message(port, IPMI_NETFN_APPLICATION, 0x0, IPMI_BMC_GET_SYSTEM_GUID, NULL, 0, (unsigned char *) &rsp, sizeof(rsp)); @@ -128,7 +129,7 @@ enum cb_err ipmi_add_sel(const int port, struct sel_event_record *sel) return CB_ERR; } - ret = ipmi_kcs_message(port, IPMI_NETFN_STORAGE, 0x0, + ret = ipmi_message(port, IPMI_NETFN_STORAGE, 0x0, IPMI_ADD_SEL_ENTRY, (const unsigned char *) sel, 16, (unsigned char *) &rsp, sizeof(rsp)); diff --git a/src/drivers/ipmi/ipmi_ops.h b/src/drivers/ipmi/ipmi_ops.h index d900272e38..7a92a28121 100644 --- a/src/drivers/ipmi/ipmi_ops.h +++ b/src/drivers/ipmi/ipmi_ops.h @@ -4,7 +4,7 @@ #define __IPMI_OPS_H #include -#include "ipmi_kcs.h" +#include "ipmi_if.h" #define IPMI_BMC_RESET_WDG_TIMER 0x22 #define IPMI_BMC_SET_WDG_TIMER 0x24 #define IPMI_BMC_GET_WDG_TIMER 0x25 diff --git a/src/drivers/ipmi/ipmi_ops_premem.c b/src/drivers/ipmi/ipmi_ops_premem.c new file mode 100644 index 0000000000..99c5842bb3 --- /dev/null +++ b/src/drivers/ipmi/ipmi_ops_premem.c @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +#include "ipmi_if.h" +#include "chip.h" + +enum cb_err ipmi_premem_init(const u16 port, const u16 device) +{ + const struct drivers_ipmi_config *conf = NULL; + const struct device *dev; + + /* Find IPMI PNP device from devicetree in romstage */ + dev = dev_find_slot_pnp(port, device); + + if (!dev) { + printk(BIOS_ERR, "IPMI: Cannot find PNP device port: %x, device %x\n", + port, device); + return CB_ERR; + } + if (!dev->enabled) { + printk(BIOS_ERR, "IPMI: device is not enabled\n"); + return CB_ERR; + } + printk(BIOS_DEBUG, "IPMI: romstage PNP KCS 0x%x\n", dev->path.pnp.port); + if (dev->chip_info) + conf = dev->chip_info; + + if (conf && conf->wait_for_bmc && conf->bmc_boot_timeout) { + struct stopwatch sw; + stopwatch_init_msecs_expire(&sw, conf->bmc_boot_timeout * 1000); + printk(BIOS_DEBUG, "IPMI: Waiting for BMC...\n"); + + while (!stopwatch_expired(&sw)) { + if (inb(dev->path.pnp.port) != 0xff) + break; + mdelay(100); + } + if (stopwatch_expired(&sw)) { + printk(BIOS_INFO, "IPMI: Waiting for BMC timed out\n"); + return CB_ERR; + } + } + + if (ipmi_process_self_test_result(dev)) + return CB_ERR; + + return CB_SUCCESS; +} diff --git a/src/drivers/ipmi/ocp/ipmi_ocp.c b/src/drivers/ipmi/ocp/ipmi_ocp.c index 11161a8ae4..9f583be934 100644 --- a/src/drivers/ipmi/ocp/ipmi_ocp.c +++ b/src/drivers/ipmi/ocp/ipmi_ocp.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include @@ -28,8 +28,9 @@ static enum cb_err ipmi_set_ppin(struct device *dev) req.cpu1_lo = xeon_sp_ppin[1].lo; req.cpu1_hi = xeon_sp_ppin[1].hi; } - ret = ipmi_kcs_message(dev->path.pnp.port, IPMI_NETFN_OEM, 0x0, IPMI_OEM_SET_PPIN, - (const unsigned char *) &req, sizeof(req), (unsigned char *) &rsp, sizeof(rsp)); + ret = ipmi_message(dev->path.pnp.port, IPMI_NETFN_OEM, 0x0, IPMI_OEM_SET_PPIN, + (const unsigned char *) &req, sizeof(req), + (unsigned char *) &rsp, sizeof(rsp)); if (ret < sizeof(struct ipmi_rsp) || rsp.completion_code) { printk(BIOS_ERR, "IPMI: %s command failed (ret=%d resp=0x%x)\n", diff --git a/src/drivers/ipmi/ocp/ipmi_ocp_romstage.c b/src/drivers/ipmi/ocp/ipmi_ocp_romstage.c index 8e43d8d159..7b0b9ea036 100644 --- a/src/drivers/ipmi/ocp/ipmi_ocp_romstage.c +++ b/src/drivers/ipmi/ocp/ipmi_ocp_romstage.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include -#include +#include #include "ipmi_ocp.h" @@ -10,9 +10,9 @@ enum cb_err ipmi_set_post_start(const int port) int ret; struct ipmi_rsp rsp; - ret = ipmi_kcs_message(port, IPMI_NETFN_OEM, 0x0, - IPMI_BMC_SET_POST_START, NULL, 0, (u8 *) &rsp, - sizeof(rsp)); + ret = ipmi_message(port, IPMI_NETFN_OEM, 0x0, + IPMI_BMC_SET_POST_START, NULL, 0, (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", @@ -42,10 +42,10 @@ enum cb_err ipmi_set_cmos_clear(void) /* IPMI OEM get bios boot order command to check if the valid bit and the CMOS clear bit are both set from the response BootMode byte. */ - ret = ipmi_kcs_message(CONFIG_BMC_KCS_BASE, IPMI_NETFN_OEM, 0x0, - IPMI_OEM_GET_BIOS_BOOT_ORDER, - NULL, 0, - (unsigned char *) &rsp, sizeof(rsp)); + ret = ipmi_message(CONFIG_BMC_KCS_BASE, IPMI_NETFN_OEM, 0x0, + IPMI_OEM_GET_BIOS_BOOT_ORDER, + NULL, 0, + (unsigned char *) &rsp, sizeof(rsp)); if (ret < sizeof(struct ipmi_rsp) || rsp.resp.completion_code) { printk(BIOS_ERR, "IPMI: %s command failed (read ret=%d resp=0x%x)\n", @@ -56,10 +56,10 @@ enum cb_err ipmi_set_cmos_clear(void) if (!IS_CMOS_AND_VALID_BIT(rsp.data.boot_mode)) { req = rsp.data; SET_CMOS_AND_VALID_BIT(req.boot_mode); - ret = ipmi_kcs_message(CONFIG_BMC_KCS_BASE, IPMI_NETFN_OEM, 0x0, - IPMI_OEM_SET_BIOS_BOOT_ORDER, - (const unsigned char *) &req, sizeof(req), - (unsigned char *) &rsp, sizeof(rsp)); + ret = ipmi_message(CONFIG_BMC_KCS_BASE, IPMI_NETFN_OEM, 0x0, + IPMI_OEM_SET_BIOS_BOOT_ORDER, + (const unsigned char *) &req, sizeof(req), + (unsigned char *) &rsp, sizeof(rsp)); if (ret < sizeof(struct ipmi_rsp) || rsp.resp.completion_code) { printk(BIOS_ERR, "IPMI: %s command failed (sent ret=%d resp=0x%x)\n", diff --git a/src/drivers/ipmi/supermicro_oem.c b/src/drivers/ipmi/supermicro_oem.c index 9d5ffc77a4..7af4e3b8a4 100644 --- a/src/drivers/ipmi/supermicro_oem.c +++ b/src/drivers/ipmi/supermicro_oem.c @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include #include "ipmi_supermicro_oem.h" @@ -35,9 +35,9 @@ static void set_coreboot_ver(const uint16_t kcs_port) bios_ver.str[i] = 0; bios_ver.ver = IPMI_LUN0_AC_SET_BIOS_VER; - ret = ipmi_kcs_message(kcs_port, IPMI_NETFN_OEM, 0, IPMI_LUN0_SET_BIOS_STRING, - (const unsigned char *) &bios_ver, sizeof(bios_ver), - (unsigned char *) &rsp, sizeof(rsp)); + ret = ipmi_message(kcs_port, IPMI_NETFN_OEM, 0, IPMI_LUN0_SET_BIOS_STRING, + (const unsigned char *) &bios_ver, sizeof(bios_ver), + (unsigned char *) &rsp, sizeof(rsp)); if (ret < sizeof(rsp) || rsp.completion_code) { printk(BIOS_ERR, "BMC_IPMI: %s command failed (ret=%d resp=0x%x)\n", __func__, ret, rsp.completion_code); @@ -54,9 +54,9 @@ static void set_coreboot_date(const uint16_t kcs_port) bios_ver.str[15] = 0; bios_ver.ver = IPMI_LUN0_AC_SET_BIOS_DATE; - ret = ipmi_kcs_message(kcs_port, IPMI_NETFN_OEM, 0, IPMI_LUN0_SET_BIOS_STRING, - (const unsigned char *) &bios_ver, sizeof(bios_ver), - (unsigned char *) &rsp, sizeof(rsp)); + ret = ipmi_message(kcs_port, IPMI_NETFN_OEM, 0, IPMI_LUN0_SET_BIOS_STRING, + (const unsigned char *) &bios_ver, sizeof(bios_ver), + (unsigned char *) &rsp, sizeof(rsp)); if (ret < sizeof(rsp) || rsp.completion_code) { printk(BIOS_ERR, "BMC_IPMI: %s command failed (ret=%d resp=0x%x)\n", __func__, ret, rsp.completion_code); diff --git a/src/mainboard/ocp/deltalake/ipmi.c b/src/mainboard/ocp/deltalake/ipmi.c index 25a5a27cba..d990b87e80 100644 --- a/src/mainboard/ocp/deltalake/ipmi.c +++ b/src/mainboard/ocp/deltalake/ipmi.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include -#include +#include #include #include #include @@ -18,7 +18,7 @@ enum cb_err ipmi_get_pcie_config(uint8_t *pcie_config) } __packed; struct ipmi_config_rsp rsp; - ret = ipmi_kcs_message(CONFIG_BMC_KCS_BASE, IPMI_NETFN_OEM, 0x0, + ret = ipmi_message(CONFIG_BMC_KCS_BASE, IPMI_NETFN_OEM, 0x0, IPMI_OEM_GET_PCIE_CONFIG, NULL, 0, (unsigned char *) &rsp, sizeof(rsp)); @@ -44,7 +44,7 @@ enum cb_err ipmi_get_slot_id(uint8_t *slot_id) } __packed; struct ipmi_config_rsp rsp; - ret = ipmi_kcs_message(CONFIG_BMC_KCS_BASE, IPMI_NETFN_OEM, 0x0, IPMI_OEM_GET_BOARD_ID, + ret = ipmi_message(CONFIG_BMC_KCS_BASE, 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) { diff --git a/src/mainboard/ocp/deltalake/romstage.c b/src/mainboard/ocp/deltalake/romstage.c index 05a7188da4..2efed1ca84 100644 --- a/src/mainboard/ocp/deltalake/romstage.c +++ b/src/mainboard/ocp/deltalake/romstage.c @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include @@ -188,7 +188,7 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) /* Since it's the first IPMI command, it's better to run get BMC selftest result first */ - if (ipmi_kcs_premem_init(CONFIG_BMC_KCS_BASE, 0) == CB_SUCCESS) { + if (ipmi_premem_init(CONFIG_BMC_KCS_BASE, 0) == CB_SUCCESS) { ipmi_set_post_start(CONFIG_BMC_KCS_BASE); init_frb2_wdt(); } diff --git a/src/mainboard/ocp/tiogapass/ipmi.c b/src/mainboard/ocp/tiogapass/ipmi.c index 74f96fe36c..e97341b2b6 100644 --- a/src/mainboard/ocp/tiogapass/ipmi.c +++ b/src/mainboard/ocp/tiogapass/ipmi.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include -#include +#include #include #include #include diff --git a/src/mainboard/ocp/tiogapass/romstage.c b/src/mainboard/ocp/tiogapass/romstage.c index 20c74660ce..842e977d3e 100644 --- a/src/mainboard/ocp/tiogapass/romstage.c +++ b/src/mainboard/ocp/tiogapass/romstage.c @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include @@ -54,7 +54,7 @@ static void mainboard_config_iio(FSPM_UPD *mupd) void mainboard_memory_init_params(FSPM_UPD *mupd) { /* It's better to run get BMC selftest result first */ - if (ipmi_kcs_premem_init(CONFIG_BMC_KCS_BASE, 0) == CB_SUCCESS) { + if (ipmi_premem_init(CONFIG_BMC_KCS_BASE, 0) == CB_SUCCESS) { ipmi_set_post_start(CONFIG_BMC_KCS_BASE); init_frb2_wdt(); }