xref: /aosp_15_r20/external/arm-trusted-firmware/bl31/aarch64/crash_reporting.S (revision 54fd6939e177f8ff529b10183254802c76df6d08)
1*54fd6939SJiyong Park/*
2*54fd6939SJiyong Park * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
3*54fd6939SJiyong Park *
4*54fd6939SJiyong Park * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park */
6*54fd6939SJiyong Park
7*54fd6939SJiyong Park#include <plat_macros.S>
8*54fd6939SJiyong Park#include <platform_def.h>
9*54fd6939SJiyong Park
10*54fd6939SJiyong Park#include <arch.h>
11*54fd6939SJiyong Park#include <asm_macros.S>
12*54fd6939SJiyong Park#include <context.h>
13*54fd6939SJiyong Park#include <lib/el3_runtime/cpu_data.h>
14*54fd6939SJiyong Park#include <lib/utils_def.h>
15*54fd6939SJiyong Park
16*54fd6939SJiyong Park	.globl	report_unhandled_exception
17*54fd6939SJiyong Park	.globl	report_unhandled_interrupt
18*54fd6939SJiyong Park	.globl	el3_panic
19*54fd6939SJiyong Park	.globl	elx_panic
20*54fd6939SJiyong Park
21*54fd6939SJiyong Park#if CRASH_REPORTING
22*54fd6939SJiyong Park
23*54fd6939SJiyong Park	/* ------------------------------------------------------
24*54fd6939SJiyong Park	 * The below section deals with dumping the system state
25*54fd6939SJiyong Park	 * when an unhandled exception is taken in EL3.
26*54fd6939SJiyong Park	 * The layout and the names of the registers which will
27*54fd6939SJiyong Park	 * be dumped during a unhandled exception is given below.
28*54fd6939SJiyong Park	 * ------------------------------------------------------
29*54fd6939SJiyong Park	 */
30*54fd6939SJiyong Park.section .rodata.crash_prints, "aS"
31*54fd6939SJiyong Parkprint_spacer:
32*54fd6939SJiyong Park	.asciz	"             = 0x"
33*54fd6939SJiyong Park
34*54fd6939SJiyong Parkgp_regs:
35*54fd6939SJiyong Park	.asciz	"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",\
36*54fd6939SJiyong Park		"x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",\
37*54fd6939SJiyong Park		"x16", "x17", "x18", "x19", "x20", "x21", "x22",\
38*54fd6939SJiyong Park		"x23", "x24", "x25", "x26", "x27", "x28", "x29", ""
39*54fd6939SJiyong Parkel3_sys_regs:
40*54fd6939SJiyong Park	.asciz	"scr_el3", "sctlr_el3", "cptr_el3", "tcr_el3",\
41*54fd6939SJiyong Park		"daif", "mair_el3", "spsr_el3", "elr_el3", "ttbr0_el3",\
42*54fd6939SJiyong Park		"esr_el3", "far_el3", ""
43*54fd6939SJiyong Park
44*54fd6939SJiyong Parknon_el3_sys_regs:
45*54fd6939SJiyong Park	.asciz	"spsr_el1", "elr_el1", "spsr_abt", "spsr_und",\
46*54fd6939SJiyong Park		"spsr_irq", "spsr_fiq", "sctlr_el1", "actlr_el1", "cpacr_el1",\
47*54fd6939SJiyong Park		"csselr_el1", "sp_el1", "esr_el1", "ttbr0_el1", "ttbr1_el1",\
48*54fd6939SJiyong Park		"mair_el1", "amair_el1", "tcr_el1", "tpidr_el1", "tpidr_el0",\
49*54fd6939SJiyong Park		"tpidrro_el0",  "par_el1", "mpidr_el1", "afsr0_el1", "afsr1_el1",\
50*54fd6939SJiyong Park		"contextidr_el1", "vbar_el1", "cntp_ctl_el0", "cntp_cval_el0",\
51*54fd6939SJiyong Park		"cntv_ctl_el0", "cntv_cval_el0", "cntkctl_el1", "sp_el0", "isr_el1", ""
52*54fd6939SJiyong Park
53*54fd6939SJiyong Park#if CTX_INCLUDE_AARCH32_REGS
54*54fd6939SJiyong Parkaarch32_regs:
55*54fd6939SJiyong Park	.asciz	"dacr32_el2", "ifsr32_el2", ""
56*54fd6939SJiyong Park#endif /* CTX_INCLUDE_AARCH32_REGS */
57*54fd6939SJiyong Park
58*54fd6939SJiyong Parkpanic_msg:
59*54fd6939SJiyong Park	.asciz "PANIC in EL3.\nx30"
60*54fd6939SJiyong Parkexcpt_msg:
61*54fd6939SJiyong Park	.asciz "Unhandled Exception in EL3.\nx30"
62*54fd6939SJiyong Parkintr_excpt_msg:
63*54fd6939SJiyong Park	.ascii "Unhandled Interrupt Exception in EL3.\n"
64*54fd6939SJiyong Parkx30_msg:
65*54fd6939SJiyong Park	.asciz "x30"
66*54fd6939SJiyong Parkexcpt_msg_el:
67*54fd6939SJiyong Park	.asciz "Unhandled Exception from EL"
68*54fd6939SJiyong Park
69*54fd6939SJiyong Park	/*
70*54fd6939SJiyong Park	 * Helper function to print from crash buf.
71*54fd6939SJiyong Park	 * The print loop is controlled by the buf size and
72*54fd6939SJiyong Park	 * ascii reg name list which is passed in x6. The
73*54fd6939SJiyong Park	 * function returns the crash buf address in x0.
74*54fd6939SJiyong Park	 * Clobbers : x0 - x7, sp
75*54fd6939SJiyong Park	 */
76*54fd6939SJiyong Parkfunc size_controlled_print
77*54fd6939SJiyong Park	/* Save the lr */
78*54fd6939SJiyong Park	mov	sp, x30
79*54fd6939SJiyong Park	/* load the crash buf address */
80*54fd6939SJiyong Park	mrs	x7, tpidr_el3
81*54fd6939SJiyong Parktest_size_list:
82*54fd6939SJiyong Park	/* Calculate x5 always as it will be clobbered by asm_print_hex */
83*54fd6939SJiyong Park	mrs	x5, tpidr_el3
84*54fd6939SJiyong Park	add	x5, x5, #CPU_DATA_CRASH_BUF_SIZE
85*54fd6939SJiyong Park	/* Test whether we have reached end of crash buf */
86*54fd6939SJiyong Park	cmp	x7, x5
87*54fd6939SJiyong Park	b.eq	exit_size_print
88*54fd6939SJiyong Park	ldrb	w4, [x6]
89*54fd6939SJiyong Park	/* Test whether we are at end of list */
90*54fd6939SJiyong Park	cbz	w4, exit_size_print
91*54fd6939SJiyong Park	mov	x4, x6
92*54fd6939SJiyong Park	/* asm_print_str updates x4 to point to next entry in list */
93*54fd6939SJiyong Park	bl	asm_print_str
94*54fd6939SJiyong Park	/* x0 = number of symbols printed + 1 */
95*54fd6939SJiyong Park	sub	x0, x4, x6
96*54fd6939SJiyong Park	/* update x6 with the updated list pointer */
97*54fd6939SJiyong Park	mov	x6, x4
98*54fd6939SJiyong Park	bl	print_alignment
99*54fd6939SJiyong Park	ldr	x4, [x7], #REGSZ
100*54fd6939SJiyong Park	bl	asm_print_hex
101*54fd6939SJiyong Park	bl	asm_print_newline
102*54fd6939SJiyong Park	b	test_size_list
103*54fd6939SJiyong Parkexit_size_print:
104*54fd6939SJiyong Park	mov	x30, sp
105*54fd6939SJiyong Park	ret
106*54fd6939SJiyong Parkendfunc size_controlled_print
107*54fd6939SJiyong Park
108*54fd6939SJiyong Park	/* -----------------------------------------------------
109*54fd6939SJiyong Park	 * This function calculates and prints required number
110*54fd6939SJiyong Park	 * of space characters followed by "= 0x", based on the
111*54fd6939SJiyong Park	 * length of ascii register name.
112*54fd6939SJiyong Park 	 * x0: length of ascii register name + 1
113*54fd6939SJiyong Park	 * ------------------------------------------------------
114*54fd6939SJiyong Park 	 */
115*54fd6939SJiyong Parkfunc print_alignment
116*54fd6939SJiyong Park	/* The minimum ascii length is 3, e.g. for "x0" */
117*54fd6939SJiyong Park	adr	x4, print_spacer - 3
118*54fd6939SJiyong Park	add	x4, x4, x0
119*54fd6939SJiyong Park	b	asm_print_str
120*54fd6939SJiyong Parkendfunc print_alignment
121*54fd6939SJiyong Park
122*54fd6939SJiyong Park	/*
123*54fd6939SJiyong Park	 * Helper function to store x8 - x15 registers to
124*54fd6939SJiyong Park	 * the crash buf. The system registers values are
125*54fd6939SJiyong Park	 * copied to x8 to x15 by the caller which are then
126*54fd6939SJiyong Park	 * copied to the crash buf by this function.
127*54fd6939SJiyong Park	 * x0 points to the crash buf. It then calls
128*54fd6939SJiyong Park	 * size_controlled_print to print to console.
129*54fd6939SJiyong Park	 * Clobbers : x0 - x7, sp
130*54fd6939SJiyong Park	 */
131*54fd6939SJiyong Parkfunc str_in_crash_buf_print
132*54fd6939SJiyong Park	/* restore the crash buf address in x0 */
133*54fd6939SJiyong Park	mrs	x0, tpidr_el3
134*54fd6939SJiyong Park	stp	x8, x9, [x0]
135*54fd6939SJiyong Park	stp	x10, x11, [x0, #REGSZ * 2]
136*54fd6939SJiyong Park	stp	x12, x13, [x0, #REGSZ * 4]
137*54fd6939SJiyong Park	stp	x14, x15, [x0, #REGSZ * 6]
138*54fd6939SJiyong Park	b	size_controlled_print
139*54fd6939SJiyong Parkendfunc str_in_crash_buf_print
140*54fd6939SJiyong Park
141*54fd6939SJiyong Park	/* ------------------------------------------------------
142*54fd6939SJiyong Park	 * This macro calculates the offset to crash buf from
143*54fd6939SJiyong Park	 * cpu_data and stores it in tpidr_el3. It also saves x0
144*54fd6939SJiyong Park	 * and x1 in the crash buf by using sp as a temporary
145*54fd6939SJiyong Park	 * register.
146*54fd6939SJiyong Park	 * ------------------------------------------------------
147*54fd6939SJiyong Park	 */
148*54fd6939SJiyong Park	.macro prepare_crash_buf_save_x0_x1
149*54fd6939SJiyong Park	/* we can corrupt this reg to free up x0 */
150*54fd6939SJiyong Park	mov	sp, x0
151*54fd6939SJiyong Park	/* tpidr_el3 contains the address to cpu_data structure */
152*54fd6939SJiyong Park	mrs	x0, tpidr_el3
153*54fd6939SJiyong Park	/* Calculate the Crash buffer offset in cpu_data */
154*54fd6939SJiyong Park	add	x0, x0, #CPU_DATA_CRASH_BUF_OFFSET
155*54fd6939SJiyong Park	/* Store crash buffer address in tpidr_el3 */
156*54fd6939SJiyong Park	msr	tpidr_el3, x0
157*54fd6939SJiyong Park	str	x1, [x0, #REGSZ]
158*54fd6939SJiyong Park	mov	x1, sp
159*54fd6939SJiyong Park	str	x1, [x0]
160*54fd6939SJiyong Park	.endm
161*54fd6939SJiyong Park
162*54fd6939SJiyong Park	/* -----------------------------------------------------
163*54fd6939SJiyong Park	 * This function allows to report a crash (if crash
164*54fd6939SJiyong Park	 * reporting is enabled) when an unhandled exception
165*54fd6939SJiyong Park	 * occurs. It prints the CPU state via the crash console
166*54fd6939SJiyong Park	 * making use of the crash buf. This function will
167*54fd6939SJiyong Park	 * not return.
168*54fd6939SJiyong Park	 * -----------------------------------------------------
169*54fd6939SJiyong Park	 */
170*54fd6939SJiyong Parkfunc report_unhandled_exception
171*54fd6939SJiyong Park	prepare_crash_buf_save_x0_x1
172*54fd6939SJiyong Park	adr	x0, excpt_msg
173*54fd6939SJiyong Park	mov	sp, x0
174*54fd6939SJiyong Park	/* This call will not return */
175*54fd6939SJiyong Park	b	do_crash_reporting
176*54fd6939SJiyong Parkendfunc report_unhandled_exception
177*54fd6939SJiyong Park
178*54fd6939SJiyong Park	/* -----------------------------------------------------
179*54fd6939SJiyong Park	 * This function allows to report a crash (if crash
180*54fd6939SJiyong Park	 * reporting is enabled) when an unhandled interrupt
181*54fd6939SJiyong Park	 * occurs. It prints the CPU state via the crash console
182*54fd6939SJiyong Park	 * making use of the crash buf. This function will
183*54fd6939SJiyong Park	 * not return.
184*54fd6939SJiyong Park	 * -----------------------------------------------------
185*54fd6939SJiyong Park	 */
186*54fd6939SJiyong Parkfunc report_unhandled_interrupt
187*54fd6939SJiyong Park	prepare_crash_buf_save_x0_x1
188*54fd6939SJiyong Park	adr	x0, intr_excpt_msg
189*54fd6939SJiyong Park	mov	sp, x0
190*54fd6939SJiyong Park	/* This call will not return */
191*54fd6939SJiyong Park	b	do_crash_reporting
192*54fd6939SJiyong Parkendfunc report_unhandled_interrupt
193*54fd6939SJiyong Park
194*54fd6939SJiyong Park	/* -----------------------------------------------------
195*54fd6939SJiyong Park	 * This function allows to report a crash from the lower
196*54fd6939SJiyong Park	 * exception level (if crash reporting is enabled) when
197*54fd6939SJiyong Park	 * panic() is invoked from C Runtime.
198*54fd6939SJiyong Park	 * It prints the CPU state via the crash console making
199*54fd6939SJiyong Park	 * use of 'cpu_context' structure where general purpose
200*54fd6939SJiyong Park	 * registers are saved and the crash buf.
201*54fd6939SJiyong Park	 * This function will not return.
202*54fd6939SJiyong Park	 *
203*54fd6939SJiyong Park 	 * x0: Exception level
204*54fd6939SJiyong Park	 * -----------------------------------------------------
205*54fd6939SJiyong Park	 */
206*54fd6939SJiyong Parkfunc elx_panic
207*54fd6939SJiyong Park	msr	spsel, #MODE_SP_ELX
208*54fd6939SJiyong Park	mov	x8, x0
209*54fd6939SJiyong Park
210*54fd6939SJiyong Park	/* Print the crash message */
211*54fd6939SJiyong Park	adr	x4, excpt_msg_el
212*54fd6939SJiyong Park	bl	asm_print_str
213*54fd6939SJiyong Park
214*54fd6939SJiyong Park	/* Print exception level */
215*54fd6939SJiyong Park	add	x0, x8, #'0'
216*54fd6939SJiyong Park	bl	plat_crash_console_putc
217*54fd6939SJiyong Park	bl	asm_print_newline
218*54fd6939SJiyong Park
219*54fd6939SJiyong Park	/* Report x0 - x29 values stored in 'gpregs_ctx' structure */
220*54fd6939SJiyong Park	/* Store the ascii list pointer in x6 */
221*54fd6939SJiyong Park	adr	x6, gp_regs
222*54fd6939SJiyong Park	add	x7, sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0
223*54fd6939SJiyong Park
224*54fd6939SJiyong Parkprint_next:
225*54fd6939SJiyong Park	ldrb	w4, [x6]
226*54fd6939SJiyong Park	/* Test whether we are at end of list */
227*54fd6939SJiyong Park	cbz	w4, print_x30
228*54fd6939SJiyong Park	mov	x4, x6
229*54fd6939SJiyong Park	/* asm_print_str updates x4 to point to next entry in list */
230*54fd6939SJiyong Park	bl	asm_print_str
231*54fd6939SJiyong Park	/* x0 = number of symbols printed + 1 */
232*54fd6939SJiyong Park	sub	x0, x4, x6
233*54fd6939SJiyong Park	/* Update x6 with the updated list pointer */
234*54fd6939SJiyong Park	mov	x6, x4
235*54fd6939SJiyong Park	bl	print_alignment
236*54fd6939SJiyong Park	ldr	x4, [x7], #REGSZ
237*54fd6939SJiyong Park	bl	asm_print_hex
238*54fd6939SJiyong Park	bl	asm_print_newline
239*54fd6939SJiyong Park	b	print_next
240*54fd6939SJiyong Park
241*54fd6939SJiyong Parkprint_x30:
242*54fd6939SJiyong Park	adr	x4, x30_msg
243*54fd6939SJiyong Park	bl	asm_print_str
244*54fd6939SJiyong Park
245*54fd6939SJiyong Park	/* Print spaces to align "x30" string */
246*54fd6939SJiyong Park	mov	x0, #4
247*54fd6939SJiyong Park	bl	print_alignment
248*54fd6939SJiyong Park
249*54fd6939SJiyong Park	/* Report x30 */
250*54fd6939SJiyong Park	ldr	x4, [x7]
251*54fd6939SJiyong Park
252*54fd6939SJiyong Park	/* ----------------------------------------------------------------
253*54fd6939SJiyong Park	 * Different virtual address space size can be defined for each EL.
254*54fd6939SJiyong Park	 * Ensure that we use the proper one by reading the corresponding
255*54fd6939SJiyong Park	 * TCR_ELx register.
256*54fd6939SJiyong Park	 * ----------------------------------------------------------------
257*54fd6939SJiyong Park	 */
258*54fd6939SJiyong Park	cmp	x8, #MODE_EL2
259*54fd6939SJiyong Park	b.lt	from_el1	/* EL1 */
260*54fd6939SJiyong Park	mrs	x2, sctlr_el2
261*54fd6939SJiyong Park	mrs	x1, tcr_el2
262*54fd6939SJiyong Park
263*54fd6939SJiyong Park	/* ----------------------------------------------------------------
264*54fd6939SJiyong Park	 * Check if pointer authentication is enabled at the specified EL.
265*54fd6939SJiyong Park	 * If it isn't, we can then skip stripping a PAC code.
266*54fd6939SJiyong Park	 * ----------------------------------------------------------------
267*54fd6939SJiyong Park	 */
268*54fd6939SJiyong Parktest_pauth:
269*54fd6939SJiyong Park	tst	x2, #(SCTLR_EnIA_BIT | SCTLR_EnIB_BIT)
270*54fd6939SJiyong Park	b.eq	no_pauth
271*54fd6939SJiyong Park
272*54fd6939SJiyong Park	/* Demangle address */
273*54fd6939SJiyong Park	and	x1, x1, #0x3F	/* T0SZ = TCR_ELx[5:0] */
274*54fd6939SJiyong Park	sub	x1, x1, #64
275*54fd6939SJiyong Park	neg	x1, x1		/* bottom_pac_bit = 64 - T0SZ */
276*54fd6939SJiyong Park	mov	x2, #-1
277*54fd6939SJiyong Park	lsl	x2, x2, x1
278*54fd6939SJiyong Park	bic	x4, x4, x2
279*54fd6939SJiyong Park
280*54fd6939SJiyong Parkno_pauth:
281*54fd6939SJiyong Park	bl	asm_print_hex
282*54fd6939SJiyong Park	bl	asm_print_newline
283*54fd6939SJiyong Park
284*54fd6939SJiyong Park	/* tpidr_el3 contains the address to cpu_data structure */
285*54fd6939SJiyong Park	mrs	x0, tpidr_el3
286*54fd6939SJiyong Park	/* Calculate the Crash buffer offset in cpu_data */
287*54fd6939SJiyong Park	add	x0, x0, #CPU_DATA_CRASH_BUF_OFFSET
288*54fd6939SJiyong Park	/* Store crash buffer address in tpidr_el3 */
289*54fd6939SJiyong Park	msr	tpidr_el3, x0
290*54fd6939SJiyong Park
291*54fd6939SJiyong Park	/* Print the rest of crash dump */
292*54fd6939SJiyong Park	b	print_el3_sys_regs
293*54fd6939SJiyong Park
294*54fd6939SJiyong Parkfrom_el1:
295*54fd6939SJiyong Park	mrs	x2, sctlr_el1
296*54fd6939SJiyong Park	mrs	x1, tcr_el1
297*54fd6939SJiyong Park	b	test_pauth
298*54fd6939SJiyong Parkendfunc	elx_panic
299*54fd6939SJiyong Park
300*54fd6939SJiyong Park	/* -----------------------------------------------------
301*54fd6939SJiyong Park	 * This function allows to report a crash (if crash
302*54fd6939SJiyong Park	 * reporting is enabled) when panic() is invoked from
303*54fd6939SJiyong Park	 * C Runtime. It prints the CPU state via the crash
304*54fd6939SJiyong Park	 * console making use of the crash buf. This function
305*54fd6939SJiyong Park	 * will not return.
306*54fd6939SJiyong Park	 * -----------------------------------------------------
307*54fd6939SJiyong Park	 */
308*54fd6939SJiyong Parkfunc el3_panic
309*54fd6939SJiyong Park	msr	spsel, #MODE_SP_ELX
310*54fd6939SJiyong Park	prepare_crash_buf_save_x0_x1
311*54fd6939SJiyong Park	adr	x0, panic_msg
312*54fd6939SJiyong Park	mov	sp, x0
313*54fd6939SJiyong Park	/* Fall through to 'do_crash_reporting' */
314*54fd6939SJiyong Park
315*54fd6939SJiyong Park	/* ------------------------------------------------------------
316*54fd6939SJiyong Park	 * The common crash reporting functionality. It requires x0
317*54fd6939SJiyong Park	 * and x1 has already been stored in crash buf, sp points to
318*54fd6939SJiyong Park	 * crash message and tpidr_el3 contains the crash buf address.
319*54fd6939SJiyong Park	 * The function does the following:
320*54fd6939SJiyong Park	 *   - Retrieve the crash buffer from tpidr_el3
321*54fd6939SJiyong Park	 *   - Store x2 to x6 in the crash buffer
322*54fd6939SJiyong Park	 *   - Initialise the crash console.
323*54fd6939SJiyong Park	 *   - Print the crash message by using the address in sp.
324*54fd6939SJiyong Park	 *   - Print x30 value to the crash console.
325*54fd6939SJiyong Park	 *   - Print x0 - x7 from the crash buf to the crash console.
326*54fd6939SJiyong Park	 *   - Print x8 - x29 (in groups of 8 registers) using the
327*54fd6939SJiyong Park	 *     crash buf to the crash console.
328*54fd6939SJiyong Park	 *   - Print el3 sys regs (in groups of 8 registers) using the
329*54fd6939SJiyong Park	 *     crash buf to the crash console.
330*54fd6939SJiyong Park	 *   - Print non el3 sys regs (in groups of 8 registers) using
331*54fd6939SJiyong Park	 *     the crash buf to the crash console.
332*54fd6939SJiyong Park	 * ------------------------------------------------------------
333*54fd6939SJiyong Park	 */
334*54fd6939SJiyong Parkdo_crash_reporting:
335*54fd6939SJiyong Park	/* Retrieve the crash buf from tpidr_el3 */
336*54fd6939SJiyong Park	mrs	x0, tpidr_el3
337*54fd6939SJiyong Park	/* Store x2 - x6, x30 in the crash buffer */
338*54fd6939SJiyong Park	stp	x2, x3, [x0, #REGSZ * 2]
339*54fd6939SJiyong Park	stp	x4, x5, [x0, #REGSZ * 4]
340*54fd6939SJiyong Park	stp	x6, x30, [x0, #REGSZ * 6]
341*54fd6939SJiyong Park	/* Initialize the crash console */
342*54fd6939SJiyong Park	bl	plat_crash_console_init
343*54fd6939SJiyong Park	/* Verify the console is initialized */
344*54fd6939SJiyong Park	cbz	x0, crash_panic
345*54fd6939SJiyong Park	/* Print the crash message. sp points to the crash message */
346*54fd6939SJiyong Park	mov	x4, sp
347*54fd6939SJiyong Park	bl	asm_print_str
348*54fd6939SJiyong Park	/* Print spaces to align "x30" string */
349*54fd6939SJiyong Park	mov	x0, #4
350*54fd6939SJiyong Park	bl	print_alignment
351*54fd6939SJiyong Park	/* Load the crash buf address */
352*54fd6939SJiyong Park	mrs	x0, tpidr_el3
353*54fd6939SJiyong Park	/* Report x30 first from the crash buf */
354*54fd6939SJiyong Park	ldr	x4, [x0, #REGSZ * 7]
355*54fd6939SJiyong Park
356*54fd6939SJiyong Park#if ENABLE_PAUTH
357*54fd6939SJiyong Park	/* Demangle address */
358*54fd6939SJiyong Park	xpaci	x4
359*54fd6939SJiyong Park#endif
360*54fd6939SJiyong Park	bl	asm_print_hex
361*54fd6939SJiyong Park	bl	asm_print_newline
362*54fd6939SJiyong Park	/* Load the crash buf address */
363*54fd6939SJiyong Park	mrs	x0, tpidr_el3
364*54fd6939SJiyong Park	/* Now mov x7 into crash buf */
365*54fd6939SJiyong Park	str	x7, [x0, #REGSZ * 7]
366*54fd6939SJiyong Park
367*54fd6939SJiyong Park	/* Report x0 - x29 values stored in crash buf */
368*54fd6939SJiyong Park	/* Store the ascii list pointer in x6 */
369*54fd6939SJiyong Park	adr	x6, gp_regs
370*54fd6939SJiyong Park	/* Print x0 to x7 from the crash buf */
371*54fd6939SJiyong Park	bl	size_controlled_print
372*54fd6939SJiyong Park	/* Store x8 - x15 in crash buf and print */
373*54fd6939SJiyong Park	bl	str_in_crash_buf_print
374*54fd6939SJiyong Park	/* Load the crash buf address */
375*54fd6939SJiyong Park	mrs	x0, tpidr_el3
376*54fd6939SJiyong Park	/* Store the rest of gp regs and print */
377*54fd6939SJiyong Park	stp	x16, x17, [x0]
378*54fd6939SJiyong Park	stp	x18, x19, [x0, #REGSZ * 2]
379*54fd6939SJiyong Park	stp	x20, x21, [x0, #REGSZ * 4]
380*54fd6939SJiyong Park	stp	x22, x23, [x0, #REGSZ * 6]
381*54fd6939SJiyong Park	bl	size_controlled_print
382*54fd6939SJiyong Park	/* Load the crash buf address */
383*54fd6939SJiyong Park	mrs	x0, tpidr_el3
384*54fd6939SJiyong Park	stp	x24, x25, [x0]
385*54fd6939SJiyong Park	stp	x26, x27, [x0, #REGSZ * 2]
386*54fd6939SJiyong Park	stp	x28, x29, [x0, #REGSZ * 4]
387*54fd6939SJiyong Park	bl	size_controlled_print
388*54fd6939SJiyong Park
389*54fd6939SJiyong Park	/* Print the el3 sys registers */
390*54fd6939SJiyong Parkprint_el3_sys_regs:
391*54fd6939SJiyong Park	adr	x6, el3_sys_regs
392*54fd6939SJiyong Park	mrs	x8, scr_el3
393*54fd6939SJiyong Park	mrs	x9, sctlr_el3
394*54fd6939SJiyong Park	mrs	x10, cptr_el3
395*54fd6939SJiyong Park	mrs	x11, tcr_el3
396*54fd6939SJiyong Park	mrs	x12, daif
397*54fd6939SJiyong Park	mrs	x13, mair_el3
398*54fd6939SJiyong Park	mrs	x14, spsr_el3
399*54fd6939SJiyong Park	mrs	x15, elr_el3
400*54fd6939SJiyong Park	bl	str_in_crash_buf_print
401*54fd6939SJiyong Park	mrs	x8, ttbr0_el3
402*54fd6939SJiyong Park	mrs	x9, esr_el3
403*54fd6939SJiyong Park	mrs	x10, far_el3
404*54fd6939SJiyong Park	bl	str_in_crash_buf_print
405*54fd6939SJiyong Park
406*54fd6939SJiyong Park	/* Print the non el3 sys registers */
407*54fd6939SJiyong Park	adr	x6, non_el3_sys_regs
408*54fd6939SJiyong Park	mrs	x8, spsr_el1
409*54fd6939SJiyong Park	mrs	x9, elr_el1
410*54fd6939SJiyong Park	mrs	x10, spsr_abt
411*54fd6939SJiyong Park	mrs	x11, spsr_und
412*54fd6939SJiyong Park	mrs	x12, spsr_irq
413*54fd6939SJiyong Park	mrs	x13, spsr_fiq
414*54fd6939SJiyong Park	mrs	x14, sctlr_el1
415*54fd6939SJiyong Park	mrs	x15, actlr_el1
416*54fd6939SJiyong Park	bl	str_in_crash_buf_print
417*54fd6939SJiyong Park	mrs	x8, cpacr_el1
418*54fd6939SJiyong Park	mrs	x9, csselr_el1
419*54fd6939SJiyong Park	mrs	x10, sp_el1
420*54fd6939SJiyong Park	mrs	x11, esr_el1
421*54fd6939SJiyong Park	mrs	x12, ttbr0_el1
422*54fd6939SJiyong Park	mrs	x13, ttbr1_el1
423*54fd6939SJiyong Park	mrs	x14, mair_el1
424*54fd6939SJiyong Park	mrs	x15, amair_el1
425*54fd6939SJiyong Park	bl	str_in_crash_buf_print
426*54fd6939SJiyong Park	mrs	x8, tcr_el1
427*54fd6939SJiyong Park	mrs	x9, tpidr_el1
428*54fd6939SJiyong Park	mrs	x10, tpidr_el0
429*54fd6939SJiyong Park	mrs	x11, tpidrro_el0
430*54fd6939SJiyong Park	mrs	x12, par_el1
431*54fd6939SJiyong Park	mrs	x13, mpidr_el1
432*54fd6939SJiyong Park	mrs	x14, afsr0_el1
433*54fd6939SJiyong Park	mrs	x15, afsr1_el1
434*54fd6939SJiyong Park	bl	str_in_crash_buf_print
435*54fd6939SJiyong Park	mrs	x8, contextidr_el1
436*54fd6939SJiyong Park	mrs	x9, vbar_el1
437*54fd6939SJiyong Park	mrs	x10, cntp_ctl_el0
438*54fd6939SJiyong Park	mrs	x11, cntp_cval_el0
439*54fd6939SJiyong Park	mrs	x12, cntv_ctl_el0
440*54fd6939SJiyong Park	mrs	x13, cntv_cval_el0
441*54fd6939SJiyong Park	mrs	x14, cntkctl_el1
442*54fd6939SJiyong Park	mrs	x15, sp_el0
443*54fd6939SJiyong Park	bl	str_in_crash_buf_print
444*54fd6939SJiyong Park	mrs	x8, isr_el1
445*54fd6939SJiyong Park	bl	str_in_crash_buf_print
446*54fd6939SJiyong Park
447*54fd6939SJiyong Park#if CTX_INCLUDE_AARCH32_REGS
448*54fd6939SJiyong Park	/* Print the AArch32 registers */
449*54fd6939SJiyong Park	adr	x6, aarch32_regs
450*54fd6939SJiyong Park	mrs	x8, dacr32_el2
451*54fd6939SJiyong Park	mrs	x9, ifsr32_el2
452*54fd6939SJiyong Park	bl	str_in_crash_buf_print
453*54fd6939SJiyong Park#endif /* CTX_INCLUDE_AARCH32_REGS */
454*54fd6939SJiyong Park
455*54fd6939SJiyong Park	/* Get the cpu specific registers to report */
456*54fd6939SJiyong Park	bl	do_cpu_reg_dump
457*54fd6939SJiyong Park	bl	str_in_crash_buf_print
458*54fd6939SJiyong Park
459*54fd6939SJiyong Park	/* Print some platform registers */
460*54fd6939SJiyong Park	plat_crash_print_regs
461*54fd6939SJiyong Park
462*54fd6939SJiyong Park	bl	plat_crash_console_flush
463*54fd6939SJiyong Park
464*54fd6939SJiyong Park	/* Done reporting */
465*54fd6939SJiyong Park	no_ret	plat_panic_handler
466*54fd6939SJiyong Parkendfunc el3_panic
467*54fd6939SJiyong Park
468*54fd6939SJiyong Park#else	/* CRASH_REPORTING */
469*54fd6939SJiyong Parkfunc report_unhandled_exception
470*54fd6939SJiyong Parkreport_unhandled_interrupt:
471*54fd6939SJiyong Park	no_ret	plat_panic_handler
472*54fd6939SJiyong Parkendfunc report_unhandled_exception
473*54fd6939SJiyong Park#endif	/* CRASH_REPORTING */
474*54fd6939SJiyong Park
475*54fd6939SJiyong Parkfunc crash_panic
476*54fd6939SJiyong Park	no_ret	plat_panic_handler
477*54fd6939SJiyong Parkendfunc crash_panic
478