blob: 417dad3ac721bca6f945fbec8c33b9aae5cb2e7b [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
Pratikkumar Prajapati4db92132023-10-05 13:12:12 -070010static bool boot_error_src_present(cl_node_t *head)
Felix Heldfba479262021-05-28 16:11:43 +020011{
Felix Heldfba479262021-05-28 16:11:43 +020012 if (!discover_crashlog()) {
13 printk(BIOS_SPEW, "Crashlog discovery result: crashlog not found\n");
14 return false;
15 }
16
Pratikkumar Prajapati4db92132023-10-05 13:12:12 -070017 collect_pmc_and_cpu_crashlog_from_srams(head);
Felix Heldfba479262021-05-28 16:11:43 +020018
19 /* Discovery tables sizes can be larger than the actual valid collected data */
20 u32 crashlog_size = cl_get_total_data_size();
21
22 return (crashlog_size > 0);
23}
Francois Toguo15cbc3b2021-01-26 10:27:49 -080024
Jonathan Zhang01acc032022-10-26 17:53:25 -070025static enum cb_err record_crashlog_into_bert(void **region, size_t *length)
Francois Toguo15cbc3b2021-01-26 10:27:49 -080026{
27 acpi_generic_error_status_t *status = NULL;
Francois Toguo Fotsoc1751462021-05-27 01:10:16 -070028 size_t gesb_header_size;
Pratikkumar Prajapati4db92132023-10-05 13:12:12 -070029 void *cl_acpi_data = NULL;
30 cl_node_t cl_list_head = {.size = 0, .data = NULL, .next = NULL};
Francois Toguo15cbc3b2021-01-26 10:27:49 -080031
Pratikkumar Prajapati4db92132023-10-05 13:12:12 -070032 if (!boot_error_src_present(&cl_list_head)) {
Felix Heldfba479262021-05-28 16:11:43 +020033 return CB_ERR;
34 }
35
Francois Toguo15cbc3b2021-01-26 10:27:49 -080036 if (!cl_get_total_data_size()) {
Julius Wernere9665952022-01-21 17:06:20 -080037 printk(BIOS_ERR, "No crashlog record present\n");
Felix Held29405482021-05-28 16:01:57 +020038 return CB_ERR;
Francois Toguo15cbc3b2021-01-26 10:27:49 -080039 }
40
41 status = bert_new_event(&CPER_SEC_FW_ERR_REC_REF_GUID);
Francois Toguo Fotsoc1751462021-05-27 01:10:16 -070042 gesb_header_size = sizeof(*status);
43
Francois Toguo15cbc3b2021-01-26 10:27:49 -080044 if (!status) {
Julius Wernere9665952022-01-21 17:06:20 -080045 printk(BIOS_ERR, "unable to allocate GSB\n");
Felix Held29405482021-05-28 16:01:57 +020046 return CB_ERR;
Francois Toguo15cbc3b2021-01-26 10:27:49 -080047 }
48
49 if (cl_get_total_data_size() > bert_storage_remaining()) {
Pratikkumar Prajapati4db92132023-10-05 13:12:12 -070050 printk(BIOS_ERR, "Crashlog entry would exceed available region\n");
Felix Held29405482021-05-28 16:01:57 +020051 return CB_ERR;
Francois Toguo15cbc3b2021-01-26 10:27:49 -080052 }
53
Pratikkumar Prajapati4db92132023-10-05 13:12:12 -070054 bool multi_entry = false;
55 cl_node_t *cl_node = cl_list_head.next;
56 while (cl_node) {
Francois Toguo15cbc3b2021-01-26 10:27:49 -080057
Pratikkumar Prajapati4db92132023-10-05 13:12:12 -070058 if ((cl_node->size <= 0) || (!(cl_node->data))) {
59 cl_node = cl_node->next;
60 continue;
Francois Toguo15cbc3b2021-01-26 10:27:49 -080061 }
62
Pratikkumar Prajapati4db92132023-10-05 13:12:12 -070063 if (multi_entry) {
64 if (!bert_append_fw_err(status)) {
65 printk(BIOS_ERR, "Crashlog entry would exceed available region\n");
Pratikkumar Prajapatie4893d62023-05-30 12:30:36 -070066 return CB_ERR;
67 }
Pratikkumar Prajapatie4893d62023-05-30 12:30:36 -070068 }
Pratikkumar Prajapati4db92132023-10-05 13:12:12 -070069
70 cl_acpi_data = new_cper_fw_error_crashlog(status, cl_node->size);
71 if (!cl_acpi_data) {
72 printk(BIOS_ERR, "Crashlog entry(size 0x%x) would exceed available region\n",
73 cl_node->size);
74 return CB_ERR;
75 }
76 memcpy(cl_acpi_data, (void *) cl_node->data, cl_node->size);
77
78 cl_node_t *temp = cl_node;
79 cl_node = cl_node->next;
80 free_cl_node(temp);
81 multi_entry = true;
Pratikkumar Prajapatie4893d62023-05-30 12:30:36 -070082 }
83
Francois Toguo Fotsoc1751462021-05-27 01:10:16 -070084 *length = status->data_length + gesb_header_size;
Francois Toguo15cbc3b2021-01-26 10:27:49 -080085 *region = (void *)status;
86
Felix Held29405482021-05-28 16:01:57 +020087 return CB_SUCCESS;
Francois Toguo15cbc3b2021-01-26 10:27:49 -080088}
Jonathan Zhang01acc032022-10-26 17:53:25 -070089
90enum cb_err acpi_soc_get_bert_region(void **region, size_t *length)
91{
92 if (CONFIG(SOC_INTEL_CRASHLOG)) {
93 return record_crashlog_into_bert(region, length);
94 } else {
95 /* Check if MCA error has been added into BERT. */
96 if (bert_should_generate_acpi_table()) {
97 bert_errors_region(region, length);
98 if (!*region) {
99 printk(BIOS_ERR, "Can't find BERT storage area\n");
100 return CB_ERR;
101 }
102 }
103 return CB_SUCCESS;
104 }
105}