aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/common/block/acpi/acpi_bert.c
diff options
context:
space:
mode:
authorFrancois Toguo <francois.toguo.fotso@intel.com>2021-01-26 10:27:49 -0800
committerPatrick Georgi <pgeorgi@google.com>2021-02-22 07:22:50 +0000
commit15cbc3b5996ae64aff2e4741c4c3ec3d7f5cc1a7 (patch)
treeec401d461fcbbace3194553db3953a4d80e8d332 /src/soc/intel/common/block/acpi/acpi_bert.c
parent619c60f94cc00251bfaedde4f1764e2f96dcdecd (diff)
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 <francois.toguo.fotso@intel.com> Change-Id: Ie3763cebcd1178709cc8597710bf062a30901809 Reviewed-on: https://review.coreboot.org/c/coreboot/+/49943 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Diffstat (limited to 'src/soc/intel/common/block/acpi/acpi_bert.c')
-rw-r--r--src/soc/intel/common/block/acpi/acpi_bert.c95
1 files changed, 95 insertions, 0 deletions
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 <acpi/acpi.h>
+#include <acpi/acpigen.h>
+#include <arch/bert_storage.h>
+#include <console/console.h>
+#include <intelblocks/acpi.h>
+#include <intelblocks/crashlog.h>
+
+
+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);
+}