RAS: Move EA handling to a separate file
authorJeenu Viswambharan <[email protected]>
Thu, 5 Jul 2018 14:24:45 +0000 (15:24 +0100)
committerJeenu Viswambharan <[email protected]>
Tue, 17 Jul 2018 07:31:31 +0000 (08:31 +0100)
A new file ea_delegate.S is introduced, and all EA-related functions are
moved into it. This makes runtime_exceptions.S less crowded and reads
better.

No functional changes.

Change-Id: I64b653b3931984cffd420563f8e8d1ba263f329f
Signed-off-by: Jeenu Viswambharan <[email protected]>
bl31/aarch64/ea_delegate.S [new file with mode: 0644]
bl31/aarch64/runtime_exceptions.S
bl31/bl31.mk

diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S
new file mode 100644 (file)
index 0000000..dce1f5a
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <asm_macros.S>
+#include <context.h>
+#include <ea_handle.h>
+
+
+       .globl  handle_lower_el_ea_esb
+       .globl  enter_lower_el_sync_ea
+       .globl  enter_lower_el_async_ea
+
+
+/*
+ * Function to delegate External Aborts synchronized by ESB instruction at EL3
+ * vector entry. This function assumes GP registers x0-x29 have been saved, and
+ * are available for use. It delegates the handling of the EA to platform
+ * handler, and returns only upon successfully handling the EA; otherwise
+ * panics. On return from this function, the original exception handler is
+ * expected to resume.
+ */
+func handle_lower_el_ea_esb
+       mov     x0, #ERROR_EA_ESB
+       mrs     x1, DISR_EL1
+       b       ea_proceed
+endfunc handle_lower_el_ea_esb
+
+
+/*
+ * This function forms the tail end of Synchronous Exception entry from lower
+ * EL, and expects to handle only Synchronous External Aborts from lower EL. If
+ * any other kind of exception is detected, then this function reports unhandled
+ * exception.
+ *
+ * Since it's part of exception vector, this function doesn't expect any GP
+ * registers to have been saved. It delegates the handling of the EA to platform
+ * handler, and upon successfully handling the EA, exits EL3; otherwise panics.
+ */
+func enter_lower_el_sync_ea
+       /*
+        * Explicitly save x30 so as to free up a register and to enable
+        * branching.
+        */
+       str     x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+
+       mrs     x30, esr_el3
+       ubfx    x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
+
+       /* Check for I/D aborts from lower EL */
+       cmp     x30, #EC_IABORT_LOWER_EL
+       b.eq    1f
+
+       cmp     x30, #EC_DABORT_LOWER_EL
+       b.ne    2f
+
+1:
+       /* Test for EA bit in the instruction syndrome */
+       mrs     x30, esr_el3
+       tbz     x30, #ESR_ISS_EABORT_EA_BIT, 2f
+
+       /* Save GP registers */
+       bl      save_gp_registers
+
+       /* Setup exception class and syndrome arguments for platform handler */
+       mov     x0, #ERROR_EA_SYNC
+       mrs     x1, esr_el3
+       adr     x30, el3_exit
+       b       ea_proceed
+
+2:
+       /* Synchronous exceptions other than the above are assumed to be EA */
+       ldr     x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+       no_ret  report_unhandled_exception
+endfunc enter_lower_el_sync_ea
+
+
+/*
+ * This function handles SErrors from lower ELs.
+ *
+ * Since it's part of exception vector, this function doesn't expect any GP
+ * registers to have been saved. It delegates the handling of the EA to platform
+ * handler, and upon successfully handling the EA, exits EL3; otherwise panics.
+ */
+func enter_lower_el_async_ea
+       /*
+        * Explicitly save x30 so as to free up a register and to enable
+        * branching
+        */
+       str     x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+
+       /* Save GP registers */
+       bl      save_gp_registers
+
+       /* Setup exception class and syndrome arguments for platform handler */
+       mov     x0, #ERROR_EA_ASYNC
+       mrs     x1, esr_el3
+       adr     x30, el3_exit
+       b       ea_proceed
+endfunc enter_lower_el_async_ea
+
+
+/*
+ * Delegate External Abort handling to platform's EA handler. This function
+ * assumes that all GP registers have been saved by the caller.
+ *
+ * x0: EA reason
+ * x1: EA syndrome
+ */
+func ea_proceed
+       /* Save EL3 state */
+       mrs     x2, spsr_el3
+       mrs     x3, elr_el3
+       stp     x2, x3, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
+
+       /*
+        * Save ESR as handling might involve lower ELs, and returning back to
+        * EL3 from there would trample the original ESR.
+        */
+       mrs     x4, scr_el3
+       mrs     x5, esr_el3
+       stp     x4, x5, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
+
+       /*
+        * Setup rest of arguments, and call platform External Abort handler.
+        *
+        * x0: EA reason (already in place)
+        * x1: Exception syndrome (already in place).
+        * x2: Cookie (unused for now).
+        * x3: Context pointer.
+        * x4: Flags (security state from SCR for now).
+        */
+       mov     x2, xzr
+       mov     x3, sp
+       ubfx    x4, x4, #0, #1
+
+       /* Switch to runtime stack */
+       ldr     x5, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
+       msr     spsel, #0
+       mov     sp, x5
+
+       mov     x29, x30
+       bl      plat_ea_handler
+       mov     x30, x29
+
+       /* Make SP point to context */
+       msr     spsel, #1
+
+       /* Restore EL3 state */
+       ldp     x1, x2, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
+       msr     spsr_el3, x1
+       msr     elr_el3, x2
+
+       /* Restore ESR_EL3 and SCR_EL3 */
+       ldp     x3, x4, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
+       msr     scr_el3, x3
+       msr     esr_el3, x4
+
+       ret
+endfunc ea_proceed
index 12f9f109b39ec327d041e1ef487eb78ed9a37081..ff77597a7fca9ec9b56facbfcd18a36fa74d7538 100644 (file)
@@ -66,9 +66,7 @@
 
        /* Save GP registers and restore them afterwards */
        bl      save_gp_registers
