xref: /rk3399_ARM-atf/plat/arm/board/automotive_rd/platform/common/cper.c (revision 10d33abec01d820ad749fdc61afc8dbc6b702b05)
1cbad38ffSSanjana Virupakshagouda /*
2cbad38ffSSanjana Virupakshagouda  * Copyright (c) 2025-2026, Arm Limited and Contributors. All rights reserved.
3cbad38ffSSanjana Virupakshagouda  *
4cbad38ffSSanjana Virupakshagouda  * SPDX-License-Identifier: BSD-3-Clause
5cbad38ffSSanjana Virupakshagouda  */
6cbad38ffSSanjana Virupakshagouda 
7cbad38ffSSanjana Virupakshagouda #include <string.h>
8cbad38ffSSanjana Virupakshagouda 
9cbad38ffSSanjana Virupakshagouda #include <arch_helpers.h>
10cbad38ffSSanjana Virupakshagouda #include <common/debug.h>
11cbad38ffSSanjana Virupakshagouda #include <lib/el3_runtime/aarch64/context.h>
12cbad38ffSSanjana Virupakshagouda #include <lib/el3_runtime/context_mgmt.h>
13cbad38ffSSanjana Virupakshagouda #include <lib/extensions/ras.h>
14cbad38ffSSanjana Virupakshagouda 
15cbad38ffSSanjana Virupakshagouda #include <cper.h>
16cbad38ffSSanjana Virupakshagouda #include <rdaspen_ras.h>
17cbad38ffSSanjana Virupakshagouda 
18cbad38ffSSanjana Virupakshagouda /* Convert ERXSTATUS_EL1 bits to CPER severity */
esb_severity_from_erx(uint64_t err_status)19cbad38ffSSanjana Virupakshagouda static inline uint32_t esb_severity_from_erx(uint64_t err_status)
20cbad38ffSSanjana Virupakshagouda {
21cbad38ffSSanjana Virupakshagouda 	if (err_status & ERX_STATUS_CE)
22cbad38ffSSanjana Virupakshagouda 		return ACPI_DATA_ENTRY_SEV_CORRECTED;
23cbad38ffSSanjana Virupakshagouda 	if (err_status & ERX_STATUS_DE)
24cbad38ffSSanjana Virupakshagouda 		return ACPI_DATA_ENTRY_SEV_RECOVERABLE;
25cbad38ffSSanjana Virupakshagouda 	if (err_status & ERX_STATUS_UE)
26cbad38ffSSanjana Virupakshagouda 		return ACPI_DATA_ENTRY_SEV_FATAL;
27cbad38ffSSanjana Virupakshagouda 	return ACPI_DATA_ENTRY_SEV_NONE;
28cbad38ffSSanjana Virupakshagouda }
29cbad38ffSSanjana Virupakshagouda 
arm_error_type_from_unit(uint64_t err_misc0)30cbad38ffSSanjana Virupakshagouda static inline uint8_t arm_error_type_from_unit(uint64_t err_misc0)
31cbad38ffSSanjana Virupakshagouda {
32cbad38ffSSanjana Virupakshagouda 	unsigned int unit = ERXMISC0_UNIT(err_misc0);
33cbad38ffSSanjana Virupakshagouda 
34cbad38ffSSanjana Virupakshagouda 	switch (unit) {
35cbad38ffSSanjana Virupakshagouda 	case ERXMISC0_UNIT_L2_TLB:
36cbad38ffSSanjana Virupakshagouda 		return ARM_ERROR_TYPE_TLB;
37cbad38ffSSanjana Virupakshagouda 	default:
38cbad38ffSSanjana Virupakshagouda 		return ARM_ERROR_TYPE_CACHE;
39cbad38ffSSanjana Virupakshagouda 	}
40cbad38ffSSanjana Virupakshagouda }
41cbad38ffSSanjana Virupakshagouda 
42cbad38ffSSanjana Virupakshagouda /*
43cbad38ffSSanjana Virupakshagouda  * ARM CACHE ERROR STRUCTURE
44cbad38ffSSanjana Virupakshagouda  *
45cbad38ffSSanjana Virupakshagouda  *  - Validation Bit (bits 15:0): Set valid bits for the fields encoded
46cbad38ffSSanjana Virupakshagouda  *  - Transaction Type (bits 17:16): INSTR / DATA / GENERIC (derived from UNIT)
47cbad38ffSSanjana Virupakshagouda  *  - Operation (bits 21:18): set to GENERIC
48cbad38ffSSanjana Virupakshagouda  *  - Level (bits 24:22): cache level (1 for L1, 2 for L2), derived from UNIT
49cbad38ffSSanjana Virupakshagouda  *  - Processor Context Corrupt (bit 25): value = 0 (not corrupted)
50cbad38ffSSanjana Virupakshagouda  *  - Corrected (bit 26): value from 'corrected' parameter
51cbad38ffSSanjana Virupakshagouda  *  - Precise PC (bit 27): value = 0
52cbad38ffSSanjana Virupakshagouda  *  - Restartable PC (bit 28): value = 0
53cbad38ffSSanjana Virupakshagouda  *  - Reserved (63:29): zero
54cbad38ffSSanjana Virupakshagouda  */
arm_cache_error_structure(uint64_t err_misc0,bool corrected)55cbad38ffSSanjana Virupakshagouda static inline uint64_t arm_cache_error_structure(uint64_t err_misc0,
56cbad38ffSSanjana Virupakshagouda 						 bool corrected)
57cbad38ffSSanjana Virupakshagouda {
58cbad38ffSSanjana Virupakshagouda 	uint64_t info = 0;
59cbad38ffSSanjana Virupakshagouda 	unsigned int unit = ERXMISC0_UNIT(err_misc0);
60cbad38ffSSanjana Virupakshagouda 
61cbad38ffSSanjana Virupakshagouda 	uint64_t tx_value = ARM_CACHE_ERR_TX_GENERIC;
62cbad38ffSSanjana Virupakshagouda 	uint64_t level_value = 0;
63cbad38ffSSanjana Virupakshagouda 
64cbad38ffSSanjana Virupakshagouda 	switch (unit) {
65cbad38ffSSanjana Virupakshagouda 	case ERXMISC0_UNIT_L1I:
66cbad38ffSSanjana Virupakshagouda 		/* TxType = Instruction, Level = 1 */
67cbad38ffSSanjana Virupakshagouda 		tx_value = ARM_CACHE_ERR_TX_INSTR;
68cbad38ffSSanjana Virupakshagouda 		level_value = 1u;
69cbad38ffSSanjana Virupakshagouda 		break;
70cbad38ffSSanjana Virupakshagouda 
71cbad38ffSSanjana Virupakshagouda 	case ERXMISC0_UNIT_L1D:
72cbad38ffSSanjana Virupakshagouda 		/* TxType = Data, Level = 1 */
73cbad38ffSSanjana Virupakshagouda 		tx_value = ARM_CACHE_ERR_TX_DATA;
74cbad38ffSSanjana Virupakshagouda 		level_value = 1u;
75cbad38ffSSanjana Virupakshagouda 		break;
76cbad38ffSSanjana Virupakshagouda 
77cbad38ffSSanjana Virupakshagouda 	case ERXMISC0_UNIT_L2_CACHE:
78cbad38ffSSanjana Virupakshagouda 		/* TxType = Generic, Level = 2 */
79cbad38ffSSanjana Virupakshagouda 		tx_value = ARM_CACHE_ERR_TX_GENERIC;
80cbad38ffSSanjana Virupakshagouda 		level_value = 2u;
81cbad38ffSSanjana Virupakshagouda 		break;
82cbad38ffSSanjana Virupakshagouda 
83cbad38ffSSanjana Virupakshagouda 	default:
84cbad38ffSSanjana Virupakshagouda 		break;
85cbad38ffSSanjana Virupakshagouda 	}
86cbad38ffSSanjana Virupakshagouda 
87cbad38ffSSanjana Virupakshagouda 	/* Validation bits (bit order: 0..6) */
88cbad38ffSSanjana Virupakshagouda 	info |= ARM_CACHE_ERR_VLD_TX_TYPE;    /* Bit 0: Transaction Type Valid */
89cbad38ffSSanjana Virupakshagouda 	info |= ARM_CACHE_ERR_VLD_OPERATION;  /* Bit 1: Operation Valid       */
90cbad38ffSSanjana Virupakshagouda 	info |= ARM_CACHE_ERR_VLD_LEVEL;      /* Bit 2: Level Valid           */
91cbad38ffSSanjana Virupakshagouda 	info |= ARM_CACHE_ERR_VLD_PCC;        /* Bit 3: PCC Valid             */
92cbad38ffSSanjana Virupakshagouda 	info |= ARM_CACHE_ERR_VLD_CORRECTED;  /* Bit 4: Corrected Valid       */
93cbad38ffSSanjana Virupakshagouda 	info |= ARM_CACHE_ERR_VLD_PRECISE_PC; /* Bit 5: Precise PC Valid      */
94cbad38ffSSanjana Virupakshagouda 	info |= ARM_CACHE_ERR_VLD_RESTART_PC; /* Bit 6: Restartable PC Valid  */
95cbad38ffSSanjana Virupakshagouda 
96cbad38ffSSanjana Virupakshagouda 	/* Transaction Type (bits 17:16) */
97cbad38ffSSanjana Virupakshagouda 	info |= (tx_value << ARM_CACHE_ERR_TX_SHIFT) & ARM_CACHE_ERR_TX_MASK;
98cbad38ffSSanjana Virupakshagouda 
99cbad38ffSSanjana Virupakshagouda 	/* Level (bits 24:22) */
100cbad38ffSSanjana Virupakshagouda 	info |= (level_value << ARM_CACHE_ERR_LEVEL_SHIFT) & ARM_CACHE_ERR_LEVEL_MASK;
101cbad38ffSSanjana Virupakshagouda 
102cbad38ffSSanjana Virupakshagouda 	/* Corrected (bit 26) */
103cbad38ffSSanjana Virupakshagouda 	if (corrected)
104cbad38ffSSanjana Virupakshagouda 		info |= (1ULL << ARM_CACHE_ERR_CORR_BIT);
105cbad38ffSSanjana Virupakshagouda 
106cbad38ffSSanjana Virupakshagouda 	return info;
107cbad38ffSSanjana Virupakshagouda }
108cbad38ffSSanjana Virupakshagouda 
109cbad38ffSSanjana Virupakshagouda /*
110cbad38ffSSanjana Virupakshagouda  * ARM PROCESSOR ERROR CONTEXT INFORMATION
111cbad38ffSSanjana Virupakshagouda  *
112cbad38ffSSanjana Virupakshagouda  * Context[0] Type-4: AArch64 GPRs (x0..x30 + SP_EL0)
113cbad38ffSSanjana Virupakshagouda  * Context[1] Type-5: EL1 registers
114cbad38ffSSanjana Virupakshagouda  */
115cbad38ffSSanjana Virupakshagouda static bool
fill_ns_context_blocks(struct EFI_ARM_PROCESSOR_ERROR_RECORD_DATA * sec)116cbad38ffSSanjana Virupakshagouda fill_ns_context_blocks(struct EFI_ARM_PROCESSOR_ERROR_RECORD_DATA *sec)
117cbad38ffSSanjana Virupakshagouda {
118cbad38ffSSanjana Virupakshagouda 	cpu_context_t *ns = cm_get_context(NON_SECURE);
119cbad38ffSSanjana Virupakshagouda 
120cbad38ffSSanjana Virupakshagouda 	if (!ns) {
121cbad38ffSSanjana Virupakshagouda 		VERBOSE("CPER: no NON_SECURE cpu_context\n");
122cbad38ffSSanjana Virupakshagouda 		return false;
123cbad38ffSSanjana Virupakshagouda 	}
124cbad38ffSSanjana Virupakshagouda 
125cbad38ffSSanjana Virupakshagouda 	/* -------- Type 4: GPRs (x0..x30 + SP_EL0) -------- */
126cbad38ffSSanjana Virupakshagouda 	gp_regs_t *gpr = get_gpregs_ctx(ns);
127cbad38ffSSanjana Virupakshagouda 
128cbad38ffSSanjana Virupakshagouda 	if (!gpr)
129cbad38ffSSanjana Virupakshagouda 		return false;
130cbad38ffSSanjana Virupakshagouda 
131cbad38ffSSanjana Virupakshagouda 	sec->CpuContextInfo[0].Hdr.Version = 0;
132cbad38ffSSanjana Virupakshagouda 	sec->CpuContextInfo[0].Hdr.RegisterContextType =
133cbad38ffSSanjana Virupakshagouda 		EFI_ARM_CONTEXT_INFO_REG_TYPE_4;
134cbad38ffSSanjana Virupakshagouda 	sec->CpuContextInfo[0].Hdr.RegisterArraySize =
135cbad38ffSSanjana Virupakshagouda 		(uint32_t)sizeof(sec->CpuContextInfo[0].RegisterArray.Type4Gpr);
136cbad38ffSSanjana Virupakshagouda 	struct EFI_ARM_AARCH64_CONTEXT_GPR *type4GprRegValues =
137cbad38ffSSanjana Virupakshagouda 		&sec->CpuContextInfo[0].RegisterArray.Type4Gpr;
138cbad38ffSSanjana Virupakshagouda 
139cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[0] = read_ctx_reg(gpr, CTX_GPREG_X0);
140cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[1] = read_ctx_reg(gpr, CTX_GPREG_X1);
141cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[2] = read_ctx_reg(gpr, CTX_GPREG_X2);
142cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[3] = read_ctx_reg(gpr, CTX_GPREG_X3);
143cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[4] = read_ctx_reg(gpr, CTX_GPREG_X4);
144cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[5] = read_ctx_reg(gpr, CTX_GPREG_X5);
145cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[6] = read_ctx_reg(gpr, CTX_GPREG_X6);
146cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[7] = read_ctx_reg(gpr, CTX_GPREG_X7);
147cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[8] = read_ctx_reg(gpr, CTX_GPREG_X8);
148cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[9] = read_ctx_reg(gpr, CTX_GPREG_X9);
149cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[10] = read_ctx_reg(gpr, CTX_GPREG_X10);
150cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[11] = read_ctx_reg(gpr, CTX_GPREG_X11);
151cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[12] = read_ctx_reg(gpr, CTX_GPREG_X12);
152cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[13] = read_ctx_reg(gpr, CTX_GPREG_X13);
153cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[14] = read_ctx_reg(gpr, CTX_GPREG_X14);
154cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[15] = read_ctx_reg(gpr, CTX_GPREG_X15);
155cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[16] = read_ctx_reg(gpr, CTX_GPREG_X16);
156cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[17] = read_ctx_reg(gpr, CTX_GPREG_X17);
157cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[18] = read_ctx_reg(gpr, CTX_GPREG_X18);
158cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[19] = read_ctx_reg(gpr, CTX_GPREG_X19);
159cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[20] = read_ctx_reg(gpr, CTX_GPREG_X20);
160cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[21] = read_ctx_reg(gpr, CTX_GPREG_X21);
161cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[22] = read_ctx_reg(gpr, CTX_GPREG_X22);
162cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[23] = read_ctx_reg(gpr, CTX_GPREG_X23);
163cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[24] = read_ctx_reg(gpr, CTX_GPREG_X24);
164cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[25] = read_ctx_reg(gpr, CTX_GPREG_X25);
165cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[26] = read_ctx_reg(gpr, CTX_GPREG_X26);
166cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[27] = read_ctx_reg(gpr, CTX_GPREG_X27);
167cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[28] = read_ctx_reg(gpr, CTX_GPREG_X28);
168cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[29] = read_ctx_reg(gpr, CTX_GPREG_X29);
169cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->X[30] = read_ctx_reg(gpr, CTX_GPREG_LR);
170cbad38ffSSanjana Virupakshagouda 	type4GprRegValues->SP = read_ctx_reg(gpr, CTX_GPREG_SP_EL0);
171cbad38ffSSanjana Virupakshagouda 
172cbad38ffSSanjana Virupakshagouda 	/* -------- Type 5: EL1 sysregs -------- */
173cbad38ffSSanjana Virupakshagouda 	el1_sysregs_t *el1 = get_el1_sysregs_ctx(ns);
174cbad38ffSSanjana Virupakshagouda 
175cbad38ffSSanjana Virupakshagouda 	if (!el1)
176cbad38ffSSanjana Virupakshagouda 		return false;
177cbad38ffSSanjana Virupakshagouda 
178cbad38ffSSanjana Virupakshagouda 	sec->CpuContextInfo[1].Hdr.Version = 0;
179cbad38ffSSanjana Virupakshagouda 	sec->CpuContextInfo[1].Hdr.RegisterContextType =
180cbad38ffSSanjana Virupakshagouda 		EFI_ARM_CONTEXT_INFO_REG_TYPE_5;
181cbad38ffSSanjana Virupakshagouda 	sec->CpuContextInfo[1].Hdr.RegisterArraySize = (uint32_t)sizeof(
182cbad38ffSSanjana Virupakshagouda 		sec->CpuContextInfo[1].RegisterArray.Type5SysRegs);
183cbad38ffSSanjana Virupakshagouda 	struct EFI_ARM_AARCH64_EL1_CONTEXT_SYSTEM_REGISTERS *type5SysRegValues =
184cbad38ffSSanjana Virupakshagouda 		&sec->CpuContextInfo[1].RegisterArray.Type5SysRegs;
185cbad38ffSSanjana Virupakshagouda 
186cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->SPSR_EL1 = read_el1_ctx_common(el1, spsr_el1);
187cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->ELR_EL1 = read_el1_ctx_common(el1, elr_el1);
188cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->ESR_EL1 = read_el1_ctx_common(el1, esr_el1);
189cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->FAR_EL1 = read_el1_ctx_common(el1, far_el1);
190cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->ISR_EL1 = 0;
191cbad38ffSSanjana Virupakshagouda 
192cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->MAIR_EL1 = read_el1_ctx_common(el1, mair_el1);
193cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->MIDR_EL1 = read_midr_el1();
194cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->MPIDR_EL1 = read_mpidr_el1();
195cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->SCTLR_EL1 = read_ctx_sctlr_el1_reg_errata(ns);
196cbad38ffSSanjana Virupakshagouda 
197cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->SP_EL0 =
198cbad38ffSSanjana Virupakshagouda 		read_ctx_reg(get_gpregs_ctx(ns), CTX_GPREG_SP_EL0);
199cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->SP_EL1 = read_el1_ctx_common(el1, sp_el1);
200cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->SPSR_EL1 = read_el1_ctx_common(el1, spsr_el1);
201cbad38ffSSanjana Virupakshagouda 
202cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->TCR_EL1 = read_ctx_tcr_el1_reg_errata(ns);
203cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->TPIDR_EL0 = read_el1_ctx_common(el1, tpidr_el0);
204cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->TPIDR_EL1 = read_el1_ctx_common(el1, tpidr_el1);
205cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->TPIDRRO_EL0 = read_el1_ctx_common(el1, tpidrro_el0);
206cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->TTBR0_EL1 = read_el1_ctx_common(el1, ttbr0_el1);
207cbad38ffSSanjana Virupakshagouda 	type5SysRegValues->TTBR1_EL1 = read_el1_ctx_common(el1, ttbr1_el1);
208cbad38ffSSanjana Virupakshagouda 
209cbad38ffSSanjana Virupakshagouda 	return true;
210cbad38ffSSanjana Virupakshagouda }
211cbad38ffSSanjana Virupakshagouda 
212cbad38ffSSanjana Virupakshagouda /*
213cbad38ffSSanjana Virupakshagouda  * cper_write_cpu_record - Build a single CPER ESB + ARM CPU section into a buffer
214cbad38ffSSanjana Virupakshagouda  *
215cbad38ffSSanjana Virupakshagouda  * This constructs a Common Platform Error Record (CPER) with:
216cbad38ffSSanjana Virupakshagouda  *   - 1 Error Status Block (ESB) header,
217cbad38ffSSanjana Virupakshagouda  *   - 1 Data Entry (ARM Processor Specific Section GUID),
218cbad38ffSSanjana Virupakshagouda  *   - 1 ARM CPU section payload containing:
219cbad38ffSSanjana Virupakshagouda  *       * Section header (EFI_ARM_PROCESSOR_ERROR_SECTION_HEADER),
220cbad38ffSSanjana Virupakshagouda  *       * One error info (EFI_ARM_PROCESSOR_ERROR_INFORMATION),
221cbad38ffSSanjana Virupakshagouda  *       * One context info (EFI_ARM_PROCESSOR_ERROR_CONTEXT_INFORMATION), containing:
222cbad38ffSSanjana Virupakshagouda  *           Type-4 (GPRs) and Type-5 (EL1) registers.
223cbad38ffSSanjana Virupakshagouda  */
224cbad38ffSSanjana Virupakshagouda 
cper_write_cpu_record(void * buf,size_t buf_size)225cbad38ffSSanjana Virupakshagouda size_t cper_write_cpu_record(void *buf, size_t buf_size)
226cbad38ffSSanjana Virupakshagouda {
227cbad38ffSSanjana Virupakshagouda 	if (!buf)
228cbad38ffSSanjana Virupakshagouda 		return 0;
229cbad38ffSSanjana Virupakshagouda 
230cbad38ffSSanjana Virupakshagouda 	uint64_t err_status = read_erxstatus_el1();
231cbad38ffSSanjana Virupakshagouda 	uint64_t err_misc0 = read_erxmisc0_el1();
232cbad38ffSSanjana Virupakshagouda 	uint64_t err_addr = read_erxaddr_el1();
233cbad38ffSSanjana Virupakshagouda 
234cbad38ffSSanjana Virupakshagouda 	/* Compute size of CPU payload section */
235cbad38ffSSanjana Virupakshagouda 
236cbad38ffSSanjana Virupakshagouda 	uint32_t context_header_size =
237cbad38ffSSanjana Virupakshagouda 		sizeof(struct EFI_ARM_PROCESSOR_ERROR_CONTEXT_INFO_HEADER);
238cbad38ffSSanjana Virupakshagouda 	uint32_t context0_size = context_header_size +
239cbad38ffSSanjana Virupakshagouda 				 sizeof(struct EFI_ARM_AARCH64_CONTEXT_GPR);
240cbad38ffSSanjana Virupakshagouda 	uint32_t context1_size =
241cbad38ffSSanjana Virupakshagouda 		context_header_size +
242cbad38ffSSanjana Virupakshagouda 		sizeof(struct EFI_ARM_AARCH64_EL1_CONTEXT_SYSTEM_REGISTERS);
243cbad38ffSSanjana Virupakshagouda 	uint32_t contexts_total_size = context0_size + context1_size;
244cbad38ffSSanjana Virupakshagouda 
245cbad38ffSSanjana Virupakshagouda 	uint32_t section_size =
246cbad38ffSSanjana Virupakshagouda 		(uint32_t)sizeof(
247cbad38ffSSanjana Virupakshagouda 			struct EFI_ARM_PROCESSOR_ERROR_SECTION_HEADER) +
248cbad38ffSSanjana Virupakshagouda 		(uint32_t)sizeof(struct EFI_ARM_PROCESSOR_ERROR_INFORMATION) *
249cbad38ffSSanjana Virupakshagouda 			CPU_ERR_INFO_NUM + contexts_total_size;
250cbad38ffSSanjana Virupakshagouda 
251cbad38ffSSanjana Virupakshagouda 	/* Total size: ESB + DataEntry + CPU payload */
252cbad38ffSSanjana Virupakshagouda 	size_t size = sizeof(struct ACPI_GENERIC_ERROR_STATUS_BLOCK_HEADER) +
253cbad38ffSSanjana Virupakshagouda 		      sizeof(struct ACPI_GENERIC_ERROR_DATA_ENTRY_HEADER) +
254cbad38ffSSanjana Virupakshagouda 		      section_size;
255cbad38ffSSanjana Virupakshagouda 
256cbad38ffSSanjana Virupakshagouda 	if (buf_size < size) {
257cbad38ffSSanjana Virupakshagouda 		WARN("RAS: ESB buffer too small (need %zu, have %zu)\n", size,
258cbad38ffSSanjana Virupakshagouda 		     buf_size);
259cbad38ffSSanjana Virupakshagouda 		return 0;
260cbad38ffSSanjana Virupakshagouda 	}
261cbad38ffSSanjana Virupakshagouda 
262cbad38ffSSanjana Virupakshagouda 	struct ACPI_GENERIC_ERROR_STATUS_BLOCK_HEADER *esb =
263cbad38ffSSanjana Virupakshagouda 		(struct ACPI_GENERIC_ERROR_STATUS_BLOCK_HEADER *)buf;
264cbad38ffSSanjana Virupakshagouda 	struct ACPI_GENERIC_ERROR_DATA_ENTRY_HEADER *de =
265cbad38ffSSanjana Virupakshagouda 		(struct ACPI_GENERIC_ERROR_DATA_ENTRY_HEADER *)(esb + 1);
266cbad38ffSSanjana Virupakshagouda 	struct EFI_ARM_PROCESSOR_ERROR_RECORD_DATA *sec =
267cbad38ffSSanjana Virupakshagouda 		(struct EFI_ARM_PROCESSOR_ERROR_RECORD_DATA *)(de + 1);
268cbad38ffSSanjana Virupakshagouda 
269cbad38ffSSanjana Virupakshagouda 	/* Error Status Block Header */
270cbad38ffSSanjana Virupakshagouda 	memset(esb, 0, sizeof(*esb));
271cbad38ffSSanjana Virupakshagouda 	esb->BlockStatus = esb_block_status((err_status & ERX_STATUS_UE) != 0,
272cbad38ffSSanjana Virupakshagouda 					    (err_status & ERX_STATUS_CE) != 0,
273cbad38ffSSanjana Virupakshagouda 					    false, false, 1);
274cbad38ffSSanjana Virupakshagouda 	esb->RawDataOffset = (uint32_t)(sizeof(*esb) + sizeof(*de));
275cbad38ffSSanjana Virupakshagouda 	esb->RawDataLength = 0;
276cbad38ffSSanjana Virupakshagouda 	esb->DataLength = (uint32_t)(sizeof(*de) + section_size);
277cbad38ffSSanjana Virupakshagouda 	esb->ErrorSeverity = esb_severity_from_erx(err_status);
278cbad38ffSSanjana Virupakshagouda 
279cbad38ffSSanjana Virupakshagouda 	/* Error Data Entry */
280cbad38ffSSanjana Virupakshagouda 	memset(de, 0, sizeof(*de));
281cbad38ffSSanjana Virupakshagouda 	de->SectionType = ARM_PROC_ERR_SECTION_GUID;
282cbad38ffSSanjana Virupakshagouda 	de->ErrorSeverity = esb->ErrorSeverity;
283cbad38ffSSanjana Virupakshagouda 	de->Revision = ACPI_DATA_ENTRY_REV_0300;
284cbad38ffSSanjana Virupakshagouda 	de->ValidationBits = 0;
285cbad38ffSSanjana Virupakshagouda 	de->Flags = (err_status & ERX_STATUS_DE) ? ACPI_SEC_FLAG_LATENT : 0;
286cbad38ffSSanjana Virupakshagouda 	de->ErrorDataLength = section_size;
287cbad38ffSSanjana Virupakshagouda 
288cbad38ffSSanjana Virupakshagouda 	/* Payload: CPU section */
289cbad38ffSSanjana Virupakshagouda 	memset(sec, 0, section_size);
290cbad38ffSSanjana Virupakshagouda 
291cbad38ffSSanjana Virupakshagouda 	/*  ARM Processor Error Section */
292cbad38ffSSanjana Virupakshagouda 	sec->CpuInfo.ValidationBit = (EFI_ARM_PROC_ERROR_MPIDR_VALID |
293cbad38ffSSanjana Virupakshagouda 				      EFI_ARM_PROC_ERROR_RUNNING_STATE_VALID);
294cbad38ffSSanjana Virupakshagouda 	sec->CpuInfo.ErrInfoNum = CPU_ERR_INFO_NUM;
295cbad38ffSSanjana Virupakshagouda 	sec->CpuInfo.ContextInfoNum = CPU_CONTEXT_INFO_NUM;
296cbad38ffSSanjana Virupakshagouda 	sec->CpuInfo.SectionLength = section_size;
297cbad38ffSSanjana Virupakshagouda 	sec->CpuInfo.AffinityLevel = 0;
298cbad38ffSSanjana Virupakshagouda 	sec->CpuInfo.MPIDR_EL1 = read_mpidr_el1();
299cbad38ffSSanjana Virupakshagouda 	sec->CpuInfo.MIDR_EL1 = read_midr_el1();
300cbad38ffSSanjana Virupakshagouda 	sec->CpuInfo.RunState = 1;
301cbad38ffSSanjana Virupakshagouda 	sec->CpuInfo.PsciState = 0;
302cbad38ffSSanjana Virupakshagouda 
303cbad38ffSSanjana Virupakshagouda 	/* ARM Processor Error Information */
304cbad38ffSSanjana Virupakshagouda 	struct EFI_ARM_PROCESSOR_ERROR_INFORMATION *ei = &sec->CpuErrInfo[0];
305cbad38ffSSanjana Virupakshagouda 	bool ce = (err_status & ERX_STATUS_CE) != 0;
306cbad38ffSSanjana Virupakshagouda 	bool phys_addr_valid = ERX_STATUS_ADDRV(err_status);
307cbad38ffSSanjana Virupakshagouda 
308cbad38ffSSanjana Virupakshagouda 	ei->Version = 0;
309cbad38ffSSanjana Virupakshagouda 	ei->Length = (uint8_t)sizeof(*ei);
310cbad38ffSSanjana Virupakshagouda 	ei->ValidationBit =
311cbad38ffSSanjana Virupakshagouda 		(EFI_ARM_PROC_ERROR_INFO_MULTIPLE_ERROR_VALID |
312cbad38ffSSanjana Virupakshagouda 		 EFI_ARM_PROC_ERROR_INFO_FLAGS_VALID |
313cbad38ffSSanjana Virupakshagouda 		 (phys_addr_valid ? EFI_ARM_PROC_ERROR_INFO_PHYS_ADDR_VALID :
314cbad38ffSSanjana Virupakshagouda 				    0));
315cbad38ffSSanjana Virupakshagouda 	ei->Type = arm_error_type_from_unit(err_misc0);
316cbad38ffSSanjana Virupakshagouda 	ei->MultipleError = 0;
317cbad38ffSSanjana Virupakshagouda 	ei->Flags = 0;
318cbad38ffSSanjana Virupakshagouda 	ei->ErrorInfo = 0;
319cbad38ffSSanjana Virupakshagouda 	ei->VirtualFaultAddress = 0;
320cbad38ffSSanjana Virupakshagouda 	ei->PhysicalFaultAddress = err_addr;
321cbad38ffSSanjana Virupakshagouda 	if (ei->Type == ARM_ERROR_TYPE_CACHE) {
322cbad38ffSSanjana Virupakshagouda 		ei->ValidationBit |= EFI_ARM_PROC_ERROR_INFO_ERROR_INFO_VALID;
323cbad38ffSSanjana Virupakshagouda 		ei->ErrorInfo = arm_cache_error_structure(err_misc0, ce);
324cbad38ffSSanjana Virupakshagouda 	}
325cbad38ffSSanjana Virupakshagouda 
326cbad38ffSSanjana Virupakshagouda 	/*  ARM Processor Error Context Information (Type 4 and 5 contexts) */
327cbad38ffSSanjana Virupakshagouda 	cm_el1_sysregs_context_save(NON_SECURE);
328cbad38ffSSanjana Virupakshagouda 	if (!fill_ns_context_blocks(sec))
329cbad38ffSSanjana Virupakshagouda 		WARN("CPER: Non-secure EL1 context unavailable; context blocks left zeroed\n");
330cbad38ffSSanjana Virupakshagouda 
331cbad38ffSSanjana Virupakshagouda 	return size;
332cbad38ffSSanjana Virupakshagouda }
333*96f40c7bSSanjana Virupakshagouda 
print_guid(struct efi_guid g)334*96f40c7bSSanjana Virupakshagouda static void print_guid(struct efi_guid g)
335*96f40c7bSSanjana Virupakshagouda {
336*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  SectionType   = {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
337*96f40c7bSSanjana Virupakshagouda 		g.time_low, g.time_mid, g.time_hi_and_version,
338*96f40c7bSSanjana Virupakshagouda 		g.clock_seq_and_node[0], g.clock_seq_and_node[1],
339*96f40c7bSSanjana Virupakshagouda 		g.clock_seq_and_node[2], g.clock_seq_and_node[3],
340*96f40c7bSSanjana Virupakshagouda 		g.clock_seq_and_node[4], g.clock_seq_and_node[5],
341*96f40c7bSSanjana Virupakshagouda 		g.clock_seq_and_node[6], g.clock_seq_and_node[7]);
342*96f40c7bSSanjana Virupakshagouda }
343*96f40c7bSSanjana Virupakshagouda 
print_cache_error_info(uint64_t info)344*96f40c7bSSanjana Virupakshagouda static void print_cache_error_info(uint64_t info)
345*96f40c7bSSanjana Virupakshagouda {
346*96f40c7bSSanjana Virupakshagouda 	uint64_t validation = (info & 0x7FULL);
347*96f40c7bSSanjana Virupakshagouda 	unsigned int tx = (unsigned int)((info & ARM_CACHE_ERR_TX_MASK) >>
348*96f40c7bSSanjana Virupakshagouda 				 ARM_CACHE_ERR_TX_SHIFT);
349*96f40c7bSSanjana Virupakshagouda 	unsigned int op = (unsigned int)((info & ARM_CACHE_ERR_OP_MASK) >>
350*96f40c7bSSanjana Virupakshagouda 				 ARM_CACHE_ERR_OP_SHIFT);
351*96f40c7bSSanjana Virupakshagouda 	unsigned int lvl = (unsigned int)((info & ARM_CACHE_ERR_LEVEL_MASK) >>
352*96f40c7bSSanjana Virupakshagouda 				  ARM_CACHE_ERR_LEVEL_SHIFT);
353*96f40c7bSSanjana Virupakshagouda 	unsigned int pcc = (unsigned int)((info >> ARM_CACHE_ERR_PCC_BIT) & 1U);
354*96f40c7bSSanjana Virupakshagouda 	unsigned int corr = (unsigned int)((info >> ARM_CACHE_ERR_CORR_BIT) & 1U);
355*96f40c7bSSanjana Virupakshagouda 	unsigned int ppc = (unsigned int)((info >> ARM_CACHE_ERR_PRECISE_PC_BIT) & 1U);
356*96f40c7bSSanjana Virupakshagouda 	unsigned int rpc = (unsigned int)((info >> ARM_CACHE_ERR_RESTART_PC_BIT) & 1U);
357*96f40c7bSSanjana Virupakshagouda 	uint64_t reserved = (info >> 29);
358*96f40c7bSSanjana Virupakshagouda 
359*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  CacheErrorInfo:\n");
360*96f40c7bSSanjana Virupakshagouda 	VERBOSE("    ValidationBit           = 0x%04llx\n",
361*96f40c7bSSanjana Virupakshagouda 		(unsigned long long)validation);
362*96f40c7bSSanjana Virupakshagouda 	VERBOSE("    TransactionType         = %u\n", tx);
363*96f40c7bSSanjana Virupakshagouda 	VERBOSE("    Operation               = %u\n", op);
364*96f40c7bSSanjana Virupakshagouda 	VERBOSE("    Level                   = %u\n", lvl);
365*96f40c7bSSanjana Virupakshagouda 	VERBOSE("    ProcessorContextCorrupt = %u\n", pcc);
366*96f40c7bSSanjana Virupakshagouda 	VERBOSE("    Corrected               = %u\n", corr);
367*96f40c7bSSanjana Virupakshagouda 	VERBOSE("    PrecisePC               = %u\n", ppc);
368*96f40c7bSSanjana Virupakshagouda 	VERBOSE("    RestartablePC           = %u\n", rpc);
369*96f40c7bSSanjana Virupakshagouda 	VERBOSE("    Reserved[63:29]         = 0x%08llx\n",
370*96f40c7bSSanjana Virupakshagouda 		(unsigned long long)reserved);
371*96f40c7bSSanjana Virupakshagouda }
372*96f40c7bSSanjana Virupakshagouda 
373*96f40c7bSSanjana Virupakshagouda static void
print_esb_header(const struct ACPI_GENERIC_ERROR_STATUS_BLOCK_HEADER * esb)374*96f40c7bSSanjana Virupakshagouda print_esb_header(const struct ACPI_GENERIC_ERROR_STATUS_BLOCK_HEADER *esb)
375*96f40c7bSSanjana Virupakshagouda {
376*96f40c7bSSanjana Virupakshagouda 	if (esb == NULL) {
377*96f40c7bSSanjana Virupakshagouda 		WARN("CPER: null ESB header\n");
378*96f40c7bSSanjana Virupakshagouda 		return;
379*96f40c7bSSanjana Virupakshagouda 	}
380*96f40c7bSSanjana Virupakshagouda 	VERBOSE("ESB.Header:\n");
381*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  BlockStatus   = 0x%08x\n", esb->BlockStatus);
382*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  RawDataOffset = 0x%08x\n", esb->RawDataOffset);
383*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  RawDataLength = %u\n", esb->RawDataLength);
384*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  DataLength    = %u\n", esb->DataLength);
385*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  ErrorSeverity = %u\n", esb->ErrorSeverity);
386*96f40c7bSSanjana Virupakshagouda }
387*96f40c7bSSanjana Virupakshagouda 
388*96f40c7bSSanjana Virupakshagouda static void
print_data_entry_header(const struct ACPI_GENERIC_ERROR_DATA_ENTRY_HEADER * de)389*96f40c7bSSanjana Virupakshagouda print_data_entry_header(const struct ACPI_GENERIC_ERROR_DATA_ENTRY_HEADER *de)
390*96f40c7bSSanjana Virupakshagouda {
391*96f40c7bSSanjana Virupakshagouda 	if (de == NULL) {
392*96f40c7bSSanjana Virupakshagouda 		WARN("CPER: null Data Entry header\n");
393*96f40c7bSSanjana Virupakshagouda 		return;
394*96f40c7bSSanjana Virupakshagouda 	}
395*96f40c7bSSanjana Virupakshagouda 	VERBOSE("DataEntry:\n");
396*96f40c7bSSanjana Virupakshagouda 	print_guid(de->SectionType);
397*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  ErrorSeverity = %u\n", de->ErrorSeverity);
398*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  Revision      = 0x%04x\n", de->Revision);
399*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  ValidationBits= 0x%02x\n", de->ValidationBits);
400*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  Flags         = 0x%02x\n", de->Flags);
401*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  ErrorDataLen  = %u\n", de->ErrorDataLength);
402*96f40c7bSSanjana Virupakshagouda }
403*96f40c7bSSanjana Virupakshagouda 
404*96f40c7bSSanjana Virupakshagouda static void
print_cpu_section_header(const struct EFI_ARM_PROCESSOR_ERROR_RECORD_DATA * sec)405*96f40c7bSSanjana Virupakshagouda print_cpu_section_header(const struct EFI_ARM_PROCESSOR_ERROR_RECORD_DATA *sec)
406*96f40c7bSSanjana Virupakshagouda {
407*96f40c7bSSanjana Virupakshagouda 	if (sec == NULL) {
408*96f40c7bSSanjana Virupakshagouda 		WARN("CPER: null CPU section\n");
409*96f40c7bSSanjana Virupakshagouda 		return;
410*96f40c7bSSanjana Virupakshagouda 	}
411*96f40c7bSSanjana Virupakshagouda 	VERBOSE("CPU Section:\n");
412*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  ValidationBit = 0x%08x\n", sec->CpuInfo.ValidationBit);
413*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  ErrInfoNum    = %u\n", sec->CpuInfo.ErrInfoNum);
414*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  CtxtInfoNum   = %u\n", sec->CpuInfo.ContextInfoNum);
415*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  SectionLength = %u\n", sec->CpuInfo.SectionLength);
416*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  MPIDR_EL1     = 0x%016llx\n",
417*96f40c7bSSanjana Virupakshagouda 		(unsigned long long)sec->CpuInfo.MPIDR_EL1);
418*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  MIDR_EL1      = 0x%016llx\n",
419*96f40c7bSSanjana Virupakshagouda 		(unsigned long long)sec->CpuInfo.MIDR_EL1);
420*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  RunState      = %u\n", sec->CpuInfo.RunState);
421*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  PsciState     = %u\n", sec->CpuInfo.PsciState);
422*96f40c7bSSanjana Virupakshagouda }
423*96f40c7bSSanjana Virupakshagouda 
424*96f40c7bSSanjana Virupakshagouda static void
print_error_info(const struct EFI_ARM_PROCESSOR_ERROR_INFORMATION * ei)425*96f40c7bSSanjana Virupakshagouda print_error_info(const struct EFI_ARM_PROCESSOR_ERROR_INFORMATION *ei)
426*96f40c7bSSanjana Virupakshagouda {
427*96f40c7bSSanjana Virupakshagouda 	if (ei == NULL) {
428*96f40c7bSSanjana Virupakshagouda 		WARN("CPER: null ErrorInfo\n");
429*96f40c7bSSanjana Virupakshagouda 		return;
430*96f40c7bSSanjana Virupakshagouda 	}
431*96f40c7bSSanjana Virupakshagouda 	VERBOSE("ErrorInfo[0]:\n");
432*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  Version       = %u\n", ei->Version);
433*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  Length        = %u\n", ei->Length);
434*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  ValidationBit = 0x%04x\n", ei->ValidationBit);
435*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  Type          = %u\n", ei->Type);
436*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  MultipleError = %u\n", ei->MultipleError);
437*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  Flags         = 0x%02x\n", ei->Flags);
438*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  ErrorInfo     = 0x%016llx\n",
439*96f40c7bSSanjana Virupakshagouda 		(unsigned long long)ei->ErrorInfo);
440*96f40c7bSSanjana Virupakshagouda 
441*96f40c7bSSanjana Virupakshagouda 	if (ei->Type == ARM_ERROR_TYPE_CACHE &&
442*96f40c7bSSanjana Virupakshagouda 	    (ei->ValidationBit & EFI_ARM_PROC_ERROR_INFO_ERROR_INFO_VALID) &&
443*96f40c7bSSanjana Virupakshagouda 	    ei->ErrorInfo != 0) {
444*96f40c7bSSanjana Virupakshagouda 		print_cache_error_info(ei->ErrorInfo);
445*96f40c7bSSanjana Virupakshagouda 	}
446*96f40c7bSSanjana Virupakshagouda 
447*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  VirtFaultAddr = 0x%016llx\n",
448*96f40c7bSSanjana Virupakshagouda 		(unsigned long long)ei->VirtualFaultAddress);
449*96f40c7bSSanjana Virupakshagouda 	VERBOSE("  PhysFaultAddr = 0x%016llx\n",
450*96f40c7bSSanjana Virupakshagouda 		(unsigned long long)ei->PhysicalFaultAddress);
451*96f40c7bSSanjana Virupakshagouda }
452*96f40c7bSSanjana Virupakshagouda 
453*96f40c7bSSanjana Virupakshagouda static void
print_context_block(const struct EFI_ARM_PROCESSOR_CONTEXT_INFORMATION * c,unsigned int idx)454*96f40c7bSSanjana Virupakshagouda print_context_block(const struct EFI_ARM_PROCESSOR_CONTEXT_INFORMATION *c,
455*96f40c7bSSanjana Virupakshagouda 		    unsigned int idx)
456*96f40c7bSSanjana Virupakshagouda {
457*96f40c7bSSanjana Virupakshagouda 	if (c == NULL) {
458*96f40c7bSSanjana Virupakshagouda 		WARN("CPER: null Context block\n");
459*96f40c7bSSanjana Virupakshagouda 		return;
460*96f40c7bSSanjana Virupakshagouda 	}
461*96f40c7bSSanjana Virupakshagouda 	VERBOSE("Context[%u]: type=%u size=%u\n", idx,
462*96f40c7bSSanjana Virupakshagouda 		c->Hdr.RegisterContextType, c->Hdr.RegisterArraySize);
463*96f40c7bSSanjana Virupakshagouda 
464*96f40c7bSSanjana Virupakshagouda 	switch (c->Hdr.RegisterContextType) {
465*96f40c7bSSanjana Virupakshagouda 	case EFI_ARM_CONTEXT_INFO_REG_TYPE_4:
466*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  GPR x0..x3: %016llx %016llx %016llx %016llx\n",
467*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)c->RegisterArray.Type4Gpr.X[0],
468*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)c->RegisterArray.Type4Gpr.X[1],
469*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)c->RegisterArray.Type4Gpr.X[2],
470*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)c->RegisterArray.Type4Gpr.X[3]);
471*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  SP = 0x%016llx\n",
472*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)c->RegisterArray.Type4Gpr.SP);
473*96f40c7bSSanjana Virupakshagouda 		break;
474*96f40c7bSSanjana Virupakshagouda 
475*96f40c7bSSanjana Virupakshagouda 	case EFI_ARM_CONTEXT_INFO_REG_TYPE_5:
476*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  EL1: SPSR=0x%016llx\n",
477*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)
478*96f40c7bSSanjana Virupakshagouda 				c->RegisterArray.Type5SysRegs.SPSR_EL1);
479*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  EL1: ELR=0x%016llx\n",
480*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)
481*96f40c7bSSanjana Virupakshagouda 				c->RegisterArray.Type5SysRegs.ELR_EL1);
482*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  EL1: ESR=0x%016llx\n",
483*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)
484*96f40c7bSSanjana Virupakshagouda 				c->RegisterArray.Type5SysRegs.ESR_EL1);
485*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  EL1: FAR=0x%016llx\n",
486*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)
487*96f40c7bSSanjana Virupakshagouda 				c->RegisterArray.Type5SysRegs.FAR_EL1);
488*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  ISR_EL1    = 0x%016llx\n",
489*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)
490*96f40c7bSSanjana Virupakshagouda 				c->RegisterArray.Type5SysRegs.ISR_EL1);
491*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  MAIR_EL1   = 0x%016llx\n",
492*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)
493*96f40c7bSSanjana Virupakshagouda 				c->RegisterArray.Type5SysRegs.MAIR_EL1);
494*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  MIDR_EL1   = 0x%016llx\n",
495*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)
496*96f40c7bSSanjana Virupakshagouda 				c->RegisterArray.Type5SysRegs.MIDR_EL1);
497*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  MPIDR_EL1  = 0x%016llx\n",
498*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)
499*96f40c7bSSanjana Virupakshagouda 				c->RegisterArray.Type5SysRegs.MPIDR_EL1);
500*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  SCTLR_EL1  = 0x%016llx\n",
501*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)
502*96f40c7bSSanjana Virupakshagouda 				c->RegisterArray.Type5SysRegs.SCTLR_EL1);
503*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  SP_EL0     = 0x%016llx\n",
504*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)
505*96f40c7bSSanjana Virupakshagouda 				c->RegisterArray.Type5SysRegs.SP_EL0);
506*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  SP_EL1     = 0x%016llx\n",
507*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)
508*96f40c7bSSanjana Virupakshagouda 				c->RegisterArray.Type5SysRegs.SP_EL1);
509*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  TCR_EL1    = 0x%016llx\n",
510*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)
511*96f40c7bSSanjana Virupakshagouda 				c->RegisterArray.Type5SysRegs.TCR_EL1);
512*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  TPIDR_EL0  = 0x%016llx\n",
513*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)
514*96f40c7bSSanjana Virupakshagouda 				c->RegisterArray.Type5SysRegs.TPIDR_EL0);
515*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  TPIDR_EL1  = 0x%016llx\n",
516*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)
517*96f40c7bSSanjana Virupakshagouda 				c->RegisterArray.Type5SysRegs.TPIDR_EL1);
518*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  TPIDRRO_EL0= 0x%016llx\n",
519*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)
520*96f40c7bSSanjana Virupakshagouda 				c->RegisterArray.Type5SysRegs.TPIDRRO_EL0);
521*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  TTBR0_EL1  = 0x%016llx\n",
522*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)
523*96f40c7bSSanjana Virupakshagouda 				c->RegisterArray.Type5SysRegs.TTBR0_EL1);
524*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  TTBR1_EL1  = 0x%016llx\n",
525*96f40c7bSSanjana Virupakshagouda 			(unsigned long long)
526*96f40c7bSSanjana Virupakshagouda 				c->RegisterArray.Type5SysRegs.TTBR1_EL1);
527*96f40c7bSSanjana Virupakshagouda 		break;
528*96f40c7bSSanjana Virupakshagouda 
529*96f40c7bSSanjana Virupakshagouda 	default:
530*96f40c7bSSanjana Virupakshagouda 		VERBOSE("  Unknown context type %u\n",
531*96f40c7bSSanjana Virupakshagouda 			c->Hdr.RegisterContextType);
532*96f40c7bSSanjana Virupakshagouda 		break;
533*96f40c7bSSanjana Virupakshagouda 	}
534*96f40c7bSSanjana Virupakshagouda }
535*96f40c7bSSanjana Virupakshagouda 
536*96f40c7bSSanjana Virupakshagouda static void
print_contexts(const struct EFI_ARM_PROCESSOR_ERROR_RECORD_DATA * sec)537*96f40c7bSSanjana Virupakshagouda print_contexts(const struct EFI_ARM_PROCESSOR_ERROR_RECORD_DATA *sec)
538*96f40c7bSSanjana Virupakshagouda {
539*96f40c7bSSanjana Virupakshagouda 	for (unsigned int i = 0; i < sec->CpuInfo.ContextInfoNum; i++)
540*96f40c7bSSanjana Virupakshagouda 		print_context_block(&sec->CpuContextInfo[i], i);
541*96f40c7bSSanjana Virupakshagouda }
542*96f40c7bSSanjana Virupakshagouda 
543*96f40c7bSSanjana Virupakshagouda /* Dump the CPER buffer contents */
print_cper(const void * buf)544*96f40c7bSSanjana Virupakshagouda void print_cper(const void *buf)
545*96f40c7bSSanjana Virupakshagouda {
546*96f40c7bSSanjana Virupakshagouda 	if (!buf) {
547*96f40c7bSSanjana Virupakshagouda 		WARN("%s : null buffer\n", __func__);
548*96f40c7bSSanjana Virupakshagouda 		return;
549*96f40c7bSSanjana Virupakshagouda 	}
550*96f40c7bSSanjana Virupakshagouda 
551*96f40c7bSSanjana Virupakshagouda 	const struct ACPI_GENERIC_ERROR_STATUS_BLOCK_HEADER *esb = buf;
552*96f40c7bSSanjana Virupakshagouda 	const struct ACPI_GENERIC_ERROR_DATA_ENTRY_HEADER *de =
553*96f40c7bSSanjana Virupakshagouda 		(const void *)(esb + 1);
554*96f40c7bSSanjana Virupakshagouda 	const struct EFI_ARM_PROCESSOR_ERROR_RECORD_DATA *sec =
555*96f40c7bSSanjana Virupakshagouda 		(const void *)(de + 1);
556*96f40c7bSSanjana Virupakshagouda 	const struct EFI_ARM_PROCESSOR_ERROR_INFORMATION *ei =
557*96f40c7bSSanjana Virupakshagouda 		&sec->CpuErrInfo[0];
558*96f40c7bSSanjana Virupakshagouda 
559*96f40c7bSSanjana Virupakshagouda 	VERBOSE("\n========== CPER DUMP ==========\n");
560*96f40c7bSSanjana Virupakshagouda 
561*96f40c7bSSanjana Virupakshagouda 	print_esb_header(esb);
562*96f40c7bSSanjana Virupakshagouda 	print_data_entry_header(de);
563*96f40c7bSSanjana Virupakshagouda 	print_cpu_section_header(sec);
564*96f40c7bSSanjana Virupakshagouda 	print_error_info(ei);
565*96f40c7bSSanjana Virupakshagouda 	print_contexts(sec);
566*96f40c7bSSanjana Virupakshagouda 
567*96f40c7bSSanjana Virupakshagouda 	VERBOSE("========== END OF CPER DUMP ==========\n\n");
568*96f40c7bSSanjana Virupakshagouda }
569