drivers/ocp/ewl: Add sending Meta's BMC SEL for memory training error
Add sending Meta's BMC SEL for memory training error occurred in EWL type 3 error. The detail definition of EWL (Enhanced Warning Log) can be found in the specification document -- BIOS Data ACPI Table (BDAT) Interface Specification v4.0 Draft 5: https://uefi.org/sites/default/files/resources/BDAT%20Specification%20v4.0%20Draft5_0.pdf Change-Id: I664e9d3da7910b47260881c0df64159c8dbe2dca Signed-off-by: Shelly Chang <Shelly_Chang@wiwynn.com> Signed-off-by: Johnny Lin <johnny_lin@wiwynn.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/69147 Reviewed-by: Jonathan Zhang <jon.zhixiong.zhang@gmail.com> Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
930dbc0d04
commit
e17fc5dc0b
|
@ -1,5 +1,5 @@
|
||||||
ramstage-$(CONFIG_IPMI_OCP) += ipmi_ocp.c ipmi_sel.c
|
ramstage-$(CONFIG_IPMI_OCP) += ipmi_ocp.c ipmi_sel.c
|
||||||
ifeq ($(CONFIG_IPMI_OCP),y)
|
ifeq ($(CONFIG_IPMI_OCP),y)
|
||||||
romstage-$(CONFIG_IPMI_KCS_ROMSTAGE) += ipmi_ocp_romstage.c
|
romstage-$(CONFIG_IPMI_KCS_ROMSTAGE) += ipmi_ocp_romstage.c ipmi_sel.c
|
||||||
smm-$(CONFIG_IPMI_BMC_SEL) += ipmi_sel.c
|
smm-$(CONFIG_IPMI_BMC_SEL) += ipmi_sel.c
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -89,6 +89,16 @@ enum fail_type {
|
||||||
PCIE_ECRC_EVNT = 5,
|
PCIE_ECRC_EVNT = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum sel_err_type {
|
||||||
|
MEM_TRAINING_ERR = 0,
|
||||||
|
MEM_CORR_ERR = 1,
|
||||||
|
MEM_UNCORR_ERR = 2,
|
||||||
|
MEM_CORR_ERR_PATROL = 3,
|
||||||
|
MEM_UNCORR_ERR_PATROL = 4,
|
||||||
|
MEM_PARITY_ERR = 5,
|
||||||
|
MEM_UNDEFINED = 0xF,
|
||||||
|
};
|
||||||
|
|
||||||
struct ipmi_sel_pcie_dev_fail {
|
struct ipmi_sel_pcie_dev_fail {
|
||||||
uint16_t record_id;
|
uint16_t record_id;
|
||||||
uint8_t record_type;
|
uint8_t record_type;
|
||||||
|
@ -102,6 +112,21 @@ struct ipmi_sel_pcie_dev_fail {
|
||||||
uint8_t rsvd2;
|
uint8_t rsvd2;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct ipmi_sel_mem_err {
|
||||||
|
uint16_t record_id;
|
||||||
|
uint8_t record_type;
|
||||||
|
uint8_t general_info;
|
||||||
|
uint32_t timestamp;
|
||||||
|
uint8_t socket;
|
||||||
|
uint8_t channel;
|
||||||
|
uint8_t dimm_slot;
|
||||||
|
uint8_t rsvd1;
|
||||||
|
uint8_t dimm_failure_type;
|
||||||
|
uint8_t major_code;
|
||||||
|
uint8_t minor_code;
|
||||||
|
uint8_t rsvd2;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
struct ipmi_config_rsp {
|
struct ipmi_config_rsp {
|
||||||
uint8_t board_sku_id;
|
uint8_t board_sku_id;
|
||||||
uint8_t board_rev_id;
|
uint8_t board_rev_id;
|
||||||
|
@ -111,6 +136,7 @@ struct ipmi_config_rsp {
|
||||||
|
|
||||||
#define SEL_RECORD_ID 0x01
|
#define SEL_RECORD_ID 0x01
|
||||||
#define SEL_PCIE_DEV_ERR 0x20
|
#define SEL_PCIE_DEV_ERR 0x20
|
||||||
|
#define SEL_INTEL_MEMORY_ERROR 0x21
|
||||||
#define SEL_PCIE_IIO_ERR 0x23
|
#define SEL_PCIE_IIO_ERR 0x23
|
||||||
#define SEL_PCIE_DEV_FAIL_ID 0x29
|
#define SEL_PCIE_DEV_FAIL_ID 0x29
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,38 @@
|
||||||
|
|
||||||
#include <soc/soc_util.h>
|
#include <soc/soc_util.h>
|
||||||
#include <lib.h>
|
#include <lib.h>
|
||||||
|
#include <drivers/ipmi/ocp/ipmi_ocp.h>
|
||||||
#include "ocp_ewl.h"
|
#include "ocp_ewl.h"
|
||||||
|
|
||||||
|
static void ipmi_send_sel_ewl_type3_err(EWL_ENTRY_HEADER *header,
|
||||||
|
EWL_ENTRY_MEMORY_LOCATION memory_location)
|
||||||
|
{
|
||||||
|
struct ipmi_sel_mem_err sel;
|
||||||
|
uint8_t socketid;
|
||||||
|
EWL_ENTRY_TYPE3 *basic_warning;
|
||||||
|
basic_warning = (EWL_ENTRY_TYPE3 *)header;
|
||||||
|
|
||||||
|
/* Ignore invalid EWL DIMM location before sending SEL */
|
||||||
|
if (memory_location.Channel == 0xff || memory_location.Dimm == 0xff)
|
||||||
|
return;
|
||||||
|
memset(&sel, 0, sizeof(struct ipmi_sel_mem_err));
|
||||||
|
sel.record_id = 0x0000;
|
||||||
|
sel.record_type = 0xfb;
|
||||||
|
sel.general_info = SEL_INTEL_MEMORY_ERROR;
|
||||||
|
sel.timestamp = 0;
|
||||||
|
socketid = get_blade_id() - 1;
|
||||||
|
sel.socket = socketid <<= 4;
|
||||||
|
sel.channel = memory_location.Channel;
|
||||||
|
sel.dimm_slot = memory_location.Dimm;
|
||||||
|
sel.rsvd1 = 0xff;
|
||||||
|
sel.dimm_failure_type = MEM_TRAINING_ERR;
|
||||||
|
sel.major_code = basic_warning->Context.MajorWarningCode;
|
||||||
|
sel.minor_code = basic_warning->Context.MinorWarningCode;
|
||||||
|
sel.rsvd2 = 0xff;
|
||||||
|
ipmi_send_to_bmc((unsigned char *)&sel, sizeof(sel));
|
||||||
|
printk(BIOS_DEBUG, "ipmi send memory training error\n");
|
||||||
|
}
|
||||||
|
|
||||||
static void process_ewl_type3(EWL_ENTRY_HEADER *header, EWL_ENTRY_MEMORY_LOCATION memory_location)
|
static void process_ewl_type3(EWL_ENTRY_HEADER *header, EWL_ENTRY_MEMORY_LOCATION memory_location)
|
||||||
{
|
{
|
||||||
/* Treat warning as type 3, collect basic information and print to serial log */
|
/* Treat warning as type 3, collect basic information and print to serial log */
|
||||||
|
@ -47,6 +77,7 @@ void get_ewl(void)
|
||||||
type3 = (EWL_ENTRY_TYPE3 *)warning_header;
|
type3 = (EWL_ENTRY_TYPE3 *)warning_header;
|
||||||
process_ewl_type3(warning_header, type3->MemoryLocation);
|
process_ewl_type3(warning_header, type3->MemoryLocation);
|
||||||
type3_flag = 1;
|
type3_flag = 1;
|
||||||
|
ipmi_send_sel_ewl_type3_err(warning_header, type3->MemoryLocation);
|
||||||
} else {
|
} else {
|
||||||
printk(BIOS_DEBUG, "EWL type: %d size:%d severity level:%d\n",
|
printk(BIOS_DEBUG, "EWL type: %d size:%d severity level:%d\n",
|
||||||
warning_header->Type,
|
warning_header->Type,
|
||||||
|
|
Loading…
Reference in New Issue