-       mov     x0, #ERROR_EA_ESB
-       mrs     x1, DISR_EL1
-       bl      delegate_ea
+       bl      handle_lower_el_ea_esb
        bl      restore_gp_registers
 
 1:
 #endif
        .endm
 
-       /*
-        * Handle External Abort by delegating to the platform's EA handler.
-        * Once the platform handler returns, the macro exits EL3 and returns to
-        * where the abort was taken from.
-        *
-        * This macro assumes that x30 is available for use.
-        *
-        * 'abort_type' is a constant passed to the platform handler, indicating
-        * the cause of the External Abort.
-        */
-       .macro handle_ea abort_type
-       /* Save GP registers */
-       bl      save_gp_registers
-
-       /* Setup exception class and syndrome arguments for platform handler */
-       mov     x0, \abort_type
-       mrs     x1, esr_el3
-       adr     x30, el3_exit
-       b       delegate_ea
-       .endm
-
        /* ---------------------------------------------------------------------
         * This macro handles Synchronous exceptions.
         * Only SMC exceptions are supported.
        cmp     x30, #EC_AARCH64_SMC
        b.eq    smc_handler64
 
-       /* Check for I/D aborts from lower EL */
-       cmp     x30, #EC_IABORT_LOWER_EL
-       b.eq    1f
-
-       cmp     x30, #EC_DABORT_LOWER_EL
-       b.ne    2f
-
-1:
-       /* Test for EA bit in the instruction syndrome */
-       mrs     x30, esr_el3
-       tbz     x30, #ESR_ISS_EABORT_EA_BIT, 2f
-       handle_ea #ERROR_EA_SYNC
-
-2:
-       /* Other kinds of synchronous exceptions are not handled */
+       /* Synchronous exceptions other than the above are assumed to be EA */
        ldr     x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
-       b       report_unhandled_exception
+       b       enter_lower_el_sync_ea
        .endm
 
 
@@ -306,13 +269,7 @@ end_vector_entry fiq_aarch64
 
 vector_entry serror_aarch64
        msr     daifclr, #DAIF_ABT_BIT
-
-       /*
-        * Explicitly save x30 so as to free up a register and to enable
-        * branching
-        */
-       str     x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
-       handle_ea #ERROR_EA_ASYNC
+       b       enter_lower_el_async_ea
 end_vector_entry serror_aarch64
 
        /* ---------------------------------------------------------------------
@@ -342,13 +299,7 @@ end_vector_entry fiq_aarch32
 
 vector_entry serror_aarch32
        msr     daifclr, #DAIF_ABT_BIT
-
-       /*
-        * Explicitly save x30 so as to free up a register and to enable
-        * branching
-        */
-       str     x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
-       handle_ea #ERROR_EA_ASYNC
+       b       enter_lower_el_async_ea
 end_vector_entry serror_aarch32
 
 
@@ -525,62 +476,3 @@ rt_svc_fw_critical_error:
        msr     spsel, #1
        no_ret  report_unhandled_exception
 endfunc smc_handler
-
-/*
- * Delegate External Abort handling to platform's EA handler. This function
- * assumes that all GP registers have been saved by the caller.
- *
- * x0: EA reason
- * x1: EA syndrome
- */
-func delegate_ea
-       /* Save EL3 state */
-       mrs     x2, spsr_el3
-       mrs     x3, elr_el3
-       stp     x2, x3, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
-
-       /*
-        * Save ESR as handling might involve lower ELs, and returning back to
-        * EL3 from there would trample the original ESR.
-        */
-       mrs     x4, scr_el3
-       mrs     x5, esr_el3
-       stp     x4, x5, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
-
-       /*
-        * Setup rest of arguments, and call platform External Abort handler.
-        *
-        * x0: EA reason (already in place)
-        * x1: Exception syndrome (already in place).
-        * x2: Cookie (unused for now).
-        * x3: Context pointer.
-        * x4: Flags (security state from SCR for now).
-        */
-       mov     x2, xzr
-       mov     x3, sp
-       ubfx    x4, x4, #0, #1
-
-       /* Switch to runtime stack */
-       ldr     x5, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
-       msr     spsel, #0
-       mov     sp, x5
-
-       mov     x29, x30
-       bl      plat_ea_handler
-       mov     x30, x29
-
-       /* Make SP point to context */
-       msr     spsel, #1
-
-       /* Restore EL3 state */
-       ldp     x1, x2, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
-       msr     spsr_el3, x1
-       msr     elr_el3, x2
-
-       /* Restore ESR_EL3 and SCR_EL3 */
-       ldp     x3, x4, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
-       msr     scr_el3, x3
-       msr     esr_el3, x4
-
-       ret
-endfunc delegate_ea
index 307ddab694fab41867d72f4123f81ce5eb7eebd9..bff965386528625b130b3e7de6001a69037e2f89 100644 (file)
@@ -19,6 +19,7 @@ BL31_SOURCES          +=      bl31/bl31_main.c                                \
                                bl31/interrupt_mgmt.c                           \
                                bl31/aarch64/bl31_entrypoint.S                  \
                                bl31/aarch64/crash_reporting.S                  \
+                               bl31/aarch64/ea_delegate.S                      \
                                bl31/aarch64/runtime_exceptions.S               \
                                bl31/bl31_context_mgmt.c                        \
                                common/runtime_svc.c                            \