Jonathan Zhang has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/44974 )
Change subject: soc/intel/xeon_sp/cpx: display FSP_PREV_BOOT_ERR_SRC_HOB ......................................................................
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, 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 --- M src/soc/intel/xeon_sp/cpx/hob_display.c 1 file changed, 50 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/74/44974/1
diff --git a/src/soc/intel/xeon_sp/cpx/hob_display.c b/src/soc/intel/xeon_sp/cpx/hob_display.c index 12c6feb..7874c6d 100644 --- a/src/soc/intel/xeon_sp/cpx/hob_display.c +++ b/src/soc/intel/xeon_sp/cpx/hob_display.c @@ -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 @@ 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,51 @@ 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; + } + + uint8_t *type; + MCBANK_ERR_INFO *mcbinfo; + for (uint16_t len = 2; len < hob->Length; ) { + type = (uint8_t *)((void *)hob + len); + if (*type == 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); + } else if (*type == PciExType) { + printk(BIOS_ERR, "\t PCI EX ERR INFO:\n"); + len += sizeof(PCI_EX_ERR_INFO); + } else if (*type == CsrOtherType) { + printk(BIOS_ERR, "\t CSR ERR INFO:\n"); + len += sizeof(CSR_ERR_INFO); + } else { + 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 +228,6 @@ 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)); }