summaryrefslogtreecommitdiff
path: root/bl31
diff options
context:
space:
mode:
authorlaurenw-arm <lauren.wehrmeister@arm.com>2019-08-20 15:51:24 -0500
committerDeepika Bhavnani <deepika.bhavnani@arm.com>2019-10-04 19:31:24 +0300
commit80942622fe760c23f0a677eac48aff37e90f4251 (patch)
tree7950a0f8c0d417e2f3519ccfb136ec48ca9b9717 /bl31
parent5f38b5362cff958225c6ad9b3d45a56b3d613fbf (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')
-rw-r--r--bl31/aarch64/ea_delegate.S39
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