blob: b3f59796c376afea69d25e96334e38d75da1a3f1 [file] [log] [blame]
Soby Mathew5e5c2072014-04-07 15:28:55 +01001/*
Antonio Nino Diazd3ec5432017-02-17 17:11:27 +00002 * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
Soby Mathew5e5c2072014-04-07 15:28:55 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Soby Mathew5e5c2072014-04-07 15:28:55 +01005 */
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00006
7#include <plat_macros.S>
8#include <platform_def.h>
9
Soby Mathew5e5c2072014-04-07 15:28:55 +010010#include <arch.h>
11#include <asm_macros.S>
12#include <context.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000013#include <lib/el3_runtime/cpu_data.h>
14#include <lib/utils_def.h>
Soby Mathew5e5c2072014-04-07 15:28:55 +010015
Soby Mathewc1adbbc2014-06-25 10:07:40 +010016 .globl report_unhandled_exception
17 .globl report_unhandled_interrupt
18 .globl el3_panic
Soby Mathew5e5c2072014-04-07 15:28:55 +010019
Andrew Thoelke385f4d42014-06-03 11:50:53 +010020#if CRASH_REPORTING
Soby Mathewc1adbbc2014-06-25 10:07:40 +010021
Soby Mathew5e5c2072014-04-07 15:28:55 +010022 /* ------------------------------------------------------
23 * The below section deals with dumping the system state
24 * when an unhandled exception is taken in EL3.
25 * The layout and the names of the registers which will
26 * be dumped during a unhandled exception is given below.
27 * ------------------------------------------------------
28 */
Soby Mathewc1adbbc2014-06-25 10:07:40 +010029.section .rodata.crash_prints, "aS"
30print_spacer:
31 .asciz " =\t\t0x"
Soby Mathew5e5c2072014-04-07 15:28:55 +010032
Soby Mathewc1adbbc2014-06-25 10:07:40 +010033gp_regs:
34 .asciz "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",\
35 "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",\
36 "x16", "x17", "x18", "x19", "x20", "x21", "x22",\
37 "x23", "x24", "x25", "x26", "x27", "x28", "x29", ""
38el3_sys_regs:
39 .asciz "scr_el3", "sctlr_el3", "cptr_el3", "tcr_el3",\
40 "daif", "mair_el3", "spsr_el3", "elr_el3", "ttbr0_el3",\
41 "esr_el3", "far_el3", ""
Soby Mathew5e5c2072014-04-07 15:28:55 +010042
Soby Mathewc1adbbc2014-06-25 10:07:40 +010043non_el3_sys_regs:
44 .asciz "spsr_el1", "elr_el1", "spsr_abt", "spsr_und",\
45 "spsr_irq", "spsr_fiq", "sctlr_el1", "actlr_el1", "cpacr_el1",\
46 "csselr_el1", "sp_el1", "esr_el1", "ttbr0_el1", "ttbr1_el1",\
47 "mair_el1", "amair_el1", "tcr_el1", "tpidr_el1", "tpidr_el0",\
48 "tpidrro_el0", "dacr32_el2", "ifsr32_el2", "par_el1",\
49 "mpidr_el1", "afsr0_el1", "afsr1_el1", "contextidr_el1",\
50 "vbar_el1", "cntp_ctl_el0", "cntp_cval_el0", "cntv_ctl_el0",\
David Cunadod1a1fd42017-10-20 11:30:57 +010051 "cntv_cval_el0", "cntkctl_el1", "sp_el0", "isr_el1", ""
Soby Mathew5e5c2072014-04-07 15:28:55 +010052
Soby Mathewc1adbbc2014-06-25 10:07:40 +010053panic_msg:
54 .asciz "PANIC in EL3 at x30 = 0x"
55excpt_msg:
56 .asciz "Unhandled Exception in EL3.\nx30 =\t\t0x"
57intr_excpt_msg:
58 .asciz "Unhandled Interrupt Exception in EL3.\nx30 =\t\t0x"
Soby Mathew5e5c2072014-04-07 15:28:55 +010059
Soby Mathewc1adbbc2014-06-25 10:07:40 +010060 /*
61 * Helper function to print newline to console.
Soby Mathew5e5c2072014-04-07 15:28:55 +010062 */
Soby Mathewc1adbbc2014-06-25 10:07:40 +010063func print_newline
64 mov x0, '\n'
65 b plat_crash_console_putc
Kévin Petita877c252015-03-24 14:03:57 +000066endfunc print_newline
Soby Mathew5e5c2072014-04-07 15:28:55 +010067
Soby Mathewc1adbbc2014-06-25 10:07:40 +010068 /*
69 * Helper function to print from crash buf.
70 * The print loop is controlled by the buf size and
71 * ascii reg name list which is passed in x6. The
72 * function returns the crash buf address in x0.
73 * Clobbers : x0 - x7, sp
74 */
75func size_controlled_print
76 /* Save the lr */
77 mov sp, x30
78 /* load the crash buf address */
79 mrs x7, tpidr_el3
80test_size_list:
81 /* Calculate x5 always as it will be clobbered by asm_print_hex */
82 mrs x5, tpidr_el3
83 add x5, x5, #CPU_DATA_CRASH_BUF_SIZE
84 /* Test whether we have reached end of crash buf */
85 cmp x7, x5
86 b.eq exit_size_print
87 ldrb w4, [x6]
88 /* Test whether we are at end of list */
89 cbz w4, exit_size_print
90 mov x4, x6
91 /* asm_print_str updates x4 to point to next entry in list */
92 bl asm_print_str
93 /* update x6 with the updated list pointer */
94 mov x6, x4
95 adr x4, print_spacer
96 bl asm_print_str
Julius Werner02eb7272017-12-12 14:23:26 -080097 ldr x4, [x7], #REGSZ
Soby Mathewc1adbbc2014-06-25 10:07:40 +010098 bl asm_print_hex
99 bl print_newline
100 b test_size_list
101exit_size_print:
102 mov x30, sp
103 ret
Kévin Petita877c252015-03-24 14:03:57 +0000104endfunc size_controlled_print
Soby Mathew5e5c2072014-04-07 15:28:55 +0100105
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100106 /*
107 * Helper function to store x8 - x15 registers to
108 * the crash buf. The system registers values are
109 * copied to x8 to x15 by the caller which are then
110 * copied to the crash buf by this function.
111 * x0 points to the crash buf. It then calls
112 * size_controlled_print to print to console.
113 * Clobbers : x0 - x7, sp
114 */
115func str_in_crash_buf_print
116 /* restore the crash buf address in x0 */
117 mrs x0, tpidr_el3
118 stp x8, x9, [x0]
Julius Werner02eb7272017-12-12 14:23:26 -0800119 stp x10, x11, [x0, #REGSZ * 2]
120 stp x12, x13, [x0, #REGSZ * 4]
121 stp x14, x15, [x0, #REGSZ * 6]
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100122 b size_controlled_print
Kévin Petita877c252015-03-24 14:03:57 +0000123endfunc str_in_crash_buf_print
Soby Mathew5e5c2072014-04-07 15:28:55 +0100124
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100125 /* ------------------------------------------------------
126 * This macro calculates the offset to crash buf from
127 * cpu_data and stores it in tpidr_el3. It also saves x0
128 * and x1 in the crash buf by using sp as a temporary
129 * register.
130 * ------------------------------------------------------
131 */
132 .macro prepare_crash_buf_save_x0_x1
133 /* we can corrupt this reg to free up x0 */
134 mov sp, x0
135 /* tpidr_el3 contains the address to cpu_data structure */
136 mrs x0, tpidr_el3
137 /* Calculate the Crash buffer offset in cpu_data */
138 add x0, x0, #CPU_DATA_CRASH_BUF_OFFSET
139 /* Store crash buffer address in tpidr_el3 */
140 msr tpidr_el3, x0
Julius Werner02eb7272017-12-12 14:23:26 -0800141 str x1, [x0, #REGSZ]
Soby Mathew5e5c2072014-04-07 15:28:55 +0100142 mov x1, sp
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100143 str x1, [x0]
Soby Mathew5e5c2072014-04-07 15:28:55 +0100144 .endm
145
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100146 /* -----------------------------------------------------
147 * This function allows to report a crash (if crash
148 * reporting is enabled) when an unhandled exception
149 * occurs. It prints the CPU state via the crash console
150 * making use of the crash buf. This function will
151 * not return.
152 * -----------------------------------------------------
153 */
154func report_unhandled_exception
155 prepare_crash_buf_save_x0_x1
156 adr x0, excpt_msg
157 mov sp, x0
158 /* This call will not return */
159 b do_crash_reporting
Kévin Petita877c252015-03-24 14:03:57 +0000160endfunc report_unhandled_exception
Soby Mathew5e5c2072014-04-07 15:28:55 +0100161
Soby Mathew5e5c2072014-04-07 15:28:55 +0100162
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100163 /* -----------------------------------------------------
164 * This function allows to report a crash (if crash
165 * reporting is enabled) when an unhandled interrupt
166 * occurs. It prints the CPU state via the crash console
167 * making use of the crash buf. This function will
168 * not return.
169 * -----------------------------------------------------
170 */
171func report_unhandled_interrupt
172 prepare_crash_buf_save_x0_x1
173 adr x0, intr_excpt_msg
174 mov sp, x0
175 /* This call will not return */
176 b do_crash_reporting
Kévin Petita877c252015-03-24 14:03:57 +0000177endfunc report_unhandled_interrupt
Soby Mathew5e5c2072014-04-07 15:28:55 +0100178
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100179 /* -----------------------------------------------------
180 * This function allows to report a crash (if crash
181 * reporting is enabled) when panic() is invoked from
182 * C Runtime. It prints the CPU state via the crash
183 * console making use of the crash buf. This function
184 * will not return.
185 * -----------------------------------------------------
186 */
187func el3_panic
188 msr spsel, #1
189 prepare_crash_buf_save_x0_x1
190 adr x0, panic_msg
191 mov sp, x0
192 /* This call will not return */
193 b do_crash_reporting
Kévin Petita877c252015-03-24 14:03:57 +0000194endfunc el3_panic
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100195
196 /* ------------------------------------------------------------
197 * The common crash reporting functionality. It requires x0
198 * and x1 has already been stored in crash buf, sp points to
199 * crash message and tpidr_el3 contains the crash buf address.
200 * The function does the following:
201 * - Retrieve the crash buffer from tpidr_el3
202 * - Store x2 to x6 in the crash buffer
203 * - Initialise the crash console.
204 * - Print the crash message by using the address in sp.
205 * - Print x30 value to the crash console.
206 * - Print x0 - x7 from the crash buf to the crash console.
207 * - Print x8 - x29 (in groups of 8 registers) using the
208 * crash buf to the crash console.
209 * - Print el3 sys regs (in groups of 8 registers) using the
210 * crash buf to the crash console.
211 * - Print non el3 sys regs (in groups of 8 registers) using
212 * the crash buf to the crash console.
213 * ------------------------------------------------------------
214 */
215func do_crash_reporting
216 /* Retrieve the crash buf from tpidr_el3 */
217 mrs x0, tpidr_el3
218 /* Store x2 - x6, x30 in the crash buffer */
Julius Werner02eb7272017-12-12 14:23:26 -0800219 stp x2, x3, [x0, #REGSZ * 2]
220 stp x4, x5, [x0, #REGSZ * 4]
221 stp x6, x30, [x0, #REGSZ * 6]
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100222 /* Initialize the crash console */
223 bl plat_crash_console_init
224 /* Verify the console is initialized */
225 cbz x0, crash_panic
226 /* Print the crash message. sp points to the crash message */
227 mov x4, sp
228 bl asm_print_str
229 /* load the crash buf address */
230 mrs x0, tpidr_el3
231 /* report x30 first from the crash buf */
Julius Werner02eb7272017-12-12 14:23:26 -0800232 ldr x4, [x0, #REGSZ * 7]
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100233 bl asm_print_hex
234 bl print_newline
235 /* Load the crash buf address */
236 mrs x0, tpidr_el3
237 /* Now mov x7 into crash buf */
Julius Werner02eb7272017-12-12 14:23:26 -0800238 str x7, [x0, #REGSZ * 7]
Soby Mathew5e5c2072014-04-07 15:28:55 +0100239
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100240 /* Report x0 - x29 values stored in crash buf*/
241 /* Store the ascii list pointer in x6 */
242 adr x6, gp_regs
243 /* Print x0 to x7 from the crash buf */
244 bl size_controlled_print
245 /* Store x8 - x15 in crash buf and print */
246 bl str_in_crash_buf_print
247 /* Load the crash buf address */
248 mrs x0, tpidr_el3
249 /* Store the rest of gp regs and print */
250 stp x16, x17, [x0]
Julius Werner02eb7272017-12-12 14:23:26 -0800251 stp x18, x19, [x0, #REGSZ * 2]
252 stp x20, x21, [x0, #REGSZ * 4]
253 stp x22, x23, [x0, #REGSZ * 6]
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100254 bl size_controlled_print
255 /* Load the crash buf address */
256 mrs x0, tpidr_el3
257 stp x24, x25, [x0]
Julius Werner02eb7272017-12-12 14:23:26 -0800258 stp x26, x27, [x0, #REGSZ * 2]
259 stp x28, x29, [x0, #REGSZ * 4]
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100260 bl size_controlled_print
Soby Mathew5e5c2072014-04-07 15:28:55 +0100261
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100262 /* Print the el3 sys registers */
263 adr x6, el3_sys_regs
264 mrs x8, scr_el3
265 mrs x9, sctlr_el3
266 mrs x10, cptr_el3
267 mrs x11, tcr_el3
268 mrs x12, daif
269 mrs x13, mair_el3
270 mrs x14, spsr_el3
271 mrs x15, elr_el3
272 bl str_in_crash_buf_print
273 mrs x8, ttbr0_el3
274 mrs x9, esr_el3
275 mrs x10, far_el3
276 bl str_in_crash_buf_print
Soby Mathew5e5c2072014-04-07 15:28:55 +0100277
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100278 /* Print the non el3 sys registers */
279 adr x6, non_el3_sys_regs
280 mrs x8, spsr_el1
281 mrs x9, elr_el1
282 mrs x10, spsr_abt
283 mrs x11, spsr_und
284 mrs x12, spsr_irq
285 mrs x13, spsr_fiq
286 mrs x14, sctlr_el1
287 mrs x15, actlr_el1
288 bl str_in_crash_buf_print
289 mrs x8, cpacr_el1
290 mrs x9, csselr_el1
Soby Mathew5e5c2072014-04-07 15:28:55 +0100291 mrs x10, sp_el1
292 mrs x11, esr_el1
293 mrs x12, ttbr0_el1
294 mrs x13, ttbr1_el1
295 mrs x14, mair_el1
296 mrs x15, amair_el1
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100297 bl str_in_crash_buf_print
298 mrs x8, tcr_el1
299 mrs x9, tpidr_el1
300 mrs x10, tpidr_el0
301 mrs x11, tpidrro_el0
302 mrs x12, dacr32_el2
303 mrs x13, ifsr32_el2
304 mrs x14, par_el1
305 mrs x15, mpidr_el1
306 bl str_in_crash_buf_print
307 mrs x8, afsr0_el1
308 mrs x9, afsr1_el1
309 mrs x10, contextidr_el1
310 mrs x11, vbar_el1
311 mrs x12, cntp_ctl_el0
312 mrs x13, cntp_cval_el0
313 mrs x14, cntv_ctl_el0
314 mrs x15, cntv_cval_el0
315 bl str_in_crash_buf_print
316 mrs x8, cntkctl_el1
David Cunadod1a1fd42017-10-20 11:30:57 +0100317 mrs x9, sp_el0
318 mrs x10, isr_el1
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100319 bl str_in_crash_buf_print
Soby Mathew5e5c2072014-04-07 15:28:55 +0100320
Soby Mathew38b4bc92014-08-14 13:36:41 +0100321 /* Get the cpu specific registers to report */
322 bl do_cpu_reg_dump
323 bl str_in_crash_buf_print
Soby Mathew0da95932014-07-16 09:23:52 +0100324
Gerald Lejeune2c7ed5b2015-11-26 15:47:53 +0100325 /* Print some platform registers */
326 plat_crash_print_regs
Soby Mathew0da95932014-07-16 09:23:52 +0100327
Antonio Nino Diazd3ec5432017-02-17 17:11:27 +0000328 bl plat_crash_console_flush
329
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100330 /* Done reporting */
Jeenu Viswambharan68aef102016-11-30 15:21:11 +0000331 no_ret plat_panic_handler
Kévin Petita877c252015-03-24 14:03:57 +0000332endfunc do_crash_reporting
Soby Mathew5e5c2072014-04-07 15:28:55 +0100333
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100334#else /* CRASH_REPORTING */
335func report_unhandled_exception
336report_unhandled_interrupt:
Jeenu Viswambharan68aef102016-11-30 15:21:11 +0000337 no_ret plat_panic_handler
Kévin Petita877c252015-03-24 14:03:57 +0000338endfunc report_unhandled_exception
Sandrine Bailleuxf4119ec2015-12-17 13:58:58 +0000339#endif /* CRASH_REPORTING */
Soby Mathew5e5c2072014-04-07 15:28:55 +0100340
Soby Mathew5e5c2072014-04-07 15:28:55 +0100341
Soby Mathewc1adbbc2014-06-25 10:07:40 +0100342func crash_panic
Jeenu Viswambharan68aef102016-11-30 15:21:11 +0000343 no_ret plat_panic_handler
Antonio Nino Diaz1f21bcf2016-02-01 13:57:25 +0000344endfunc crash_panic