xref: /rk3399_ARM-atf/bl31/aarch64/crash_reporting.S (revision 7303319b3823e9e33748d963e9173f3678aba4da)
1a43d431bSSoby Mathew/*
258fadd62SIgor Podgainõi * Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved.
3a43d431bSSoby Mathew *
482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
5a43d431bSSoby Mathew */
609d40e0eSAntonio Nino Diaz
709d40e0eSAntonio Nino Diaz#include <plat_macros.S>
809d40e0eSAntonio Nino Diaz#include <platform_def.h>
909d40e0eSAntonio Nino Diaz
10a43d431bSSoby Mathew#include <arch.h>
11a43d431bSSoby Mathew#include <asm_macros.S>
12a43d431bSSoby Mathew#include <context.h>
1309d40e0eSAntonio Nino Diaz#include <lib/el3_runtime/cpu_data.h>
14*98859b99SSammit Joshi#include <lib/per_cpu/per_cpu_macros.S>
1509d40e0eSAntonio Nino Diaz#include <lib/utils_def.h>
16a43d431bSSoby Mathew
17626ed510SSoby Mathew	.globl	report_unhandled_exception
18626ed510SSoby Mathew	.globl	report_unhandled_interrupt
19f300ef66SGovindraj Raja	.globl	report_el3_panic
207e619eccSGovindraj Raja	.globl	report_elx_panic
21a43d431bSSoby Mathew
229c22b323SAndrew Thoelke#if CRASH_REPORTING
23626ed510SSoby Mathew
24a43d431bSSoby Mathew	/* ------------------------------------------------------
25a43d431bSSoby Mathew	 * The below section deals with dumping the system state
26a43d431bSSoby Mathew	 * when an unhandled exception is taken in EL3.
27a43d431bSSoby Mathew	 * The layout and the names of the registers which will
28a43d431bSSoby Mathew	 * be dumped during a unhandled exception is given below.
29a43d431bSSoby Mathew	 * ------------------------------------------------------
30a43d431bSSoby Mathew	 */
31626ed510SSoby Mathew.section .rodata.crash_prints, "aS"
32626ed510SSoby Mathewprint_spacer:
336c6a470fSAlexei Fedorov	.asciz	"             = 0x"
34a43d431bSSoby Mathew
35626ed510SSoby Mathewgp_regs:
36626ed510SSoby Mathew	.asciz	"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",\
37626ed510SSoby Mathew		"x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",\
38626ed510SSoby Mathew		"x16", "x17", "x18", "x19", "x20", "x21", "x22",\
39626ed510SSoby Mathew		"x23", "x24", "x25", "x26", "x27", "x28", "x29", ""
40626ed510SSoby Mathewel3_sys_regs:
41626ed510SSoby Mathew	.asciz	"scr_el3", "sctlr_el3", "cptr_el3", "tcr_el3",\
42626ed510SSoby Mathew		"daif", "mair_el3", "spsr_el3", "elr_el3", "ttbr0_el3",\
43626ed510SSoby Mathew		"esr_el3", "far_el3", ""
44a43d431bSSoby Mathew
458f152319SBoyan Karatotevnon_el3_sys_regs:
468f152319SBoyan Karatotev	.asciz	"mpidr_el1", "sp_el0", "isr_el1", ""
47c424b91eSImre Kis
48c424b91eSImre Kis#if CTX_INCLUDE_AARCH32_REGS
49c424b91eSImre Kisaarch32_regs:
50c424b91eSImre Kis	.asciz	"dacr32_el2", "ifsr32_el2", ""
51c424b91eSImre Kis#endif /* CTX_INCLUDE_AARCH32_REGS */
52a43d431bSSoby Mathew
53626ed510SSoby Mathewpanic_msg:
546c6a470fSAlexei Fedorov	.asciz "PANIC in EL3.\nx30"
55626ed510SSoby Mathewexcpt_msg:
566c6a470fSAlexei Fedorov	.asciz "Unhandled Exception in EL3.\nx30"
57626ed510SSoby Mathewintr_excpt_msg:
58b4292bc6SAlexei Fedorov	.ascii "Unhandled Interrupt Exception in EL3.\n"
59b4292bc6SAlexei Fedorovx30_msg:
60b4292bc6SAlexei Fedorov	.asciz "x30"
61b4292bc6SAlexei Fedorovexcpt_msg_el:
627e619eccSGovindraj Raja	.asciz "Unhandled Exception from lower EL.\n"
63626ed510SSoby Mathew
64626ed510SSoby Mathew	/*
65626ed510SSoby Mathew	 * Helper function to print from crash buf.
66626ed510SSoby Mathew	 * The print loop is controlled by the buf size and
67626ed510SSoby Mathew	 * ascii reg name list which is passed in x6. The
68626ed510SSoby Mathew	 * function returns the crash buf address in x0.
6958fadd62SIgor Podgainõi	 * Clobbers : x0 - x7, x20, sp
70626ed510SSoby Mathew	 */
7158fadd62SIgor Podgainõifunc size_controlled_print_helper
7258fadd62SIgor Podgainõi#if ENABLE_FEAT_D128
7358fadd62SIgor Podgainõisize_controlled_print_128:
7458fadd62SIgor Podgainõi	/* Set flag to print 128-bit registers */
7558fadd62SIgor Podgainõi	mov	x20, #1
7658fadd62SIgor Podgainõi	b	1f
7758fadd62SIgor Podgainõi
7858fadd62SIgor Podgainõisize_controlled_print:
7958fadd62SIgor Podgainõi	/* Set flag to print 64-bit registers */
8058fadd62SIgor Podgainõi	mov	x20, #0
8158fadd62SIgor Podgainõi1:
8258fadd62SIgor Podgainõi#else
8358fadd62SIgor Podgainõisize_controlled_print:
8458fadd62SIgor Podgainõi#endif
85626ed510SSoby Mathew	/* Save the lr */
86626ed510SSoby Mathew	mov	sp, x30
87626ed510SSoby Mathew	/* load the crash buf address */
88626ed510SSoby Mathew	mrs	x7, tpidr_el3
89626ed510SSoby Mathewtest_size_list:
90626ed510SSoby Mathew	/* Calculate x5 always as it will be clobbered by asm_print_hex */
91626ed510SSoby Mathew	mrs	x5, tpidr_el3
924779becdSBoyan Karatotev	add	x5, x5, #CPU_DATA_CRASH_BUF_BYTES
93626ed510SSoby Mathew	/* Test whether we have reached end of crash buf */
94626ed510SSoby Mathew	cmp	x7, x5
95626ed510SSoby Mathew	b.eq	exit_size_print
96626ed510SSoby Mathew	ldrb	w4, [x6]
97626ed510SSoby Mathew	/* Test whether we are at end of list */
98626ed510SSoby Mathew	cbz	w4, exit_size_print
99626ed510SSoby Mathew	mov	x4, x6
100626ed510SSoby Mathew	/* asm_print_str updates x4 to point to next entry in list */
101626ed510SSoby Mathew	bl	asm_print_str
1026c6a470fSAlexei Fedorov	/* x0 = number of symbols printed + 1 */
1036c6a470fSAlexei Fedorov	sub	x0, x4, x6
104626ed510SSoby Mathew	/* update x6 with the updated list pointer */
105626ed510SSoby Mathew	mov	x6, x4
1066c6a470fSAlexei Fedorov	bl	print_alignment
10758fadd62SIgor Podgainõi	/* Print the high 64 bits (or whole 64-bit register) */
108155a1006SJulius Werner	ldr	x4, [x7], #REGSZ
109626ed510SSoby Mathew	bl	asm_print_hex
11058fadd62SIgor Podgainõi#if ENABLE_FEAT_D128
11158fadd62SIgor Podgainõi	cbz	x20, 2f
11258fadd62SIgor Podgainõi	/* Print the low 64 bits in case of a 128-bit register */
11358fadd62SIgor Podgainõi	ldr	x4, [x7], #REGSZ
11458fadd62SIgor Podgainõi	bl	asm_print_hex
11558fadd62SIgor Podgainõi2:
11658fadd62SIgor Podgainõi#endif
11753d7e003SJustin Chadwell	bl	asm_print_newline
118626ed510SSoby Mathew	b	test_size_list
119626ed510SSoby Mathewexit_size_print:
120626ed510SSoby Mathew	mov	x30, sp
121626ed510SSoby Mathew	ret
12258fadd62SIgor Podgainõiendfunc size_controlled_print_helper
123626ed510SSoby Mathew
1246c6a470fSAlexei Fedorov	/* -----------------------------------------------------
1256c6a470fSAlexei Fedorov	 * This function calculates and prints required number
1266c6a470fSAlexei Fedorov	 * of space characters followed by "= 0x", based on the
1276c6a470fSAlexei Fedorov	 * length of ascii register name.
1286c6a470fSAlexei Fedorov 	 * x0: length of ascii register name + 1
1296c6a470fSAlexei Fedorov	 * ------------------------------------------------------
1306c6a470fSAlexei Fedorov 	 */
1316c6a470fSAlexei Fedorovfunc print_alignment
1326c6a470fSAlexei Fedorov	/* The minimum ascii length is 3, e.g. for "x0" */
1336c6a470fSAlexei Fedorov	adr	x4, print_spacer - 3
1346c6a470fSAlexei Fedorov	add	x4, x4, x0
1356c6a470fSAlexei Fedorov	b	asm_print_str
1366c6a470fSAlexei Fedorovendfunc print_alignment
1376c6a470fSAlexei Fedorov
138626ed510SSoby Mathew	/*
139626ed510SSoby Mathew	 * Helper function to store x8 - x15 registers to
140626ed510SSoby Mathew	 * the crash buf. The system registers values are
141626ed510SSoby Mathew	 * copied to x8 to x15 by the caller which are then
142626ed510SSoby Mathew	 * copied to the crash buf by this function.
143626ed510SSoby Mathew	 * x0 points to the crash buf. It then calls
144626ed510SSoby Mathew	 * size_controlled_print to print to console.
14558fadd62SIgor Podgainõi	 * Clobbers : x0 - x7, x20, sp
146626ed510SSoby Mathew	 */
147626ed510SSoby Mathewfunc str_in_crash_buf_print
148626ed510SSoby Mathew	/* restore the crash buf address in x0 */
149626ed510SSoby Mathew	mrs	x0, tpidr_el3
150626ed510SSoby Mathew	stp	x8, x9, [x0]
151155a1006SJulius Werner	stp	x10, x11, [x0, #REGSZ * 2]
152155a1006SJulius Werner	stp	x12, x13, [x0, #REGSZ * 4]
153155a1006SJulius Werner	stp	x14, x15, [x0, #REGSZ * 6]
154626ed510SSoby Mathew	b	size_controlled_print
1558b779620SKévin Petitendfunc str_in_crash_buf_print
156626ed510SSoby Mathew
15758fadd62SIgor Podgainõi	/*
15858fadd62SIgor Podgainõi	 * An equivalent helper function for storing x8 - x15
15958fadd62SIgor Podgainõi	 * registers in a different order inside the crash buf.
16058fadd62SIgor Podgainõi	 * In the end the function size_controlled_print_128 is
16158fadd62SIgor Podgainõi	 * called to print the registers to the console.
16258fadd62SIgor Podgainõi	 * Clobbers : x0 - x7, x20, sp
16358fadd62SIgor Podgainõi	 */
16458fadd62SIgor Podgainõifunc str_in_crash_buf_print_128
16558fadd62SIgor Podgainõi	/* restore the crash buf address in x0 */
16658fadd62SIgor Podgainõi	mrs	x0, tpidr_el3
16758fadd62SIgor Podgainõi	stp	x8, x9, [x0]
16858fadd62SIgor Podgainõi	stp	x10, x11, [x0, #REGSZ * 2]
16958fadd62SIgor Podgainõi	stp	x12, x13, [x0, #REGSZ * 4]
17058fadd62SIgor Podgainõi	stp	x14, x15, [x0, #REGSZ * 6]
17158fadd62SIgor Podgainõi	b	size_controlled_print_128
17258fadd62SIgor Podgainõiendfunc str_in_crash_buf_print_128
17358fadd62SIgor Podgainõi
174626ed510SSoby Mathew	/* ------------------------------------------------------
175626ed510SSoby Mathew	 * This macro calculates the offset to crash buf from
176626ed510SSoby Mathew	 * cpu_data and stores it in tpidr_el3. It also saves x0
177626ed510SSoby Mathew	 * and x1 in the crash buf by using sp as a temporary
178626ed510SSoby Mathew	 * register.
179626ed510SSoby Mathew	 * ------------------------------------------------------
180626ed510SSoby Mathew	 */
181626ed510SSoby Mathew	.macro prepare_crash_buf_save_x0_x1
182626ed510SSoby Mathew	/* we can corrupt this reg to free up x0 */
183626ed510SSoby Mathew	mov	sp, x0
184626ed510SSoby Mathew	/* tpidr_el3 contains the address to cpu_data structure */
185*98859b99SSammit Joshi	per_cpu_cur percpu_data, x0, x2
186626ed510SSoby Mathew	/* Calculate the Crash buffer offset in cpu_data */
1874779becdSBoyan Karatotev	add	x0, x0, #CPU_DATA_CRASH_BUF
188626ed510SSoby Mathew	/* Store crash buffer address in tpidr_el3 */
189626ed510SSoby Mathew	msr	tpidr_el3, x0
190155a1006SJulius Werner	str	x1, [x0, #REGSZ]
191626ed510SSoby Mathew	mov	x1, sp
192626ed510SSoby Mathew	str	x1, [x0]
193626ed510SSoby Mathew	.endm
194a43d431bSSoby Mathew
195a43d431bSSoby Mathew	/* -----------------------------------------------------
196626ed510SSoby Mathew	 * This function allows to report a crash (if crash
197626ed510SSoby Mathew	 * reporting is enabled) when an unhandled exception
198626ed510SSoby Mathew	 * occurs. It prints the CPU state via the crash console
199626ed510SSoby Mathew	 * making use of the crash buf. This function will
200626ed510SSoby Mathew	 * not return.
201a43d431bSSoby Mathew	 * -----------------------------------------------------
202a43d431bSSoby Mathew	 */
203626ed510SSoby Mathewfunc report_unhandled_exception
204626ed510SSoby Mathew	prepare_crash_buf_save_x0_x1
205626ed510SSoby Mathew	adr	x0, excpt_msg
206626ed510SSoby Mathew	mov	sp, x0
207626ed510SSoby Mathew	/* This call will not return */
208626ed510SSoby Mathew	b	do_crash_reporting
2098b779620SKévin Petitendfunc report_unhandled_exception
210a43d431bSSoby Mathew
211626ed510SSoby Mathew	/* -----------------------------------------------------
212626ed510SSoby Mathew	 * This function allows to report a crash (if crash
213626ed510SSoby Mathew	 * reporting is enabled) when an unhandled interrupt
214626ed510SSoby Mathew	 * occurs. It prints the CPU state via the crash console
215626ed510SSoby Mathew	 * making use of the crash buf. This function will
216626ed510SSoby Mathew	 * not return.
217626ed510SSoby Mathew	 * -----------------------------------------------------
218626ed510SSoby Mathew	 */
219626ed510SSoby Mathewfunc report_unhandled_interrupt
220626ed510SSoby Mathew	prepare_crash_buf_save_x0_x1
221626ed510SSoby Mathew	adr	x0, intr_excpt_msg
222626ed510SSoby Mathew	mov	sp, x0
223626ed510SSoby Mathew	/* This call will not return */
224626ed510SSoby Mathew	b	do_crash_reporting
2258b779620SKévin Petitendfunc report_unhandled_interrupt
226a43d431bSSoby Mathew
227626ed510SSoby Mathew	/* -----------------------------------------------------
228b4292bc6SAlexei Fedorov	 * This function allows to report a crash from the lower
229b4292bc6SAlexei Fedorov	 * exception level (if crash reporting is enabled) when
2307e619eccSGovindraj Raja	 * lower_el_panic() is invoked from C Runtime.
231b4292bc6SAlexei Fedorov	 * It prints the CPU state via the crash console making
232b4292bc6SAlexei Fedorov	 * use of 'cpu_context' structure where general purpose
233b4292bc6SAlexei Fedorov	 * registers are saved and the crash buf.
234b4292bc6SAlexei Fedorov	 * This function will not return.
235b4292bc6SAlexei Fedorov	 * -----------------------------------------------------
236b4292bc6SAlexei Fedorov	 */
2377e619eccSGovindraj Rajafunc report_elx_panic
238b4292bc6SAlexei Fedorov	msr	spsel, #MODE_SP_ELX
239b4292bc6SAlexei Fedorov
240b4292bc6SAlexei Fedorov	/* Print the crash message */
241b4292bc6SAlexei Fedorov	adr	x4, excpt_msg_el
242b4292bc6SAlexei Fedorov	bl	asm_print_str
243b4292bc6SAlexei Fedorov
244b4292bc6SAlexei Fedorov	/* Report x0 - x29 values stored in 'gpregs_ctx' structure */
245b4292bc6SAlexei Fedorov	/* Store the ascii list pointer in x6 */
246b4292bc6SAlexei Fedorov	adr	x6, gp_regs
247b4292bc6SAlexei Fedorov	add	x7, sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0
248b4292bc6SAlexei Fedorov
249b4292bc6SAlexei Fedorovprint_next:
250b4292bc6SAlexei Fedorov	ldrb	w4, [x6]
251b4292bc6SAlexei Fedorov	/* Test whether we are at end of list */
252b4292bc6SAlexei Fedorov	cbz	w4, print_x30
253b4292bc6SAlexei Fedorov	mov	x4, x6
254b4292bc6SAlexei Fedorov	/* asm_print_str updates x4 to point to next entry in list */
255b4292bc6SAlexei Fedorov	bl	asm_print_str
256b4292bc6SAlexei Fedorov	/* x0 = number of symbols printed + 1 */
257b4292bc6SAlexei Fedorov	sub	x0, x4, x6
258b4292bc6SAlexei Fedorov	/* Update x6 with the updated list pointer */
259b4292bc6SAlexei Fedorov	mov	x6, x4
260b4292bc6SAlexei Fedorov	bl	print_alignment
261b4292bc6SAlexei Fedorov	ldr	x4, [x7], #REGSZ
262b4292bc6SAlexei Fedorov	bl	asm_print_hex
263b4292bc6SAlexei Fedorov	bl	asm_print_newline
264b4292bc6SAlexei Fedorov	b	print_next
265b4292bc6SAlexei Fedorov
266b4292bc6SAlexei Fedorovprint_x30:
267b4292bc6SAlexei Fedorov	adr	x4, x30_msg
268b4292bc6SAlexei Fedorov	bl	asm_print_str
269b4292bc6SAlexei Fedorov
270b4292bc6SAlexei Fedorov	/* Print spaces to align "x30" string */
271b4292bc6SAlexei Fedorov	mov	x0, #4
272b4292bc6SAlexei Fedorov	bl	print_alignment
273b4292bc6SAlexei Fedorov
274b4292bc6SAlexei Fedorov	/* Report x30 */
275b4292bc6SAlexei Fedorov	ldr	x4, [x7]
276b4292bc6SAlexei Fedorov
277b4292bc6SAlexei Fedorov	/* ----------------------------------------------------------------
278b4292bc6SAlexei Fedorov	 * Different virtual address space size can be defined for each EL.
279b4292bc6SAlexei Fedorov	 * Ensure that we use the proper one by reading the corresponding
280b4292bc6SAlexei Fedorov	 * TCR_ELx register.
281b4292bc6SAlexei Fedorov	 * ----------------------------------------------------------------
282b4292bc6SAlexei Fedorov	 */
283b4292bc6SAlexei Fedorov	cmp	x8, #MODE_EL2
284b4292bc6SAlexei Fedorov	b.lt	from_el1	/* EL1 */
285b4292bc6SAlexei Fedorov	mrs	x2, sctlr_el2
286b4292bc6SAlexei Fedorov	mrs	x1, tcr_el2
287b4292bc6SAlexei Fedorov
288b4292bc6SAlexei Fedorov	/* ----------------------------------------------------------------
289b4292bc6SAlexei Fedorov	 * Check if pointer authentication is enabled at the specified EL.
290b4292bc6SAlexei Fedorov	 * If it isn't, we can then skip stripping a PAC code.
291b4292bc6SAlexei Fedorov	 * ----------------------------------------------------------------
292b4292bc6SAlexei Fedorov	 */
293b4292bc6SAlexei Fedorovtest_pauth:
294b4292bc6SAlexei Fedorov	tst	x2, #(SCTLR_EnIA_BIT | SCTLR_EnIB_BIT)
295b4292bc6SAlexei Fedorov	b.eq	no_pauth
296b4292bc6SAlexei Fedorov
297b4292bc6SAlexei Fedorov	/* Demangle address */
298b4292bc6SAlexei Fedorov	and	x1, x1, #0x3F	/* T0SZ = TCR_ELx[5:0] */
299b4292bc6SAlexei Fedorov	sub	x1, x1, #64
300b4292bc6SAlexei Fedorov	neg	x1, x1		/* bottom_pac_bit = 64 - T0SZ */
301b4292bc6SAlexei Fedorov	mov	x2, #-1
302b4292bc6SAlexei Fedorov	lsl	x2, x2, x1
303b4292bc6SAlexei Fedorov	bic	x4, x4, x2
304b4292bc6SAlexei Fedorov
305b4292bc6SAlexei Fedorovno_pauth:
306b4292bc6SAlexei Fedorov	bl	asm_print_hex
307b4292bc6SAlexei Fedorov	bl	asm_print_newline
308b4292bc6SAlexei Fedorov
309b4292bc6SAlexei Fedorov	/* tpidr_el3 contains the address to cpu_data structure */
310*98859b99SSammit Joshi	per_cpu_cur percpu_data, x0, x2
311b4292bc6SAlexei Fedorov	/* Calculate the Crash buffer offset in cpu_data */
3124779becdSBoyan Karatotev	add	x0, x0, #CPU_DATA_CRASH_BUF
313b4292bc6SAlexei Fedorov	/* Store crash buffer address in tpidr_el3 */
314b4292bc6SAlexei Fedorov	msr	tpidr_el3, x0
315b4292bc6SAlexei Fedorov
316b4292bc6SAlexei Fedorov	/* Print the rest of crash dump */
317b4292bc6SAlexei Fedorov	b	print_el3_sys_regs
318b4292bc6SAlexei Fedorov
319b4292bc6SAlexei Fedorovfrom_el1:
320b4292bc6SAlexei Fedorov	mrs	x2, sctlr_el1
321b4292bc6SAlexei Fedorov	mrs	x1, tcr_el1
322b4292bc6SAlexei Fedorov	b	test_pauth
3237e619eccSGovindraj Rajaendfunc	report_elx_panic
324b4292bc6SAlexei Fedorov
325b4292bc6SAlexei Fedorov	/* -----------------------------------------------------
326626ed510SSoby Mathew	 * This function allows to report a crash (if crash
327626ed510SSoby Mathew	 * reporting is enabled) when panic() is invoked from
328626ed510SSoby Mathew	 * C Runtime. It prints the CPU state via the crash
329626ed510SSoby Mathew	 * console making use of the crash buf. This function
330626ed510SSoby Mathew	 * will not return.
331626ed510SSoby Mathew	 * -----------------------------------------------------
332626ed510SSoby Mathew	 */
333f300ef66SGovindraj Rajafunc report_el3_panic
3346c6a470fSAlexei Fedorov	msr	spsel, #MODE_SP_ELX
335626ed510SSoby Mathew	prepare_crash_buf_save_x0_x1
336626ed510SSoby Mathew	adr	x0, panic_msg
337626ed510SSoby Mathew	mov	sp, x0
338b4292bc6SAlexei Fedorov	/* Fall through to 'do_crash_reporting' */
339a43d431bSSoby Mathew
340626ed510SSoby Mathew	/* ------------------------------------------------------------
341626ed510SSoby Mathew	 * The common crash reporting functionality. It requires x0
342626ed510SSoby Mathew	 * and x1 has already been stored in crash buf, sp points to
343626ed510SSoby Mathew	 * crash message and tpidr_el3 contains the crash buf address.
344626ed510SSoby Mathew	 * The function does the following:
345626ed510SSoby Mathew	 *   - Retrieve the crash buffer from tpidr_el3
346626ed510SSoby Mathew	 *   - Store x2 to x6 in the crash buffer
347626ed510SSoby Mathew	 *   - Initialise the crash console.
348626ed510SSoby Mathew	 *   - Print the crash message by using the address in sp.
349626ed510SSoby Mathew	 *   - Print x30 value to the crash console.
350626ed510SSoby Mathew	 *   - Print x0 - x7 from the crash buf to the crash console.
351626ed510SSoby Mathew	 *   - Print x8 - x29 (in groups of 8 registers) using the
352626ed510SSoby Mathew	 *     crash buf to the crash console.
353626ed510SSoby Mathew	 *   - Print el3 sys regs (in groups of 8 registers) using the
354626ed510SSoby Mathew	 *     crash buf to the crash console.
355626ed510SSoby Mathew	 *   - Print non el3 sys regs (in groups of 8 registers) using
35658fadd62SIgor Podgainõi	 *     the crash buf to the crash console. A group may be
35758fadd62SIgor Podgainõi	 *     interrupted in case a potential group of 128-bit
35858fadd62SIgor Podgainõi	 *     sys regs needs to be printed.
359626ed510SSoby Mathew	 * ------------------------------------------------------------
360626ed510SSoby Mathew	 */
361b4292bc6SAlexei Fedorovdo_crash_reporting:
362626ed510SSoby Mathew	/* Retrieve the crash buf from tpidr_el3 */
363626ed510SSoby Mathew	mrs	x0, tpidr_el3
364626ed510SSoby Mathew	/* Store x2 - x6, x30 in the crash buffer */
365155a1006SJulius Werner	stp	x2, x3, [x0, #REGSZ * 2]
366155a1006SJulius Werner	stp	x4, x5, [x0, #REGSZ * 4]
367155a1006SJulius Werner	stp	x6, x30, [x0, #REGSZ * 6]
368626ed510SSoby Mathew	/* Initialize the crash console */
369626ed510SSoby Mathew	bl	plat_crash_console_init
370626ed510SSoby Mathew	/* Verify the console is initialized */
371626ed510SSoby Mathew	cbz	x0, crash_panic
372626ed510SSoby Mathew	/* Print the crash message. sp points to the crash message */
373626ed510SSoby Mathew	mov	x4, sp
374626ed510SSoby Mathew	bl	asm_print_str
3756c6a470fSAlexei Fedorov	/* Print spaces to align "x30" string */
3766c6a470fSAlexei Fedorov	mov	x0, #4
3776c6a470fSAlexei Fedorov	bl	print_alignment
378b4292bc6SAlexei Fedorov	/* Load the crash buf address */
379626ed510SSoby Mathew	mrs	x0, tpidr_el3
380b4292bc6SAlexei Fedorov	/* Report x30 first from the crash buf */
381155a1006SJulius Werner	ldr	x4, [x0, #REGSZ * 7]
38268c76088SAlexei Fedorov
38368c76088SAlexei Fedorov#if ENABLE_PAUTH
3848d9f5f25SBoyan Karatotev#if ENABLE_PAUTH == 2
3858d9f5f25SBoyan Karatotev	/* Skip if not present in hardware */
3868d9f5f25SBoyan Karatotev	is_feat_pauth_present_asm x0, x1
3878d9f5f25SBoyan Karatotev	beq	1f
3888d9f5f25SBoyan Karatotev#endif
3898d9f5f25SBoyan Karatotev	/*
3908d9f5f25SBoyan Karatotev	 * The assembler must see support for xpaci. So turn the compiler
3918d9f5f25SBoyan Karatotev	 * extension on. GCC prior to 10 doesn't understand the PAuth extension
3928d9f5f25SBoyan Karatotev	 * but it does understand armv8.3-a in general. Avoid using 8.3 if
3938d9f5f25SBoyan Karatotev	 * the compiler understands "pauth" so we don't downgrade a higher
3948d9f5f25SBoyan Karatotev	 * -march that was specified on the commandline.
3958d9f5f25SBoyan Karatotev	 */
3968d9f5f25SBoyan Karatotev#if __GNUC__ < 10
3978d9f5f25SBoyan Karatotev	.arch armv8.3-a
3988d9f5f25SBoyan Karatotev#else
3998d9f5f25SBoyan Karatotev	.arch_extension pauth
4008d9f5f25SBoyan Karatotev#endif
40168c76088SAlexei Fedorov	/* Demangle address */
40268c76088SAlexei Fedorov	xpaci	x4
4038d9f5f25SBoyan Karatotev1:
40468c76088SAlexei Fedorov#endif
405626ed510SSoby Mathew	bl	asm_print_hex
40653d7e003SJustin Chadwell	bl	asm_print_newline
407626ed510SSoby Mathew	/* Load the crash buf address */
408626ed510SSoby Mathew	mrs	x0, tpidr_el3
409626ed510SSoby Mathew	/* Now mov x7 into crash buf */
410155a1006SJulius Werner	str	x7, [x0, #REGSZ * 7]
411a43d431bSSoby Mathew
412626ed510SSoby Mathew	/* Report x0 - x29 values stored in crash buf */
413626ed510SSoby Mathew	/* Store the ascii list pointer in x6 */
414626ed510SSoby Mathew	adr	x6, gp_regs
415626ed510SSoby Mathew	/* Print x0 to x7 from the crash buf */
416626ed510SSoby Mathew	bl	size_controlled_print
417626ed510SSoby Mathew	/* Store x8 - x15 in crash buf and print */
418626ed510SSoby Mathew	bl	str_in_crash_buf_print
419626ed510SSoby Mathew	/* Load the crash buf address */
420626ed510SSoby Mathew	mrs	x0, tpidr_el3
421626ed510SSoby Mathew	/* Store the rest of gp regs and print */
422626ed510SSoby Mathew	stp	x16, x17, [x0]
423155a1006SJulius Werner	stp	x18, x19, [x0, #REGSZ * 2]
424155a1006SJulius Werner	stp	x20, x21, [x0, #REGSZ * 4]
425155a1006SJulius Werner	stp	x22, x23, [x0, #REGSZ * 6]
426626ed510SSoby Mathew	bl	size_controlled_print
427626ed510SSoby Mathew	/* Load the crash buf address */
428626ed510SSoby Mathew	mrs	x0, tpidr_el3
429626ed510SSoby Mathew	stp	x24, x25, [x0]
430155a1006SJulius Werner	stp	x26, x27, [x0, #REGSZ * 2]
431155a1006SJulius Werner	stp	x28, x29, [x0, #REGSZ * 4]
432626ed510SSoby Mathew	bl	size_controlled_print
433a43d431bSSoby Mathew
434626ed510SSoby Mathew	/* Print the el3 sys registers */
435b4292bc6SAlexei Fedorovprint_el3_sys_regs:
436626ed510SSoby Mathew	adr	x6, el3_sys_regs
437626ed510SSoby Mathew	mrs	x8, scr_el3
438626ed510SSoby Mathew	mrs	x9, sctlr_el3
439626ed510SSoby Mathew	mrs	x10, cptr_el3
440626ed510SSoby Mathew	mrs	x11, tcr_el3
441626ed510SSoby Mathew	mrs	x12, daif
442626ed510SSoby Mathew	mrs	x13, mair_el3
443626ed510SSoby Mathew	mrs	x14, spsr_el3
444626ed510SSoby Mathew	mrs	x15, elr_el3
445626ed510SSoby Mathew	bl	str_in_crash_buf_print
446626ed510SSoby Mathew	mrs	x8, ttbr0_el3
447626ed510SSoby Mathew	mrs	x9, esr_el3
448626ed510SSoby Mathew	mrs	x10, far_el3
449626ed510SSoby Mathew	bl	str_in_crash_buf_print
450a43d431bSSoby Mathew
451626ed510SSoby Mathew	/* Print the non el3 sys registers */
4528f152319SBoyan Karatotev	adr	x6, non_el3_sys_regs
45358fadd62SIgor Podgainõi	mrs	x8, mpidr_el1
4548f152319SBoyan Karatotev	mrs	x9, sp_el0
4558f152319SBoyan Karatotev	mrs	x10, isr_el1
456626ed510SSoby Mathew	bl	str_in_crash_buf_print
457a43d431bSSoby Mathew
458c424b91eSImre Kis#if CTX_INCLUDE_AARCH32_REGS
459c424b91eSImre Kis	/* Print the AArch32 registers */
460c424b91eSImre Kis	adr	x6, aarch32_regs
461c424b91eSImre Kis	mrs	x8, dacr32_el2
462c424b91eSImre Kis	mrs	x9, ifsr32_el2
463c424b91eSImre Kis	bl	str_in_crash_buf_print
464c424b91eSImre Kis#endif /* CTX_INCLUDE_AARCH32_REGS */
465c424b91eSImre Kis
466d3f70af6SSoby Mathew	/* Get the cpu specific registers to report */
467d3f70af6SSoby Mathew	bl	do_cpu_reg_dump
468d3f70af6SSoby Mathew	bl	str_in_crash_buf_print
4698c106902SSoby Mathew
4709ff67fa6SGerald Lejeune	/* Print some platform registers */
4719ff67fa6SGerald Lejeune	plat_crash_print_regs
4728c106902SSoby Mathew
473801cf93cSAntonio Nino Diaz	bl	plat_crash_console_flush
474801cf93cSAntonio Nino Diaz
475626ed510SSoby Mathew	/* Done reporting */
476a806dad5SJeenu Viswambharan	no_ret	plat_panic_handler
477f300ef66SGovindraj Rajaendfunc report_el3_panic
478a43d431bSSoby Mathew
479626ed510SSoby Mathew#else	/* CRASH_REPORTING */
480626ed510SSoby Mathewfunc report_unhandled_exception
481626ed510SSoby Mathewreport_unhandled_interrupt:
482a806dad5SJeenu Viswambharan	no_ret	plat_panic_handler
4838b779620SKévin Petitendfunc report_unhandled_exception
4841645d3eeSSandrine Bailleux#endif	/* CRASH_REPORTING */
4859c22b323SAndrew Thoelke
486626ed510SSoby Mathewfunc crash_panic
487a806dad5SJeenu Viswambharan	no_ret	plat_panic_handler
4888b779620SKévin Petitendfunc crash_panic
489