1a43d431bSSoby Mathew/* 2*58fadd62SIgor 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> 1409d40e0eSAntonio Nino Diaz#include <lib/utils_def.h> 15a43d431bSSoby Mathew 16626ed510SSoby Mathew .globl report_unhandled_exception 17626ed510SSoby Mathew .globl report_unhandled_interrupt 18f300ef66SGovindraj Raja .globl report_el3_panic 197e619eccSGovindraj Raja .globl report_elx_panic 20a43d431bSSoby Mathew 219c22b323SAndrew Thoelke#if CRASH_REPORTING 22626ed510SSoby Mathew 23a43d431bSSoby Mathew /* ------------------------------------------------------ 24a43d431bSSoby Mathew * The below section deals with dumping the system state 25a43d431bSSoby Mathew * when an unhandled exception is taken in EL3. 26a43d431bSSoby Mathew * The layout and the names of the registers which will 27a43d431bSSoby Mathew * be dumped during a unhandled exception is given below. 28a43d431bSSoby Mathew * ------------------------------------------------------ 29a43d431bSSoby Mathew */ 30626ed510SSoby Mathew.section .rodata.crash_prints, "aS" 31626ed510SSoby Mathewprint_spacer: 326c6a470fSAlexei Fedorov .asciz " = 0x" 33a43d431bSSoby Mathew 34626ed510SSoby Mathewgp_regs: 35626ed510SSoby Mathew .asciz "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",\ 36626ed510SSoby Mathew "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",\ 37626ed510SSoby Mathew "x16", "x17", "x18", "x19", "x20", "x21", "x22",\ 38626ed510SSoby Mathew "x23", "x24", "x25", "x26", "x27", "x28", "x29", "" 39626ed510SSoby Mathewel3_sys_regs: 40626ed510SSoby Mathew .asciz "scr_el3", "sctlr_el3", "cptr_el3", "tcr_el3",\ 41626ed510SSoby Mathew "daif", "mair_el3", "spsr_el3", "elr_el3", "ttbr0_el3",\ 42626ed510SSoby Mathew "esr_el3", "far_el3", "" 43a43d431bSSoby Mathew 44*58fadd62SIgor Podgainõinon_el3_sys_regs_1: 45626ed510SSoby Mathew .asciz "spsr_el1", "elr_el1", "spsr_abt", "spsr_und",\ 46a43d431bSSoby Mathew "spsr_irq", "spsr_fiq", "sctlr_el1", "actlr_el1", "cpacr_el1",\ 47*58fadd62SIgor Podgainõi "csselr_el1", "sp_el1", "esr_el1", "" 48*58fadd62SIgor Podgainõi 49*58fadd62SIgor Podgainõittbr_regs: 50*58fadd62SIgor Podgainõi .asciz "ttbr0_el1", "ttbr0_el2", "ttbr1_el1", "vttbr_el2", "" 51*58fadd62SIgor Podgainõi 52*58fadd62SIgor Podgainõinon_el3_sys_regs_2: 53*58fadd62SIgor Podgainõi .asciz "mair_el1", "amair_el1", "tcr_el1", "tpidr_el1",\ 54*58fadd62SIgor Podgainõi "tpidr_el0", "tpidrro_el0", "" 55*58fadd62SIgor Podgainõi 56*58fadd62SIgor Podgainõipar_reg: 57*58fadd62SIgor Podgainõi .asciz "par_el1", "" 58*58fadd62SIgor Podgainõi 59*58fadd62SIgor Podgainõinon_el3_sys_regs_3: 60*58fadd62SIgor Podgainõi .asciz "mpidr_el1", "afsr0_el1", "afsr1_el1", "contextidr_el1",\ 61*58fadd62SIgor Podgainõi "vbar_el1", "cntp_ctl_el0", "cntp_cval_el0", "cntv_ctl_el0",\ 62*58fadd62SIgor Podgainõi "cntv_cval_el0", "cntkctl_el1", "sp_el0", "isr_el1", "" 63c424b91eSImre Kis 64c424b91eSImre Kis#if CTX_INCLUDE_AARCH32_REGS 65c424b91eSImre Kisaarch32_regs: 66c424b91eSImre Kis .asciz "dacr32_el2", "ifsr32_el2", "" 67c424b91eSImre Kis#endif /* CTX_INCLUDE_AARCH32_REGS */ 68a43d431bSSoby Mathew 69626ed510SSoby Mathewpanic_msg: 706c6a470fSAlexei Fedorov .asciz "PANIC in EL3.\nx30" 71626ed510SSoby Mathewexcpt_msg: 726c6a470fSAlexei Fedorov .asciz "Unhandled Exception in EL3.\nx30" 73626ed510SSoby Mathewintr_excpt_msg: 74b4292bc6SAlexei Fedorov .ascii "Unhandled Interrupt Exception in EL3.\n" 75b4292bc6SAlexei Fedorovx30_msg: 76b4292bc6SAlexei Fedorov .asciz "x30" 77b4292bc6SAlexei Fedorovexcpt_msg_el: 787e619eccSGovindraj Raja .asciz "Unhandled Exception from lower EL.\n" 79626ed510SSoby Mathew 80626ed510SSoby Mathew /* 81626ed510SSoby Mathew * Helper function to print from crash buf. 82626ed510SSoby Mathew * The print loop is controlled by the buf size and 83626ed510SSoby Mathew * ascii reg name list which is passed in x6. The 84626ed510SSoby Mathew * function returns the crash buf address in x0. 85*58fadd62SIgor Podgainõi * Clobbers : x0 - x7, x20, sp 86626ed510SSoby Mathew */ 87*58fadd62SIgor Podgainõifunc size_controlled_print_helper 88*58fadd62SIgor Podgainõi#if ENABLE_FEAT_D128 89*58fadd62SIgor Podgainõisize_controlled_print_128: 90*58fadd62SIgor Podgainõi /* Set flag to print 128-bit registers */ 91*58fadd62SIgor Podgainõi mov x20, #1 92*58fadd62SIgor Podgainõi b 1f 93*58fadd62SIgor Podgainõi 94*58fadd62SIgor Podgainõisize_controlled_print: 95*58fadd62SIgor Podgainõi /* Set flag to print 64-bit registers */ 96*58fadd62SIgor Podgainõi mov x20, #0 97*58fadd62SIgor Podgainõi1: 98*58fadd62SIgor Podgainõi#else 99*58fadd62SIgor Podgainõisize_controlled_print: 100*58fadd62SIgor Podgainõi#endif 101626ed510SSoby Mathew /* Save the lr */ 102626ed510SSoby Mathew mov sp, x30 103626ed510SSoby Mathew /* load the crash buf address */ 104626ed510SSoby Mathew mrs x7, tpidr_el3 105626ed510SSoby Mathewtest_size_list: 106626ed510SSoby Mathew /* Calculate x5 always as it will be clobbered by asm_print_hex */ 107626ed510SSoby Mathew mrs x5, tpidr_el3 108626ed510SSoby Mathew add x5, x5, #CPU_DATA_CRASH_BUF_SIZE 109626ed510SSoby Mathew /* Test whether we have reached end of crash buf */ 110626ed510SSoby Mathew cmp x7, x5 111626ed510SSoby Mathew b.eq exit_size_print 112626ed510SSoby Mathew ldrb w4, [x6] 113626ed510SSoby Mathew /* Test whether we are at end of list */ 114626ed510SSoby Mathew cbz w4, exit_size_print 115626ed510SSoby Mathew mov x4, x6 116626ed510SSoby Mathew /* asm_print_str updates x4 to point to next entry in list */ 117626ed510SSoby Mathew bl asm_print_str 1186c6a470fSAlexei Fedorov /* x0 = number of symbols printed + 1 */ 1196c6a470fSAlexei Fedorov sub x0, x4, x6 120626ed510SSoby Mathew /* update x6 with the updated list pointer */ 121626ed510SSoby Mathew mov x6, x4 1226c6a470fSAlexei Fedorov bl print_alignment 123*58fadd62SIgor Podgainõi /* Print the high 64 bits (or whole 64-bit register) */ 124155a1006SJulius Werner ldr x4, [x7], #REGSZ 125626ed510SSoby Mathew bl asm_print_hex 126*58fadd62SIgor Podgainõi#if ENABLE_FEAT_D128 127*58fadd62SIgor Podgainõi cbz x20, 2f 128*58fadd62SIgor Podgainõi /* Print the low 64 bits in case of a 128-bit register */ 129*58fadd62SIgor Podgainõi ldr x4, [x7], #REGSZ 130*58fadd62SIgor Podgainõi bl asm_print_hex 131*58fadd62SIgor Podgainõi2: 132*58fadd62SIgor Podgainõi#endif 13353d7e003SJustin Chadwell bl asm_print_newline 134626ed510SSoby Mathew b test_size_list 135626ed510SSoby Mathewexit_size_print: 136626ed510SSoby Mathew mov x30, sp 137626ed510SSoby Mathew ret 138*58fadd62SIgor Podgainõiendfunc size_controlled_print_helper 139626ed510SSoby Mathew 1406c6a470fSAlexei Fedorov /* ----------------------------------------------------- 1416c6a470fSAlexei Fedorov * This function calculates and prints required number 1426c6a470fSAlexei Fedorov * of space characters followed by "= 0x", based on the 1436c6a470fSAlexei Fedorov * length of ascii register name. 1446c6a470fSAlexei Fedorov * x0: length of ascii register name + 1 1456c6a470fSAlexei Fedorov * ------------------------------------------------------ 1466c6a470fSAlexei Fedorov */ 1476c6a470fSAlexei Fedorovfunc print_alignment 1486c6a470fSAlexei Fedorov /* The minimum ascii length is 3, e.g. for "x0" */ 1496c6a470fSAlexei Fedorov adr x4, print_spacer - 3 1506c6a470fSAlexei Fedorov add x4, x4, x0 1516c6a470fSAlexei Fedorov b asm_print_str 1526c6a470fSAlexei Fedorovendfunc print_alignment 1536c6a470fSAlexei Fedorov 154626ed510SSoby Mathew /* 155626ed510SSoby Mathew * Helper function to store x8 - x15 registers to 156626ed510SSoby Mathew * the crash buf. The system registers values are 157626ed510SSoby Mathew * copied to x8 to x15 by the caller which are then 158626ed510SSoby Mathew * copied to the crash buf by this function. 159626ed510SSoby Mathew * x0 points to the crash buf. It then calls 160626ed510SSoby Mathew * size_controlled_print to print to console. 161*58fadd62SIgor Podgainõi * Clobbers : x0 - x7, x20, sp 162626ed510SSoby Mathew */ 163626ed510SSoby Mathewfunc str_in_crash_buf_print 164626ed510SSoby Mathew /* restore the crash buf address in x0 */ 165626ed510SSoby Mathew mrs x0, tpidr_el3 166626ed510SSoby Mathew stp x8, x9, [x0] 167155a1006SJulius Werner stp x10, x11, [x0, #REGSZ * 2] 168155a1006SJulius Werner stp x12, x13, [x0, #REGSZ * 4] 169155a1006SJulius Werner stp x14, x15, [x0, #REGSZ * 6] 170626ed510SSoby Mathew b size_controlled_print 1718b779620SKévin Petitendfunc str_in_crash_buf_print 172626ed510SSoby Mathew 173*58fadd62SIgor Podgainõi /* 174*58fadd62SIgor Podgainõi * An equivalent helper function for storing x8 - x15 175*58fadd62SIgor Podgainõi * registers in a different order inside the crash buf. 176*58fadd62SIgor Podgainõi * In the end the function size_controlled_print_128 is 177*58fadd62SIgor Podgainõi * called to print the registers to the console. 178*58fadd62SIgor Podgainõi * Clobbers : x0 - x7, x20, sp 179*58fadd62SIgor Podgainõi */ 180*58fadd62SIgor Podgainõifunc str_in_crash_buf_print_128 181*58fadd62SIgor Podgainõi /* restore the crash buf address in x0 */ 182*58fadd62SIgor Podgainõi mrs x0, tpidr_el3 183*58fadd62SIgor Podgainõi stp x8, x9, [x0] 184*58fadd62SIgor Podgainõi stp x10, x11, [x0, #REGSZ * 2] 185*58fadd62SIgor Podgainõi stp x12, x13, [x0, #REGSZ * 4] 186*58fadd62SIgor Podgainõi stp x14, x15, [x0, #REGSZ * 6] 187*58fadd62SIgor Podgainõi b size_controlled_print_128 188*58fadd62SIgor Podgainõiendfunc str_in_crash_buf_print_128 189*58fadd62SIgor Podgainõi 190626ed510SSoby Mathew /* ------------------------------------------------------ 191626ed510SSoby Mathew * This macro calculates the offset to crash buf from 192626ed510SSoby Mathew * cpu_data and stores it in tpidr_el3. It also saves x0 193626ed510SSoby Mathew * and x1 in the crash buf by using sp as a temporary 194626ed510SSoby Mathew * register. 195626ed510SSoby Mathew * ------------------------------------------------------ 196626ed510SSoby Mathew */ 197626ed510SSoby Mathew .macro prepare_crash_buf_save_x0_x1 198626ed510SSoby Mathew /* we can corrupt this reg to free up x0 */ 199626ed510SSoby Mathew mov sp, x0 200626ed510SSoby Mathew /* tpidr_el3 contains the address to cpu_data structure */ 201626ed510SSoby Mathew mrs x0, tpidr_el3 202626ed510SSoby Mathew /* Calculate the Crash buffer offset in cpu_data */ 203626ed510SSoby Mathew add x0, x0, #CPU_DATA_CRASH_BUF_OFFSET 204626ed510SSoby Mathew /* Store crash buffer address in tpidr_el3 */ 205626ed510SSoby Mathew msr tpidr_el3, x0 206155a1006SJulius Werner str x1, [x0, #REGSZ] 207626ed510SSoby Mathew mov x1, sp 208626ed510SSoby Mathew str x1, [x0] 209626ed510SSoby Mathew .endm 210a43d431bSSoby Mathew 211a43d431bSSoby Mathew /* ----------------------------------------------------- 212626ed510SSoby Mathew * This function allows to report a crash (if crash 213626ed510SSoby Mathew * reporting is enabled) when an unhandled exception 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. 217a43d431bSSoby Mathew * ----------------------------------------------------- 218a43d431bSSoby Mathew */ 219626ed510SSoby Mathewfunc report_unhandled_exception 220626ed510SSoby Mathew prepare_crash_buf_save_x0_x1 221626ed510SSoby Mathew adr x0, 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_exception 226a43d431bSSoby Mathew 227626ed510SSoby Mathew /* ----------------------------------------------------- 228626ed510SSoby Mathew * This function allows to report a crash (if crash 229626ed510SSoby Mathew * reporting is enabled) when an unhandled interrupt 230626ed510SSoby Mathew * occurs. It prints the CPU state via the crash console 231626ed510SSoby Mathew * making use of the crash buf. This function will 232626ed510SSoby Mathew * not return. 233626ed510SSoby Mathew * ----------------------------------------------------- 234626ed510SSoby Mathew */ 235626ed510SSoby Mathewfunc report_unhandled_interrupt 236626ed510SSoby Mathew prepare_crash_buf_save_x0_x1 237626ed510SSoby Mathew adr x0, intr_excpt_msg 238626ed510SSoby Mathew mov sp, x0 239626ed510SSoby Mathew /* This call will not return */ 240626ed510SSoby Mathew b do_crash_reporting 2418b779620SKévin Petitendfunc report_unhandled_interrupt 242a43d431bSSoby Mathew 243626ed510SSoby Mathew /* ----------------------------------------------------- 244b4292bc6SAlexei Fedorov * This function allows to report a crash from the lower 245b4292bc6SAlexei Fedorov * exception level (if crash reporting is enabled) when 2467e619eccSGovindraj Raja * lower_el_panic() is invoked from C Runtime. 247b4292bc6SAlexei Fedorov * It prints the CPU state via the crash console making 248b4292bc6SAlexei Fedorov * use of 'cpu_context' structure where general purpose 249b4292bc6SAlexei Fedorov * registers are saved and the crash buf. 250b4292bc6SAlexei Fedorov * This function will not return. 251b4292bc6SAlexei Fedorov * ----------------------------------------------------- 252b4292bc6SAlexei Fedorov */ 2537e619eccSGovindraj Rajafunc report_elx_panic 254b4292bc6SAlexei Fedorov msr spsel, #MODE_SP_ELX 255b4292bc6SAlexei Fedorov 256b4292bc6SAlexei Fedorov /* Print the crash message */ 257b4292bc6SAlexei Fedorov adr x4, excpt_msg_el 258b4292bc6SAlexei Fedorov bl asm_print_str 259b4292bc6SAlexei Fedorov 260b4292bc6SAlexei Fedorov /* Report x0 - x29 values stored in 'gpregs_ctx' structure */ 261b4292bc6SAlexei Fedorov /* Store the ascii list pointer in x6 */ 262b4292bc6SAlexei Fedorov adr x6, gp_regs 263b4292bc6SAlexei Fedorov add x7, sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0 264b4292bc6SAlexei Fedorov 265b4292bc6SAlexei Fedorovprint_next: 266b4292bc6SAlexei Fedorov ldrb w4, [x6] 267b4292bc6SAlexei Fedorov /* Test whether we are at end of list */ 268b4292bc6SAlexei Fedorov cbz w4, print_x30 269b4292bc6SAlexei Fedorov mov x4, x6 270b4292bc6SAlexei Fedorov /* asm_print_str updates x4 to point to next entry in list */ 271b4292bc6SAlexei Fedorov bl asm_print_str 272b4292bc6SAlexei Fedorov /* x0 = number of symbols printed + 1 */ 273b4292bc6SAlexei Fedorov sub x0, x4, x6 274b4292bc6SAlexei Fedorov /* Update x6 with the updated list pointer */ 275b4292bc6SAlexei Fedorov mov x6, x4 276b4292bc6SAlexei Fedorov bl print_alignment 277b4292bc6SAlexei Fedorov ldr x4, [x7], #REGSZ 278b4292bc6SAlexei Fedorov bl asm_print_hex 279b4292bc6SAlexei Fedorov bl asm_print_newline 280b4292bc6SAlexei Fedorov b print_next 281b4292bc6SAlexei Fedorov 282b4292bc6SAlexei Fedorovprint_x30: 283b4292bc6SAlexei Fedorov adr x4, x30_msg 284b4292bc6SAlexei Fedorov bl asm_print_str 285b4292bc6SAlexei Fedorov 286b4292bc6SAlexei Fedorov /* Print spaces to align "x30" string */ 287b4292bc6SAlexei Fedorov mov x0, #4 288b4292bc6SAlexei Fedorov bl print_alignment 289b4292bc6SAlexei Fedorov 290b4292bc6SAlexei Fedorov /* Report x30 */ 291b4292bc6SAlexei Fedorov ldr x4, [x7] 292b4292bc6SAlexei Fedorov 293b4292bc6SAlexei Fedorov /* ---------------------------------------------------------------- 294b4292bc6SAlexei Fedorov * Different virtual address space size can be defined for each EL. 295b4292bc6SAlexei Fedorov * Ensure that we use the proper one by reading the corresponding 296b4292bc6SAlexei Fedorov * TCR_ELx register. 297b4292bc6SAlexei Fedorov * ---------------------------------------------------------------- 298b4292bc6SAlexei Fedorov */ 299b4292bc6SAlexei Fedorov cmp x8, #MODE_EL2 300b4292bc6SAlexei Fedorov b.lt from_el1 /* EL1 */ 301b4292bc6SAlexei Fedorov mrs x2, sctlr_el2 302b4292bc6SAlexei Fedorov mrs x1, tcr_el2 303b4292bc6SAlexei Fedorov 304b4292bc6SAlexei Fedorov /* ---------------------------------------------------------------- 305b4292bc6SAlexei Fedorov * Check if pointer authentication is enabled at the specified EL. 306b4292bc6SAlexei Fedorov * If it isn't, we can then skip stripping a PAC code. 307b4292bc6SAlexei Fedorov * ---------------------------------------------------------------- 308b4292bc6SAlexei Fedorov */ 309b4292bc6SAlexei Fedorovtest_pauth: 310b4292bc6SAlexei Fedorov tst x2, #(SCTLR_EnIA_BIT | SCTLR_EnIB_BIT) 311b4292bc6SAlexei Fedorov b.eq no_pauth 312b4292bc6SAlexei Fedorov 313b4292bc6SAlexei Fedorov /* Demangle address */ 314b4292bc6SAlexei Fedorov and x1, x1, #0x3F /* T0SZ = TCR_ELx[5:0] */ 315b4292bc6SAlexei Fedorov sub x1, x1, #64 316b4292bc6SAlexei Fedorov neg x1, x1 /* bottom_pac_bit = 64 - T0SZ */ 317b4292bc6SAlexei Fedorov mov x2, #-1 318b4292bc6SAlexei Fedorov lsl x2, x2, x1 319b4292bc6SAlexei Fedorov bic x4, x4, x2 320b4292bc6SAlexei Fedorov 321b4292bc6SAlexei Fedorovno_pauth: 322b4292bc6SAlexei Fedorov bl asm_print_hex 323b4292bc6SAlexei Fedorov bl asm_print_newline 324b4292bc6SAlexei Fedorov 325b4292bc6SAlexei Fedorov /* tpidr_el3 contains the address to cpu_data structure */ 326b4292bc6SAlexei Fedorov mrs x0, tpidr_el3 327b4292bc6SAlexei Fedorov /* Calculate the Crash buffer offset in cpu_data */ 328b4292bc6SAlexei Fedorov add x0, x0, #CPU_DATA_CRASH_BUF_OFFSET 329b4292bc6SAlexei Fedorov /* Store crash buffer address in tpidr_el3 */ 330b4292bc6SAlexei Fedorov msr tpidr_el3, x0 331b4292bc6SAlexei Fedorov 332b4292bc6SAlexei Fedorov /* Print the rest of crash dump */ 333b4292bc6SAlexei Fedorov b print_el3_sys_regs 334b4292bc6SAlexei Fedorov 335b4292bc6SAlexei Fedorovfrom_el1: 336b4292bc6SAlexei Fedorov mrs x2, sctlr_el1 337b4292bc6SAlexei Fedorov mrs x1, tcr_el1 338b4292bc6SAlexei Fedorov b test_pauth 3397e619eccSGovindraj Rajaendfunc report_elx_panic 340b4292bc6SAlexei Fedorov 341b4292bc6SAlexei Fedorov /* ----------------------------------------------------- 342626ed510SSoby Mathew * This function allows to report a crash (if crash 343626ed510SSoby Mathew * reporting is enabled) when panic() is invoked from 344626ed510SSoby Mathew * C Runtime. It prints the CPU state via the crash 345626ed510SSoby Mathew * console making use of the crash buf. This function 346626ed510SSoby Mathew * will not return. 347626ed510SSoby Mathew * ----------------------------------------------------- 348626ed510SSoby Mathew */ 349f300ef66SGovindraj Rajafunc report_el3_panic 3506c6a470fSAlexei Fedorov msr spsel, #MODE_SP_ELX 351626ed510SSoby Mathew prepare_crash_buf_save_x0_x1 352626ed510SSoby Mathew adr x0, panic_msg 353626ed510SSoby Mathew mov sp, x0 354b4292bc6SAlexei Fedorov /* Fall through to 'do_crash_reporting' */ 355a43d431bSSoby Mathew 356626ed510SSoby Mathew /* ------------------------------------------------------------ 357626ed510SSoby Mathew * The common crash reporting functionality. It requires x0 358626ed510SSoby Mathew * and x1 has already been stored in crash buf, sp points to 359626ed510SSoby Mathew * crash message and tpidr_el3 contains the crash buf address. 360626ed510SSoby Mathew * The function does the following: 361626ed510SSoby Mathew * - Retrieve the crash buffer from tpidr_el3 362626ed510SSoby Mathew * - Store x2 to x6 in the crash buffer 363626ed510SSoby Mathew * - Initialise the crash console. 364626ed510SSoby Mathew * - Print the crash message by using the address in sp. 365626ed510SSoby Mathew * - Print x30 value to the crash console. 366626ed510SSoby Mathew * - Print x0 - x7 from the crash buf to the crash console. 367626ed510SSoby Mathew * - Print x8 - x29 (in groups of 8 registers) using the 368626ed510SSoby Mathew * crash buf to the crash console. 369626ed510SSoby Mathew * - Print el3 sys regs (in groups of 8 registers) using the 370626ed510SSoby Mathew * crash buf to the crash console. 371626ed510SSoby Mathew * - Print non el3 sys regs (in groups of 8 registers) using 372*58fadd62SIgor Podgainõi * the crash buf to the crash console. A group may be 373*58fadd62SIgor Podgainõi * interrupted in case a potential group of 128-bit 374*58fadd62SIgor Podgainõi * sys regs needs to be printed. 375626ed510SSoby Mathew * ------------------------------------------------------------ 376626ed510SSoby Mathew */ 377b4292bc6SAlexei Fedorovdo_crash_reporting: 378626ed510SSoby Mathew /* Retrieve the crash buf from tpidr_el3 */ 379626ed510SSoby Mathew mrs x0, tpidr_el3 380626ed510SSoby Mathew /* Store x2 - x6, x30 in the crash buffer */ 381155a1006SJulius Werner stp x2, x3, [x0, #REGSZ * 2] 382155a1006SJulius Werner stp x4, x5, [x0, #REGSZ * 4] 383155a1006SJulius Werner stp x6, x30, [x0, #REGSZ * 6] 384626ed510SSoby Mathew /* Initialize the crash console */ 385626ed510SSoby Mathew bl plat_crash_console_init 386626ed510SSoby Mathew /* Verify the console is initialized */ 387626ed510SSoby Mathew cbz x0, crash_panic 388626ed510SSoby Mathew /* Print the crash message. sp points to the crash message */ 389626ed510SSoby Mathew mov x4, sp 390626ed510SSoby Mathew bl asm_print_str 3916c6a470fSAlexei Fedorov /* Print spaces to align "x30" string */ 3926c6a470fSAlexei Fedorov mov x0, #4 3936c6a470fSAlexei Fedorov bl print_alignment 394b4292bc6SAlexei Fedorov /* Load the crash buf address */ 395626ed510SSoby Mathew mrs x0, tpidr_el3 396b4292bc6SAlexei Fedorov /* Report x30 first from the crash buf */ 397155a1006SJulius Werner ldr x4, [x0, #REGSZ * 7] 39868c76088SAlexei Fedorov 39968c76088SAlexei Fedorov#if ENABLE_PAUTH 40068c76088SAlexei Fedorov /* Demangle address */ 40168c76088SAlexei Fedorov xpaci x4 40268c76088SAlexei Fedorov#endif 403626ed510SSoby Mathew bl asm_print_hex 40453d7e003SJustin Chadwell bl asm_print_newline 405626ed510SSoby Mathew /* Load the crash buf address */ 406626ed510SSoby Mathew mrs x0, tpidr_el3 407626ed510SSoby Mathew /* Now mov x7 into crash buf */ 408155a1006SJulius Werner str x7, [x0, #REGSZ * 7] 409a43d431bSSoby Mathew 410626ed510SSoby Mathew /* Report x0 - x29 values stored in crash buf */ 411626ed510SSoby Mathew /* Store the ascii list pointer in x6 */ 412626ed510SSoby Mathew adr x6, gp_regs 413626ed510SSoby Mathew /* Print x0 to x7 from the crash buf */ 414626ed510SSoby Mathew bl size_controlled_print 415626ed510SSoby Mathew /* Store x8 - x15 in crash buf and print */ 416626ed510SSoby Mathew bl str_in_crash_buf_print 417626ed510SSoby Mathew /* Load the crash buf address */ 418626ed510SSoby Mathew mrs x0, tpidr_el3 419626ed510SSoby Mathew /* Store the rest of gp regs and print */ 420626ed510SSoby Mathew stp x16, x17, [x0] 421155a1006SJulius Werner stp x18, x19, [x0, #REGSZ * 2] 422155a1006SJulius Werner stp x20, x21, [x0, #REGSZ * 4] 423155a1006SJulius Werner stp x22, x23, [x0, #REGSZ * 6] 424626ed510SSoby Mathew bl size_controlled_print 425626ed510SSoby Mathew /* Load the crash buf address */ 426626ed510SSoby Mathew mrs x0, tpidr_el3 427626ed510SSoby Mathew stp x24, x25, [x0] 428155a1006SJulius Werner stp x26, x27, [x0, #REGSZ * 2] 429155a1006SJulius Werner stp x28, x29, [x0, #REGSZ * 4] 430626ed510SSoby Mathew bl size_controlled_print 431a43d431bSSoby Mathew 432626ed510SSoby Mathew /* Print the el3 sys registers */ 433b4292bc6SAlexei Fedorovprint_el3_sys_regs: 434626ed510SSoby Mathew adr x6, el3_sys_regs 435626ed510SSoby Mathew mrs x8, scr_el3 436626ed510SSoby Mathew mrs x9, sctlr_el3 437626ed510SSoby Mathew mrs x10, cptr_el3 438626ed510SSoby Mathew mrs x11, tcr_el3 439626ed510SSoby Mathew mrs x12, daif 440626ed510SSoby Mathew mrs x13, mair_el3 441626ed510SSoby Mathew mrs x14, spsr_el3 442626ed510SSoby Mathew mrs x15, elr_el3 443626ed510SSoby Mathew bl str_in_crash_buf_print 444626ed510SSoby Mathew mrs x8, ttbr0_el3 445626ed510SSoby Mathew mrs x9, esr_el3 446626ed510SSoby Mathew mrs x10, far_el3 447626ed510SSoby Mathew bl str_in_crash_buf_print 448a43d431bSSoby Mathew 449626ed510SSoby Mathew /* Print the non el3 sys registers */ 450*58fadd62SIgor Podgainõi adr x6, non_el3_sys_regs_1 451626ed510SSoby Mathew mrs x8, spsr_el1 452626ed510SSoby Mathew mrs x9, elr_el1 453626ed510SSoby Mathew mrs x10, spsr_abt 454626ed510SSoby Mathew mrs x11, spsr_und 455626ed510SSoby Mathew mrs x12, spsr_irq 456626ed510SSoby Mathew mrs x13, spsr_fiq 457626ed510SSoby Mathew mrs x14, sctlr_el1 458626ed510SSoby Mathew mrs x15, actlr_el1 459626ed510SSoby Mathew bl str_in_crash_buf_print 460626ed510SSoby Mathew mrs x8, cpacr_el1 461626ed510SSoby Mathew mrs x9, csselr_el1 462a43d431bSSoby Mathew mrs x10, sp_el1 463a43d431bSSoby Mathew mrs x11, esr_el1 464626ed510SSoby Mathew bl str_in_crash_buf_print 465*58fadd62SIgor Podgainõi 466*58fadd62SIgor Podgainõi adr x6, ttbr_regs 467*58fadd62SIgor Podgainõi#if ENABLE_FEAT_D128 468*58fadd62SIgor Podgainõi is_feat_sysreg128_present_asm x19 469*58fadd62SIgor Podgainõi /* Fallback to 64-bit if FEAT_SYSREG128 is disabled */ 470*58fadd62SIgor Podgainõi cbz x19, ttbr_regs_64_bit 471*58fadd62SIgor Podgainõi bl read_ttbr0_el1 472*58fadd62SIgor Podgainõi mov x8, x1 473*58fadd62SIgor Podgainõi mov x9, x0 474*58fadd62SIgor Podgainõi bl read_ttbr0_el2 475*58fadd62SIgor Podgainõi mov x10, x1 476*58fadd62SIgor Podgainõi mov x11, x0 477*58fadd62SIgor Podgainõi bl read_ttbr1_el1 478*58fadd62SIgor Podgainõi mov x12, x1 479*58fadd62SIgor Podgainõi mov x13, x0 480*58fadd62SIgor Podgainõi bl read_vttbr_el2 481*58fadd62SIgor Podgainõi mov x14, x1 482*58fadd62SIgor Podgainõi mov x15, x0 483*58fadd62SIgor Podgainõi bl str_in_crash_buf_print_128 484*58fadd62SIgor Podgainõi b 1f 485*58fadd62SIgor Podgainõi 486*58fadd62SIgor Podgainõittbr_regs_64_bit: 487*58fadd62SIgor Podgainõi#endif 488*58fadd62SIgor Podgainõi mrs x8, ttbr0_el1 489*58fadd62SIgor Podgainõi mrs x9, ttbr0_el2 490*58fadd62SIgor Podgainõi mrs x10, ttbr1_el1 491*58fadd62SIgor Podgainõi mrs x11, vttbr_el2 492626ed510SSoby Mathew bl str_in_crash_buf_print 493*58fadd62SIgor Podgainõi1: 494*58fadd62SIgor Podgainõi adr x6, non_el3_sys_regs_2 495*58fadd62SIgor Podgainõi mrs x8, mair_el1 496*58fadd62SIgor Podgainõi mrs x9, amair_el1 497*58fadd62SIgor Podgainõi mrs x10, tcr_el1 498*58fadd62SIgor Podgainõi mrs x11, tpidr_el1 499*58fadd62SIgor Podgainõi mrs x12, tpidr_el0 500*58fadd62SIgor Podgainõi mrs x13, tpidrro_el0 501626ed510SSoby Mathew bl str_in_crash_buf_print 502*58fadd62SIgor Podgainõi 503*58fadd62SIgor Podgainõi adr x6, par_reg 504*58fadd62SIgor Podgainõi#if ENABLE_FEAT_D128 505*58fadd62SIgor Podgainõi /* Fallback to 64-bit if FEAT_SYSREG128 is disabled */ 506*58fadd62SIgor Podgainõi cbz x19, par_reg_64_bit 507*58fadd62SIgor Podgainõi bl read_par_el1 508*58fadd62SIgor Podgainõi mov x8, x1 509*58fadd62SIgor Podgainõi mov x9, x0 510*58fadd62SIgor Podgainõi bl str_in_crash_buf_print_128 511*58fadd62SIgor Podgainõi b 2f 512*58fadd62SIgor Podgainõi 513*58fadd62SIgor Podgainõipar_reg_64_bit: 514*58fadd62SIgor Podgainõi#endif 515*58fadd62SIgor Podgainõi mrs x8, par_el1 516*58fadd62SIgor Podgainõi bl str_in_crash_buf_print 517*58fadd62SIgor Podgainõi2: 518*58fadd62SIgor Podgainõi adr x6, non_el3_sys_regs_3 519*58fadd62SIgor Podgainõi mrs x8, mpidr_el1 520*58fadd62SIgor Podgainõi mrs x9, afsr0_el1 521*58fadd62SIgor Podgainõi mrs x10, afsr1_el1 522*58fadd62SIgor Podgainõi mrs x11, contextidr_el1 523*58fadd62SIgor Podgainõi mrs x12, vbar_el1 524*58fadd62SIgor Podgainõi mrs x13, cntp_ctl_el0 525*58fadd62SIgor Podgainõi mrs x14, cntp_cval_el0 526*58fadd62SIgor Podgainõi mrs x15, cntv_ctl_el0 527*58fadd62SIgor Podgainõi bl str_in_crash_buf_print 528*58fadd62SIgor Podgainõi mrs x8, cntv_cval_el0 529*58fadd62SIgor Podgainõi mrs x9, cntkctl_el1 530*58fadd62SIgor Podgainõi mrs x10, sp_el0 531*58fadd62SIgor Podgainõi mrs x11, isr_el1 532626ed510SSoby Mathew bl str_in_crash_buf_print 533a43d431bSSoby Mathew 534c424b91eSImre Kis#if CTX_INCLUDE_AARCH32_REGS 535c424b91eSImre Kis /* Print the AArch32 registers */ 536c424b91eSImre Kis adr x6, aarch32_regs 537c424b91eSImre Kis mrs x8, dacr32_el2 538c424b91eSImre Kis mrs x9, ifsr32_el2 539c424b91eSImre Kis bl str_in_crash_buf_print 540c424b91eSImre Kis#endif /* CTX_INCLUDE_AARCH32_REGS */ 541c424b91eSImre Kis 542d3f70af6SSoby Mathew /* Get the cpu specific registers to report */ 543d3f70af6SSoby Mathew bl do_cpu_reg_dump 544d3f70af6SSoby Mathew bl str_in_crash_buf_print 5458c106902SSoby Mathew 5469ff67fa6SGerald Lejeune /* Print some platform registers */ 5479ff67fa6SGerald Lejeune plat_crash_print_regs 5488c106902SSoby Mathew 549801cf93cSAntonio Nino Diaz bl plat_crash_console_flush 550801cf93cSAntonio Nino Diaz 551626ed510SSoby Mathew /* Done reporting */ 552a806dad5SJeenu Viswambharan no_ret plat_panic_handler 553f300ef66SGovindraj Rajaendfunc report_el3_panic 554a43d431bSSoby Mathew 555626ed510SSoby Mathew#else /* CRASH_REPORTING */ 556626ed510SSoby Mathewfunc report_unhandled_exception 557626ed510SSoby Mathewreport_unhandled_interrupt: 558a806dad5SJeenu Viswambharan no_ret plat_panic_handler 5598b779620SKévin Petitendfunc report_unhandled_exception 5601645d3eeSSandrine Bailleux#endif /* CRASH_REPORTING */ 5619c22b323SAndrew Thoelke 562626ed510SSoby Mathewfunc crash_panic 563a806dad5SJeenu Viswambharan no_ret plat_panic_handler 5648b779620SKévin Petitendfunc crash_panic 565