blob: 85fbc03f6e9039d54046469b484e076bc1cfc997 [file] [log] [blame]
Francois Toguo15cbc3b2021-01-26 10:27:49 -08001/* SPDX-License-Identifier: GPL-2.0-or-later */
2
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>
9
Felix Heldfba479262021-05-28 16:11:43 +020010static bool boot_error_src_present(void)
11{
12 if (!CONFIG(SOC_INTEL_CRASHLOG)) {
13 printk(BIOS_DEBUG, "Crashlog disabled.\n");
14 return false;
15 }
16
17 if (!discover_crashlog()) {
18 printk(BIOS_SPEW, "Crashlog discovery result: crashlog not found\n");
19 return false;
20 }
21
22 collect_pmc_and_cpu_crashlog_from_srams();
23
24 /* Discovery tables sizes can be larger than the actual valid collected data */
25 u32 crashlog_size = cl_get_total_data_size();
26
27 return (crashlog_size > 0);
28}
Francois Toguo15cbc3b2021-01-26 10:27:49 -080029
Felix Held29405482021-05-28 16:01:57 +020030enum cb_err acpi_soc_get_bert_region(void **region, size_t *length)
Francois Toguo15cbc3b2021-01-26 10:27:49 -080031{
32 acpi_generic_error_status_t *status = NULL;
33 size_t cpu_record_size, pmc_record_size;
Francois Toguo Fotsoc1751462021-05-27 01:10:16 -070034 size_t gesb_header_size;
Francois Toguo15cbc3b2021-01-26 10:27:49 -080035 void *cl_data = NULL;
36
Felix Heldfba479262021-05-28 16:11:43 +020037 if (!boot_error_src_present()) {
38 return CB_ERR;
39 }
40
Francois Toguo15cbc3b2021-01-26 10:27:49 -080041 if (!cl_get_total_data_size()) {
42 printk(BIOS_ERR, "Error: No crashlog record present\n");
Felix Held29405482021-05-28 16:01:57 +020043 return CB_ERR;
Francois Toguo15cbc3b2021-01-26 10:27:49 -080044 }
45
46 status = bert_new_event(&CPER_SEC_FW_ERR_REC_REF_GUID);
Francois Toguo Fotsoc1751462021-05-27 01:10:16 -070047 gesb_header_size = sizeof(*status);
48
Francois Toguo15cbc3b2021-01-26 10:27:49 -080049 if (!status) {
50 printk(BIOS_ERR, "Error: unable to allocate GSB\n");
Felix Held29405482021-05-28 16:01:57 +020051 return CB_ERR;
Francois Toguo15cbc3b2021-01-26 10:27:49 -080052 }
53
54 if (cl_get_total_data_size() > bert_storage_remaining()) {
55 printk(BIOS_ERR, "Error: Crashlog entry would exceed "
56 "available region\n");
Felix Held29405482021-05-28 16:01:57 +020057 return CB_ERR;
Francois Toguo15cbc3b2021-01-26 10:27:49 -080058 }
59
60 cpu_record_size = cl_get_cpu_record_size();
61 if (cpu_record_size) {
62 cl_data = new_cper_fw_error_crashlog(status, cpu_record_size);
63 if (!cl_data) {
64 printk(BIOS_ERR, "Error: Crashlog CPU entry(size %lu) "
65 "would exceed available region\n",
66 cpu_record_size);
Felix Held29405482021-05-28 16:01:57 +020067 return CB_ERR;
Francois Toguo15cbc3b2021-01-26 10:27:49 -080068 }
69 printk(BIOS_DEBUG, "cl_data %p, cpu_record_size %lu\n",
70 cl_data, cpu_record_size);
71 cl_fill_cpu_records(cl_data);
72 }
73
74 pmc_record_size = cl_get_pmc_record_size();
75 if (pmc_record_size) {
76 /* Allocate new FW ERR structure in case CPU crashlog is present */
77 if (cpu_record_size && !bert_append_fw_err(status)) {
78 printk(BIOS_ERR, "Error: Crashlog PMC entry would "
79 "exceed available region\n");
Felix Held29405482021-05-28 16:01:57 +020080 return CB_ERR;
Francois Toguo15cbc3b2021-01-26 10:27:49 -080081 }
82
83 cl_data = new_cper_fw_error_crashlog(status, pmc_record_size);
84 if (!cl_data) {
85 printk(BIOS_ERR, "Error: Crashlog PMC entry(size %lu) "
86 "would exceed available region\n",
87 pmc_record_size);
Felix Held29405482021-05-28 16:01:57 +020088 return CB_ERR;
Francois Toguo15cbc3b2021-01-26 10:27:49 -080089 }
90 printk(BIOS_DEBUG, "cl_data %p, pmc_record_size %lu\n",
91 cl_data, pmc_record_size);
92 cl_fill_pmc_records(cl_data);
93 }
94
Francois Toguo Fotsoc1751462021-05-27 01:10:16 -070095 *length = status->data_length + gesb_header_size;
Francois Toguo15cbc3b2021-01-26 10:27:49 -080096 *region = (void *)status;
97
Felix Held29405482021-05-28 16:01:57 +020098 return CB_SUCCESS;
Francois Toguo15cbc3b2021-01-26 10:27:49 -080099}