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>
This commit is contained in:
Sergii Dmytruk 2021-10-22 01:02:32 +03:00 committed by Martin Roth
parent 36d7f82d98
commit ef7dd5d54d
19 changed files with 245 additions and 246 deletions

View File

@ -42,6 +42,15 @@ The following registers can be set:
* `gpe_interrupt` * `gpe_interrupt`
* Integer * Integer
* The bit in GPE (SCI) used to notify about a change on the KCS. * 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 [IPMI]: https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/ipmi-second-gen-interface-spec-v2-rev1-1.pdf

View File

@ -1,8 +1,10 @@
ramstage-$(CONFIG_IPMI_KCS) += ipmi_if.c
ramstage-$(CONFIG_IPMI_KCS) += ipmi_kcs.c ramstage-$(CONFIG_IPMI_KCS) += ipmi_kcs.c
ramstage-$(CONFIG_IPMI_KCS) += ipmi_kcs_ops.c ramstage-$(CONFIG_IPMI_KCS) += ipmi_kcs_ops.c
ramstage-$(CONFIG_IPMI_KCS) += ipmi_ops.c ramstage-$(CONFIG_IPMI_KCS) += ipmi_ops.c
ramstage-$(CONFIG_IPMI_KCS) += ipmi_fru.c ramstage-$(CONFIG_IPMI_KCS) += ipmi_fru.c
ramstage-$(CONFIG_DRIVERS_IPMI_SUPERMICRO_OEM) += supermicro_oem.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_kcs.c
romstage-$(CONFIG_IPMI_KCS_ROMSTAGE) += ipmi_ops.c romstage-$(CONFIG_IPMI_KCS_ROMSTAGE) += ipmi_ops.c

View File

@ -8,6 +8,7 @@
#include <stdint.h> #include <stdint.h>
struct drivers_ipmi_config { struct drivers_ipmi_config {
#if CONFIG(IPMI_KCS)
u8 bmc_i2c_address; u8 bmc_i2c_address;
u8 have_nv_storage; u8 have_nv_storage;
u8 nv_storage_device_address; u8 nv_storage_device_address;
@ -25,6 +26,9 @@ struct drivers_ipmi_config {
/* "POST complete" GPIO and polarity */ /* "POST complete" GPIO and polarity */
u32 post_complete_gpio; u32 post_complete_gpio;
bool post_complete_invert; bool post_complete_invert;
unsigned int uid; /* Auto-filled by ipmi_ssdt() */
#endif
/* /*
* Wait for BMC to boot. * Wait for BMC to boot.
* This can be used if the BMC takes a long time to boot after PoR: * 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. * Will be used if wait_for_bmc is true.
*/ */
u16 bmc_boot_timeout; u16 bmc_boot_timeout;
unsigned int uid; /* Auto-filled by ipmi_ssdt() */
}; };
#endif /* _IMPI_CHIP_H_ */ #endif /* _IMPI_CHIP_H_ */

View File

@ -5,6 +5,7 @@
#include <delay.h> #include <delay.h>
#include <stdlib.h> #include <stdlib.h>
#include "ipmi_if.h"
#include "ipmi_ops.h" #include "ipmi_ops.h"
#define MAX_FRU_BUSY_RETRY 5 #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; req->count = CONFIG_IPMI_FRU_SINGLE_RW_SZ;
while (retry_count <= MAX_FRU_BUSY_RETRY) { 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, IPMI_READ_FRU_DATA, (const unsigned char *) req,
sizeof(*req), (unsigned char *) &rsp, sizeof(rsp)); sizeof(*req), (unsigned char *) &rsp, sizeof(rsp));
if (rsp.resp.completion_code == 0x81) { if (rsp.resp.completion_code == 0x81) {

101
src/drivers/ipmi/ipmi_if.c Normal file
View File

@ -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;
}

View File

@ -1,7 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __IPMI_KCS_H #ifndef __IPMI_IF_H
#define __IPMI_KCS_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_CHASSIS 0x00
#define IPMI_NETFN_BRIDGE 0x02 #define IPMI_NETFN_BRIDGE 0x02
@ -25,16 +29,6 @@
#define IPMI_CMD_ACPI_POWERON 0x06 #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 { struct ipmi_rsp {
uint8_t lun; uint8_t lun;
uint8_t cmd; uint8_t cmd;
@ -61,4 +55,25 @@ struct ipmi_selftest_rsp {
uint8_t param; uint8_t param;
} __packed; } __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 */

