]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
Fix crash dump for lower EL
authorAlexei Fedorov <Alexei.Fedorov@arm.com>
Tue, 3 Mar 2020 13:31:58 +0000 (13:31 +0000)
committerAlexei Fedorov <Alexei.Fedorov@arm.com>
Fri, 6 Mar 2020 14:17:35 +0000 (14:17 +0000)
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: Alexei Fedorov <Alexei.Fedorov@arm.com>
bl31/aarch64/crash_reporting.S
common/aarch64/debug.S
common/backtrace/backtrace.c
docs/design/firmware-design.rst
include/arch/aarch64/arch.h
include/common/debug.h
plat/common/aarch64/plat_common.c

index 97db2a167999b080d6b1d64469a959936a8d9a6e..d56b513b87fbc0c19d88a3348f1388a88dc6e180 100644 (file)
@@ -16,6 +16,7 @@
        .globl  report_unhandled_exception
        .globl  report_unhandled_interrupt
        .globl  el3_panic
+       .globl  elx_panic
 
 #if CRASH_REPORTING
 
@@ -59,7 +60,11 @@ panic_msg:
 excpt_msg:
        .asciz "Unhandled Exception in EL3.\nx30"
 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.
@@ -170,7 +175,6 @@ func report_unhandled_exception
        b       do_crash_reporting
 endfunc report_unhandled_exception
 
-
        /* -----------------------------------------------------
         * This function allows to report a crash (if crash
         * reporting is enabled) when an unhandled interrupt
@@ -187,6 +191,112 @@ func report_unhandled_interrupt
        b       do_crash_reporting
 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
         * reporting is enabled) when panic() is invoked from
@@ -200,9 +310,7 @@ func el3_panic
        prepare_crash_buf_save_x0_x1
        adr     x0, panic_msg
        mov     sp, x0
-       /* This call will not return */
-       b       do_crash_reporting
-endfunc el3_panic
+       /* Fall through to 'do_crash_reporting' */
 
        /* ------------------------------------------------------------
         * The common crash reporting functionality. It requires x0
@@ -223,7 +331,7 @@ endfunc el3_panic
         *     the crash buf to the crash console.
         * ------------------------------------------------------------
         */
-func do_crash_reporting
+do_crash_reporting:
        /* Retrieve the crash buf from tpidr_el3 */
        mrs     x0, tpidr_el3
        /* Store x2 - x6, x30 in the crash buffer */
@@ -240,9 +348,9 @@ func do_crash_reporting
        /* Print spaces to align "x30" string */
        mov     x0, #4
        bl      print_alignment
-       /* load the crash buf address */
+       /* Load the crash buf address */
        mrs     x0, tpidr_el3
