xref: /aosp_15_r20/external/coreboot/src/arch/x86/include/arch/bert_storage.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #ifndef _BERT_STORAGE_H_
4 #define _BERT_STORAGE_H_
5 
6 #include <acpi/acpi.h>
7 #include <types.h>
8 
9 /* Items in the BERT region
10  *
11  *  * Each item begins with a Generic Error Status Block
12  *  * Zero or more Generic Error Data Entries follow, and
13  *    are associated with the Status Block
14  *  * Each Generic Error Data Entry must be a certain type,
15  *    as defined in the UEFI CPER appendix
16  *  * Each type may allow zero or more additional sets of
17  *    data, e.g. error descriptions, or processor contexts.
18  *
19  * In the example layout below, there are three BERT region
20  * entries.  The first two are a single error.  The third
21  * has two errors, with one providing a variable amount
22  * of additional information.
23  *
24  * +====================================================================+
25  * | Generic Error  | Generic Error   | Platform Memory Error           |
26  * | Status         | Data Entry      |                                 |
27  * |====================================================================|
28  * | Generic Error  | Generic Error   | Generic Processor Error         |
29  * | Status         | Data Entry      |                                 |
30  * |====================================================================|
31  * | Generic Error  | Generic Error   | IA32/X64 Processor Error        |
32  * | Status         | Data Entry      |    +----------------------------+
33  * |                |                 |    | Error Check Data           |
34  * |                |                 |    +----------------------------+
35  * |                |                 |    | MSR Context                |
36  * |                |                 |    +----------------------------+
37  * |                |                 |    | X64 Registers Context      |
38  * |                +-----------------+----+----------------------------+
39  * |                | Generic Error   | PCI Express Error               |
40  * |                | Data Entry      |                                 |
41  * +--------------------------------------------------------------------+
42  */
43 
44 #define CRASHLOG_RECORD_TYPE	0x2
45 #define CRASHLOG_FW_ERR_REV	0x2
46 
47 /* Get the region where BERT error structures have been constructed for
48  * generating the ACPI table
49  */
50 void bert_errors_region(void **start, size_t *size);
51 
52 /* Get amount of available storage left for error info */
53 size_t bert_storage_remaining(void);
54 /* Find if errors were added, a BERT region is present, and ACPI table needed */
55 bool bert_errors_present(void);
56 /* The BERT table should only be generated when BERT support is enabled and there's an error */
bert_should_generate_acpi_table(void)57 static inline bool bert_should_generate_acpi_table(void)
58 {
59 	return CONFIG(ACPI_BERT) && bert_errors_present();
60 }
61 
62 /* Get the number of entries associated with status */
bert_entry_count(acpi_generic_error_status_t * status)63 static inline size_t bert_entry_count(acpi_generic_error_status_t *status)
64 {
65 	return (status->block_status & GENERIC_ERR_STS_ENTRY_COUNT_MASK)
66 				>> GENERIC_ERR_STS_ENTRY_COUNT_SHIFT;
67 }
68 
69 /* Increment the number of entries this status describes */
bert_bump_entry_count(acpi_generic_error_status_t * status)70 static inline void bert_bump_entry_count(acpi_generic_error_status_t *status)
71 {
72 	int count;
73 
74 	count = bert_entry_count(status) + 1;
75 	status->block_status &= ~GENERIC_ERR_STS_ENTRY_COUNT_MASK;
76 	status->block_status |= count << GENERIC_ERR_STS_ENTRY_COUNT_SHIFT;
77 }
78 
79 /* Find the address of the first Generic Data structure from its status entry */
acpi_hest_generic_data3(acpi_generic_error_status_t * status)80 static inline acpi_hest_generic_data_v300_t *acpi_hest_generic_data3(
81 		acpi_generic_error_status_t *status)
82 {
83 	return (acpi_hest_generic_data_v300_t *)
84 			((u8 *)status + sizeof(*status));
85 }
86 
87 /* Find the address of a Generic Data structure's CPER error record section */
88 #define section_of_acpientry(A, B) ((typeof(A))((u8 *)(B) + sizeof(*(B))))
89 
90 /* Add a context to an existing IA32/X64-type error entry */
91 cper_ia32x64_context_t *new_cper_ia32x64_ctx(
92 		acpi_generic_error_status_t *status,
93 		cper_ia32x64_proc_error_section_t *x86err, int type, int num);
94 
95 /* Helper to add an MSR context to an existing IA32/X64-type error entry */
96 cper_ia32x64_context_t *cper_new_ia32x64_context_msr(
97 		acpi_generic_error_status_t *status,
98 		cper_ia32x64_proc_error_section_t *x86err, u32 addr, int num);
99 
100 /* Add check info to an existing IA32/X64-type error entry */
101 cper_ia32x64_proc_error_info_t *new_cper_ia32x64_check(
102 		acpi_generic_error_status_t *status,
103 		cper_ia32x64_proc_error_section_t *x86err,
104 		enum cper_x86_check_type type);
105 
106 /* Append a new ACPI Generic Error Data Entry plus CPER Error Section to an
107  * existing ACPI Generic Error Status Block.  The caller is responsible for
108  * the setting the status and entry severity, as well as populating all fields
109  * of the error section.
110  */
111 acpi_hest_generic_data_v300_t *bert_append_error_datasection(
112 		acpi_generic_error_status_t *status, guid_t *guid);
113 
114 /* Helper to append an ACPI Generic Error Data Entry plus a CPER Processor
115  * Generic Error Section.  As many fields are populated as possible for the
116  * caller.
117  */
118 acpi_hest_generic_data_v300_t *bert_append_genproc(
119 					acpi_generic_error_status_t *status);
120 
121 /* Helper to append an ACPI Generic Error Data Entry plus a CPER IA32/X64
122  * Processor Error Section.  As many fields are populated as possible for the
123  * caller.
124  */
125 acpi_hest_generic_data_v300_t *bert_append_ia32x64(
126 					acpi_generic_error_status_t *status);
127 
128 void *new_cper_fw_error_crashlog(acpi_generic_error_status_t *status, size_t cl_size);
129 acpi_hest_generic_data_v300_t *bert_append_fw_err(acpi_generic_error_status_t *status);
130 
131 /* Add a new event to the BERT region.  An event consists of an ACPI Error
132  * Status Block, a Generic Error Data Entry, and an associated CPER Error
133  * Section.
134  */
135 acpi_generic_error_status_t *bert_new_event(guid_t *guid);
136 
137 #endif /* _BERT_STORAGE_H_ */
138