View File

@ -4,7 +4,7 @@
#include <device/device.h> #include <device/device.h>
#include <arch/io.h> #include <arch/io.h>
#include <timer.h> #include <timer.h>
#include "ipmi_kcs.h" #include "ipmi_if.h"
#define IPMI_KCS_STATE(_x) ((_x) >> 6) #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; return ret;
} }
int ipmi_kcs_message(int port, int netfn, int lun, int cmd, int ipmi_message(int port, int netfn, int lun, int cmd,
const unsigned char *inmsg, int inlen, const unsigned char *inmsg, int inlen,
unsigned char *outmsg, int outlen) unsigned char *outmsg, int outlen)
{ {
if (ipmi_kcs_send_message(port, netfn, lun, cmd, inmsg, inlen)) { if (ipmi_kcs_send_message(port, netfn, lun, cmd, inmsg, inlen)) {
printk(BIOS_ERR, "ipmi_kcs_send_message failed\n"); printk(BIOS_ERR, "ipmi_kcs_send_message failed\n");

View File

@ -24,7 +24,7 @@
#include <version.h> #include <version.h>
#include <delay.h> #include <delay.h>
#include <timer.h> #include <timer.h>
#include "ipmi_kcs.h" #include "ipmi_if.h"
#include "ipmi_supermicro_oem.h" #include "ipmi_supermicro_oem.h"
#include "chip.h" #include "chip.h"
@ -37,46 +37,6 @@ static u8 bmc_revision_minor = 0x0;
static struct boot_state_callback bscb_post_complete; 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) static void bmc_set_post_complete_gpio_callback(void *arg)
{ {
struct drivers_ipmi_config *conf = 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; uint32_t man_id = 0, prod_id = 0;
struct drivers_ipmi_config *conf = dev->chip_info; struct drivers_ipmi_config *conf = dev->chip_info;
const struct gpio_operations *gpio_ops; const struct gpio_operations *gpio_ops;
struct ipmi_selftest_rsp selftestrsp = {0};
uint8_t retry_count;
if (!conf) { if (!conf) {
printk(BIOS_WARNING, "IPMI: chip_info is missing! Skip init.\n"); 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..."); if (ipmi_process_self_test_result(dev))
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");
/* Don't write tables if communication failed */ /* Don't write tables if communication failed */
dev->enabled = 0; 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)) { if (!ipmi_get_device_id(dev, &rsp)) {
/* Queried the IPMI revision from BMC */ /* Queried the IPMI revision from BMC */

View File

@ -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;
}

View File

@ -2,6 +2,7 @@
#include <console/console.h> #include <console/console.h>
#include "ipmi_ops.h" #include "ipmi_ops.h"
#include "ipmi_if.h"
#include <string.h> #include <string.h>
#include <types.h> #include <types.h>
@ -18,7 +19,7 @@ enum cb_err ipmi_init_and_start_bmc_wdt(const int port, uint16_t countdown,
/* clear BIOS FRB2 expiration flag */ /* clear BIOS FRB2 expiration flag */
req.timer_use_expiration_flags_clr = 2; req.timer_use_expiration_flags_clr = 2;
req.initial_countdown_val = countdown; 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, IPMI_BMC_SET_WDG_TIMER,
(const unsigned char *) &req, sizeof(req), (const unsigned char *) &req, sizeof(req),
(unsigned char *) &rsp, sizeof(rsp)); (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 */ /* 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, IPMI_BMC_RESET_WDG_TIMER, NULL, 0,
(unsigned char *) &rsp, sizeof(rsp)); (unsigned char *) &rsp, sizeof(rsp));
@ -56,7 +57,7 @@ enum cb_err ipmi_stop_bmc_wdt(const int port)
struct ipmi_rsp resp; struct ipmi_rsp resp;
/* Get current timer first */ /* 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, IPMI_BMC_GET_WDG_TIMER, NULL, 0,
(unsigned char *) &rsp, sizeof(rsp)); (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.timer_use &= ~(1 << 6);
rsp.data.initial_countdown_val = 0; rsp.data.initial_countdown_val = 0;
req = rsp.data; 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, IPMI_BMC_SET_WDG_TIMER,
(const unsigned char *) &req, sizeof(req), (const unsigned char *) &req, sizeof(req),
(unsigned char *) &resp, sizeof(resp)); (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; 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, IPMI_BMC_GET_SYSTEM_GUID, NULL, 0,
(unsigned char *) &rsp, sizeof(rsp)); (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; 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, IPMI_ADD_SEL_ENTRY, (const unsigned char *) sel,
16, (unsigned char *) &rsp, sizeof(rsp)); 16, (unsigned char *) &rsp, sizeof(rsp));

View File

@ -4,7 +4,7 @@
#define __IPMI_OPS_H #define __IPMI_OPS_H
#include <types.h> #include <types.h>
#include "ipmi_kcs.h" #include "ipmi_if.h"
#define IPMI_BMC_RESET_WDG_TIMER 0x22 #define IPMI_BMC_RESET_WDG_TIMER 0x22
#define IPMI_BMC_SET_WDG_TIMER 0x24 #define IPMI_BMC_SET_WDG_TIMER 0x24
#define IPMI_BMC_GET_WDG_TIMER 0x25 #define IPMI_BMC_GET_WDG_TIMER 0x25

View File

@ -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;
}

View File

@ -10,7 +10,7 @@
#include <console/console.h> #include <console/console.h>
#include <device/device.h> #include <device/device.h>
#include <device/pnp.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 <drivers/ocp/dmi/ocp_dmi.h>
#include <types.h> #include <types.h>
@ -28,8 +28,9 @@ static enum cb_err ipmi_set_ppin(struct device *dev)
req.cpu1_lo = xeon_sp_ppin[1].lo; req.cpu1_lo = xeon_sp_ppin[1].lo;
req.cpu1_hi = xeon_sp_ppin[1].hi; req.cpu1_hi = xeon_sp_ppin[1].hi;
} }
ret = ipmi_kcs_message(dev->path.pnp.port, IPMI_NETFN_OEM, 0x0, IPMI_OEM_SET_PPIN, 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)); (const unsigned char *) &req, sizeof(req),
(unsigned char *) &rsp, sizeof(rsp));
if (ret < sizeof(struct ipmi_rsp) || rsp.completion_code) { if (ret < sizeof(struct ipmi_rsp) || rsp.completion_code) {
printk(BIOS_ERR, "IPMI: %s command failed (ret=%d resp=0x%x)\n", printk(BIOS_ERR, "IPMI: %s command failed (ret=%d resp=0x%x)\n",

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */ /* SPDX-License-Identifier: GPL-2.0-or-later */
#include <console/console.h> #include <console/console.h>
#include <drivers/ipmi/ipmi_kcs.h> #include <drivers/ipmi/ipmi_if.h>
#include "ipmi_ocp.h" #include "ipmi_ocp.h"
@ -10,9 +10,9 @@ enum cb_err ipmi_set_post_start(const int port)
int ret; int ret;
struct ipmi_rsp rsp; struct ipmi_rsp rsp;
ret = ipmi_kcs_message(port, IPMI_NETFN_OEM, 0x0, ret = ipmi_message(port, IPMI_NETFN_OEM, 0x0,
IPMI_BMC_SET_POST_START, NULL, 0, (u8 *) &rsp, IPMI_BMC_SET_POST_START, NULL, 0, (u8 *) &rsp,
sizeof(rsp)); sizeof(rsp));
if (ret < sizeof(struct ipmi_rsp) || rsp.completion_code) { if (ret < sizeof(struct ipmi_rsp) || rsp.completion_code) {
printk(BIOS_ERR, "IPMI: %s command failed (ret=%d rsp=0x%x)\n", 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 /* 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. */ the CMOS clear bit are both set from the response BootMode byte. */
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_BIOS_BOOT_ORDER, IPMI_OEM_GET_BIOS_BOOT_ORDER,
NULL, 0, NULL, 0,
(unsigned char *) &rsp, sizeof(rsp)); (unsigned char *) &rsp, sizeof(rsp));
if (ret < sizeof(struct ipmi_rsp) || rsp.resp.completion_code) { if (ret < sizeof(struct ipmi_rsp) || rsp.resp.completion_code) {
printk(BIOS_ERR, "IPMI: %s command failed (read ret=%d resp=0x%x)\n", 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)) { if (!IS_CMOS_AND_VALID_BIT(rsp.data.boot_mode)) {
req = rsp.data; req = rsp.data;
SET_CMOS_AND_VALID_BIT(req.boot_mode); SET_CMOS_AND_VALID_BIT(req.boot_mode);
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_SET_BIOS_BOOT_ORDER, IPMI_OEM_SET_BIOS_BOOT_ORDER,
(const unsigned char *) &req, sizeof(req), (const unsigned char *) &req, sizeof(req),
(unsigned char *) &rsp, sizeof(rsp)); (unsigned char *) &rsp, sizeof(rsp));
if (ret < sizeof(struct ipmi_rsp) || rsp.resp.completion_code) { if (ret < sizeof(struct ipmi_rsp) || rsp.resp.completion_code) {
printk(BIOS_ERR, "IPMI: %s command failed (sent ret=%d resp=0x%x)\n", printk(BIOS_ERR, "IPMI: %s command failed (sent ret=%d resp=0x%x)\n",

View File

@ -3,7 +3,7 @@
#include <types.h> #include <types.h>
#include <console/console.h> #include <console/console.h>
#include <drivers/ipmi/ipmi_kcs.h> #include <drivers/ipmi/ipmi_if.h>
#include <string.h> #include <string.h>
#include <build.h> #include <build.h>
#include "ipmi_supermicro_oem.h" #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.str[i] = 0;
bios_ver.ver = IPMI_LUN0_AC_SET_BIOS_VER; bios_ver.ver = IPMI_LUN0_AC_SET_BIOS_VER;
ret = ipmi_kcs_message(kcs_port, IPMI_NETFN_OEM, 0, IPMI_LUN0_SET_BIOS_STRING, ret = ipmi_message(kcs_port, IPMI_NETFN_OEM, 0, IPMI_LUN0_SET_BIOS_STRING,
(const unsigned char *) &bios_ver, sizeof(bios_ver), (const unsigned char *) &bios_ver, sizeof(bios_ver),
(unsigned char *) &rsp, sizeof(rsp)); (unsigned char *) &rsp, sizeof(rsp));
if (ret < sizeof(rsp) || rsp.completion_code) { if (ret < sizeof(rsp) || rsp.completion_code) {
printk(BIOS_ERR, "BMC_IPMI: %s command failed (ret=%d resp=0x%x)\n", printk(BIOS_ERR, "BMC_IPMI: %s command failed (ret=%d resp=0x%x)\n",
__func__, ret, rsp.completion_code); __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.str[15] = 0;
bios_ver.ver = IPMI_LUN0_AC_SET_BIOS_DATE; bios_ver.ver = IPMI_LUN0_AC_SET_BIOS_DATE;
ret = ipmi_kcs_message(kcs_port, IPMI_NETFN_OEM, 0, IPMI_LUN0_SET_BIOS_STRING, ret = ipmi_message(kcs_port, IPMI_NETFN_OEM, 0, IPMI_LUN0_SET_BIOS_STRING,
(const unsigned char *) &bios_ver, sizeof(bios_ver), (const unsigned char *) &bios_ver, sizeof(bios_ver),
(unsigned char *) &rsp, sizeof(rsp)); (unsigned char *) &rsp, sizeof(rsp));
if (ret < sizeof(rsp) || rsp.completion_code) { if (ret < sizeof(rsp) || rsp.completion_code) {
printk(BIOS_ERR, "BMC_IPMI: %s command failed (ret=%d resp=0x%x)\n", printk(BIOS_ERR, "BMC_IPMI: %s command failed (ret=%d resp=0x%x)\n",
__func__, ret, rsp.completion_code); __func__, ret, rsp.completion_code);

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */ /* SPDX-License-Identifier: GPL-2.0-or-later */
#include <console/console.h> #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/ipmi_ops.h>
#include <drivers/ipmi/ocp/ipmi_ocp.h> #include <drivers/ipmi/ocp/ipmi_ocp.h>
#include <drivers/vpd/vpd.h> #include <drivers/vpd/vpd.h>
@ -18,7 +18,7 @@ enum cb_err ipmi_get_pcie_config(uint8_t *pcie_config)
} __packed; } __packed;
struct ipmi_config_rsp rsp; 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, IPMI_OEM_GET_PCIE_CONFIG, NULL, 0, (unsigned char *) &rsp,
sizeof(rsp)); sizeof(rsp));
@ -44,7 +44,7 @@ enum cb_err ipmi_get_slot_id(uint8_t *slot_id)
} __packed; } __packed;
struct ipmi_config_rsp rsp; 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)); NULL, 0, (unsigned char *) &rsp, sizeof(rsp));
if (ret < sizeof(struct ipmi_rsp) || rsp.resp.completion_code) { if (ret < sizeof(struct ipmi_rsp) || rsp.resp.completion_code) {

View File

@ -2,7 +2,7 @@
#include <console/console.h> #include <console/console.h>
#include <console/uart.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/ipmi/ocp/ipmi_ocp.h>
#include <drivers/vpd/vpd.h> #include <drivers/vpd/vpd.h>
#include <fsp/api.h> #include <fsp/api.h>
@ -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 /* Since it's the first IPMI command, it's better to run get BMC
selftest result first */ 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); ipmi_set_post_start(CONFIG_BMC_KCS_BASE);
init_frb2_wdt(); init_frb2_wdt();
} }

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
#include <console/console.h> #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/ipmi_ops.h>
#include <drivers/ipmi/ocp/ipmi_ocp.h> #include <drivers/ipmi/ocp/ipmi_ocp.h>
#include <drivers/vpd/vpd.h> #include <drivers/vpd/vpd.h>

View File

@ -2,7 +2,7 @@
#include <fsp/api.h> #include <fsp/api.h>
#include <FspmUpd.h> #include <FspmUpd.h>
#include <drivers/ipmi/ipmi_kcs.h> #include <drivers/ipmi/ipmi_if.h>
#include <drivers/ipmi/ocp/ipmi_ocp.h> #include <drivers/ipmi/ocp/ipmi_ocp.h>
#include <soc/romstage.h> #include <soc/romstage.h>
#include <string.h> #include <string.h>
@ -54,7 +54,7 @@ static void mainboard_config_iio(FSPM_UPD *mupd)
void mainboard_memory_init_params(FSPM_UPD *mupd) void mainboard_memory_init_params(FSPM_UPD *mupd)
{ {
/* It's better to run get BMC selftest result first */ /* 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); ipmi_set_post_start(CONFIG_BMC_KCS_BASE);
init_frb2_wdt(); init_frb2_wdt();
} }