1/*	$NetBSD: apei_cper.h,v 1.2 2024/03/26 22:16:12 rillig 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 */
45struct 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
65enum {				/* struct cper_header::error_severity */
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
72enum {				/* struct cper_header::validation_bits */
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 */
81enum {				/* 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 */
90enum {
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 * https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record.html#memory-error-section
114 *
115 * Type: {0xa5bc1114,0x6f64,0x4ede,{0xb8,0x63,0x3e,0x83,0xed,0x7c,0x83,0xb1}}
116 */
117
118struct cper_memory_error {
119	uint64_t	ValidationBits;
120	uint64_t	ErrorStatus;
121	uint64_t	PhysicalAddress;
122	uint64_t	PhysicalAddressMask;
123	uint16_t	Node;
124	uint16_t	Card;
125	uint16_t	Module;
126	uint16_t	Bank;
127	uint16_t	Device;
128	uint16_t	Row;
129	uint16_t	Column;
130	uint16_t	BitPosition;
131	uint64_t	RequestorId;
132	uint64_t	ResponderId;
133	uint64_t	TargetId;
134	uint8_t		MemoryErrorType;
135} __packed;
136__CTASSERT(sizeof(struct cper_memory_error) == 73);
137
138struct cper_memory_error_ext {
139	struct cper_memory_error	Base;
140	uint8_t		Extended;
141	uint16_t	RankNumber;
142	uint16_t	CardHandle;
143	uint16_t	ModuleHandle;
144} __packed;
145__CTASSERT(sizeof(struct cper_memory_error_ext) == 80);
146
147enum {				/* struct cper_memory_error::validation_bits */
148	CPER_MEMORY_ERROR_VALID_ERROR_STATUS		= __BIT(0),
149	CPER_MEMORY_ERROR_VALID_PHYSICAL_ADDRESS	= __BIT(1),
150	CPER_MEMORY_ERROR_VALID_PHYSICAL_ADDRESS_MASK	= __BIT(2),
151	CPER_MEMORY_ERROR_VALID_NODE			= __BIT(3),
152	CPER_MEMORY_ERROR_VALID_CARD			= __BIT(4),
153	CPER_MEMORY_ERROR_VALID_MODULE			= __BIT(5),
154	CPER_MEMORY_ERROR_VALID_BANK			= __BIT(6),
155	CPER_MEMORY_ERROR_VALID_DEVICE			= __BIT(7),
156	CPER_MEMORY_ERROR_VALID_ROW			= __BIT(8),
157	CPER_MEMORY_ERROR_VALID_COLUMN			= __BIT(9),
158	CPER_MEMORY_ERROR_VALID_BIT_POSITION		= __BIT(10),
159	CPER_MEMORY_ERROR_VALID_REQUESTOR_ID		= __BIT(11),
160	CPER_MEMORY_ERROR_VALID_RESPONDER_ID		= __BIT(12),
161	CPER_MEMORY_ERROR_VALID_TARGET_ID		= __BIT(13),
162	CPER_MEMORY_ERROR_VALID_MEMORY_ERROR_TYPE	= __BIT(14),
163	CPER_MEMORY_ERROR_VALID_RANK_NUMBER		= __BIT(15),
164	CPER_MEMORY_ERROR_VALID_CARD_HANDLE		= __BIT(16),
165	CPER_MEMORY_ERROR_VALID_MODULE_HANDLE		= __BIT(17),
166	CPER_MEMORY_ERROR_VALID_EXTENDED_ROW		= __BIT(18),
167	CPER_MEMORY_ERROR_VALID_BANK_GROUP		= __BIT(19),
168	CPER_MEMORY_ERROR_VALID_BANK_ADDRESS		= __BIT(20),
169	CPER_MEMORY_ERROR_VALID_CHIP_ID			= __BIT(21),
170};
171
172#define	CPER_MEMORY_ERROR_VALIDATION_BITS_FMT	"\177\020"		      \
173	"b\000"	"ERROR_STATUS\0"					      \
174	"b\001"	"PHYSICAL_ADDRESS\0"					      \
175	"b\002"	"PHYSICAL_ADDRESS_MASK\0"				      \
176	"b\003"	"NODE\0"						      \
177	"b\004"	"CARD\0"						      \
178	"b\005"	"MODULE\0"						      \
179	"b\006"	"BANK\0"						      \
180	"b\007"	"DEVICE\0"						      \
181	"b\010"	"ROW\0"							      \
182	"b\011"	"COLUMN\0"						      \
183	"b\012"	"BIT_POSITION\0"					      \
184	"b\013"	"REQUESTOR_ID\0"					      \
185	"b\014"	"RESPONDER_ID\0"					      \
186	"b\015"	"TARGET_ID\0"						      \
187	"b\016"	"MEMORY_ERROR_TYPE\0"					      \
188	"b\017"	"RANK_NUMBER\0"						      \
189	"b\020"	"CARD_HANDLE\0"						      \
190	"b\021"	"MODULE_HANDLE\0"					      \
191	"b\022"	"EXTENDED_ROW\0"					      \
192	"b\023"	"BANK_GROUP\0"						      \
193	"b\024"	"BANK_ADDRESS\0"					      \
194	"b\025"	"CHIP_ID\0"						      \
195	"\0"
196
197enum {				/* struct cper_memory_error::bank */
198	CPER_MEMORY_ERROR_BANK_ADDRESS	= __BITS(7,0),
199	CPER_MEMORY_ERROR_BANK_GROUP	= __BITS(15,8),
200};
201
202#define	CPER_MEMORY_ERROR_TYPES(F)					      \
203	F(CPER_MEMORY_ERROR_UNKNOWN, UNKNOWN, 0)			      \
204	F(CPER_MEMORY_ERROR_NO_ERROR, NO_ERROR, 1)			      \
205	F(CPER_MEMORY_ERROR_SINGLEBIT_ECC, SINGLEBIT_ECC, 2)		      \
206	F(CPER_MEMORY_ERROR_MULTIBIT_ECC, MULTIBIT_ECC, 3)		      \
207	F(CPER_MEMORY_ERROR_SINGLESYM_CHIPKILL_ECC, SINGLESYM_CHIPKILL_ECC, 4)\
208	F(CPER_MEMORY_ERROR_MULTISYM_CHIPKILL_ECC, MULTISYM_CHIPKILL_ECC, 5)  \
209	F(CPER_MEMORY_ERROR_MASTER_ABORT, MASTER_ABORT, 6)		      \
210	F(CPER_MEMORY_ERROR_TARGET_ABORT, TARGET_ABORT, 7)		      \
211	F(CPER_MEMORY_ERROR_PARITY_ERROR, PARITY_ERROR, 8)		      \
212	F(CPER_MEMORY_ERROR_WATCHDOG_TIMEOUT, WATCHDOG_TIMEOUT, 9)	      \
213	F(CPER_MEMORY_ERROR_INVALID_ADDRESS, INVALID_ADDRESS, 10)	      \
214	F(CPER_MEMORY_ERROR_MIRROR_BROKEN, MIRROR_BROKEN, 11)		      \
215	F(CPER_MEMORY_ERROR_MEMORY_SPARING, MEMORY_SPARING, 12)		      \
216	F(CPER_MEMORY_ERROR_SCRUB_CORRECTED_ERROR, SCRUB_CORRECTED_ERROR, 13) \
217	F(CPER_MEMORY_ERROR_SCRUB_UNCORRECTED_ERROR, SCRUB_UNCORRECTED_ERROR, \
218	    14)								      \
219	F(CPER_MEMORY_ERROR_PHYSMEM_MAPOUT_EVENT, PHYSMEM_MAPOUT_EVENT, 15)   \
220	/* end of CPER_MEMORY_ERROR_TYPES */
221
222enum cper_memory_error_type { /* struct cper_memory_error::memory_error_type */
223#define	CPER_MEMORY_ERROR_TYPE_DEF(LN, SN, V)	LN = V,
224	CPER_MEMORY_ERROR_TYPES(CPER_MEMORY_ERROR_TYPE_DEF)
225#undef	CPER_MEMORY_ERROR_TYPE_DEF
226};
227
228enum {				/* struct cper_memory_error_ext::extended */
229	CPER_MEMORY_ERROR_EXTENDED_ROWBIT16		= __BIT(0),
230	CPER_MEMORY_ERROR_EXTENDED_ROWBIT17		= __BIT(1),
231	CPER_MEMORY_ERROR_EXTENDED_CHIPID		= __BITS(7,5),
232};
233
234#endif	/* _SYS_DEV_ACPI_APEI_CPER_H_ */
235