blob: 16040417d3c2ec63f7bc7d96b81690aeb7f1f4ca [file] [log] [blame]
Marshall Dawsonfd39f912018-09-04 12:07:21 -06001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2018 Advanced Micro Devices, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef _CPER_H_
17#define _CPER_H_
18
19#include <types.h>
20#include <uuid.h>
21#include <bcd.h>
22#include <rtc.h>
23
24/* This file contains some definitions and helpers for implementing structures
25 * in the UEFI specification, Appendix "Common Platform Error Record". This
26 * is not a complete definition, but contains enough to generate a BERT ACPI
27 * table.
28 *
29 * All table numbers and references correspond with UEFI spec version 2.7,
30 * errata A, available at uefi.org.
31 */
32
33/* Error Record Header, Timestamp field (Table 251) */
34typedef struct cper_timestamp { /* BCD values */
35 u8 sec;
36 u8 min;
37 u8 hour;
38 u8 precise; /* b[0] precise - timestamp of error, b[7:1] rsvd */
39 u8 day;
40 u8 month;
41 u8 year;
42 u8 century;
43} __packed cper_timestamp_t;
44
45#define CPER_TIMESTAMP_PRECISE BIT(0)
46
47/* Section Descriptor, Flags field (Table 253) */
48#define CPER_SEC_PRIMARY BIT(0)
49#define CPER_SEC_CONTAINMENT_WARNING BIT(1)
50#define CPER_SEC_RESET BIT(2)
51#define CPER_SEC_ERROR_THRESHOLD_EXCEEDED BIT(3)
52#define CPER_SEC_RESOURCE_NOT_ACCESSIBLE BIT(4)
53#define CPER_SEC_LATENT_ERROR BIT(5)
54#define CPER_SEC_PROPAGATED BIT(6)
55#define CPER_SEC_OVERFLOW BIT(7)
56
57/* Section Descriptor, Section Types values (Table 253) */
58#define CPER_SEC_PROC_GENERIC_GUID \
59 GUID_INIT(0x9876ccad, 0x47b4, 0x4bdb, \
60 0xb6, 0x5e, 0x16, 0xf1, 0x93, 0xc4, 0xf3, 0xdb)
61#define CPER_SEC_PROC_IA32X64_GUID \
62 GUID_INIT(0xdc3ea0b0, 0xa144, 0x4797, \
63 0xb9, 0x5b, 0x53, 0xfa, 0x24, 0x2b, 0x6e, 0x1d)
64#define CPER_SEC_PROC_ARM_GUID \
65 GUID_INIT(0xe19e3d16, 0xbc11, 0x11e4, \
66 0x9c, 0xaa, 0xc2, 0x05, 0x1d, 0x5d, 0x46, 0xb0)
67#define CPER_SEC_PLATFORM_MEM_GUID \
68 GUID_INIT(0xa5bc1114, 0x6f64, 0x4ede, \
69 0xb8, 0x63, 0x3e, 0x83, 0xed, 0x7c, 0x83, 0xb1)
70#define CPER_SEC_PLATFORM_MEM2_GUID \
71 GUID_INIT(0x61ec04fc, 0x48e6, 0xd813, \
72 0x25, 0xc9, 0x8d, 0xaa, 0x44, 0x75, 0x0b, 0x12)
73#define CPER_SEC_PCIE_GUID \
74 GUID_INIT(0xd995e954, 0xbbc1, 0x430f, \
75 0xad, 0x91, 0xb4, 0x4d, 0xcb, 0x3c, 0x6f, 0x35)
76#define CPER_SEC_FW_ERR_REC_REF_GUID \
77 GUID_INIT(0x81212a96, 0x09ed, 0x4996, \
78 0x94, 0x71, 0x8d, 0x72, 0x9c, 0x8e, 0x69, 0xed)
79#define CPER_SEC_PCI_X_BUS_GUID \
80 GUID_INIT(0xc5753963, 0x3b84, 0x4095, \
81 0xbf, 0x78, 0xed, 0xda, 0xd3, 0xf9, 0xc9, 0xdd)
82#define CPER_SEC_PCI_DEV_GUID \
83 GUID_INIT(0xeb5e4685, 0xca66, 0x4769, \
84 0xb6, 0xa2, 0x26, 0x06, 0x8b, 0x00, 0x13, 0x26)
85#define CPER_SEC_DMAR_GENERIC_GUID \
86 GUID_INIT(0x5b51fef7, 0xc79d, 0x4434, \
87 0x8f, 0x1b, 0xaa, 0x62, 0xde, 0x3e, 0x2c, 0x64)
88#define CPER_SEC_DMAR_VT_GUID \
89 GUID_INIT(0x71761d37, 0x32b2, 0x45cd, \
90 0xa7, 0xd0, 0xb0, 0xfe, 0xdd, 0x93, 0xe8, 0xcf)
91#define CPER_SEC_DMAR_IOMMU_GUID \
92 GUID_INIT(0x036f84e1, 0x7f37, 0x428c, \
93 0xa7, 0x9e, 0x57, 0x5f, 0xdf, 0xaa, 0x84, 0xec)
94
95/*
96 * Processor Generic Error Section (Table 254)
97 */
98typedef struct cper_proc_generic_error_section {
99 u64 validation;
100 u8 proc_type;
101 u8 proc_isa;
102 u8 error_type;
103 u8 operation;
104 u8 flags;
105 u8 level;
106 u16 reserved;
107 u64 cpu_version;
108 char cpu_brand_string[128];
109 u64 proc_id;
110 u64 target_addr;
111 u64 requestor_id;
112 u64 responder_id;
113 u64 instruction_ip;
114} __packed cper_proc_generic_error_section_t;
115
116/* Processor Generic Error Section, Validation Bits field (Table 254) */
117#define GENPROC_VALID_PROC_TYPE BIT(0)
118#define GENPROC_VALID_PROC_ISA BIT(1)
119#define GENPROC_VALID_PROC_ERR_TYPE BIT(2)
120#define GENPROC_VALID_OPERATION BIT(3)
121#define GENPROC_VALID_FLAGS BIT(4)
122#define GENPROC_VALID_LEVEL BIT(5)
123#define GENPROC_VALID_CPU_VERSION BIT(6)
124#define GENPROC_VALID_CPU_BRAND BIT(7)
125#define GENPROC_VALID_CPU_ID BIT(8) /* LAPIC ID, not CPUID */
126#define GENPROC_VALID_TGT_ADDR BIT(9)
127#define GENPROC_VALID_REQR_ID BIT(10)
128#define GENPROC_VALID_RSPR_ID BIT(11)
129#define GENPROC_VALID_INSTR_IP BIT(12)
130
131/* Processor Generic Error Section, Processor Type field (Table 254) */
132#define GENPROC_PROCTYPE_IA32X64 0x0
133#define GENPROC_PROCTYPE_IA64 0x1
134#define GENPROC_PROCTYPE_ARM 0x2
135
136/* Processor Generic Error Section, Processor ISA (@time of fail) (Table 254) */
137#define GENPROC_ISA_IA32 0x0
138#define GENPROC_ISA_IA64 0x1
139#define GENPROC_ISA_X64 0x2
140#define GENPROC_ISA_ARM32 0x3
141#define GENPROC_ISA_ARM64 0x4
142
143/* error_type definitions */
144/* Processor Generic Error Section, Processor Error Type field (Table 254) */
145#define GENPROC_ERRTYPE_UNKNOWN 0x0
146#define GENPROC_ERRTYPE_CACHE 0x1
147#define GENPROC_ERRTYPE_TLB 0x2
148#define GENPROC_ERRTYPE_BUS 0x4
149#define GENPROC_ERRTYPE_UARCH 0x8
150
151/* Processor Generic Error Section, Operation field (Table 254) */
152#define GENPROC_ERROP_UNKNOWN 0x0
153#define GENPROC_ERROP_READ 0x1
154#define GENPROC_ERROP_WRITE 0x2
155#define GENPROC_ERROP_EXECUTION 0x3
156
157/* Processor Generic Error Section, Flags field (Table 254) */
158#define GENPROC_FLAG_RESTARTABLE 0x0
159#define GENPROC_FLAG_PRECISE_IP 0x1
160#define GENPROC_FLAG_OVERFLOW 0x2
161#define GENPROC_FLAG_CORRECTED 0x3
162
163/*
164 * IA32/X64 Processor Error Section (Table 255)
165 */
166typedef struct cper_ia32x64_proc_error_section {
167 u64 validation;
168 u64 apicid;
169 u64 cpuid[6];
170 /* PROC_ERR_INFO_NUM x 64-byte structures */
171 /* PROC_CONTEXT_INFO_NUM x context structures */
172} __packed cper_ia32x64_proc_error_section_t;
173
174/* IA32/X64 Processor Error, Validation Bits field (Table 255) */
175#define I32X64SEC_VALID_LAPIC BIT(0)
176#define I32X64SEC_VALID_CPUID BIT(1)
177#define I32X64SEC_VALID_ERRNUM_SH 2
178#define I32X64SEC_VALID_ERRNUM_MAX 0x3f
179#define I32X64SEC_VALID_ERRNUM_MASK \
180 (I32X64SEC_VALID_ERRNUM_MAX \
181 << I32X64SEC_VALID_ERRNUM_SH)
182#define I32X64SEC_VALID_CTXNUM_SH 8
183#define I32X64SEC_VALID_CTXNUM_MAX 0x3f
184#define I32X64SEC_VALID_CTXNUM_MASK \
185 (I32X64SEC_VALID_CTXNUM_MAX \
186 << I32X64SEC_VALID_CTXNUM_SH)
187
188/* IA32/X64 Processor Error Information Structure (Table 256) */
189typedef struct cper_ia32x64_proc_error_info {
190 guid_t type; /* cache, tlb, bus, micro-architecture specific */
191 u64 validation;
192 u64 check_info;
193 u64 target_id;
194 u64 requestor_id;
195 u64 responder_id;
196 u64 instruction_ip;
197} cper_ia32x64_proc_error_info_t;
198
199/* IA32/X64 Processor Error Information Structs, Err Struct Types (Table 256) */
200#define X86_PROCESSOR_CACHE_CHK_ERROR_GUID \
201 GUID_INIT(0xa55701f5, 0xe3ef, 0x43de, \
202 0xac, 0x72, 0x24, 0x9b, 0x57, 0x3f, 0xad, 0x2c)
203#define X86_PROCESSOR_TLB_CHK_ERROR_GUID \
204 GUID_INIT(0xfc06b535, 0x5e1f, 0x4562, \
205 0x9f, 0x25, 0x0a, 0x3b, 0x9a, 0xdb, 0x63, 0xc3)
206#define X86_PROCESSOR_BUS_CHK_ERROR_GUID \
207 GUID_INIT(0x1cf3f8b3, 0xc5b1, 0x49a2, \
208 0xaa, 0x59, 0x5e, 0xef, 0x92, 0xff, 0xa6, 0x3c)
209#define X86_PROCESSOR_MS_CHK_ERROR_GUID \
210 GUID_INIT(0x48ab7f57, 0xdc34, 0x4f6c, \
211 0xa7, 0xd3, 0xb0, 0xb5, 0xb0, 0xa7, 0x43, 0x14)
212
213enum cper_x86_check_type {
214 X86_PROCESSOR_CACHE_CHK, /* X86_PROCESSOR_CACHE_CHK_ERROR_GUID */
215 X86_PROCESSOR_TLB_CHK, /* X86_PROCESSOR_TLB_CHK_ERROR_GUID */
216 X86_PROCESSOR_BUS_CHK, /* X86_PROCESSOR_BUS_CHK_ERROR_GUID */
217 X86_PROCESSOR_MS_CHK /* X86_PROCESSOR_MS_CHK_ERROR_GUID */
218};
Marshall Dawson03b99772018-09-06 12:08:09 -0600219#define X86_PROCESSOR_CHK_MAX X86_PROCESSOR_MS_CHK
Marshall Dawsonfd39f912018-09-04 12:07:21 -0600220
221/* IA32/X64 Processor Error Information Structure, Validation Bits (Tbl 256) */
222#define I32X64ERRINFO_VALID_CHECK BIT(0)
223#define I32X64ERRINFO_VALID_TGT_ADDR BIT(1)
224#define I32X64ERRINFO_VALID_RQST_ID BIT(2)
225#define I32X64ERRINFO_VALID_RSPD_ID BIT(3)
226#define I32X64ERRINFO_VALID_IPPTR BIT(4)
227
228/* IA32/X64 Proc. Error Info: Cache/TLB/Check defs (Tables 257, 258, 259) */
229#define X86_PROC_CHK_XACT_TYPE_VALID BIT(0) /* CACHE|TLB|BUS */
230#define X86_PROC_CHK_OPERATION_VALID BIT(1) /* CACHE|TLB|BUS */
231#define X86_PROC_CHK_LEVEL_VALID BIT(2) /* CACHE|TLB|BUS */
232#define X86_PROC_CHK_CONTEXT_CORPT_VALID BIT(3) /* CACHE|TLB|BUS */
233#define X86_PROC_CHK_UNCORRECTED_VALID BIT(4) /* CACHE|TLB|BUS */
234#define X86_PROC_CHK_PRECISE_IP_VALID BIT(5) /* CACHE|TLB|BUS */
235#define X86_PROC_CHK_RESTARTABLE_VALID BIT(6) /* CACHE|TLB|BUS */
236#define X86_PROC_CHK_OVERFLOW_VALID BIT(7) /* CACHE|TLB|BUS */
237#define X86_PROC_CHK_PART_TYPE_VALID BIT(8) /* | |BUS */
238#define X86_PROC_CHK_TIMEOUT_VALID BIT(9) /* | |BUS */
239#define X86_PROC_CHK_ADDR_SPACE_VALID BIT(10) /* | |BUS */
240#define X86_PROC_CHK_XACT_SH 16 /* CA|TLB|BUS */
241#define X86_PROC_CHK_XACT_MASK (0x3 << X86_PROC_CHK_XACT_SH)
242#define X86_PROC_CHK_XACT_INSTRUCTION (0 << X86_PROC_CHK_XACT_SH)
243#define X86_PROC_CHK_XACT_DATA (1 << X86_PROC_CHK_XACT_SH)
244#define X86_PROC_CHK_XACT_GENERIC (2 << X86_PROC_CHK_XACT_SH)
245#define X86_PROC_CHK_OPER_SH 18 /* CA|TLB|BUS */
246#define X86_PROC_CHK_OPER_MASK (0xf << X86_PROC_CHK_OPER_SH)
247#define X86_PROC_CHK_OPER_GENERIC (0 << X86_PROC_CHK_OPER_SH)
248#define X86_PROC_CHK_OPER_GENREAD (1 << X86_PROC_CHK_OPER_SH)
249#define X86_PROC_CHK_OPER_GENWRITE (2 << X86_PROC_CHK_OPER_SH)
250#define X86_PROC_CHK_OPER_DATAREAD (3 << X86_PROC_CHK_OPER_SH)
251#define X86_PROC_CHK_OPER_DATAWRITE (4 << X86_PROC_CHK_OPER_SH)
252#define X86_PROC_CHK_OPER_FETCH (5 << X86_PROC_CHK_OPER_SH)
253#define X86_PROC_CHK_OPER_PREFETCH (6 << X86_PROC_CHK_OPER_SH)
254 /* CA| | */
255#define X86_PROC_CHK_OPER_EVICTION (7 << X86_PROC_CHK_OPER_SH)
256#define X86_PROC_CHK_OPER_SNOOP (8 << X86_PROC_CHK_OPER_SH)
257#define X86_PROC_CHK_LEVEL_SH 22 /* CA|TLB|BUS */
258#define X86_PROC_CHK_LEVEL_MASK (0x7 << X86_PROC_CHK_LEVEL_SH)
259#define X86_PROC_CHK_LEVEL_1 (1 << X86_PROC_CHK_LEVEL_SH)
260#define X86_PROC_CHK_LEVEL_2 (2 << X86_PROC_CHK_LEVEL_SH)
261#define X86_PROC_CHK_LEVEL_3 (3 << X86_PROC_CHK_LEVEL_SH)
262#define X86_PROC_CHK_CTX_CORRUPT (1 << 25) /* CA|TLB|BUS */
263#define X86_PROC_CHK_UNCORRECTED (1 << 26) /* CA|TLB|BUS */
264#define X86_PROC_CHK_PRECISE_IP (1 << 27) /* CA|TLB|BUS */
265#define X86_PROC_CHK_RESTARTABLE_IP (1 << 28) /* CA|TLB|BUS */
266#define X86_PROC_CHK_OVERFLOW (1 << 29) /* CA|TLB|BUS */
267#define X86_PROC_CHK_PARTIC_SH 30 /* | |BUS */
268#define X86_PROC_CHK_PARTIC_MASK (3 << X86_PROC_CHK_PARTIC_SH)
269#define X86_PROC_CHK_ORIGINATED (0 << X86_PROC_CHK_PARTIC_SH)
270#define X86_PROC_CHK_RESPONDED (1 << X86_PROC_CHK_PARTIC_SH)
271#define X86_PROC_CHK_OBSERVED (2 << X86_PROC_CHK_PARTIC_SH)
272#define X86_PROC_CHK_TIMEOUT 0x100000000 /* BIT(32) */
273#define X86_PROC_CHK_SPACE_SH 33 /* | |BUS */
274#define X86_PROC_CHK_SPACE_MASK (0x3 << X86_PROC_CHK_SPACE_SH)
275#define X86_PROC_CHK_SPACE_MEM (0 << X86_PROC_CHK_SPACE_SH)
276#define X86_PROC_CHK_SPACE_IO (2 << X86_PROC_CHK_SPACE_SH)
277#define X86_PROC_CHK_SPACE_OTHER (3 << X86_PROC_CHK_SPACE_SH)
278/* MS check defines & aligns (Table 260 */
279#define X86_PROC_MS_ERROR_TYPE_VALID BIT(0)
280#define X86_PROC_MS_CONTEXT_CORPT_VALID BIT(1)
281#define X86_PROC_MS_UNCORRECTED_VALID BIT(2)
282#define X86_PROC_MS_PRECISE_IP_VALID BIT(3)
283#define X86_PROC_MS_RESTARTABLE_IP_VALID BIT(4)
284#define X86_PROC_MS_OVERFLOW_VALID BIT(5)
285#define X86_PROC_MS_CHK_XACT_SH 16
286#define X86_PROC_MS_CHK_XACT_MASK (0x7 << X86_PROC_MS_CHK_XACT_SH)
287#define X86_PROC_MS_CHK_XACT_TYPE_NOERR (0 << X86_PROC_MS_CHK_XACT_SH)
288#define X86_PROC_MS_CHK_XACT_TYPE_UNCL (1 << X86_PROC_MS_CHK_XACT_SH)
289#define X86_PROC_MS_CHK_XACT_TYPE_UCODE_ROM (2 << X86_PROC_MS_CHK_XACT_SH)
290#define X86_PROC_MS_CHK_XACT_TYPE_EXT (3 << X86_PROC_MS_CHK_XACT_SH)
291#define X86_PROC_MS_CHK_XACT_TYPE_FRC (4 << X86_PROC_MS_CHK_XACT_SH)
292#define X86_PROC_MS_CHK_XACT_TYPE_INT_UNCL (5 << X86_PROC_MS_CHK_XACT_SH)
293#define X86_PROC_MS_CHK_CTX_CORRUPT (1 << 19)
294#define X86_PROC_MS_CHK_UNCORRECTED (1 << 20)
295#define X86_PROC_MS_CHK_PRECISE_IP (1 << 21)
296#define X86_PROC_MS_CHK_RESTARTABLE_IP (1 << 22)
297#define X86_PROC_MS_CHK_OVERFLOW (1 << 23)
298
299/* IA32/X64 Processor Context Information (Table 261) */
300typedef struct cper_ia32x64_context {
301 u16 type;
302 u16 array_size;
303 u32 msr_addr;
304 u64 mmap_addr;
305 /* N bytes of register array */
306} cper_ia32x64_context_t;
307
308/* IA32/X64 Processor Context Information, Types field (Table 261) */
309#define CPER_IA32X64_CTX_UNCL 0
310#define CPER_IA32X64_CTX_MSR 1
311#define CPER_IA32X64_CTX_32BIT_EX 2
312#define CPER_IA32X64_CTX_64BIT_EX 3
313#define CPER_IA32X64_CTX_FXSAVE 4
314#define CPER_IA32X64_CTX_32BIT_DBG 5
315#define CPER_IA32X64_CTX_64BIT_DBG 6
316#define CPER_IA32X64_CTX_MEMMAPPED 7
317
318/* IA32/X64 Processor Context IA32 Register State (Table 262) */
319typedef struct cper_ia32x64_ctx_ia32state {
320 u32 eax;
321 u32 ebx;
322 u32 ecx;
323 u32 edx;
324 u32 esi;
325 u32 edi;
326 u32 ebp;
327 u32 esp;
328 u16 cs;
329 u16 ds;
330 u16 ss;
331 u16 es;
332 u16 fs;
333 u16 gs;
334 u32 eflags;
335 u32 eip;
336 u32 cr0;
337 u32 cr1;
338 u32 cr2;
339 u32 cr3;
340 u32 cr4;
341 u64 gdtr;
342 u64 idtr;
343 u16 ldtr;
344 u16 tr;
345} cper_ia32x64_ctx_ia32state_t;
346
347/* IA32/X64 Processor Context X64 Register state (Table 263) */
348typedef struct cper_ia32x64_ctx_x64state {
349 u64 rax;
350 u64 rbx;
351 u64 rcx;
352 u64 rdx;
353 u64 rsi;
354 u64 rdi;
355 u64 rbp;
356 u64 rsp;
357 u64 r8;
358 u64 r9;
359 u64 r10;
360 u64 r11;
361 u64 r12;
362 u64 r13;
363 u64 r14;
364 u64 r15;
365 u16 cs;
366 u16 ds;
367 u16 ss;
368 u16 es;
369 u16 fs;
370 u16 gs;
371 u32 reserved;
372 u64 rflags;
373 u64 eip;
374 u64 cr0;
375 u64 cr1;
376 u64 cr2;
377 u64 cr3;
378 u64 cr4;
379 u64 cr8;
380 u8 gdtr[16];
381 u8 idtr[16];
382 u16 ldtr;
383 u16 tr;
384} cper_ia32x64_ctx_x64state_t;
385
386static inline cper_timestamp_t cper_timestamp(int precise)
387{
388 cper_timestamp_t ts;
389#if IS_ENABLED(CONFIG_RTC)
390 struct rtc_time time;
391
392 rtc_get(&time);
393 ts.sec = bin2bcd(time.sec);
394 ts.min = bin2bcd(time.min);
395 ts.hour = bin2bcd(time.hour);
396 ts.day = bin2bcd(time.mday);
397 ts.month = bin2bcd(time.mon);
398 ts.year = bin2bcd(time.year % 100);
399 ts.century = bin2bcd(time.year / 100);
400 ts.precise = precise;
401#else
402 ts.sec = 0;
403 ts.min = 0;
404 ts.hour = 0;
405 ts.day = 0;
406 ts.month = 0;
407 ts.year = 0;
408 ts.century = 0;
409 ts.precise = 0;
410#endif
411 return ts;
412}
413
414/* Calculate the size of an IA32/X64 context by its type. Some types have a
415 * predetermined size, and others are variable size. All sizes are rounded up
416 * to the nearest multiple of 16 bytes (See Processor Context field of
417 * Table 255).
418 *
419 * type is one of:
420 * CPER_IA32X64_CTX_UNCL
421 * CPER_IA32X64_CTX_MSR
422 * CPER_IA32X64_CTX_32BIT_EX
423 * CPER_IA32X64_CTX_64BIT_EX
424 * CPER_IA32X64_CTX_FXSAVE
425 * CPER_IA32X64_CTX_32BIT_DBG
426 * CPER_IA32X64_CTX_64BIT_DBG
427 * CPER_IA32X64_CTX_MEMMAPPED
428 * num is the number of items in the context's register array
429 */
430static inline size_t cper_ia32x64_ctx_sz_bytype(int type, int arr_num)
431{
432 size_t sz = sizeof(cper_ia32x64_context_t);
433
434 switch (type) {
435 case CPER_IA32X64_CTX_32BIT_EX:
436 return ALIGN_UP(sz + sizeof(cper_ia32x64_ctx_ia32state_t), 16);
437 case CPER_IA32X64_CTX_64BIT_EX:
438 return ALIGN_UP(sz + sizeof(cper_ia32x64_ctx_x64state_t), 16);
439 case CPER_IA32X64_CTX_UNCL:
440 case CPER_IA32X64_CTX_MSR:
441 case CPER_IA32X64_CTX_FXSAVE:
442 case CPER_IA32X64_CTX_32BIT_DBG:
443 case CPER_IA32X64_CTX_64BIT_DBG:
444 case CPER_IA32X64_CTX_MEMMAPPED:
445 default:
446 /* Table 261: "size ... is determined by (Array Size / 8)" */
447 return ALIGN_UP(sz + arr_num * 8, 16);
448 }
449}
450
451static inline size_t cper_ia32x64_check_sz(void)
452{
453 return sizeof(cper_ia32x64_proc_error_info_t); /* all the same size */
454}
455
456/* Return PROC_ERR_INFO_NUM for an IA32/X64 Processor Error Record */
457static inline int cper_ia32x64_proc_num_chks(
458 cper_ia32x64_proc_error_section_t *x86err)
459{
460 int mask;
461 int shift;
462
463 mask = I32X64SEC_VALID_ERRNUM_MASK;
464 shift = I32X64SEC_VALID_ERRNUM_SH;
465
466 return (x86err->validation & mask) >> shift;
467}
468
469/* Return PROC_CONTEXT_INFO_NUM for an IA32/X64 Processor Error Record */
470static inline int cper_ia32x64_proc_num_ctxs(
471 cper_ia32x64_proc_error_section_t *x86err)
472{
473 int mask;
474 int shift;
475
476 mask = I32X64SEC_VALID_CTXNUM_MASK;
477 shift = I32X64SEC_VALID_CTXNUM_SH;
478
479 return (x86err->validation & mask) >> shift;
480}
481
482/* Do PROC_ERR_INFO_NUM++ of an IA32/X64 error section. Caller should ensure
483 * the max is not being exceeded.
484 */
485static inline void cper_bump_ia32x64_chk_count(
486 cper_ia32x64_proc_error_section_t *x86err)
487{
488 int count;
489
490 count = cper_ia32x64_proc_num_chks(x86err) + 1;
491 x86err->validation &= ~I32X64SEC_VALID_ERRNUM_MASK;
492 x86err->validation |= count << I32X64SEC_VALID_ERRNUM_SH;
493}
494
495/* Do PROC_CONTEXT_INFO_NUM++ of an IA32/X64 error section. Caller should
496 * ensure the max is not being exceeded.
497 */
498static inline void cper_bump_ia32x64_ctx_count(
499 cper_ia32x64_proc_error_section_t *x86err)
500{
501 int count;
502
503 count = cper_ia32x64_proc_num_ctxs(x86err) + 1;
504 x86err->validation &= ~I32X64SEC_VALID_CTXNUM_MASK;
505 x86err->validation |= count << I32X64SEC_VALID_CTXNUM_SH;
506}
507
508#endif /* _CPER_H_ */