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:
parent
36d7f82d98
commit
ef7dd5d54d
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 @@ 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_ */
|
||||
|
|
|
@ -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 @@ 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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 @@ 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 */
|
|
@ -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 @@ 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");
|
||||
|
|
|
@ -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 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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 @@ 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));
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 @@ 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",
|
||||
|
|
|
@ -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 @@ 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",
|
||||
|
|
|
@ -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 @@ 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);
|
||||
|
|
|
@ -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 @@ 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) {
|
||||
|
|
|
@ -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 @@ 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();
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 @@ 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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue