Commit b4292bc6 authored by Alexei Fedorov's avatar Alexei Fedorov
Browse files

Fix crash dump for lower EL



This patch provides a fix for incorrect crash dump data for
lower EL when TF-A is built with HANDLE_EA_EL3_FIRST=1 option
which enables routing of External Aborts and SErrors to EL3.

Change-Id: I9d5e6775e6aad21db5b78362da6c3a3d897df977
Signed-off-by: default avatarAlexei Fedorov <Alexei.Fedorov@arm.com>
parent 03ea84c3
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
.globl report_unhandled_exception .globl report_unhandled_exception
.globl report_unhandled_interrupt .globl report_unhandled_interrupt
.globl el3_panic .globl el3_panic
.globl elx_panic
#if CRASH_REPORTING #if CRASH_REPORTING
...@@ -59,7 +60,11 @@ panic_msg: ...@@ -59,7 +60,11 @@ panic_msg:
excpt_msg: excpt_msg:
.asciz "Unhandled Exception in EL3.\nx30" .asciz "Unhandled Exception in EL3.\nx30"
intr_excpt_msg: intr_excpt_msg:
.asciz "Unhandled Interrupt Exception in EL3.\nx30" .ascii "Unhandled Interrupt Exception in EL3.\n"
x30_msg:
.asciz "x30"
excpt_msg_el:
.asciz "Unhandled Exception from EL"
/* /*
* Helper function to print from crash buf. * Helper function to print from crash buf.
...@@ -170,7 +175,6 @@ func report_unhandled_exception ...@@ -170,7 +175,6 @@ func report_unhandled_exception
b do_crash_reporting b do_crash_reporting
endfunc report_unhandled_exception endfunc report_unhandled_exception
/* ----------------------------------------------------- /* -----------------------------------------------------
* This function allows to report a crash (if crash * This function allows to report a crash (if crash
* reporting is enabled) when an unhandled interrupt * reporting is enabled) when an unhandled interrupt
...@@ -187,6 +191,112 @@ func report_unhandled_interrupt ...@@ -187,6 +191,112 @@ func report_unhandled_interrupt
b do_crash_reporting b do_crash_reporting
endfunc report_unhandled_interrupt endfunc report_unhandled_interrupt
/* -----------------------------------------------------
* This function allows to report a crash from the lower
* exception level (if crash reporting is enabled) when
* panic() is invoked from C Runtime.
* It prints the CPU state via the crash console making
* use of 'cpu_context' structure where general purpose
* registers are saved and the crash buf.
* This function will not return.
*
* x0: Exception level
* -----------------------------------------------------
*/
func elx_panic
msr spsel, #MODE_SP_ELX
mov x8, x0
/* Print the crash message */
adr x4, excpt_msg_el
bl asm_print_str
/* Print exception level */
add x0, x8, #'0'
bl plat_crash_console_putc
bl asm_print_newline
/* Report x0 - x29 values stored in 'gpregs_ctx' structure */
/* Store the ascii list pointer in x6 */
adr x6, gp_regs
add x7, sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0
print_next:
ldrb w4, [x6]
/* Test whether we are at end of list */
cbz w4, print_x30
mov x4, x6
/* asm_print_str updates x4 to point to next entry in list */
bl asm_print_str
/* x0 = number of symbols printed + 1 */
sub x0, x4, x6
/* Update x6 with the updated list pointer */
mov x6, x4
bl print_alignment
ldr x4, [x7], #REGSZ
bl asm_print_hex
bl asm_print_newline
b print_next
print_x30:
adr x4, x30_msg
bl asm_print_str
/* Print spaces to align "x30" string */
mov x0, #4
bl print_alignment
/* Report x30 */
ldr x4, [x7]
/* ----------------------------------------------------------------
* Different virtual address space size can be defined for each EL.
* Ensure that we use the proper one by reading the corresponding
* TCR_ELx register.
* ----------------------------------------------------------------
*/
cmp x8, #MODE_EL2
b.lt from_el1 /* EL1 */
mrs x2, sctlr_el2
mrs x1, tcr_el2
/* ----------------------------------------------------------------
* Check if pointer authentication is enabled at the specified EL.
* If it isn't, we can then skip stripping a PAC code.
* ----------------------------------------------------------------
*/
test_pauth:
tst x2, #(SCTLR_EnIA_BIT | SCTLR_EnIB_BIT)
b.eq no_pauth
/* Demangle address */
and x1, x1, #0x3F /* T0SZ = TCR_ELx[5:0] */
sub x1, x1, #64
neg x1, x1 /* bottom_pac_bit = 64 - T0SZ */
mov x2, #-1
lsl x2, x2, x1
bic x4, x4, x2
no_pauth:
bl asm_print_hex
bl asm_print_newline
/* tpidr_el3 contains the address to cpu_data structure */
mrs x0, tpidr_el3
/* Calculate the Crash buffer offset in cpu_data */
add x0, x0, #CPU_DATA_CRASH_BUF_OFFSET
/* Store crash buffer address in tpidr_el3 */
msr tpidr_el3, x0
/* Print the rest of crash dump */
b print_el3_sys_regs
from_el1:
mrs x2, sctlr_el1
mrs x1, tcr_el1
b test_pauth
endfunc elx_panic
/* ----------------------------------------------------- /* -----------------------------------------------------
* This function allows to report a crash (if crash * This function allows to report a crash (if crash
* reporting is enabled) when panic() is invoked from * reporting is enabled) when panic() is invoked from
...@@ -200,9 +310,7 @@ func el3_panic ...@@ -200,9 +310,7 @@ func el3_panic
prepare_crash_buf_save_x0_x1 prepare_crash_buf_save_x0_x1
adr x0, panic_msg adr x0, panic_msg
mov sp, x0 mov sp, x0
/* This call will not return */ /* Fall through to 'do_crash_reporting' */
b do_crash_reporting
endfunc el3_panic
/* ------------------------------------------------------------ /* ------------------------------------------------------------
* The common crash reporting functionality. It requires x0 * The common crash reporting functionality. It requires x0
...@@ -223,7 +331,7 @@ endfunc el3_panic ...@@ -223,7 +331,7 @@ endfunc el3_panic
* the crash buf to the crash console. * the crash buf to the crash console.
* ------------------------------------------------------------ * ------------------------------------------------------------
*/ */
func do_crash_reporting do_crash_reporting:
/* Retrieve the crash buf from tpidr_el3 */ /* Retrieve the crash buf from tpidr_el3 */
mrs x0, tpidr_el3 mrs x0, tpidr_el3
/* Store x2 - x6, x30 in the crash buffer */ /* Store x2 - x6, x30 in the crash buffer */
...@@ -240,9 +348,9 @@ func do_crash_reporting ...@@ -240,9 +348,9 @@ func do_crash_reporting
/* Print spaces to align "x30" string */ /* Print spaces to align "x30" string */
mov x0, #4 mov x0, #4
bl print_alignment bl print_alignment
/* load the crash buf address */ /* Load the crash buf address */
mrs x0, tpidr_el3 mrs x0, tpidr_el3
/* report x30 first from the crash buf */ /* Report x30 first from the crash buf */
ldr x4, [x0, #REGSZ * 7] ldr x4, [x0, #REGSZ * 7]
#if ENABLE_PAUTH #if ENABLE_PAUTH
...@@ -256,7 +364,7 @@ func do_crash_reporting ...@@ -256,7 +364,7 @@ func do_crash_reporting
/* Now mov x7 into crash buf */ /* Now mov x7 into crash buf */
str x7, [x0, #REGSZ * 7] str x7, [x0, #REGSZ * 7]
/* Report x0 - x29 values stored in crash buf*/ /* Report x0 - x29 values stored in crash buf */
/* Store the ascii list pointer in x6 */ /* Store the ascii list pointer in x6 */
adr x6, gp_regs adr x6, gp_regs
/* Print x0 to x7 from the crash buf */ /* Print x0 to x7 from the crash buf */
...@@ -279,6 +387,7 @@ func do_crash_reporting ...@@ -279,6 +387,7 @@ func do_crash_reporting
bl size_controlled_print bl size_controlled_print
/* Print the el3 sys registers */ /* Print the el3 sys registers */
print_el3_sys_regs:
adr x6, el3_sys_regs adr x6, el3_sys_regs
mrs x8, scr_el3 mrs x8, scr_el3
mrs x9, sctlr_el3 mrs x9, sctlr_el3
...@@ -354,7 +463,7 @@ func do_crash_reporting ...@@ -354,7 +463,7 @@ func do_crash_reporting
/* Done reporting */ /* Done reporting */
no_ret plat_panic_handler no_ret plat_panic_handler
endfunc do_crash_reporting endfunc el3_panic
#else /* CRASH_REPORTING */ #else /* CRASH_REPORTING */
func report_unhandled_exception func report_unhandled_exception
...@@ -363,7 +472,6 @@ report_unhandled_interrupt: ...@@ -363,7 +472,6 @@ report_unhandled_interrupt:
endfunc report_unhandled_exception endfunc report_unhandled_exception
#endif /* CRASH_REPORTING */ #endif /* CRASH_REPORTING */
func crash_panic func crash_panic
no_ret plat_panic_handler no_ret plat_panic_handler
endfunc crash_panic endfunc crash_panic
/* /*
* Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -156,16 +156,32 @@ endfunc asm_print_newline ...@@ -156,16 +156,32 @@ endfunc asm_print_newline
/* This is for the non el3 BL stages to compile through */ /* This is for the non el3 BL stages to compile through */
.weak el3_panic .weak el3_panic
.weak elx_panic
func do_panic func do_panic
#if CRASH_REPORTING #if CRASH_REPORTING
str x0, [sp, #-0x10]! str x0, [sp, #-0x10]!
mrs x0, currentel mrs x0, currentel
ubfx x0, x0, #2, #2 ubfx x0, x0, #MODE_EL_SHIFT, #MODE_EL_WIDTH
cmp x0, #0x3 cmp x0, #MODE_EL3
#if !HANDLE_EA_EL3_FIRST
ldr x0, [sp], #0x10 ldr x0, [sp], #0x10
b.eq el3_panic b.eq el3_panic
#endif #else
b.ne to_panic_common
/* Check EL the exception taken from */
mrs x0, spsr_el3
ubfx x0, x0, #SPSR_EL_SHIFT, #SPSR_EL_WIDTH
cmp x0, #MODE_EL3
b.ne elx_panic
ldr x0, [sp], #0x10
b el3_panic
to_panic_common:
ldr x0, [sp], #0x10
#endif /* HANDLE_EA_EL3_FIRST */
#endif /* CRASH_REPORTING */
panic_common: panic_common:
/* /*
......
...@@ -37,7 +37,7 @@ struct frame_record { ...@@ -37,7 +37,7 @@ struct frame_record {
uintptr_t return_addr; uintptr_t return_addr;
}; };
static const char *get_el_str(unsigned int el) const char *get_el_str(unsigned int el)
{ {
if (el == 3U) { if (el == 3U) {
return "EL3"; return "EL3";
......
...@@ -1177,83 +1177,104 @@ The sample crash output is shown below. ...@@ -1177,83 +1177,104 @@ The sample crash output is shown below.
:: ::
x0 :0x000000004F00007C x0 = 0x000000002a4a0000
x1 :0x0000000007FFFFFF x1 = 0x0000000000000001
x2 :0x0000000004014D50 x2 = 0x0000000000000002
x3 :0x0000000000000000 x3 = 0x0000000000000003
x4 :0x0000000088007998 x4 = 0x0000000000000004
x5 :0x00000000001343AC x5 = 0x0000000000000005
x6 :0x0000000000000016 x6 = 0x0000000000000006
x7 :0x00000000000B8A38 x7 = 0x0000000000000007
x8 :0x00000000001343AC x8 = 0x0000000000000008
x9 :0x00000000000101A8 x9 = 0x0000000000000009
x10 :0x0000000000000002 x10 = 0x0000000000000010
x11 :0x000000000000011C x11 = 0x0000000000000011
x12 :0x00000000FEFDC644 x12 = 0x0000000000000012
x13 :0x00000000FED93FFC x13 = 0x0000000000000013
x14 :0x0000000000247950 x14 = 0x0000000000000014
x15 :0x00000000000007A2 x15 = 0x0000000000000015
x16 :0x00000000000007A4 x16 = 0x0000000000000016
x17 :0x0000000000247950 x17 = 0x0000000000000017
x18 :0x0000000000000000 x18 = 0x0000000000000018
x19 :0x00000000FFFFFFFF x19 = 0x0000000000000019
x20 :0x0000000004014D50 x20 = 0x0000000000000020
x21 :0x000000000400A38C x21 = 0x0000000000000021
x22 :0x0000000000247950 x22 = 0x0000000000000022
x23 :0x0000000000000010 x23 = 0x0000000000000023
x24 :0x0000000000000024 x24 = 0x0000000000000024
x25 :0x00000000FEFDC868 x25 = 0x0000000000000025
x26 :0x00000000FEFDC86A x26 = 0x0000000000000026
x27 :0x00000000019EDEDC x27 = 0x0000000000000027
x28 :0x000000000A7CFDAA x28 = 0x0000000000000028
x29 :0x0000000004010780 x29 = 0x0000000000000029
x30 :0x000000000400F004 x30 = 0x0000000088000b78
scr_el3 :0x0000000000000D3D scr_el3 = 0x000000000003073d
sctlr_el3 :0x0000000000C8181F sctlr_el3 = 0x00000000b0cd183f
cptr_el3 :0x0000000000000000 cptr_el3 = 0x0000000000000000
tcr_el3 :0x0000000080803520 tcr_el3 = 0x000000008080351c
daif :0x00000000000003C0 daif = 0x00000000000002c0
mair_el3 :0x00000000000004FF mair_el3 = 0x00000000004404ff
spsr_el3 :0x00000000800003CC spsr_el3 = 0x0000000060000349
elr_el3 :0x000000000400C0CC elr_el3 = 0x0000000088000114
ttbr0_el3 :0x00000000040172A0 ttbr0_el3 = 0x0000000004018201
esr_el3 :0x0000000096000210 esr_el3 = 0x00000000be000000
sp_el3 :0x0000000004014D50 far_el3 = 0x0000000000000000
far_el3 :0x000000004F00007C spsr_el1 = 0x0000000000000000
spsr_el1 :0x0000000000000000 elr_el1 = 0x0000000000000000
elr_el1 :0x0000000000000000 spsr_abt = 0x0000000000000000
spsr_abt :0x0000000000000000 spsr_und = 0x0000000000000000
spsr_und :0x0000000000000000 spsr_irq = 0x0000000000000000
spsr_irq :0x0000000000000000 spsr_fiq = 0x0000000000000000
spsr_fiq :0x0000000000000000 sctlr_el1 = 0x0000000030d00800
sctlr_el1 :0x0000000030C81807 actlr_el1 = 0x0000000000000000
actlr_el1 :0x0000000000000000 cpacr_el1 = 0x0000000000000000
cpacr_el1 :0x0000000000300000 csselr_el1 = 0x0000000000000000
csselr_el1 :0x0000000000000002 sp_el1 = 0x0000000000000000
sp_el1 :0x0000000004028800 esr_el1 = 0x0000000000000000
esr_el1 :0x0000000000000000 ttbr0_el1 = 0x0000000000000000
ttbr0_el1 :0x000000000402C200 ttbr1_el1 = 0x0000000000000000
ttbr1_el1 :0x0000000000000000 mair_el1 = 0x0000000000000000
mair_el1 :0x00000000000004FF amair_el1 = 0x0000000000000000
amair_el1 :0x0000000000000000 tcr_el1 = 0x0000000000000000
tcr_el1 :0x0000000000003520 tpidr_el1 = 0x0000000000000000
tpidr_el1 :0x0000000000000000 tpidr_el0 = 0x0000000000000000
tpidr_el0 :0x0000000000000000 tpidrro_el0 = 0x0000000000000000
tpidrro_el0 :0x0000000000000000 par_el1 = 0x0000000000000000
dacr32_el2 :0x0000000000000000 mpidr_el1 = 0x0000000080000000
ifsr32_el2 :0x0000000000000000 afsr0_el1 = 0x0000000000000000
par_el1 :0x0000000000000000 afsr1_el1 = 0x0000000000000000
far_el1 :0x0000000000000000 contextidr_el1 = 0x0000000000000000
afsr0_el1 :0x0000000000000000 vbar_el1 = 0x0000000000000000
afsr1_el1 :0x0000000000000000 cntp_ctl_el0 = 0x0000000000000000
contextidr_el1 :0x0000000000000000 cntp_cval_el0 = 0x0000000000000000
vbar_el1 :0x0000000004027000 cntv_ctl_el0 = 0x0000000000000000
cntp_ctl_el0 :0x0000000000000000 cntv_cval_el0 = 0x0000000000000000
cntp_cval_el0 :0x0000000000000000 cntkctl_el1 = 0x0000000000000000
cntv_ctl_el0 :0x0000000000000000 sp_el0 = 0x0000000004014940
cntv_cval_el0 :0x0000000000000000 isr_el1 = 0x0000000000000000
cntkctl_el1 :0x0000000000000000 dacr32_el2 = 0x0000000000000000
sp_el0 :0x0000000004010780 ifsr32_el2 = 0x0000000000000000
icc_hppir0_el1 = 0x00000000000003ff
icc_hppir1_el1 = 0x00000000000003ff
icc_ctlr_el3 = 0x0000000000080400
gicd_ispendr regs (Offsets 0x200-0x278)
Offset Value
0x200: 0x0000000000000000
0x208: 0x0000000000000000
0x210: 0x0000000000000000
0x218: 0x0000000000000000
0x220: 0x0000000000000000
0x228: 0x0000000000000000
0x230: 0x0000000000000000
0x238: 0x0000000000000000
0x240: 0x0000000000000000
0x248: 0x0000000000000000
0x250: 0x0000000000000000
0x258: 0x0000000000000000
0x260: 0x0000000000000000
0x268: 0x0000000000000000
0x270: 0x0000000000000000
0x278: 0x0000000000000000
Guidelines for Reset Handlers Guidelines for Reset Handlers
----------------------------- -----------------------------
......
/* /*
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
...@@ -452,6 +452,9 @@ ...@@ -452,6 +452,9 @@
#define SPSR_M_AARCH64 U(0x0) #define SPSR_M_AARCH64 U(0x0)
#define SPSR_M_AARCH32 U(0x1) #define SPSR_M_AARCH32 U(0x1)
#define SPSR_EL_SHIFT U(2)
#define SPSR_EL_WIDTH U(2)
#define SPSR_SSBS_BIT_AARCH64 BIT_64(12) #define SPSR_SSBS_BIT_AARCH64 BIT_64(12)
#define SPSR_SSBS_BIT_AARCH32 BIT_64(23) #define SPSR_SSBS_BIT_AARCH32 BIT_64(23)
...@@ -557,6 +560,7 @@ ...@@ -557,6 +560,7 @@
#define MODE_EL_SHIFT U(0x2) #define MODE_EL_SHIFT U(0x2)
#define MODE_EL_MASK U(0x3) #define MODE_EL_MASK U(0x3)
#define MODE_EL_WIDTH U(0x2)
#define MODE_EL3 U(0x3) #define MODE_EL3 U(0x3)
#define MODE_EL2 U(0x2) #define MODE_EL2 U(0x2)
#define MODE_EL1 U(0x1) #define MODE_EL1 U(0x1)
......
/* /*
* Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -91,6 +91,7 @@ ...@@ -91,6 +91,7 @@
#if ENABLE_BACKTRACE #if ENABLE_BACKTRACE
void backtrace(const char *cookie); void backtrace(const char *cookie);
const char *get_el_str(unsigned int el);
#else #else
#define backtrace(x) #define backtrace(x)
#endif #endif
......
/* /*
* Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -64,6 +64,18 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) ...@@ -64,6 +64,18 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
} }
#endif #endif
#if !ENABLE_BACKTRACE
static const char *get_el_str(unsigned int el)
{
if (el == MODE_EL3) {
return "EL3";
} else if (el == MODE_EL2) {
return "EL2";
}
return "S-EL1";
}
#endif /* !ENABLE_BACKTRACE */
/* RAS functions common to AArch64 ARM platforms */ /* RAS functions common to AArch64 ARM platforms */
void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
void *handle, uint64_t flags) void *handle, uint64_t flags)
...@@ -74,9 +86,17 @@ void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, ...@@ -74,9 +86,17 @@ void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
if (handled != 0) if (handled != 0)
return; return;
#endif #endif
unsigned int level = (unsigned int)GET_EL(read_spsr_el3());
ERROR("Unhandled External Abort received on 0x%lx at EL3!\n", ERROR("Unhandled External Abort received on 0x%lx from %s\n",
read_mpidr_el1()); read_mpidr_el1(), get_el_str(level));
ERROR(" exception reason=%u syndrome=0x%llx\n", ea_reason, syndrome); ERROR("exception reason=%u syndrome=0x%llx\n", ea_reason, syndrome);
#if HANDLE_EA_EL3_FIRST
/* Skip backtrace for lower EL */
if (level != MODE_EL3) {
(void)console_flush();
do_panic();
}
#endif
panic(); panic();
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment