Martin Roth has submitted this change. ( https://review.coreboot.org/c/coreboot/+/67056 )
Change subject: drivers/ipmi: prepare for adding more interfaces ......................................................................
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 sergii.dmytruk@3mdeb.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/67056 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Krystian Hebel krystian.hebel@3mdeb.com --- M Documentation/drivers/ipmi_kcs.md M src/drivers/ipmi/Makefile.inc M src/drivers/ipmi/chip.h M src/drivers/ipmi/ipmi_fru.c A src/drivers/ipmi/ipmi_if.c R src/drivers/ipmi/ipmi_if.h M src/drivers/ipmi/ipmi_kcs.c M src/drivers/ipmi/ipmi_kcs_ops.c D src/drivers/ipmi/ipmi_kcs_ops_premem.c M src/drivers/ipmi/ipmi_ops.c M src/drivers/ipmi/ipmi_ops.h A src/drivers/ipmi/ipmi_ops_premem.c M src/drivers/ipmi/ocp/ipmi_ocp.c M src/drivers/ipmi/ocp/ipmi_ocp_romstage.c M src/drivers/ipmi/supermicro_oem.c M src/mainboard/ocp/deltalake/ipmi.c M src/mainboard/ocp/deltalake/romstage.c M src/mainboard/ocp/tiogapass/ipmi.c M src/mainboard/ocp/tiogapass/romstage.c 19 files changed, 262 insertions(+), 246 deletions(-)
Approvals: build bot (Jenkins): Verified Krystian Hebel: Looks good to me, approved
diff --git a/Documentation/drivers/ipmi_kcs.md b/Documentation/drivers/ipmi_kcs.md index f6f0fb9..c4db492 100644 --- a/Documentation/drivers/ipmi_kcs.md +++ b/Documentation/drivers/ipmi_kcs.md @@ -42,6 +42,15 @@ * `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/... diff --git a/src/drivers/ipmi/Makefile.inc b/src/drivers/ipmi/Makefile.inc index e4bcf31..85f3dde 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 4e9d9e1..3b970c9 100644 --- a/src/drivers/ipmi/chip.h +++ b/src/drivers/ipmi/chip.h @@ -8,6 +8,7 @@ #include <stdint.h>
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 @@ /* "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 @@ * 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 822e5bf..f165307 100644 --- a/src/drivers/ipmi/ipmi_fru.c +++ b/src/drivers/ipmi/ipmi_fru.c @@ -5,6 +5,7 @@ #include <delay.h> #include <stdlib.h>
+#include "ipmi_if.h" #include "ipmi_ops.h"
#define MAX_FRU_BUSY_RETRY 5 @@ -34,7 +35,7 @@ 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 0000000..4ff9004 --- /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 <console/console.h> +#include <delay.h> + +#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 33ddd5f..984b469 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 <stdint.h>
#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 @@ 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 12cbe82f1..6678272 100644 --- a/src/drivers/ipmi/ipmi_kcs.c +++ b/src/drivers/ipmi/ipmi_kcs.c @@ -4,7 +4,7 @@ #include <device/device.h> #include <arch/io.h> #include <timer.h> -#include "ipmi_kcs.h" +#include "ipmi_if.h"
#define IPMI_KCS_STATE(_x) ((_x) >> 6)
@@ -219,9 +219,9 @@ 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 4ffa91f..a2ad7ab 100644 --- a/src/drivers/ipmi/ipmi_kcs_ops.c +++ b/src/drivers/ipmi/ipmi_kcs_ops.c @@ -24,7 +24,7 @@ #include <version.h> #include <delay.h> #include <timer.h> -#include "ipmi_kcs.h" +#include "ipmi_if.h" #include "ipmi_supermicro_oem.h" #include "chip.h"
@@ -37,46 +37,6 @@
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 @@ 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 @@ } }
- 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 e1ae0dc..0000000 --- a/src/drivers/ipmi/ipmi_kcs_ops_premem.c +++ /dev/null @@ -1,113 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include <arch/io.h> -#include <console/console.h> -#include <device/pnp.h> -#include <delay.h> -#include <timer.h> - -#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 73a02e1..d9b3256 100644 --- a/src/drivers/ipmi/ipmi_ops.c +++ b/src/drivers/ipmi/ipmi_ops.c @@ -2,6 +2,7 @@
#include <console/console.h> #include "ipmi_ops.h" +#include "ipmi_if.h" #include <string.h> #include <types.h>
@@ -18,7 +19,7 @@ /* 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 @@ }
/* 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 @@ 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 @@ 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 @@ 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 @@ 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 d900272..7a92a28 100644 --- a/src/drivers/ipmi/ipmi_ops.h +++ b/src/drivers/ipmi/ipmi_ops.h @@ -4,7 +4,7 @@ #define __IPMI_OPS_H
#include <types.h> -#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 0000000..99c5842 --- /dev/null +++ b/src/drivers/ipmi/ipmi_ops_premem.c @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <arch/io.h> +#include <console/console.h> +#include <device/pnp.h> +#include <delay.h> +#include <timer.h> + +#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 11161a8..9f583be 100644 --- a/src/drivers/ipmi/ocp/ipmi_ocp.c +++ b/src/drivers/ipmi/ocp/ipmi_ocp.c @@ -10,7 +10,7 @@ #include <console/console.h> #include <device/device.h> #include <device/pnp.h> -#include <drivers/ipmi/ipmi_kcs.h> +#include <drivers/ipmi/ipmi_if.h> #include <drivers/ocp/dmi/ocp_dmi.h> #include <types.h>
@@ -28,8 +28,9 @@ 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 8e43d8d..7b0b9ea 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 <console/console.h> -#include <drivers/ipmi/ipmi_kcs.h> +#include <drivers/ipmi/ipmi_if.h>
#include "ipmi_ocp.h"
@@ -10,9 +10,9 @@ 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 @@
/* 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 @@ 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 9d5ffc7..7af4e3b 100644 --- a/src/drivers/ipmi/supermicro_oem.c +++ b/src/drivers/ipmi/supermicro_oem.c @@ -3,7 +3,7 @@ #include <types.h>
#include <console/console.h> -#include <drivers/ipmi/ipmi_kcs.h> +#include <drivers/ipmi/ipmi_if.h> #include <string.h> #include <build.h> #include "ipmi_supermicro_oem.h" @@ -35,9 +35,9 @@ 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 @@ 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 25a5a27..d990b87 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 <console/console.h> -#include <drivers/ipmi/ipmi_kcs.h> +#include <drivers/ipmi/ipmi_if.h> #include <drivers/ipmi/ipmi_ops.h> #include <drivers/ipmi/ocp/ipmi_ocp.h> #include <drivers/vpd/vpd.h> @@ -18,7 +18,7 @@ } __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 @@ } __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 05a7188..2efed1c 100644 --- a/src/mainboard/ocp/deltalake/romstage.c +++ b/src/mainboard/ocp/deltalake/romstage.c @@ -2,7 +2,7 @@
#include <console/console.h> #include <console/uart.h> -#include <drivers/ipmi/ipmi_kcs.h> +#include <drivers/ipmi/ipmi_if.h> #include <drivers/ipmi/ocp/ipmi_ocp.h> #include <drivers/vpd/vpd.h> #include <fsp/api.h> @@ -188,7 +188,7 @@
/* 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 74f96fe..e97341b 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 <console/console.h> -#include <drivers/ipmi/ipmi_kcs.h> +#include <drivers/ipmi/ipmi_if.h> #include <drivers/ipmi/ipmi_ops.h> #include <drivers/ipmi/ocp/ipmi_ocp.h> #include <drivers/vpd/vpd.h> diff --git a/src/mainboard/ocp/tiogapass/romstage.c b/src/mainboard/ocp/tiogapass/romstage.c index 20c7466..842e977 100644 --- a/src/mainboard/ocp/tiogapass/romstage.c +++ b/src/mainboard/ocp/tiogapass/romstage.c @@ -2,7 +2,7 @@
#include <fsp/api.h> #include <FspmUpd.h> -#include <drivers/ipmi/ipmi_kcs.h> +#include <drivers/ipmi/ipmi_if.h> #include <drivers/ipmi/ocp/ipmi_ocp.h> #include <soc/romstage.h> #include <string.h> @@ -54,7 +54,7 @@ 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(); }