diff options
author | Jeenu Viswambharan <jeenu.viswambharan@arm.com> | 2017-11-30 12:54:15 +0000 |
---|---|---|
committer | Jeenu Viswambharan <jeenu.viswambharan@arm.com> | 2018-05-04 08:32:42 +0100 |
commit | 76454abf4a2a5df482a753fc435b2de0219659bf (patch) | |
tree | 8195331234b5517463c1b60eafc6d56a7a134449 /bl31 | |
parent | ef653d93ccd6ba1888c61706469021fc623c3318 (diff) | |
download | trusted-firmware-a-76454abf4a2a5df482a753fc435b2de0219659bf.tar.gz |
AArch64: Introduce External Abort handling
At present, any External Abort routed to EL3 is reported as an unhandled
exception and cause a panic. This patch enables ARM Trusted Firmware to
handle External Aborts routed to EL3.
With this patch, when an External Abort is received at EL3, its handling
is delegated to plat_ea_handler() function. Platforms can provide their
own implementation of this function. This patch adds a weak definition
of the said function that prints out a message and just panics.
In order to support handling External Aborts at EL3, the build option
HANDLE_EA_EL3_FIRST must be set to 1.
Before this patch, HANDLE_EA_EL3_FIRST wasn't passed down to
compilation; this patch fixes that too.
Change-Id: I4d07b7e65eb191ff72d63b909ae9512478cd01a1
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
Diffstat (limited to 'bl31')
-rw-r--r-- | bl31/aarch64/runtime_exceptions.S | 113 |
1 files changed, 107 insertions, 6 deletions
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S index e8cde54701..494ccd7972 100644 --- a/bl31/aarch64/runtime_exceptions.S +++ b/bl31/aarch64/runtime_exceptions.S @@ -8,6 +8,7 @@ #include <asm_macros.S> #include <context.h> #include <cpu_data.h> +#include <ea_handle.h> #include <interrupt_mgmt.h> #include <platform_def.h> #include <runtime_svc.h> @@ -35,6 +36,27 @@ .globl fiq_aarch32 .globl serror_aarch32 + /* + * 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. @@ -69,6 +91,20 @@ 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 */ ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] b report_unhandled_exception @@ -232,11 +268,14 @@ vector_entry fiq_aarch64 check_vector_size fiq_aarch64 vector_entry serror_aarch64 + msr daifclr, #DAIF_ABT_BIT + /* - * SError exceptions from lower ELs are not currently supported. - * Report their occurrence. + * Explicitly save x30 so as to free up a register and to enable + * branching */ - b report_unhandled_exception + str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] + handle_ea #ERROR_EA_ASYNC check_vector_size serror_aarch64 /* --------------------------------------------------------------------- @@ -262,11 +301,14 @@ vector_entry fiq_aarch32 check_vector_size fiq_aarch32 vector_entry serror_aarch32 + msr daifclr, #DAIF_ABT_BIT + /* - * SError exceptions from lower ELs are not currently supported. - * Report their occurrence. + * Explicitly save x30 so as to free up a register and to enable + * branching */ - b report_unhandled_exception + str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] + handle_ea #ERROR_EA_ASYNC check_vector_size serror_aarch32 @@ -443,3 +485,62 @@ 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 |