-       /* report x30 first from the crash buf */
+       /* Report x30 first from the crash buf */
        ldr     x4, [x0, #REGSZ * 7]
 
 #if ENABLE_PAUTH
@@ -256,7 +364,7 @@ func do_crash_reporting
        /* Now mov x7 into crash buf */
        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 */
        adr     x6, gp_regs
        /* Print x0 to x7 from the crash buf */
@@ -279,6 +387,7 @@ func do_crash_reporting
        bl      size_controlled_print
 
        /* Print the el3 sys registers */
+print_el3_sys_regs:
        adr     x6, el3_sys_regs
        mrs     x8, scr_el3
        mrs     x9, sctlr_el3
@@ -354,7 +463,7 @@ func do_crash_reporting
 
        /* Done reporting */
        no_ret  plat_panic_handler
-endfunc do_crash_reporting
+endfunc el3_panic
 
 #else  /* CRASH_REPORTING */
 func report_unhandled_exception
@@ -363,7 +472,6 @@ report_unhandled_interrupt:
 endfunc report_unhandled_exception
 #endif /* CRASH_REPORTING */
 
-
 func crash_panic
        no_ret  plat_panic_handler
 endfunc crash_panic
index e6e32985393a3aed34be4629e4cf124a170f0c73..7db24396e1071263ec65bbcf2c50b2659f02c9e2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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
  */
@@ -156,16 +156,32 @@ endfunc asm_print_newline
 
 /* This is for the non el3 BL stages to compile through */
        .weak el3_panic
+       .weak elx_panic
 
 func do_panic
 #if CRASH_REPORTING
        str     x0, [sp, #-0x10]!
        mrs     x0, currentel
-       ubfx    x0, x0, #2, #2
-       cmp     x0, #0x3
+       ubfx    x0, x0, #MODE_EL_SHIFT, #MODE_EL_WIDTH
+       cmp     x0, #MODE_EL3
+#if !HANDLE_EA_EL3_FIRST
        ldr     x0, [sp], #0x10
        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:
 /*
index 907117f3674882728248c86e2815962f9cac56ba..ef575006fd47d4c5b64e379a57cd000875783a1b 100644 (file)
@@ -37,7 +37,7 @@ struct frame_record {
        uintptr_t return_addr;
 };
 
-static const char *get_el_str(unsigned int el)
+const char *get_el_str(unsigned int el)
 {
        if (el == 3U) {
                return "EL3";
index d0d6ef69761e7c56896a23910569b9e644365483..8297dc78523adbd9458706208ea291e82653a4c1 100644 (file)
@@ -1177,83 +1177,104 @@ The sample crash output is shown below.
 
 ::
 
-    x0  :0x000000004F00007C
-    x1  :0x0000000007FFFFFF
-    x2  :0x0000000004014D50
-    x3  :0x0000000000000000
-    x4  :0x0000000088007998
-    x5  :0x00000000001343AC
-    x6  :0x0000000000000016
-    x7  :0x00000000000B8A38
-    x8  :0x00000000001343AC
-    x9  :0x00000000000101A8
-    x10 :0x0000000000000002
-    x11 :0x000000000000011C
-    x12 :0x00000000FEFDC644
-    x13 :0x00000000FED93FFC
-    x14 :0x0000000000247950
-    x15 :0x00000000000007A2
-    x16 :0x00000000000007A4
-    x17 :0x0000000000247950
-    x18 :0x0000000000000000
-    x19 :0x00000000FFFFFFFF
-    x20 :0x0000000004014D50
-    x21 :0x000000000400A38C
-    x22 :0x0000000000247950
-    x23 :0x0000000000000010
-    x24 :0x0000000000000024
-    x25 :0x00000000FEFDC868
-    x26 :0x00000000FEFDC86A
-    x27 :0x00000000019EDEDC
-    x28 :0x000000000A7CFDAA
-    x29 :0x0000000004010780
-    x30 :0x000000000400F004
-    scr_el3 :0x0000000000000D3D
-    sctlr_el3   :0x0000000000C8181F
-    cptr_el3    :0x0000000000000000
-    tcr_el3 :0x0000000080803520
-    daif    :0x00000000000003C0
-    mair_el3    :0x00000000000004FF
-    spsr_el3    :0x00000000800003CC
-    elr_el3 :0x000000000400C0CC
-    ttbr0_el3   :0x00000000040172A0
-    esr_el3 :0x0000000096000210
-    sp_el3  :0x0000000004014D50
-    far_el3 :0x000000004F00007C
-    spsr_el1    :0x0000000000000000
-    elr_el1 :0x0000000000000000
-    spsr_abt    :0x0000000000000000
-    spsr_und    :0x0000000000000000
-    spsr_irq    :0x0000000000000000
-    spsr_fiq    :0x0000000000000000
-    sctlr_el1   :0x0000000030C81807
-    actlr_el1   :0x0000000000000000
-    cpacr_el1   :0x0000000000300000
-    csselr_el1  :0x0000000000000002
-    sp_el1  :0x0000000004028800
-    esr_el1 :0x0000000000000000
-    ttbr0_el1   :0x000000000402C200
-    ttbr1_el1   :0x0000000000000000
-    mair_el1    :0x00000000000004FF
-    amair_el1   :0x0000000000000000
-    tcr_el1 :0x0000000000003520
-    tpidr_el1   :0x0000000000000000
-    tpidr_el0   :0x0000000000000000
-    tpidrro_el0 :0x0000000000000000
-    dacr32_el2  :0x0000000000000000
-    ifsr32_el2  :0x0000000000000000
-    par_el1 :0x0000000000000000
-    far_el1 :0x0000000000000000
-    afsr0_el1   :0x0000000000000000
-    afsr1_el1   :0x0000000000000000
-    contextidr_el1  :0x0000000000000000
-    vbar_el1    :0x0000000004027000
-    cntp_ctl_el0    :0x0000000000000000
-    cntp_cval_el0   :0x0000000000000000
-    cntv_ctl_el0    :0x0000000000000000
-    cntv_cval_el0   :0x0000000000000000
-    cntkctl_el1 :0x0000000000000000
-    sp_el0  :0x0000000004010780
+    x0             = 0x000000002a4a0000
+    x1             = 0x0000000000000001
+    x2             = 0x0000000000000002
+    x3             = 0x0000000000000003
+    x4             = 0x0000000000000004
+    x5             = 0x0000000000000005
+    x6             = 0x0000000000000006
+    x7             = 0x0000000000000007
+    x8             = 0x0000000000000008
+    x9             = 0x0000000000000009
+    x10            = 0x0000000000000010
+    x11            = 0x0000000000000011
+    x12            = 0x0000000000000012
+    x13            = 0x0000000000000013
+    x14            = 0x0000000000000014
+    x15            = 0x0000000000000015
+    x16            = 0x0000000000000016
+    x17            = 0x0000000000000017
+    x18            = 0x0000000000000018
+    x19            = 0x0000000000000019
+    x20            = 0x0000000000000020
+    x21            = 0x0000000000000021
+    x22            = 0x0000000000000022
+    x23            = 0x0000000000000023
+    x24            = 0x0000000000000024
+    x25            = 0x0000000000000025
+    x26            = 0x0000000000000026
+    x27            = 0x0000000000000027
+    x28            = 0x0000000000000028
+    x29            = 0x0000000000000029
+    x30            = 0x0000000088000b78
+    scr_el3        = 0x000000000003073d
+    sctlr_el3      = 0x00000000b0cd183f
+    cptr_el3       = 0x0000000000000000
+    tcr_el3        = 0x000000008080351c
+    daif           = 0x00000000000002c0
+    mair_el3       = 0x00000000004404ff
+    spsr_el3       = 0x0000000060000349
+    elr_el3        = 0x0000000088000114
+    ttbr0_el3      = 0x0000000004018201
+    esr_el3        = 0x00000000be000000
+    far_el3        = 0x0000000000000000
+    spsr_el1       = 0x0000000000000000
+    elr_el1        = 0x0000000000000000
+    spsr_abt       = 0x0000000000000000
+    spsr_und       = 0x0000000000000000
+    spsr_irq       = 0x0000000000000000
+    spsr_fiq       = 0x0000000000000000
+    sctlr_el1      = 0x0000000030d00800
+    actlr_el1      = 0x0000000000000000
+    cpacr_el1      = 0x0000000000000000
+    csselr_el1     = 0x0000000000000000
+    sp_el1         = 0x0000000000000000
+    esr_el1        = 0x0000000000000000
+    ttbr0_el1      = 0x0000000000000000
+    ttbr1_el1      = 0x0000000000000000
+    mair_el1       = 0x0000000000000000
+    amair_el1      = 0x0000000000000000
+    tcr_el1        = 0x0000000000000000
+    tpidr_el1      = 0x0000000000000000
+    tpidr_el0      = 0x0000000000000000
+    tpidrro_el0    = 0x0000000000000000
+    par_el1        = 0x0000000000000000
+    mpidr_el1      = 0x0000000080000000
+    afsr0_el1      = 0x0000000000000000
+    afsr1_el1      = 0x0000000000000000
+    contextidr_el1 = 0x0000000000000000
+    vbar_el1       = 0x0000000000000000
+    cntp_ctl_el0   = 0x0000000000000000
+    cntp_cval_el0  = 0x0000000000000000
+    cntv_ctl_el0   = 0x0000000000000000
+    cntv_cval_el0  = 0x0000000000000000
+    cntkctl_el1    = 0x0000000000000000
+    sp_el0         = 0x0000000004014940
+    isr_el1        = 0x0000000000000000
+    dacr32_el2     = 0x0000000000000000
+    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
 -----------------------------
index b0c265047890f559baa463b858b5897c854b7c06..2b2c11652dc8f4e28d29d239ed7a4ae00015cbf8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
  *
  * SPDX-License-Identifier: BSD-3-Clause
 #define SPSR_M_AARCH64         U(0x0)
 #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_AARCH32  BIT_64(23)
 
 
 #define MODE_EL_SHIFT          U(0x2)
 #define MODE_EL_MASK           U(0x3)
+#define MODE_EL_WIDTH          U(0x2)
 #define MODE_EL3               U(0x3)
 #define MODE_EL2               U(0x2)
 #define MODE_EL1               U(0x1)
index 245e698654447b68d3a5e2559b3c4fc0b5837c6b..9aef15b514fe802e12e6923082fe02c56f3b3247 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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
  */
@@ -91,6 +91,7 @@
 
 #if ENABLE_BACKTRACE
 void backtrace(const char *cookie);
+const char *get_el_str(unsigned int el);
 #else
 #define backtrace(x)
 #endif
index f8d3129523cf1ed5abf8e3f93d20c8392618c4c2..63871d9e5758d424bb5504d4af6782d2bb500502 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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
  */
@@ -64,6 +64,18 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode)
 }
 #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 */
 void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
                void *handle, uint64_t flags)
@@ -74,9 +86,17 @@ void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
        if (handled != 0)
                return;
 #endif
+       unsigned int level = (unsigned int)GET_EL(read_spsr_el3());
 
-       ERROR("Unhandled External Abort received on 0x%lx at EL3!\n",
-                       read_mpidr_el1());
-       ERROR(" exception reason=%u syndrome=0x%llx\n", ea_reason, syndrome);
+       ERROR("Unhandled External Abort received on 0x%lx from %s\n",
+               read_mpidr_el1(), get_el_str(level));
+       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();
 }