diff options
author | laurenw-arm <lauren.wehrmeister@arm.com> | 2019-08-20 15:51:24 -0500 |
---|---|---|
committer | Deepika Bhavnani <deepika.bhavnani@arm.com> | 2019-10-04 19:31:24 +0300 |
commit | 80942622fe760c23f0a677eac48aff37e90f4251 (patch) | |
tree | 7950a0f8c0d417e2f3519ccfb136ec48ca9b9717 /bl31/aarch64 | |
parent | 5f38b5362cff958225c6ad9b3d45a56b3d613fbf (diff) |
Neoverse N1 Errata Workaround 1542419
Coherent I-cache is causing a prefetch violation where when the core
executes an instruction that has recently been modified, the core might
fetch a stale instruction which violates the ordering of instruction
fetches.
The workaround includes an instruction sequence to implementation
defined registers to trap all EL0 IC IVAU instructions to EL3 and a trap
handler to execute a TLB inner-shareable invalidation to an arbitrary
address followed by a DSB.
Signed-off-by: Lauren Wehrmeister <lauren.wehrmeister@arm.com>
Change-Id: Ic3b7cbb11cf2eaf9005523ef5578a372593ae4d6
Diffstat (limited to 'bl31/aarch64')
-rw-r--r-- | bl31/aarch64/ea_delegate.S | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S index 6e71a063..3cc4d56a 100644 --- a/bl31/aarch64/ea_delegate.S +++ b/bl31/aarch64/ea_delegate.S @@ -11,7 +11,8 @@ #include <bl31/ea_handle.h> #include <context.h> #include <lib/extensions/ras_arch.h> - +#include <cpu_macros.S> +#include <context.h> .globl handle_lower_el_ea_esb .globl enter_lower_el_sync_ea @@ -35,9 +36,9 @@ 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. + * EL, and expects to handle Synchronous External Aborts from lower EL and CPU + * Implementation Defined Exceptions. 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 @@ -58,12 +59,33 @@ func enter_lower_el_sync_ea b.eq 1f cmp x30, #EC_DABORT_LOWER_EL - b.ne 2f + b.eq 1f + + /* Save GP registers */ + stp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] + stp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2] + stp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4] + + /* Get the cpu_ops pointer */ + bl get_cpu_ops_ptr + + /* Get the cpu_ops exception handler */ + ldr x0, [x0, #CPU_E_HANDLER_FUNC] + + /* + * If the reserved function pointer is NULL, this CPU does not have an + * implementation defined exception handler function + */ + cbz x0, 2f + mrs x1, esr_el3 + ubfx x1, x1, #ESR_EC_SHIFT, #ESR_EC_LENGTH + blr x0 + b 2f 1: /* Test for EA bit in the instruction syndrome */ mrs x30, esr_el3 - tbz x30, #ESR_ISS_EABORT_EA_BIT, 2f + tbz x30, #ESR_ISS_EABORT_EA_BIT, 3f /* * Save general purpose and ARMv8.3-PAuth registers (if enabled). @@ -84,6 +106,11 @@ func enter_lower_el_sync_ea b delegate_sync_ea 2: + ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] + ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2] + ldp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4] + +3: /* 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 |