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> 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*8f152319SBoyan Karatotevnon_el3_sys_regs: 45*8f152319SBoyan Karatotev .asciz "mpidr_el1", "sp_el0", "isr_el1", "" 46c424b91eSImre Kis 47c424b91eSImre Kis#if CTX_INCLUDE_AARCH32_REGS 48c424b91eSImre Kisaarch32_regs: 49c424b91eSImre Kis .asciz "dacr32_el2", "ifsr32_el2", "" 50c424b91eSImre Kis#endif /* CTX_INCLUDE_AARCH32_REGS */ 51a43d431bSSoby Mathew 52626ed510SSoby Mathewpanic_msg: 536c6a470fSAlexei Fedorov .asciz "PANIC in EL3.\nx30" 54626ed510SSoby Mathewexcpt_msg: 556c6a470fSAlexei Fedorov .asciz "Unhandled Exception in EL3.\nx30" 56626ed510SSoby Mathewintr_excpt_msg: 57b4292bc6SAlexei Fedorov .ascii "Unhandled Interrupt Exception in EL3.\n" 58b4292bc6SAlexei Fedorovx30_msg: 59b4292bc6SAlexei Fedorov .asciz "x30" 60b4292bc6SAlexei Fedorovexcpt_msg_el: 617e619eccSGovindraj Raja .asciz "Unhandled Exception from lower EL.\n" 62626ed510SSoby Mathew 63626ed510SSoby Mathew /* 64626ed510SSoby Mathew * Helper function to print from crash buf. 65626ed510SSoby Mathew * The print loop is controlled by the buf size and 66626ed510SSoby Mathew * ascii reg name list which is passed in x6. The 67626ed510SSoby Mathew * function returns the crash buf address in x0. 6858fadd62SIgor Podgainõi * Clobbers : x0 - x7, x20, sp 69626ed510SSoby Mathew */ 7058fadd62SIgor Podgainõifunc size_controlled_print_helper 7158fadd62SIgor Podgainõi#if ENABLE_FEAT_D128 7258fadd62SIgor Podgainõisize_controlled_print_128: 7358fadd62SIgor Podgainõi /* Set flag to print 128-bit registers */ 7458fadd62SIgor Podgainõi mov x20, #1 7558fadd62SIgor Podgainõi b 1f 7658fadd62SIgor Podgainõi 7758fadd62SIgor Podgainõisize_controlled_print: 7858fadd62SIgor Podgainõi /* Set flag to print 64-bit registers */ 7958fadd62SIgor Podgainõi mov x20, #0 8058fadd62SIgor Podgainõi1: 8158fadd62SIgor Podgainõi#else 8258fadd62SIgor Podgainõisize_controlled_print: 8358fadd62SIgor Podgainõi#endif 84626ed510SSoby Mathew /* Save the lr */ 85626ed510SSoby Mathew mov sp, x30 86626ed510SSoby Mathew /* load the crash buf address */ 87626ed510SSoby Mathew mrs x7, tpidr_el3 88626ed510SSoby Mathewtest_size_list: 89626ed510SSoby Mathew /* Calculate x5 always as it will be clobbered by asm_print_hex */ 90626ed510SSoby Mathew mrs x5, tpidr_el3 914779becdSBoyan Karatotev add x5, x5, #CPU_DATA_CRASH_BUF_BYTES 92626ed510SSoby Mathew /* Test whether we have reached end of crash buf */ 93626ed510SSoby Mathew cmp x7, x5 94626ed510SSoby Mathew b.eq exit_size_print 95626ed510SSoby Mathew ldrb w4, [x6] 96626ed510SSoby Mathew /* Test whether we are at end of list */ 97626ed510SSoby Mathew cbz w4, exit_size_print 98626ed510SSoby Mathew mov x4, x6 99626ed510SSoby Mathew /* asm_print_str updates x4 to point to next entry in list */ 100626ed510SSoby Mathew bl asm_print_str 1016c6a470fSAlexei Fedorov /* x0 = number of symbols printed + 1 */ 1026c6a470fSAlexei Fedorov sub x0, x4, x6 103626ed510SSoby Mathew /* update x6 with the updated list pointer */ 104626ed510SSoby Mathew mov x6, x4 1056c6a470fSAlexei Fedorov bl print_alignment 10658fadd62SIgor Podgainõi /* Print the high 64 bits (or whole 64-bit register) */ 107155a1006SJulius Werner ldr x4, [x7], #REGSZ 108626ed510SSoby Mathew bl asm_print_hex 10958fadd62SIgor Podgainõi#if ENABLE_FEAT_D128 11058fadd62SIgor Podgainõi cbz x20, 2f 11158fadd62SIgor Podgainõi /* Print the low 64 bits in case of a 128-bit register */ 11258fadd62SIgor Podgainõi ldr x4, [x7], #REGSZ 11358fadd62SIgor Podgainõi bl asm_print_hex 11458fadd62SIgor Podgainõi2: 11558fadd62SIgor Podgainõi#endif 11653d7e003SJustin Chadwell bl asm_print_newline 117626ed510SSoby Mathew b test_size_list 118626ed510SSoby Mathewexit_size_print: 119626ed510SSoby Mathew mov x30, sp 120626ed510SSoby Mathew ret 12158fadd62SIgor Podgainõiendfunc size_controlled_print_helper 122626ed510SSoby Mathew 1236c6a470fSAlexei Fedorov /* ----------------------------------------------------- 1246c6a470fSAlexei Fedorov * This function calculates and prints required number 1256c6a470fSAlexei Fedorov * of space characters followed by "= 0x", based on the 1266c6a470fSAlexei Fedorov * length of ascii register name. 1276c6a470fSAlexei Fedorov * x0: length of ascii register name + 1 1286c6a470fSAlexei Fedorov * ------------------------------------------------------ 1296c6a470fSAlexei Fedorov */ 1306c6a470fSAlexei Fedorovfunc print_alignment 1316c6a470fSAlexei Fedorov /* The minimum ascii length is 3, e.g. for "x0" */ 1326c6a470fSAlexei Fedorov adr x4, print_spacer - 3 1336c6a470fSAlexei Fedorov add x4, x4, x0 1346c6a470fSAlexei Fedorov b asm_print_str 1356c6a470fSAlexei Fedorovendfunc print_alignment 1366c6a470fSAlexei Fedorov 137626ed510SSoby Mathew /* 138626ed510SSoby Mathew * Helper function to store x8 - x15 registers to 139626ed510SSoby Mathew * the crash buf. The system registers values are 140626ed510SSoby Mathew * copied to x8 to x15 by the caller which are then 141626ed510SSoby Mathew * copied to the crash buf by this function. 142626ed510SSoby Mathew * x0 points to the crash buf. It then calls 143626ed510SSoby Mathew * size_controlled_print to print to console. 14458fadd62SIgor Podgainõi * Clobbers : x0 - x7, x20, sp 145626ed510SSoby Mathew */ 146626ed510SSoby Mathewfunc str_in_crash_buf_print 147626ed510SSoby Mathew /* restore the crash buf address in x0 */ 148626ed510SSoby Mathew mrs x0, tpidr_el3 149626ed510SSoby Mathew stp x8, x9, [x0] 150155a1006SJulius Werner stp x10, x11, [x0, #REGSZ * 2] 151155a1006SJulius Werner stp x12, x13, [x0, #REGSZ * 4] 152155a1006SJulius Werner stp x14, x15, [x0, #REGSZ * 6] 153626ed510SSoby Mathew b size_controlled_print 1548b779620SKévin Petitendfunc str_in_crash_buf_print 155626ed510SSoby Mathew 15658fadd62SIgor Podgainõi /* 15758fadd62SIgor Podgainõi * An equivalent helper function for storing x8 - x15 15858fadd62SIgor Podgainõi * registers in a different order inside the crash buf. 15958fadd62SIgor Podgainõi * In the end the function size_controlled_print_128 is 16058fadd62SIgor Podgainõi * called to print the registers to the console. 16158fadd62SIgor Podgainõi * Clobbers : x0 - x7, x20, sp 16258fadd62SIgor Podgainõi */ 16358fadd62SIgor Podgainõifunc str_in_crash_buf_print_128 16458fadd62SIgor Podgainõi /* restore the crash buf address in x0 */ 16558fadd62SIgor Podgainõi mrs x0, tpidr_el3 16658fadd62SIgor Podgainõi stp x8, x9, [x0] 16758fadd62SIgor Podgainõi stp x10, x11, [x0, #REGSZ * 2] 16858fadd62SIgor Podgainõi stp x12, x13, [x0, #REGSZ * 4] 16958fadd62SIgor Podgainõi stp x14, x15, [x0, #REGSZ * 6] 17058fadd62SIgor Podgainõi b size_controlled_print_128 17158fadd62SIgor Podgainõiendfunc str_in_crash_buf_print_128 17258fadd62SIgor Podgainõi 173626ed510SSoby Mathew /* ------------------------------------------------------ 174626ed510SSoby Mathew * This macro calculates the offset to crash buf from 175626ed510SSoby Mathew * cpu_data and stores it in tpidr_el3. It also saves x0 176626ed510SSoby Mathew * and x1 in the crash buf by using sp as a temporary 177626ed510SSoby Mathew * register. 178626ed510SSoby Mathew * ------------------------------------------------------ 179626ed510SSoby Mathew */ 180626ed510SSoby Mathew .macro prepare_crash_buf_save_x0_x1 181626ed510SSoby Mathew /* we can corrupt this reg to free up x0 */ 182626ed510SSoby Mathew mov sp, x0 183626ed510SSoby Mathew /* tpidr_el3 contains the address to cpu_data structure */ 184626ed510SSoby Mathew mrs x0, tpidr_el3 185626ed510SSoby Mathew /* Calculate the Crash buffer offset in cpu_data */ 1864779becdSBoyan Karatotev add x0, x0, #CPU_DATA_CRASH_BUF 187626ed510SSoby Mathew /* Store crash buffer address in tpidr_el3 */ 188626ed510SSoby Mathew msr tpidr_el3, x0 189155a1006SJulius Werner str x1, [x0, #REGSZ] 190626ed510SSoby Mathew mov x1, sp 191626ed510SSoby Mathew str x1, [x0] 192626ed510SSoby Mathew .endm 193a43d431bSSoby Mathew 194a43d431bSSoby Mathew /* ----------------------------------------------------- 195626ed510SSoby Mathew * This function allows to report a crash (if crash 196626ed510SSoby Mathew * reporting is enabled) when an unhandled exception 197626ed510SSoby Mathew * occurs. It prints the CPU state via the crash console 198626ed510SSoby Mathew * making use of the crash buf. This function will 199626ed510SSoby Mathew * not return. 200a43d431bSSoby Mathew * ----------------------------------------------------- 201a43d431bSSoby Mathew */ 202626ed510SSoby Mathewfunc report_unhandled_exception 203626ed510SSoby Mathew prepare_crash_buf_save_x0_x1 204626ed510SSoby Mathew adr x0, excpt_msg 205626ed510SSoby Mathew mov sp, x0 206626ed510SSoby Mathew /* This call will not return */ 207626ed510SSoby Mathew b do_crash_reporting 2088b779620SKévin Petitendfunc report_unhandled_exception 209a43d431bSSoby Mathew 210626ed510SSoby Mathew /* ----------------------------------------------------- 211626ed510SSoby Mathew * This function allows to report a crash (if crash 212626ed510SSoby Mathew * reporting is enabled) when an unhandled interrupt 213626ed510SSoby Mathew * occurs. It prints the CPU state via the crash console 214626ed510SSoby Mathew * making use of the crash buf. This function will 215626ed510SSoby Mathew * not return. 216626ed510SSoby Mathew * ----------------------------------------------------- 217626ed510SSoby Mathew */ 218626ed510SSoby Mathewfunc report_unhandled_interrupt 219626ed510SSoby Mathew prepare_crash_buf_save_x0_x1 220626ed510SSoby Mathew adr x0, intr_excpt_msg 221626ed510SSoby Mathew mov sp, x0 222626ed510SSoby Mathew /* This call will not return */ 223626ed510SSoby Mathew b do_crash_reporting 2248b779620SKévin Petitendfunc report_unhandled_interrupt 225a43d431bSSoby Mathew 226626ed510SSoby Mathew /* ----------------------------------------------------- 227b4292bc6SAlexei Fedorov * This function allows to report a crash from the lower 228b4292bc6SAlexei Fedorov * exception level (if crash reporting is enabled) when 2297e619eccSGovindraj Raja * lower_el_panic() is invoked from C Runtime. 230b4292bc6SAlexei Fedorov * It prints the CPU state via the crash console making 231b4292bc6SAlexei Fedorov * use of 'cpu_context' structure where general purpose 232b4292bc6SAlexei Fedorov * registers are saved and the crash buf. 233b4292bc6SAlexei Fedorov * This function will not return. 234b4292bc6SAlexei Fedorov * ----------------------------------------------------- 235b4292bc6SAlexei Fedorov */ 2367e619eccSGovindraj Rajafunc report_elx_panic 237b4292bc6SAlexei Fedorov msr spsel, #MODE_SP_ELX 238b4292bc6SAlexei Fedorov 239b4292bc6SAlexei Fedorov /* Print the crash message */ 240b4292bc6SAlexei Fedorov adr x4, excpt_msg_el 241b4292bc6SAlexei Fedorov bl asm_print_str 242b4292bc6SAlexei Fedorov 243b4292bc6SAlexei Fedorov /* Report x0 - x29 values stored in 'gpregs_ctx' structure */ 244b4292bc6SAlexei Fedorov /* Store the ascii list pointer in x6 */ 245b4292bc6SAlexei Fedorov adr x6, gp_regs 246b4292bc6SAlexei Fedorov add x7, sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0 247b4292bc6SAlexei Fedorov 248b4292bc6SAlexei Fedorovprint_next: 249b4292bc6SAlexei Fedorov ldrb w4, [x6] 250b4292bc6SAlexei Fedorov /* Test whether we are at end of list */ 251b4292bc6SAlexei Fedorov cbz w4, print_x30 252b4292bc6SAlexei Fedorov mov x4, x6 253b4292bc6SAlexei Fedorov /* asm_print_str updates x4 to point to next entry in list */ 254b4292bc6SAlexei Fedorov bl asm_print_str 255b4292bc6SAlexei Fedorov /* x0 = number of symbols printed + 1 */ 256b4292bc6SAlexei Fedorov sub x0, x4, x6 257b4292bc6SAlexei Fedorov /* Update x6 with the updated list pointer */ 258b4292bc6SAlexei Fedorov mov x6, x4 259b4292bc6SAlexei Fedorov bl print_alignment 260b4292bc6SAlexei Fedorov ldr x4, [x7], #REGSZ 261b4292bc6SAlexei Fedorov bl asm_print_hex 262b4292bc6SAlexei Fedorov bl asm_print_newline 263b4292bc6SAlexei Fedorov b print_next 264b4292bc6SAlexei Fedorov 265b4292bc6SAlexei Fedorovprint_x30: 266b4292bc6SAlexei Fedorov adr x4, x30_msg 267b4292bc6SAlexei Fedorov bl asm_print_str 268b4292bc6SAlexei Fedorov 269b4292bc6SAlexei Fedorov /* Print spaces to align "x30" string */ 270b4292bc6SAlexei Fedorov mov x0, #4 271b4292bc6SAlexei Fedorov bl print_alignment 272b4292bc6SAlexei Fedorov 273b4292bc6SAlexei Fedorov /* Report x30 */ 274b4292bc6SAlexei Fedorov ldr x4, [x7] 275b4292bc6SAlexei Fedorov 276b4292bc6SAlexei Fedorov /* ---------------------------------------------------------------- 277b4292bc6SAlexei Fedorov * Different virtual address space size can be defined for each EL. 278b4292bc6SAlexei Fedorov * Ensure that we use the proper one by reading the corresponding 279b4292bc6SAlexei Fedorov * TCR_ELx register. 280b4292bc6SAlexei Fedorov * ---------------------------------------------------------------- 281b4292bc6SAlexei Fedorov */ 282b4292bc6SAlexei Fedorov cmp x8, #MODE_EL2 283b4292bc6SAlexei Fedorov b.lt from_el1 /* EL1 */ 284b4292bc6SAlexei Fedorov mrs x2, sctlr_el2 285b4292bc6SAlexei Fedorov mrs x1, tcr_el2 286b4292bc6SAlexei Fedorov 287b4292bc6SAlexei Fedorov /* ---------------------------------------------------------------- 288b4292bc6SAlexei Fedorov * Check if pointer authentication is enabled at the specified EL. 289b4292bc6SAlexei Fedorov * If it isn't, we can then skip stripping a PAC code. 290b4292bc6SAlexei Fedorov * ---------------------------------------------------------------- 291b4292bc6SAlexei Fedorov */ 292b4292bc6SAlexei Fedorovtest_pauth: 293b4292bc6SAlexei Fedorov tst x2, #(SCTLR_EnIA_BIT | SCTLR_EnIB_BIT) 294b4292bc6SAlexei Fedorov b.eq no_pauth 295b4292bc6SAlexei Fedorov 296b4292bc6SAlexei Fedorov /* Demangle address */ 297b4292bc6SAlexei Fedorov and x1, x1, #0x3F /* T0SZ = TCR_ELx[5:0] */ 298b4292bc6SAlexei Fedorov sub x1, x1, #64 299b4292bc6SAlexei Fedorov neg x1, x1 /* bottom_pac_bit = 64 - T0SZ */ 300b4292bc6SAlexei Fedorov mov x2, #-1 301b4292bc6SAlexei Fedorov lsl x2, x2, x1 302b4292bc6SAlexei Fedorov bic x4, x4, x2 303b4292bc6SAlexei Fedorov 304b4292bc6SAlexei Fedorovno_pauth: 305b4292bc6SAlexei Fedorov bl asm_print_hex 306b4292bc6SAlexei Fedorov bl asm_print_newline 307b4292bc6SAlexei Fedorov 308b4292bc6SAlexei Fedorov /* tpidr_el3 contains the address to cpu_data structure */ 309b4292bc6SAlexei Fedorov mrs x0, tpidr_el3 310b4292bc6SAlexei Fedorov /* Calculate the Crash buffer offset in cpu_data */ 3114779becdSBoyan Karatotev add x0, x0, #CPU_DATA_CRASH_BUF 312b4292bc6SAlexei Fedorov /* Store crash buffer address in tpidr_el3 */ 313b4292bc6SAlexei Fedorov msr tpidr_el3, x0 314b4292bc6SAlexei Fedorov 315b4292bc6SAlexei Fedorov /* Print the rest of crash dump */ 316b4292bc6SAlexei Fedorov b print_el3_sys_regs 317b4292bc6SAlexei Fedorov 318b4292bc6SAlexei Fedorovfrom_el1: 319b4292bc6SAlexei Fedorov mrs x2, sctlr_el1 320b4292bc6SAlexei Fedorov mrs x1, tcr_el1 321b4292bc6SAlexei Fedorov b test_pauth 3227e619eccSGovindraj Rajaendfunc report_elx_panic 323b4292bc6SAlexei Fedorov 324b4292bc6SAlexei Fedorov /* ----------------------------------------------------- 325626ed510SSoby Mathew * This function allows to report a crash (if crash 326626ed510SSoby Mathew * reporting is enabled) when panic() is invoked from 327626ed510SSoby Mathew * C Runtime. It prints the CPU state via the crash 328626ed510SSoby Mathew * console making use of the crash buf. This function 329626ed510SSoby Mathew * will not return. 330626ed510SSoby Mathew * ----------------------------------------------------- 331626ed510SSoby Mathew */ 332f300ef66SGovindraj Rajafunc report_el3_panic 3336c6a470fSAlexei Fedorov msr spsel, #MODE_SP_ELX 334626ed510SSoby Mathew prepare_crash_buf_save_x0_x1 335626ed510SSoby Mathew adr x0, panic_msg 336626ed510SSoby Mathew mov sp, x0 337b4292bc6SAlexei Fedorov /* Fall through to 'do_crash_reporting' */ 338a43d431bSSoby Mathew 339626ed510SSoby Mathew /* ------------------------------------------------------------ 340626ed510SSoby Mathew * The common crash reporting functionality. It requires x0 341626ed510SSoby Mathew * and x1 has already been stored in crash buf, sp points to 342626ed510SSoby Mathew * crash message and tpidr_el3 contains the crash buf address. 343626ed510SSoby Mathew * The function does the following: 344626ed510SSoby Mathew * - Retrieve the crash buffer from tpidr_el3 345626ed510SSoby Mathew * - Store x2 to x6 in the crash buffer 346626ed510SSoby Mathew * - Initialise the crash console. 347626ed510SSoby Mathew * - Print the crash message by using the address in sp. 348626ed510SSoby Mathew * - Print x30 value to the crash console. 349626ed510SSoby Mathew * - Print x0 - x7 from the crash buf to the crash console. 350626ed510SSoby Mathew * - Print x8 - x29 (in groups of 8 registers) using the 351626ed510SSoby Mathew * crash buf to the crash console. 352626ed510SSoby Mathew * - Print el3 sys regs (in groups of 8 registers) using the 353626ed510SSoby Mathew * crash buf to the crash console. 354626ed510SSoby Mathew * - Print non el3 sys regs (in groups of 8 registers) using 35558fadd62SIgor Podgainõi * the crash buf to the crash console. A group may be 35658fadd62SIgor Podgainõi * interrupted in case a potential group of 128-bit 35758fadd62SIgor Podgainõi * sys regs needs to be printed. 358626ed510SSoby Mathew * ------------------------------------------------------------ 359626ed510SSoby Mathew */ 360b4292bc6SAlexei Fedorovdo_crash_reporting: 361626ed510SSoby Mathew /* Retrieve the crash buf from tpidr_el3 */ 362626ed510SSoby Mathew mrs x0, tpidr_el3 363626ed510SSoby Mathew /* Store x2 - x6, x30 in the crash buffer */ 364155a1006SJulius Werner stp x2, x3, [x0, #REGSZ * 2] 365155a1006SJulius Werner stp x4, x5, [x0, #REGSZ * 4] 366155a1006SJulius Werner stp x6, x30, [x0, #REGSZ * 6] 367626ed510SSoby Mathew /* Initialize the crash console */ 368626ed510SSoby Mathew bl plat_crash_console_init 369626ed510SSoby Mathew /* Verify the console is initialized */ 370626ed510SSoby Mathew cbz x0, crash_panic 371626ed510SSoby Mathew /* Print the crash message. sp points to the crash message */ 372626ed510SSoby Mathew mov x4, sp 373626ed510SSoby Mathew bl asm_print_str 3746c6a470fSAlexei Fedorov /* Print spaces to align "x30" string */ 3756c6a470fSAlexei Fedorov mov x0, #4 3766c6a470fSAlexei Fedorov bl print_alignment 377b4292bc6SAlexei Fedorov /* Load the crash buf address */ 378626ed510SSoby Mathew mrs x0, tpidr_el3 379b4292bc6SAlexei Fedorov /* Report x30 first from the crash buf */ 380155a1006SJulius Werner ldr x4, [x0, #REGSZ * 7] 38168c76088SAlexei Fedorov 38268c76088SAlexei Fedorov#if ENABLE_PAUTH 3838d9f5f25SBoyan Karatotev#if ENABLE_PAUTH == 2 3848d9f5f25SBoyan Karatotev /* Skip if not present in hardware */ 3858d9f5f25SBoyan Karatotev is_feat_pauth_present_asm x0, x1 3868d9f5f25SBoyan Karatotev beq 1f 3878d9f5f25SBoyan Karatotev#endif 3888d9f5f25SBoyan Karatotev /* 3898d9f5f25SBoyan Karatotev * The assembler must see support for xpaci. So turn the compiler 3908d9f5f25SBoyan Karatotev * extension on. GCC prior to 10 doesn't understand the PAuth extension 3918d9f5f25SBoyan Karatotev * but it does understand armv8.3-a in general. Avoid using 8.3 if 3928d9f5f25SBoyan Karatotev * the compiler understands "pauth" so we don't downgrade a higher 3938d9f5f25SBoyan Karatotev * -march that was specified on the commandline. 3948d9f5f25SBoyan Karatotev */ 3958d9f5f25SBoyan Karatotev#if __GNUC__ < 10 3968d9f5f25SBoyan Karatotev .arch armv8.3-a 3978d9f5f25SBoyan Karatotev#else 3988d9f5f25SBoyan Karatotev .arch_extension pauth 3998d9f5f25SBoyan Karatotev#endif 40068c76088SAlexei Fedorov /* Demangle address */ 40168c76088SAlexei Fedorov xpaci x4 4028d9f5f25SBoyan Karatotev1: 40368c76088SAlexei Fedorov#endif 404626ed510SSoby Mathew bl asm_print_hex 40553d7e003SJustin Chadwell bl asm_print_newline 406626ed510SSoby Mathew /* Load the crash buf address */ 407626ed510SSoby Mathew mrs x0, tpidr_el3 408626ed510SSoby Mathew /* Now mov x7 into crash buf */ 409155a1006SJulius Werner str x7, [x0, #REGSZ * 7] 410a43d431bSSoby Mathew 411626ed510SSoby Mathew /* Report x0 - x29 values stored in crash buf */ 412626ed510SSoby Mathew /* Store the ascii list pointer in x6 */ 413626ed510SSoby Mathew adr x6, gp_regs 414626ed510SSoby Mathew /* Print x0 to x7 from the crash buf */ 415626ed510SSoby Mathew bl size_controlled_print 416626ed510SSoby Mathew /* Store x8 - x15 in crash buf and print */ 417626ed510SSoby Mathew bl str_in_crash_buf_print 418626ed510SSoby Mathew /* Load the crash buf address */ 419626ed510SSoby Mathew mrs x0, tpidr_el3 420626ed510SSoby Mathew /* Store the rest of gp regs and print */ 421626ed510SSoby Mathew stp x16, x17, [x0] 422155a1006SJulius Werner stp x18, x19, [x0, #REGSZ * 2] 423155a1006SJulius Werner stp x20, x21, [x0, #REGSZ * 4] 424155a1006SJulius Werner stp x22, x23, [x0, #REGSZ * 6] 425626ed510SSoby Mathew bl size_controlled_print 426626ed510SSoby Mathew /* Load the crash buf address */ 427626ed510SSoby Mathew mrs x0, tpidr_el3 428626ed510SSoby Mathew stp x24, x25, [x0] 429155a1006SJulius Werner stp x26, x27, [x0, #REGSZ * 2] 430155a1006SJulius Werner stp x28, x29, [x0, #REGSZ * 4] 431626ed510SSoby Mathew bl size_controlled_print 432a43d431bSSoby Mathew 433626ed510SSoby Mathew /* Print the el3 sys registers */ 434b4292bc6SAlexei Fedorovprint_el3_sys_regs: 435626ed510SSoby Mathew adr x6, el3_sys_regs 436626ed510SSoby Mathew mrs x8, scr_el3 437626ed510SSoby Mathew mrs x9, sctlr_el3 438626ed510SSoby Mathew mrs x10, cptr_el3 439626ed510SSoby Mathew mrs x11, tcr_el3 440626ed510SSoby Mathew mrs x12, daif 441626ed510SSoby Mathew mrs x13, mair_el3 442626ed510SSoby Mathew mrs x14, spsr_el3 443626ed510SSoby Mathew mrs x15, elr_el3 444626ed510SSoby Mathew bl str_in_crash_buf_print 445626ed510SSoby Mathew mrs x8, ttbr0_el3 446626ed510SSoby Mathew mrs x9, esr_el3 447626ed510SSoby Mathew mrs x10, far_el3 448626ed510SSoby Mathew bl str_in_crash_buf_print 449a43d431bSSoby Mathew 450626ed510SSoby Mathew /* Print the non el3 sys registers */ 451*8f152319SBoyan Karatotev adr x6, non_el3_sys_regs 45258fadd62SIgor Podgainõi mrs x8, mpidr_el1 453*8f152319SBoyan Karatotev mrs x9, sp_el0 454*8f152319SBoyan Karatotev mrs x10, isr_el1 455626ed510SSoby Mathew bl str_in_crash_buf_print 456a43d431bSSoby Mathew 457c424b91eSImre Kis#if CTX_INCLUDE_AARCH32_REGS 458c424b91eSImre Kis /* Print the AArch32 registers */ 459c424b91eSImre Kis adr x6, aarch32_regs 460c424b91eSImre Kis mrs x8, dacr32_el2 461c424b91eSImre Kis mrs x9, ifsr32_el2 462c424b91eSImre Kis bl str_in_crash_buf_print 463c424b91eSImre Kis#endif /* CTX_INCLUDE_AARCH32_REGS */ 464c424b91eSImre Kis 465d3f70af6SSoby Mathew /* Get the cpu specific registers to report */ 466d3f70af6SSoby Mathew bl do_cpu_reg_dump 467d3f70af6SSoby Mathew bl str_in_crash_buf_print 4688c106902SSoby Mathew 4699ff67fa6SGerald Lejeune /* Print some platform registers */ 4709ff67fa6SGerald Lejeune plat_crash_print_regs 4718c106902SSoby Mathew 472801cf93cSAntonio Nino Diaz bl plat_crash_console_flush 473801cf93cSAntonio Nino Diaz 474626ed510SSoby Mathew /* Done reporting */ 475a806dad5SJeenu Viswambharan no_ret plat_panic_handler 476f300ef66SGovindraj Rajaendfunc report_el3_panic 477a43d431bSSoby Mathew 478626ed510SSoby Mathew#else /* CRASH_REPORTING */ 479626ed510SSoby Mathewfunc report_unhandled_exception 480626ed510SSoby Mathewreport_unhandled_interrupt: 481a806dad5SJeenu Viswambharan no_ret plat_panic_handler 4828b779620SKévin Petitendfunc report_unhandled_exception 4831645d3eeSSandrine Bailleux#endif /* CRASH_REPORTING */ 4849c22b323SAndrew Thoelke 485626ed510SSoby Mathewfunc crash_panic 486a806dad5SJeenu Viswambharan no_ret plat_panic_handler 4878b779620SKévin Petitendfunc crash_panic 488