soc/intel/xeon_sp/cpx: display FSP_PREV_BOOT_ERR_SRC_HOB

Before MRC code execution, FSP interrogates EMCA MSR registers and other
registers to see if there are fatal errors happened during previous boot
session. If there are, error records are saved into
FSP_PREV_BOOT_ERR_SRC_HOB.

When the value of Length field of FSP_PREV_BOOT_ERR_SRC_HOB is 2, that means
the HOB does not contain any valid error record.

TESTED=Injects MCE error through cscript, reboot into OS, check boot log:
0x75904d70, 0x00000400 bytes: HOB_TYPE_GUID_EXTENSION
        5138b5c5-9369-48ec-5b9738a2f7096675: FSP_PREV_BOOT_ERR_SRC_HOB_GUID
================ PREV_BOOT_ERR_SRC HOB DATA ================
hob: 0x75904d88, Length: 0x42
         MCBANK ERR INFO:
                 Segment: 0, Socket: 0, ApicId: 0x0
                 McBankNum: 0x3
                 McBankStatus: 0xfe00000000800400
                 McBankAddr: 0xf0ff
                 McBankMisc: 0xfffffff0
         MCBANK ERR INFO:
                 Segment: 0, Socket: 0, ApicId: 0x0
                 McBankNum: 0x4
                 McBankStatus: 0xfe00000000800400
                 McBankAddr: 0xfff0
                 McBankMisc: 0xfffffff0
0x75904d88: 42 00 01 00 00 00 00 00 03 00 00 04 80 00 00 00  B...............
0x75904d98: 00 fe ff f0 00 00 00 00 00 00 f0 ff ff ff 00 00  ................
0x75904da8: 00 00 01 00 00 00 00 00 04 00 00 04 80 00 00 00  ................
0x75904db8: 00 fe f0 ff 00 00 00 00 00 00 f0 ff ff ff 00 00  ................
0x75904dc8: 00 00

Change-Id: Idbace4c2500440b3c1cf2628dd921ca1a989ae81
Signed-off-by: Jonathan Zhang <jonzhang@fb.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/44974
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Jonathan Zhang 2020-08-04 12:59:24 -07:00 committed by Patrick Georgi
parent 7f4395f40e
commit 9366885a42

View file

@ -5,11 +5,13 @@
#include <fsp/util.h>
#include <hob_iiouds.h>
#include <hob_memmap.h>
#include <hob_prevbooterr.h>
#include <lib.h>
#include <soc/soc_util.h>
static const uint8_t fsp_hob_iio_uds_guid[16] = FSP_HOB_IIO_UNIVERSAL_DATA_GUID;
static const uint8_t fsp_hob_memmap_guid[16] = FSP_SYSTEM_MEMORYMAP_HOB_GUID;
static const uint8_t fsp_hob_prevbooterr_guid[16] = FSP_PREV_BOOT_ERR_SRC_HOB_GUID;
struct guid_name_map {
const void *guid;
@ -19,6 +21,7 @@ struct guid_name_map {
static const struct guid_name_map guid_names[] = {
{ fsp_hob_iio_uds_guid, "FSP_HOB_IIO_UNIVERSAL_DATA_GUID" },
{ fsp_hob_memmap_guid, "FSP_SYSTEM_MEMORYMAP_HOB_GUID" },
{ fsp_hob_prevbooterr_guid, "FSP_PREV_BOOT_ERR_SRC_HOB_GUID" },
};
const char *soc_get_guid_name(const uint8_t *guid)
@ -167,6 +170,55 @@ static void soc_display_iio_universal_data_hob(const IIO_UDS *hob)
hexdump(hob, sizeof(*hob));
}
/*
* Display PREV_BOOT_ERR_SRC_HOB. Check various issues:
* a. Length field of the HOB needs to be more than 2.
* b. CPX-SP FSP only implements MC_BANK_INFO type.
* c. Type field (first field of each record) needs to be of enum ERROR_ACCESS_TYPE.
*/
static void soc_display_prevbooterr_hob(const PREV_BOOT_ERR_SRC_HOB *hob)
{
printk(BIOS_DEBUG, "================ PREV_BOOT_ERR_SRC HOB DATA ================\n");
printk(BIOS_DEBUG, "hob: %p, Length: 0x%x\n", hob, hob->Length);
if (hob->Length <= 2) {
printk(BIOS_INFO, "PREV_BOOT_ERR_SRC_HOB does not have valid error record.\n");
return;
}
MCBANK_ERR_INFO *mcbinfo;
for (uint16_t len = 2; len < hob->Length; ) {
const uint8_t type = *(uint8_t *)((void *)hob + len);
switch (type) {
case McBankType:
printk(BIOS_DEBUG, "\t MCBANK ERR INFO:\n");
mcbinfo = (MCBANK_ERR_INFO *)((void *)hob + len);
printk(BIOS_DEBUG, "\t\t Segment: %d, Socket: %d, ApicId: 0x%x\n",
mcbinfo->Segment, mcbinfo->Socket, mcbinfo->ApicId);
printk(BIOS_DEBUG, "\t\t McBankNum: 0x%x\n", mcbinfo->McBankNum);
printk(BIOS_DEBUG, "\t\t McBankStatus: 0x%llx\n",
mcbinfo->McBankStatus);
printk(BIOS_DEBUG, "\t\t McBankAddr: 0x%llx\n", mcbinfo->McbankAddr);
printk(BIOS_DEBUG, "\t\t McBankMisc: 0x%llx\n", mcbinfo->McBankMisc);
len += sizeof(MCBANK_ERR_INFO);
break;
case PciExType:
printk(BIOS_ERR, "\t PCI EX ERR INFO:\n");
len += sizeof(PCI_EX_ERR_INFO);
break;
case CsrOtherType:
printk(BIOS_ERR, "\t CSR ERR INFO:\n");
len += sizeof(CSR_ERR_INFO);
break;
default:
printk(BIOS_ERR, "\t illegal ERROR_ACCESS_TYPE:%d\n", type);
break;
}
}
hexdump(hob, hob->Length);
}
void soc_display_hob(const struct hob_header *hob)
{
uint8_t *guid;
@ -180,4 +232,6 @@ void soc_display_hob(const struct hob_header *hob)
soc_display_iio_universal_data_hob((const IIO_UDS *)(guid + 16));
else if (fsp_guid_compare(guid, fsp_hob_memmap_guid))
soc_display_memmap_hob((const struct SystemMemoryMapHob **)(guid + 16));
else if (fsp_guid_compare(guid, fsp_hob_prevbooterr_guid))
soc_display_prevbooterr_hob((const PREV_BOOT_ERR_SRC_HOB *)(guid + 16));
}