aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/common/block/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/common/block/acpi')
-rw-r--r--src/soc/intel/common/block/acpi/Kconfig9
-rw-r--r--src/soc/intel/common/block/acpi/Makefile.inc1
-rw-r--r--src/soc/intel/common/block/acpi/acpi_bert.c95
3 files changed, 104 insertions, 1 deletions
diff --git a/src/soc/intel/common/block/acpi/Kconfig b/src/soc/intel/common/block/acpi/Kconfig
index a4f9844c70..8912ff3105 100644
--- a/src/soc/intel/common/block/acpi/Kconfig
+++ b/src/soc/intel/common/block/acpi/Kconfig
@@ -10,7 +10,13 @@ config SOC_INTEL_COMMON_BLOCK_ACPI_LPIT
depends on HAVE_ACPI_TABLES
select ACPI_LPIT
help
- Generate LPIT table with LPI state entries.
+ Generate LPIT table with LPI state entries
+
+config SOC_INTEL_COMMON_BLOCK_CRASHLOG
+ bool
+ depends on SOC_INTEL_CRASHLOG
+ help
+ Generate crash data for BERT table
if SOC_INTEL_COMMON_BLOCK_ACPI
@@ -19,4 +25,5 @@ config SOC_INTEL_COMMON_BLOCK_ACPI_CPPC
help
Generate CPPC entries for Intel SpeedShift
+
endif
diff --git a/src/soc/intel/common/block/acpi/Makefile.inc b/src/soc/intel/common/block/acpi/Makefile.inc
index c605088dbe..89565a6fd9 100644
--- a/src/soc/intel/common/block/acpi/Makefile.inc
+++ b/src/soc/intel/common/block/acpi/Makefile.inc
@@ -1,3 +1,4 @@
ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI) += acpi.c
ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI_LPIT) += lpit.c
+ramstage-$(CONFIG_ACPI_BERT) += acpi_bert.c
ramstage-$(CONFIG_SOC_INTEL_COMMON_ACPI_WAKE_SOURCE) += acpi_wake_source.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 <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);
+}