summaryrefslogtreecommitdiffstats
path: root/src/arch/x86/include/arch/bert_storage.h
blob: d088f02ee9133dcee7375eced943e541a640d992 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* SPDX-License-Identifier: GPL-2.0-only */
/* This file is part of the coreboot project. */

#ifndef _BERT_STORAGE_H_
#define _BERT_STORAGE_H_

#include <stdint.h>
#include <acpi/acpi.h>

/* Items in the BERT region
 *
 *  * Each item begins with a Generic Error Status Block
 *  * Zero or more Generic Error Data Entries follow, and
 *    are associated with the Status Block
 *  * Each Generic Error Data Entry must be a certain type,
 *    as defined in the UEFI CPER appendix
 *  * Each type may allow zero or more additional sets of
 *    data, e.g. error descriptions, or processor contexts.
 *
 * In the example layout below, there are three BERT region
 * entries.  The first two are a single error.  The third
 * has two errors, with one providing a variable amount
 * of additional information.
 *
 * +====================================================================+
 * | Generic Error  | Generic Error   | Platform Memory Error           |
 * | Status         | Data Entry      |                                 |
 * |====================================================================|
 * | Generic Error  | Generic Error   | Generic Processor Error         |
 * | Status         | Data Entry      |                                 |
 * |====================================================================|
 * | Generic Error  | Generic Error   | IA32/X64 Processor Error        |
 * | Status         | Data Entry      |    +----------------------------+
 * |                |                 |    | Error Check Data           |
 * |                |                 |    +----------------------------+
 * |                |                 |    | MSR Context                |
 * |                |                 |    +----------------------------+
 * |                |                 |    | X64 Registers Context      |
 * |                +-----------------+----+----------------------------+
 * |                | Generic Error   | PCI Express Error               |
 * |                | Data Entry      |                                 |
 * +--------------------------------------------------------------------+
 */

/* Get implementation-specific reserved area for generating BERT info */
void bert_reserved_region(void **start, size_t *size);

/* Get the region where BERT error structures have been constructed for
 * generating the ACPI table
 */
void bert_errors_region(void **start, size_t *size);

/* Get amount of available storage left for error info */
size_t bert_storage_remaining(void);
/* Find if errors were added, a BERT region is present, and ACPI table needed */
int bert_errors_present(void);

/* Get the number of entries associated with status */
static inline size_t bert_entry_count(acpi_generic_error_status_t *status)
{
	return (status->block_status & GENERIC_ERR_STS_ENTRY_COUNT_MASK)
				>> GENERIC_ERR_STS_ENTRY_COUNT_SHIFT;
}

/* Increment the number of entries this status describes */
static inline void bert_bump_entry_count(acpi_generic_error_status_t *status)
{
	int count;

	count = bert_entry_count(status) + 1;
	status->block_status &= ~GENERIC_ERR_STS_ENTRY_COUNT_MASK;
	status->block_status |= count << GENERIC_ERR_STS_ENTRY_COUNT_SHIFT;
}

/* Find the address of the first Generic Data structure from its status entry */
static inline acpi_hest_generic_data_v300_t *acpi_hest_generic_data3(
		acpi_generic_error_status_t *status)
{
	return (acpi_hest_generic_data_v300_t *)
			((u8 *)status + sizeof(*status));
}

/* Find the address of a Generic Data structure's CPER error record section */
#define section_of_acpientry(A, B) ((typeof(A))((u8 *)(B) + sizeof(*(B))))


/* Add a context to an existing IA32/X64-type error entry */
cper_ia32x64_context_t *new_cper_ia32x64_ctx(
		acpi_generic_error_status_t *status,
		cper_ia32x64_proc_error_section_t *x86err, int type, int num);

/* Helper to add an MSR context to an existing IA32/X64-type error entry */
cper_ia32x64_context_t *cper_new_ia32x64_context_msr(
		acpi_generic_error_status_t *status,
		cper_ia32x64_proc_error_section_t *x86err, u32 addr, int num);

/* Add check info to an existing IA32/X64-type error entry */
cper_ia32x64_proc_error_info_t *new_cper_ia32x64_check(
		acpi_generic_error_status_t *status,
		cper_ia32x64_proc_error_section_t *x86err,
		enum cper_x86_check_type type);

/* Append a new ACPI Generic Error Data Entry plus CPER Error Section to an
 * existing ACPI Generic Error Status Block.  The caller is responsible for
 * the setting the status and entry severity, as well as populating all fields
 * of the error section.
 */
acpi_hest_generic_data_v300_t *bert_append_error_datasection(
		acpi_generic_error_status_t *status, guid_t *guid);

/* Helper to append an ACPI Generic Error Data Entry plus a CPER Processor
 * Generic Error Section.  As many fields are populated as possible for the
 * caller.
 */
acpi_hest_generic_data_v300_t *bert_append_genproc(
					acpi_generic_error_status_t *status);

/* Helper to append an ACPI Generic Error Data Entry plus a CPER IA32/X64
 * Processor Error Section.  As many fields are populated as possible for the
 * caller.
 */
acpi_hest_generic_data_v300_t *bert_append_ia32x64(
					acpi_generic_error_status_t *status);

/* Add a new event to the BERT region.  An event consists of an ACPI Error
 * Status Block, a Generic Error Data Entry, and an associated CPER Error
 * Section.
 */
acpi_generic_error_status_t *bert_new_event(guid_t *guid);

#endif /* _BERT_STORAGE_H_ */