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