soc/intel/pantherlake: Remove soc_info.[hc] interface
[coreboot2.git] / src / soc / intel / common / block / acpi / acpi_bert.c
blob8c1bd34a02c1ae0709633c8e85c0a82429d6a3cf
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 #include <acpi/acpi.h>
4 #include <acpi/acpigen.h>
5 #include <arch/bert_storage.h>
6 #include <console/console.h>
7 #include <intelblocks/acpi.h>
8 #include <intelblocks/crashlog.h>
10 static bool boot_error_src_present(cl_node_t *head)
12 if (!discover_crashlog()) {
13 printk(BIOS_SPEW, "Crashlog discovery result: crashlog not found\n");
14 return false;
17 collect_pmc_and_cpu_crashlog_from_srams(head);
19 /* Discovery tables sizes can be larger than the actual valid collected data */
20 u32 crashlog_size = cl_get_total_data_size();
22 return (crashlog_size > 0);
25 static enum cb_err record_crashlog_into_bert(void **region, size_t *length)
27 acpi_generic_error_status_t *status = NULL;
28 size_t gesb_header_size;
29 void *cl_acpi_data = NULL;
30 cl_node_t cl_list_head = {.size = 0, .data = NULL, .next = NULL};
32 if (!boot_error_src_present(&cl_list_head)) {
33 return CB_ERR;
36 if (!cl_get_total_data_size()) {
37 printk(BIOS_ERR, "No crashlog record present\n");
38 return CB_ERR;
41 status = bert_new_event(&CPER_SEC_FW_ERR_REC_REF_GUID);
42 gesb_header_size = sizeof(*status);
44 if (!status) {
45 printk(BIOS_ERR, "unable to allocate GSB\n");
46 return CB_ERR;
49 if (cl_get_total_data_size() > bert_storage_remaining()) {
50 printk(BIOS_ERR, "Crashlog entry would exceed available region\n");
51 return CB_ERR;
54 bool multi_entry = false;
55 cl_node_t *cl_node = cl_list_head.next;
56 while (cl_node) {
57 if ((cl_node->size <= 0) || (!(cl_node->data))) {
58 cl_node = cl_node->next;
59 continue;
62 if (multi_entry) {
63 if (!bert_append_fw_err(status)) {
64 printk(BIOS_ERR, "Crashlog entry would exceed available region\n");
65 return CB_ERR;
69 cl_acpi_data = new_cper_fw_error_crashlog(status, cl_node->size);
70 if (!cl_acpi_data) {
71 printk(BIOS_ERR, "Crashlog entry(size 0x%x) would exceed available region\n",
72 cl_node->size);
73 return CB_ERR;
75 memcpy(cl_acpi_data, (void *) cl_node->data, cl_node->size);
77 cl_node_t *temp = cl_node;
78 cl_node = cl_node->next;
79 free_cl_node(temp);
80 multi_entry = true;
83 *length = status->data_length + gesb_header_size;
84 *region = (void *)status;
86 return CB_SUCCESS;
89 enum cb_err acpi_soc_get_bert_region(void **region, size_t *length)
91 if (CONFIG(SOC_INTEL_CRASHLOG)) {
92 return record_crashlog_into_bert(region, length);
93 } else {
94 /* Check if MCA error has been added into BERT. */
95 if (bert_should_generate_acpi_table()) {
96 bert_errors_region(region, length);
97 if (!*region) {
98 printk(BIOS_ERR, "Can't find BERT storage area\n");
99 return CB_ERR;
102 return CB_SUCCESS;