xref: /rk3399_ARM-atf/bl31/aarch64/crash_reporting.S (revision 09d40e0e08283a249e7dce0e106c07c5141f9b7e)
1a43d431bSSoby Mathew/*
2801cf93cSAntonio Nino Diaz * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
3a43d431bSSoby Mathew *
482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
5a43d431bSSoby Mathew */
6*09d40e0eSAntonio Nino Diaz
7*09d40e0eSAntonio Nino Diaz#include <plat_macros.S>
8*09d40e0eSAntonio Nino Diaz#include <platform_def.h>
9*09d40e0eSAntonio Nino Diaz
10a43d431bSSoby Mathew#include <arch.h>
11a43d431bSSoby Mathew#include <asm_macros.S>
12a43d431bSSoby Mathew#include <context.h>
13*09d40e0eSAntonio Nino Diaz#include <lib/el3_runtime/cpu_data.h>
14*09d40e0eSAntonio Nino Diaz#include <lib/utils_def.h>
15a43d431bSSoby Mathew
16626ed510SSoby Mathew	.globl	report_unhandled_exception
17626ed510SSoby Mathew	.globl	report_unhandled_interrupt
18626ed510SSoby Mathew	.globl	el3_panic
19a43d431bSSoby Mathew
209c22b323SAndrew Thoelke#if CRASH_REPORTING
21626ed510SSoby Mathew
22a43d431bSSoby Mathew	/* ------------------------------------------------------
23a43d431bSSoby Mathew	 * The below section deals with dumping the system state
24a43d431bSSoby Mathew	 * when an unhandled exception is taken in EL3.
25a43d431bSSoby Mathew	 * The layout and the names of the registers which will
26a43d431bSSoby Mathew	 * be dumped during a unhandled exception is given below.
27a43d431bSSoby Mathew	 * ------------------------------------------------------
28a43d431bSSoby Mathew	 */
29626ed510SSoby Mathew.section .rodata.crash_prints, "aS"
30626ed510SSoby Mathewprint_spacer:
31626ed510SSoby Mathew	.asciz	" =\t\t0x"
32a43d431bSSoby Mathew
33626ed510SSoby Mathewgp_regs:
34626ed510SSoby Mathew	.asciz	"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",\
35626ed510SSoby Mathew		"x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",\
36626ed510SSoby Mathew		"x16", "x17", "x18", "x19", "x20", "x21", "x22",\
37626ed510SSoby Mathew		"x23", "x24", "x25", "x26", "x27", "x28", "x29", ""
38626ed510SSoby Mathewel3_sys_regs:
39626ed510SSoby Mathew	.asciz	"scr_el3", "sctlr_el3", "cptr_el3", "tcr_el3",\
40626ed510SSoby Mathew		"daif", "mair_el3", "spsr_el3", "elr_el3", "ttbr0_el3",\
41626ed510SSoby Mathew		"esr_el3", "far_el3", ""
42a43d431bSSoby Mathew
43626ed510SSoby Mathewnon_el3_sys_regs:
44626ed510SSoby Mathew	.asciz	"spsr_el1", "elr_el1", "spsr_abt", "spsr_und",\
45a43d431bSSoby Mathew		"spsr_irq", "spsr_fiq", "sctlr_el1", "actlr_el1", "cpacr_el1",\
46a43d431bSSoby Mathew		"csselr_el1", "sp_el1", "esr_el1", "ttbr0_el1", "ttbr1_el1",\
47626ed510SSoby Mathew		"mair_el1", "amair_el1", "tcr_el1", "tpidr_el1", "tpidr_el0",\
48626ed510SSoby Mathew		"tpidrro_el0", "dacr32_el2", "ifsr32_el2", "par_el1",\
49626ed510SSoby Mathew		"mpidr_el1", "afsr0_el1", "afsr1_el1", "contextidr_el1",\
50626ed510SSoby Mathew		"vbar_el1", "cntp_ctl_el0", "cntp_cval_el0", "cntv_ctl_el0",\
5191089f36SDavid Cunado		"cntv_cval_el0", "cntkctl_el1", "sp_el0", "isr_el1", ""
52a43d431bSSoby Mathew
53626ed510SSoby Mathewpanic_msg:
54626ed510SSoby Mathew	.asciz "PANIC in EL3 at x30 = 0x"
55626ed510SSoby Mathewexcpt_msg:
56626ed510SSoby Mathew	.asciz "Unhandled Exception in EL3.\nx30 =\t\t0x"
57626ed510SSoby Mathewintr_excpt_msg:
58626ed510SSoby Mathew	.asciz "Unhandled Interrupt Exception in EL3.\nx30 =\t\t0x"
59626ed510SSoby Mathew
60626ed510SSoby Mathew	/*
61626ed510SSoby Mathew	 * Helper function to print newline to console.
62626ed510SSoby Mathew	 */
63626ed510SSoby Mathewfunc print_newline
64626ed510SSoby Mathew	mov	x0, '\n'
65626ed510SSoby Mathew	b	plat_crash_console_putc
668b779620SKévin Petitendfunc print_newline
67626ed510SSoby Mathew
68626ed510SSoby Mathew	/*
69626ed510SSoby Mathew	 * Helper function to print from crash buf.
70626ed510SSoby Mathew	 * The print loop is controlled by the buf size and
71626ed510SSoby Mathew	 * ascii reg name list which is passed in x6. The
72626ed510SSoby Mathew	 * function returns the crash buf address in x0.
73626ed510SSoby Mathew	 * Clobbers : x0 - x7, sp
74626ed510SSoby Mathew	 */
75626ed510SSoby Mathewfunc size_controlled_print
76626ed510SSoby Mathew	/* Save the lr */
77626ed510SSoby Mathew	mov	sp, x30
78626ed510SSoby Mathew	/* load the crash buf address */
79626ed510SSoby Mathew	mrs	x7, tpidr_el3
80626ed510SSoby Mathewtest_size_list:
81626ed510SSoby Mathew	/* Calculate x5 always as it will be clobbered by asm_print_hex */
82626ed510SSoby Mathew	mrs	x5, tpidr_el3
83626ed510SSoby Mathew	add	x5, x5, #CPU_DATA_CRASH_BUF_SIZE
84626ed510SSoby Mathew	/* Test whether we have reached end of crash buf */
85626ed510SSoby Mathew	cmp	x7, x5
86626ed510SSoby Mathew	b.eq	exit_size_print
87626ed510SSoby Mathew	ldrb	w4, [x6]
88626ed510SSoby Mathew	/* Test whether we are at end of list */
89626ed510SSoby Mathew	cbz	w4, exit_size_print
90626ed510SSoby Mathew	mov	x4, x6
91626ed510SSoby Mathew	/* asm_print_str updates x4 to point to next entry in list */
92626ed510SSoby Mathew	bl	asm_print_str
93626ed510SSoby Mathew	/* update x6 with the updated list pointer */
94626ed510SSoby Mathew	mov	x6, x4
95626ed510SSoby Mathew	adr	x4, print_spacer
96626ed510SSoby Mathew	bl	asm_print_str
97155a1006SJulius Werner	ldr	x4, [x7], #REGSZ
98626ed510SSoby Mathew	bl	asm_print_hex
99626ed510SSoby Mathew	bl	print_newline
100626ed510SSoby Mathew	b	test_size_list
101626ed510SSoby Mathewexit_size_print:
102626ed510SSoby Mathew	mov	x30, sp
103626ed510SSoby Mathew	ret
1048b779620SKévin Petitendfunc size_controlled_print
105626ed510SSoby Mathew
106626ed510SSoby Mathew	/*
107626ed510SSoby Mathew	 * Helper function to store x8 - x15 registers to
108626ed510SSoby Mathew	 * the crash buf. The system registers values are
109626ed510SSoby Mathew	 * copied to x8 to x15 by the caller which are then
110626ed510SSoby Mathew	 * copied to the crash buf by this function.
111626ed510SSoby Mathew	 * x0 points to the crash buf. It then calls
112626ed510SSoby Mathew	 * size_controlled_print to print to console.
113626ed510SSoby Mathew	 * Clobbers : x0 - x7, sp
114626ed510SSoby Mathew	 */
115626ed510SSoby Mathewfunc str_in_crash_buf_print
116626ed510SSoby Mathew	/* restore the crash buf address in x0 */
117626ed510SSoby Mathew	mrs	x0, tpidr_el3
118626ed510SSoby Mathew	stp	x8, x9, [x0]
119155a1006SJulius Werner	stp	x10, x11, [x0, #REGSZ * 2]
120155a1006SJulius Werner	stp	x12, x13, [x0, #REGSZ * 4]
121155a1006SJulius Werner	stp	x14, x15, [x0, #REGSZ * 6]
122626ed510SSoby Mathew	b	size_controlled_print
1238b779620SKévin Petitendfunc str_in_crash_buf_print
124626ed510SSoby Mathew
125626ed510SSoby Mathew	/* ------------------------------------------------------
126626ed510SSoby Mathew	 * This macro calculates the offset to crash buf from
127626ed510SSoby Mathew	 * cpu_data and stores it in tpidr_el3. It also saves x0
128626ed510SSoby Mathew	 * and x1 in the crash buf by using sp as a temporary
129626ed510SSoby Mathew	 * register.
130626ed510SSoby Mathew	 * ------------------------------------------------------
131626ed510SSoby Mathew	 */
132626ed510SSoby Mathew	.macro prepare_crash_buf_save_x0_x1
133626ed510SSoby Mathew	/* we can corrupt this reg to free up x0 */
134626ed510SSoby Mathew	mov	sp, x0
135626ed510SSoby Mathew	/* tpidr_el3 contains the address to cpu_data structure */
136626ed510SSoby Mathew	mrs	x0, tpidr_el3
137626ed510SSoby Mathew	/* Calculate the Crash buffer offset in cpu_data */
138626ed510SSoby Mathew	add	x0, x0, #CPU_DATA_CRASH_BUF_OFFSET
139626ed510SSoby Mathew	/* Store crash buffer address in tpidr_el3 */
140626ed510SSoby Mathew	msr	tpidr_el3, x0
141155a1006SJulius Werner	str	x1, [x0, #REGSZ]
142626ed510SSoby Mathew	mov	x1, sp
143626ed510SSoby Mathew	str	x1, [x0]
144626ed510SSoby Mathew	.endm
145a43d431bSSoby Mathew
146a43d431bSSoby Mathew	/* -----------------------------------------------------
147626ed510SSoby Mathew	 * This function allows to report a crash (if crash
148626ed510SSoby Mathew	 * reporting is enabled) when an unhandled exception
149626ed510SSoby Mathew	 * occurs. It prints the CPU state via the crash console
150626ed510SSoby Mathew	 * making use of the crash buf. This function will
151626ed510SSoby Mathew	 * not return.
152a43d431bSSoby Mathew	 * -----------------------------------------------------
153a43d431bSSoby Mathew	 */
154626ed510SSoby Mathewfunc report_unhandled_exception
155626ed510SSoby Mathew	prepare_crash_buf_save_x0_x1
156626ed510SSoby Mathew	adr	x0, excpt_msg
157626ed510SSoby Mathew	mov	sp, x0
158626ed510SSoby Mathew	/* This call will not return */
159626ed510SSoby Mathew	b	do_crash_reporting
1608b779620SKévin Petitendfunc report_unhandled_exception
161a43d431bSSoby Mathew
162a43d431bSSoby Mathew
163626ed510SSoby Mathew	/* -----------------------------------------------------
164626ed510SSoby Mathew	 * This function allows to report a crash (if crash
165626ed510SSoby Mathew	 * reporting is enabled) when an unhandled interrupt
166626ed510SSoby Mathew	 * occurs. It prints the CPU state via the crash console
167626ed510SSoby Mathew	 * making use of the crash buf. This function will
168626ed510SSoby Mathew	 * not return.
169626ed510SSoby Mathew	 * -----------------------------------------------------
170626ed510SSoby Mathew	 */
171626ed510SSoby Mathewfunc report_unhandled_interrupt
172626ed510SSoby Mathew	prepare_crash_buf_save_x0_x1
173626ed510SSoby Mathew	adr	x0, intr_excpt_msg
174626ed510SSoby Mathew	mov	sp, x0
175626ed510SSoby Mathew	/* This call will not return */
176626ed510SSoby Mathew	b	do_crash_reporting
1778b779620SKévin Petitendfunc report_unhandled_interrupt
178a43d431bSSoby Mathew
179626ed510SSoby Mathew	/* -----------------------------------------------------
180626ed510SSoby Mathew	 * This function allows to report a crash (if crash
181626ed510SSoby Mathew	 * reporting is enabled) when panic() is invoked from
182626ed510SSoby Mathew	 * C Runtime. It prints the CPU state via the crash
183626ed510SSoby Mathew	 * console making use of the crash buf. This function
184626ed510SSoby Mathew	 * will not return.
185626ed510SSoby Mathew	 * -----------------------------------------------------
186626ed510SSoby Mathew	 */
187626ed510SSoby Mathewfunc el3_panic
188626ed510SSoby Mathew	msr	spsel, #1
189626ed510SSoby Mathew	prepare_crash_buf_save_x0_x1
190626ed510SSoby Mathew	adr	x0, panic_msg
191626ed510SSoby Mathew	mov	sp, x0
192626ed510SSoby Mathew	/* This call will not return */
193626ed510SSoby Mathew	b	do_crash_reporting
1948b779620SKévin Petitendfunc el3_panic
195a43d431bSSoby Mathew
196626ed510SSoby Mathew	/* ------------------------------------------------------------
197626ed510SSoby Mathew	 * The common crash reporting functionality. It requires x0
198626ed510SSoby Mathew	 * and x1 has already been stored in crash buf, sp points to
199626ed510SSoby Mathew	 * crash message and tpidr_el3 contains the crash buf address.
200626ed510SSoby Mathew	 * The function does the following:
201626ed510SSoby Mathew	 *   - Retrieve the crash buffer from tpidr_el3
202626ed510SSoby Mathew	 *   - Store x2 to x6 in the crash buffer
203626ed510SSoby Mathew	 *   - Initialise the crash console.
204626ed510SSoby Mathew	 *   - Print the crash message by using the address in sp.
205626ed510SSoby Mathew	 *   - Print x30 value to the crash console.
206626ed510SSoby Mathew	 *   - Print x0 - x7 from the crash buf to the crash console.
207626ed510SSoby Mathew	 *   - Print x8 - x29 (in groups of 8 registers) using the
208626ed510SSoby Mathew	 *     crash buf to the crash console.
209626ed510SSoby Mathew	 *   - Print el3 sys regs (in groups of 8 registers) using the
210626ed510SSoby Mathew	 *     crash buf to the crash console.
211626ed510SSoby Mathew	 *   - Print non el3 sys regs (in groups of 8 registers) using
212626ed510SSoby Mathew	 *     the crash buf to the crash console.
213626ed510SSoby Mathew	 * ------------------------------------------------------------
214626ed510SSoby Mathew	 */
215626ed510SSoby Mathewfunc do_crash_reporting
216626ed510SSoby Mathew	/* Retrieve the crash buf from tpidr_el3 */
217626ed510SSoby Mathew	mrs	x0, tpidr_el3
218626ed510SSoby Mathew	/* Store x2 - x6, x30 in the crash buffer */
219155a1006SJulius Werner	stp	x2, x3, [x0, #REGSZ * 2]
220155a1006SJulius Werner	stp	x4, x5, [x0, #REGSZ * 4]
221155a1006SJulius Werner	stp	x6, x30, [x0, #REGSZ * 6]
222626ed510SSoby Mathew	/* Initialize the crash console */
223626ed510SSoby Mathew	bl	plat_crash_console_init
224626ed510SSoby Mathew	/* Verify the console is initialized */
225626ed510SSoby Mathew	cbz	x0, crash_panic
226626ed510SSoby Mathew	/* Print the crash message. sp points to the crash message */
227626ed510SSoby Mathew	mov	x4, sp
228626ed510SSoby Mathew	bl	asm_print_str
229626ed510SSoby Mathew	/* load the crash buf address */
230626ed510SSoby Mathew	mrs	x0, tpidr_el3
231626ed510SSoby Mathew	/* report x30 first from the crash buf */
232155a1006SJulius Werner	ldr	x4, [x0, #REGSZ * 7]
233626ed510SSoby Mathew	bl	asm_print_hex
234626ed510SSoby Mathew	bl	print_newline
235626ed510SSoby Mathew	/* Load the crash buf address */
236626ed510SSoby Mathew	mrs	x0, tpidr_el3
237626ed510SSoby Mathew	/* Now mov x7 into crash buf */
238155a1006SJulius Werner	str	x7, [x0, #REGSZ * 7]
239a43d431bSSoby Mathew
240626ed510SSoby Mathew	/* Report x0 - x29 values stored in crash buf*/
241626ed510SSoby Mathew	/* Store the ascii list pointer in x6 */
242626ed510SSoby Mathew	adr	x6, gp_regs
243626ed510SSoby Mathew	/* Print x0 to x7 from the crash buf */
244626ed510SSoby Mathew	bl	size_controlled_print
245626ed510SSoby Mathew	/* Store x8 - x15 in crash buf and print */
246626ed510SSoby Mathew	bl	str_in_crash_buf_print
247626ed510SSoby Mathew	/* Load the crash buf address */
248626ed510SSoby Mathew	mrs	x0, tpidr_el3
249626ed510SSoby Mathew	/* Store the rest of gp regs and print */
250626ed510SSoby Mathew	stp	x16, x17, [x0]
251155a1006SJulius Werner	stp	x18, x19, [x0, #REGSZ * 2]
252155a1006SJulius Werner	stp	x20, x21, [x0, #REGSZ * 4]
253155a1006SJulius Werner	stp	x22, x23, [x0, #REGSZ * 6]
254626ed510SSoby Mathew	bl	size_controlled_print
255626ed510SSoby Mathew	/* Load the crash buf address */
256626ed510SSoby Mathew	mrs	x0, tpidr_el3
257626ed510SSoby Mathew	stp	x24, x25, [x0]
258155a1006SJulius Werner	stp	x26, x27, [x0, #REGSZ * 2]
259155a1006SJulius Werner	stp	x28, x29, [x0, #REGSZ * 4]
260626ed510SSoby Mathew	bl	size_controlled_print
261a43d431bSSoby Mathew
262626ed510SSoby Mathew	/* Print the el3 sys registers */
263626ed510SSoby Mathew	adr	x6, el3_sys_regs
264626ed510SSoby Mathew	mrs	x8, scr_el3
265626ed510SSoby Mathew	mrs	x9, sctlr_el3
266626ed510SSoby Mathew	mrs	x10, cptr_el3
267626ed510SSoby Mathew	mrs	x11, tcr_el3
268626ed510SSoby Mathew	mrs	x12, daif
269626ed510SSoby Mathew	mrs	x13, mair_el3
270626ed510SSoby Mathew	mrs	x14, spsr_el3
271626ed510SSoby Mathew	mrs	x15, elr_el3
272626ed510SSoby Mathew	bl	str_in_crash_buf_print
273626ed510SSoby Mathew	mrs	x8, ttbr0_el3
274626ed510SSoby Mathew	mrs	x9, esr_el3
275626ed510SSoby Mathew	mrs	x10, far_el3
276626ed510SSoby Mathew	bl	str_in_crash_buf_print
277a43d431bSSoby Mathew
278626ed510SSoby Mathew	/* Print the non el3 sys registers */
279626ed510SSoby Mathew	adr	x6, non_el3_sys_regs
280626ed510SSoby Mathew	mrs	x8, spsr_el1
281626ed510SSoby Mathew	mrs	x9, elr_el1
282626ed510SSoby Mathew	mrs	x10, spsr_abt
283626ed510SSoby Mathew	mrs	x11, spsr_und
284626ed510SSoby Mathew	mrs	x12, spsr_irq
285626ed510SSoby Mathew	mrs	x13, spsr_fiq
286626ed510SSoby Mathew	mrs	x14, sctlr_el1
287626ed510SSoby Mathew	mrs	x15, actlr_el1
288626ed510SSoby Mathew	bl	str_in_crash_buf_print
289626ed510SSoby Mathew	mrs	x8, cpacr_el1
290626ed510SSoby Mathew	mrs	x9, csselr_el1
291a43d431bSSoby Mathew	mrs	x10, sp_el1
292a43d431bSSoby Mathew	mrs	x11, esr_el1
293a43d431bSSoby Mathew	mrs	x12, ttbr0_el1
294a43d431bSSoby Mathew	mrs	x13, ttbr1_el1
295a43d431bSSoby Mathew	mrs	x14, mair_el1
296a43d431bSSoby Mathew	mrs	x15, amair_el1
297626ed510SSoby Mathew	bl	str_in_crash_buf_print
298626ed510SSoby Mathew	mrs	x8, tcr_el1
299626ed510SSoby Mathew	mrs	x9, tpidr_el1
300626ed510SSoby Mathew	mrs	x10, tpidr_el0
301626ed510SSoby Mathew	mrs	x11, tpidrro_el0
302626ed510SSoby Mathew	mrs	x12, dacr32_el2
303626ed510SSoby Mathew	mrs	x13, ifsr32_el2
304626ed510SSoby Mathew	mrs	x14, par_el1
305626ed510SSoby Mathew	mrs	x15, mpidr_el1
306626ed510SSoby Mathew	bl	str_in_crash_buf_print
307626ed510SSoby Mathew	mrs	x8, afsr0_el1
308626ed510SSoby Mathew	mrs	x9, afsr1_el1
309626ed510SSoby Mathew	mrs	x10, contextidr_el1
310626ed510SSoby Mathew	mrs	x11, vbar_el1
311626ed510SSoby Mathew	mrs	x12, cntp_ctl_el0
312626ed510SSoby Mathew	mrs	x13, cntp_cval_el0
313626ed510SSoby Mathew	mrs	x14, cntv_ctl_el0
314626ed510SSoby Mathew	mrs	x15, cntv_cval_el0
315626ed510SSoby Mathew	bl	str_in_crash_buf_print
316626ed510SSoby Mathew	mrs	x8, cntkctl_el1
31791089f36SDavid Cunado	mrs	x9, sp_el0
31891089f36SDavid Cunado	mrs	x10, isr_el1
319626ed510SSoby Mathew	bl	str_in_crash_buf_print
320a43d431bSSoby Mathew
321d3f70af6SSoby Mathew	/* Get the cpu specific registers to report */
322d3f70af6SSoby Mathew	bl	do_cpu_reg_dump
323d3f70af6SSoby Mathew	bl	str_in_crash_buf_print
3248c106902SSoby Mathew
3259ff67fa6SGerald Lejeune	/* Print some platform registers */
3269ff67fa6SGerald Lejeune	plat_crash_print_regs
3278c106902SSoby Mathew
328801cf93cSAntonio Nino Diaz	bl	plat_crash_console_flush
329801cf93cSAntonio Nino Diaz
330626ed510SSoby Mathew	/* Done reporting */
331a806dad5SJeenu Viswambharan	no_ret	plat_panic_handler
3328b779620SKévin Petitendfunc do_crash_reporting
333a43d431bSSoby Mathew
334626ed510SSoby Mathew#else	/* CRASH_REPORTING */
335626ed510SSoby Mathewfunc report_unhandled_exception
336626ed510SSoby Mathewreport_unhandled_interrupt:
337a806dad5SJeenu Viswambharan	no_ret	plat_panic_handler
3388b779620SKévin Petitendfunc report_unhandled_exception
3391645d3eeSSandrine Bailleux#endif	/* CRASH_REPORTING */
3409c22b323SAndrew Thoelke
341a43d431bSSoby Mathew
342626ed510SSoby Mathewfunc crash_panic
343a806dad5SJeenu Viswambharan	no_ret	plat_panic_handler
3448b779620SKévin Petitendfunc crash_panic
345