From 15cbc3b5996ae64aff2e4741c4c3ec3d7f5cc1a7 Mon Sep 17 00:00:00 2001 From: Francois Toguo Date: Tue, 26 Jan 2021 10:27:49 -0800 Subject: soc/intel/tigerlake: Add CrashLog implementation for intel TGL CrashLog is a diagnostic feature for Intel TGL based platforms. It is meant to capture the state of the platform before a crash. The state of relevant registers is preserved across a warm reset. BUG=None TEST=CrashLog data generated, extracted, processed, decoded sucessfully on delbin. Signed-off-by: Francois Toguo Change-Id: Ie3763cebcd1178709cc8597710bf062a30901809 Reviewed-on: https://review.coreboot.org/c/coreboot/+/49943 Tested-by: build bot (Jenkins) Reviewed-by: Tim Wawrzynczak --- src/soc/intel/common/block/acpi/acpi_bert.c | 95 +++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/soc/intel/common/block/acpi/acpi_bert.c (limited to 'src/soc/intel/common/block/acpi/acpi_bert.c') diff --git a/src/soc/intel/common/block/acpi/acpi_bert.c b/src/soc/intel/common/block/acpi/acpi_bert.c new file mode 100644 index 0000000000..d090dfd2cf --- /dev/null +++ b/src/soc/intel/common/block/acpi/acpi_bert.c @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include +#include + + +void acpi_soc_fill_bert(acpi_bert_t *bert, + void **region, + size_t *length) +{ + acpi_generic_error_status_t *status = NULL; + size_t cpu_record_size, pmc_record_size; + void *cl_data = NULL; + + if (!cl_get_total_data_size()) { + printk(BIOS_ERR, "Error: No crashlog record present\n"); + return; + } + + status = bert_new_event(&CPER_SEC_FW_ERR_REC_REF_GUID); + if (!status) { + printk(BIOS_ERR, "Error: unable to allocate GSB\n"); + return; + } + + if (cl_get_total_data_size() > bert_storage_remaining()) { + printk(BIOS_ERR, "Error: Crashlog entry would exceed " + "available region\n"); + return; + } + + cpu_record_size = cl_get_cpu_record_size(); + if (cpu_record_size) { + cl_data = new_cper_fw_error_crashlog(status, cpu_record_size); + if (!cl_data) { + printk(BIOS_ERR, "Error: Crashlog CPU entry(size %lu) " + "would exceed available region\n", + cpu_record_size); + return; + } + printk(BIOS_DEBUG, "cl_data %p, cpu_record_size %lu\n", + cl_data, cpu_record_size); + cl_fill_cpu_records(cl_data); + } + + pmc_record_size = cl_get_pmc_record_size(); + if (pmc_record_size) { + /* Allocate new FW ERR structure in case CPU crashlog is present */ + if (cpu_record_size && !bert_append_fw_err(status)) { + printk(BIOS_ERR, "Error: Crashlog PMC entry would " + "exceed available region\n"); + return; + } + + cl_data = new_cper_fw_error_crashlog(status, pmc_record_size); + if (!cl_data) { + printk(BIOS_ERR, "Error: Crashlog PMC entry(size %lu) " + "would exceed available region\n", + pmc_record_size); + return; + } + printk(BIOS_DEBUG, "cl_data %p, pmc_record_size %lu\n", + cl_data, pmc_record_size); + cl_fill_pmc_records(cl_data); + } + + *length = status->raw_data_length; + *region = (void *)status; + +} + +bool acpi_is_boot_error_src_present(void) +{ + + if (!CONFIG(SOC_INTEL_CRASHLOG)) { + printk(BIOS_DEBUG, "Crashlog disabled.\n"); + return false; + } + + if (!discover_crashlog()) { + printk(BIOS_SPEW, "Crashlog discovery result: crashlog not found\n"); + return false; + } + + collect_pmc_and_cpu_crashlog_from_srams(); + + /* Discovery tables sizes can be larger than the actual valid collected data */ + u32 crashlog_size = cl_get_total_data_size(); + + return (crashlog_size > 0); +} -- cgit v1.2.3