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