apei_cper.h revision 1.5 1 /* $NetBSD: apei_cper.h,v 1.5 2024/10/27 12:59:08 riastradh Exp $ */
2
3 /*-
4 * Copyright (c) 2024 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /*
30 * UEFI Common Platform Error Record
31 *
32 * https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record.html
33 */
34
35 #ifndef _SYS_DEV_ACPI_APEI_CPER_H_
36 #define _SYS_DEV_ACPI_APEI_CPER_H_
37
38 #include <sys/types.h>
39
40 #include <sys/cdefs.h>
41
42 /*
43 * https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record.html#record-header
44 */
45 struct cper_header {
46 char SignatureStart[4]; /* `CPER' */
47 uint16_t Revision;
48 uint32_t SignatureEnd; /* 0xffffffff */
49 uint16_t SectionCount;
50 uint32_t ErrorSeverity;
51 uint32_t ValidationBits;
52 uint32_t RecordLength;
53 uint64_t Timestamp;
54 uint8_t PlatformId[16];
55 uint8_t PartitionId[16];
56 uint8_t CreatorId[16];
57 uint8_t NotificationType[16];
58 uint64_t RecordId;
59 uint32_t Flags;
60 uint64_t PersistenceInfo;
61 uint8_t Reserved[12];
62 } __packed;
63 __CTASSERT(sizeof(struct cper_header) == 128);
64
65 enum { /* struct cper_header::ErrorSeverity */
66 CPER_ERROR_SEVERITY_RECOVERABLE = 0,
67 CPER_ERROR_SEVERITY_FATAL = 1,
68 CPER_ERROR_SEVERITY_CORRECTED = 2,
69 CPER_ERROR_SEVERITY_INFORMATIONAL = 3,
70 };
71
72 enum { /* struct cper_header::ValidationBits */
73 CPER_VALID_PLATFORM_ID = __BIT(0),
74 CPER_VALID_TIMESTAMP = __BIT(1),
75 CPER_VALID_PARTITION_ID = __BIT(2),
76 };
77
78 /*
79 * https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record.html#error-record-header-flags
80 */
81 enum { /* struct cper_header::Flags */
82 CPER_HW_ERROR_FLAG_RECOVERED = __BIT(0),
83 CPER_HW_ERROR_FLAG_PREVERR = __BIT(1),
84 CPER_HW_ERROR_FLAG_SIMULATED = __BIT(2),
85 };
86
87 /*
88 * https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record.html#section-descriptor-format
89 */
90 enum {
91 CPER_SECTION_FLAG_PRIMARY = __BIT(0),
92 CPER_SECTION_FLAG_CONTAINMENT_WARNING = __BIT(1),
93 CPER_SECTION_FLAG_RESET = __BIT(2),
94 CPER_SECTION_FLAG_ERROR_THRESHOLD_EXCEEDED = __BIT(3),
95 CPER_SECTION_FLAG_RESOURCE_NOT_ACCESSIBLE = __BIT(4),
96 CPER_SECTION_FLAG_LATENT_ERROR = __BIT(5),
97 CPER_SECTION_FLAG_PROPAGATED = __BIT(6),
98 CPER_SECTION_FLAG_OVERFLOW = __BIT(7),
99 };
100
101 #define CPER_SECTION_FLAGS_FMT "\177\020" \
102 "b\000" "PRIMARY\0" \
103 "b\001" "CONTAINMENT_WARNING\0" \
104 "b\002" "RESET\0" \
105 "b\003" "ERROR_THRESHOLD_EXCEEDED\0" \
106 "b\004" "RESOURCE_NOT_ACCESSIBLE\0" \
107 "b\005" "LATENT_ERROR\0" \
108 "b\006" "PROPAGATED\0" \
109 "b\007" "OVERFLOW\0" \
110 "\0"
111
112 /*
113 * N.2.5. Memory Error Section
114 *
115 * https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record.html#memory-error-section
116 *
117 * Type: {0xa5bc1114,0x6f64,0x4ede,{0xb8,0x63,0x3e,0x83,0xed,0x7c,0x83,0xb1}}
118 */
119
120 struct cper_memory_error {
121 uint64_t ValidationBits;
122 uint64_t ErrorStatus;
123 uint64_t PhysicalAddress;
124 uint64_t PhysicalAddressMask;
125 uint16_t Node;
126 uint16_t Card;
127 uint16_t Module;
128 uint16_t Bank;
129 uint16_t Device;
130 uint16_t Row;
131 uint16_t Column;
132 uint16_t BitPosition;
133 uint64_t RequestorId;
134 uint64_t ResponderId;
135 uint64_t TargetId;
136 uint8_t MemoryErrorType;
137 } __packed;
138 __CTASSERT(sizeof(struct cper_memory_error) == 73);
139
140 struct cper_memory_error_ext {
141 struct cper_memory_error Base;
142 uint8_t Extended;
143 uint16_t RankNumber;
144 uint16_t CardHandle;
145 uint16_t ModuleHandle;
146 } __packed;
147 __CTASSERT(sizeof(struct cper_memory_error_ext) == 80);
148
149 enum { /* struct cper_memory_error::ValidationBits */
150 CPER_MEMORY_ERROR_VALID_ERROR_STATUS = __BIT(0),
151 CPER_MEMORY_ERROR_VALID_PHYSICAL_ADDRESS = __BIT(1),
152 CPER_MEMORY_ERROR_VALID_PHYSICAL_ADDRESS_MASK = __BIT(2),
153 CPER_MEMORY_ERROR_VALID_NODE = __BIT(3),
154 CPER_MEMORY_ERROR_VALID_CARD = __BIT(4),
155 CPER_MEMORY_ERROR_VALID_MODULE = __BIT(5),
156 CPER_MEMORY_ERROR_VALID_BANK = __BIT(6),
157 CPER_MEMORY_ERROR_VALID_DEVICE = __BIT(7),
158 CPER_MEMORY_ERROR_VALID_ROW = __BIT(8),
159 CPER_MEMORY_ERROR_VALID_COLUMN = __BIT(9),
160 CPER_MEMORY_ERROR_VALID_BIT_POSITION = __BIT(10),
161 CPER_MEMORY_ERROR_VALID_REQUESTOR_ID = __BIT(11),
162 CPER_MEMORY_ERROR_VALID_RESPONDER_ID = __BIT(12),
163 CPER_MEMORY_ERROR_VALID_TARGET_ID = __BIT(13),
164 CPER_MEMORY_ERROR_VALID_MEMORY_ERROR_TYPE = __BIT(14),
165 CPER_MEMORY_ERROR_VALID_RANK_NUMBER = __BIT(15),
166 CPER_MEMORY_ERROR_VALID_CARD_HANDLE = __BIT(16),
167 CPER_MEMORY_ERROR_VALID_MODULE_HANDLE = __BIT(17),
168 CPER_MEMORY_ERROR_VALID_EXTENDED_ROW = __BIT(18),
169 CPER_MEMORY_ERROR_VALID_BANK_GROUP = __BIT(19),
170 CPER_MEMORY_ERROR_VALID_BANK_ADDRESS = __BIT(20),
171 CPER_MEMORY_ERROR_VALID_CHIP_ID = __BIT(21),
172 };
173
174 #define CPER_MEMORY_ERROR_VALIDATION_BITS_FMT "\177\020" \
175 "b\000" "ERROR_STATUS\0" \
176 "b\001" "PHYSICAL_ADDRESS\0" \
177 "b\002" "PHYSICAL_ADDRESS_MASK\0" \
178 "b\003" "NODE\0" \
179 "b\004" "CARD\0" \
180 "b\005" "MODULE\0" \
181 "b\006" "BANK\0" \
182 "b\007" "DEVICE\0" \
183 "b\010" "ROW\0" \
184 "b\011" "COLUMN\0" \
185 "b\012" "BIT_POSITION\0" \
186 "b\013" "REQUESTOR_ID\0" \
187 "b\014" "RESPONDER_ID\0" \
188 "b\015" "TARGET_ID\0" \
189 "b\016" "MEMORY_ERROR_TYPE\0" \
190 "b\017" "RANK_NUMBER\0" \
191 "b\020" "CARD_HANDLE\0" \
192 "b\021" "MODULE_HANDLE\0" \
193 "b\022" "EXTENDED_ROW\0" \
194 "b\023" "BANK_GROUP\0" \
195 "b\024" "BANK_ADDRESS\0" \
196 "b\025" "CHIP_ID\0" \
197 "\0"
198
199 enum { /* struct cper_memory_error::Bank */
200 CPER_MEMORY_ERROR_BANK_ADDRESS = __BITS(7,0),
201 CPER_MEMORY_ERROR_BANK_GROUP = __BITS(15,8),
202 };
203
204 #define CPER_MEMORY_ERROR_TYPES(F) \
205 F(CPER_MEMORY_ERROR_UNKNOWN, UNKNOWN, 0) \
206 F(CPER_MEMORY_ERROR_NO_ERROR, NO_ERROR, 1) \
207 F(CPER_MEMORY_ERROR_SINGLEBIT_ECC, SINGLEBIT_ECC, 2) \
208 F(CPER_MEMORY_ERROR_MULTIBIT_ECC, MULTIBIT_ECC, 3) \
209 F(CPER_MEMORY_ERROR_SINGLESYM_CHIPKILL_ECC, SINGLESYM_CHIPKILL_ECC, 4)\
210 F(CPER_MEMORY_ERROR_MULTISYM_CHIPKILL_ECC, MULTISYM_CHIPKILL_ECC, 5) \
211 F(CPER_MEMORY_ERROR_MASTER_ABORT, MASTER_ABORT, 6) \
212 F(CPER_MEMORY_ERROR_TARGET_ABORT, TARGET_ABORT, 7) \
213 F(CPER_MEMORY_ERROR_PARITY_ERROR, PARITY_ERROR, 8) \
214 F(CPER_MEMORY_ERROR_WATCHDOG_TIMEOUT, WATCHDOG_TIMEOUT, 9) \
215 F(CPER_MEMORY_ERROR_INVALID_ADDRESS, INVALID_ADDRESS, 10) \
216 F(CPER_MEMORY_ERROR_MIRROR_BROKEN, MIRROR_BROKEN, 11) \
217 F(CPER_MEMORY_ERROR_MEMORY_SPARING, MEMORY_SPARING, 12) \
218 F(CPER_MEMORY_ERROR_SCRUB_CORRECTED_ERROR, SCRUB_CORRECTED_ERROR, 13) \
219 F(CPER_MEMORY_ERROR_SCRUB_UNCORRECTED_ERROR, SCRUB_UNCORRECTED_ERROR, \
220 14) \
221 F(CPER_MEMORY_ERROR_PHYSMEM_MAPOUT_EVENT, PHYSMEM_MAPOUT_EVENT, 15) \
222 /* end of CPER_MEMORY_ERROR_TYPES */
223
224 enum cper_memory_error_type { /* struct cper_memory_error::MemoryErrorType */
225 #define CPER_MEMORY_ERROR_TYPE_DEF(LN, SN, V) LN = V,
226 CPER_MEMORY_ERROR_TYPES(CPER_MEMORY_ERROR_TYPE_DEF)
227 #undef CPER_MEMORY_ERROR_TYPE_DEF
228 };
229
230 enum { /* struct cper_memory_error_ext::Extended */
231 CPER_MEMORY_ERROR_EXTENDED_ROWBIT16 = __BIT(0),
232 CPER_MEMORY_ERROR_EXTENDED_ROWBIT17 = __BIT(1),
233 CPER_MEMORY_ERROR_EXTENDED_CHIPID = __BITS(7,5),
234 };
235
236 /*
237 * N.2.7. PCI Express Error Section
238 *
239 * https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record.html#pci-express-error-section
240 *
241 * Type: {0xd995e954,0xbbc1,0x430f,{0xad,0x91,0xb4,0x4d,0xcb,0x3c,0x6f,0x35}}
242 */
243
244 struct cper_pcie_error {
245 uint64_t ValidationBits;
246 uint32_t PortType;
247 uint32_t Version;
248 uint32_t CommandStatus;
249 uint32_t Reserved0;
250 struct {
251 uint8_t VendorID[2];
252 uint8_t DeviceID[2]; /* product */
253 uint8_t ClassCode[3];
254 uint8_t Function;
255 uint8_t Device;
256 uint8_t Segment[2];
257 uint8_t Bus;
258 uint8_t SecondaryBus;
259 uint8_t Slot[2]; /* bits 0:2 resv, bits 3:15 slot */
260 uint8_t Reserved0;
261 } DeviceID;
262 uint64_t DeviceSerial;
263 uint32_t BridgeControlStatus;
264 uint8_t CapabilityStructure[60];
265 uint8_t AERInfo[96];
266 } __packed;
267 __CTASSERT(sizeof(struct cper_pcie_error) == 208);
268
269 enum { /* struct cper_pcie_error::ValidationBits */
270 CPER_PCIE_ERROR_VALID_PORT_TYPE = __BIT(0),
271 CPER_PCIE_ERROR_VALID_VERSION = __BIT(1),
272 CPER_PCIE_ERROR_VALID_COMMAND_STATUS = __BIT(2),
273 CPER_PCIE_ERROR_VALID_DEVICE_ID = __BIT(3),
274 CPER_PCIE_ERROR_VALID_DEVICE_SERIAL = __BIT(4),
275 CPER_PCIE_ERROR_VALID_BRIDGE_CONTROL_STATUS = __BIT(5),
276 CPER_PCIE_ERROR_VALID_CAPABILITY_STRUCTURE = __BIT(6),
277 CPER_PCIE_ERROR_VALID_AER_INFO = __BIT(7),
278 };
279
280 #define CPER_PCIE_ERROR_VALIDATION_BITS_FMT "\177\020" \
281 "b\000" "PORT_TYPE\0" \
282 "b\001" "VERSION\0" \
283 "b\002" "COMMAND_STATUS\0" \
284 "b\003" "DEVICE_ID\0" \
285 "b\004" "DEVICE_SERIAL\0" \
286 "b\005" "BRIDGE_CONTROL_STATUS\0" \
287 "b\006" "CAPABILITY_STRUCTURE\0" \
288 "b\007" "AER_INFO\0" \
289 "\0"
290
291 #define CPER_PCIE_ERROR_PORT_TYPES(F) \
292 F(CPER_PCIE_ERROR_PORT_TYPE_PCIE_ENDPOINT, PCIE_ENDPOINT, 0) \
293 F(CPER_PCIE_ERROR_PORT_TYPE_LEGACY_PCI_ENDPOINT, LEGACY_PCI_ENDPOINT, \
294 1) \
295 F(CPER_PCIE_ERROR_PORT_TYPE_ROOTPORT5_UPSTREAMSWITCH, \
296 ROOTPORT5_UPSTREAMSWITCH, 4) \
297 F(CPER_PCIE_ERROR_PORT_TYPE_DOWNSTREAMSWITCH, DOWNSTREAMSWITCH, 6) \
298 F(CPER_PCIE_ERROR_PORT_TYPE_PCIE_PCI_BRIDGE, PCIE_PCI_BRIDGE, 7) \
299 F(CPER_PCIE_ERROR_PORT_TYPE_PCI_PCIE_BRIDGE, PCI_PCIE_BRIDGE, 8) \
300 F(CPER_PCIE_ERROR_PORT_TYPE_RCIEP_DEV, RCIEP_DEV, 9) \
301 /* Root Complex Integrated Endpoint Device */ \
302 F(CPER_PCIE_ERROR_PORT_TYPE_RCEC, RCEC, 10) \
303 /* Root Complex Event Collector */ \
304 /* end of CPER_PCIE_ERROR_PORT_TYPES */
305
306 enum cper_pcie_error_port_type { /* struct cper_pcie_error::PortType */
307 #define CPER_PCIE_ERROR_PORT_TYPE_DEF(LN, SN, V) LN = V,
308 CPER_PCIE_ERROR_PORT_TYPES(CPER_PCIE_ERROR_PORT_TYPE_DEF)
309 #undef CPER_PCIE_ERROR_PORT_TYPE_DEF
310 };
311
312 #endif /* _SYS_DEV_ACPI_APEI_CPER_H_ */
313