Neoverse N1 Errata Workaround 1542419
[project/bcm63xx/atf.git] / lib / cpus / aarch64 / neoverse_n1.S
index 31e7a3a71991df2fa8ce9370d963016334175c7c..c9bb005e3114b0bc554a53419bda80c6a923dcc3 100644 (file)
@@ -9,6 +9,7 @@
 #include <neoverse_n1.h>
 #include <cpuamu.h>
 #include <cpu_macros.S>
+#include <context.h>
 
 /* Hardware handled coherency */
 #if HW_ASSISTED_COHERENCY == 0
 #error "Neoverse-N1 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
+#if ERRATA_N1_IC_TRAP
+       .global neoverse_n1_errata_ic_trap_handler
+#endif
+
 /* --------------------------------------------------
  * Errata Workaround for Neoverse N1 Erratum 1043202.
  * This applies to revision r0p0 and r1p0 of Neoverse N1.
@@ -337,6 +342,41 @@ func check_errata_1315703
        b       cpu_rev_var_ls
 endfunc check_errata_1315703
 
+/* --------------------------------------------------
+ * Errata Workaround for Neoverse N1 Erratum 1542419.
+ * This applies to revisions r3p0 - r4p0 of Neoverse N1
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_n1_1542419_wa
+       /* Compare x0 against revision r3p0 and r4p0 */
+       mov     x17, x30
+       bl      check_errata_1542419
+       cbz     x0, 1f
+
+        /* Apply instruction patching sequence */
+       ldr     x0, =0x0
+       msr     CPUPSELR_EL3, x0
+       ldr     x0, =0xEE670D35
+       msr     CPUPOR_EL3, x0
+       ldr     x0, =0xFFFF0FFF
+       msr     CPUPMR_EL3, x0
+       ldr     x0, =0x08000020007D
+       msr     CPUPCR_EL3, x0
+       isb
+1:
+       ret     x17
+endfunc errata_n1_1542419_wa
+
+func check_errata_1542419
+       /* Applies to everything r3p0 - r4p0. */
+       mov     x1, #0x30
+       mov     x2, #0x40
+       b       cpu_rev_var_range
+endfunc check_errata_1542419
+
 func neoverse_n1_reset_func
        mov     x19, x30
 
@@ -406,6 +446,11 @@ func neoverse_n1_reset_func
        bl      errata_n1_1315703_wa
 #endif
 
+#if ERRATA_N1_1542419
+       mov     x0, x18
+       bl      errata_n1_1542419_wa
+#endif
+
 #if ENABLE_AMU
        /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
        mrs     x0, actlr_el3
@@ -471,6 +516,7 @@ func neoverse_n1_errata_report
        report_errata ERRATA_N1_1262888, neoverse_n1, 1262888
        report_errata ERRATA_N1_1275112, neoverse_n1, 1275112
        report_errata ERRATA_N1_1315703, neoverse_n1, 1315703
+       report_errata ERRATA_N1_1542419, neoverse_n1, 1542419
        report_errata ERRATA_DSU_936184, neoverse_n1, dsu_936184
 
        ldp     x8, x30, [sp], #16
@@ -478,6 +524,42 @@ func neoverse_n1_errata_report
 endfunc neoverse_n1_errata_report
 #endif
 
+/*
+ * Handle trap of EL0 IC IVAU instructions to EL3 by executing a TLB
+ * inner-shareable invalidation to an arbitrary address followed by a DSB.
+ *
+ * x1: Exception Syndrome
+ */
+func neoverse_n1_errata_ic_trap_handler
+       cmp     x1, #NEOVERSE_N1_EC_IC_TRAP
+       b.ne    1f
+       tlbi    vae3is, xzr
+       dsb     sy
+
+        # Skip the IC instruction itself
+        mrs     x3, elr_el3
+        add     x3, x3, #4
+        msr     elr_el3, x3
+
+       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]
+       ldr     x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+
+#if IMAGE_BL31 && RAS_EXTENSION
+       /*
+        * Issue Error Synchronization Barrier to synchronize SErrors before
+        * exiting EL3. We're running with EAs unmasked, so any synchronized
+        * errors would be taken immediately; therefore no need to inspect
+        * DISR_EL1 register.
+        */
+       esb
+#endif
+       eret
+1:
+       ret
+endfunc neoverse_n1_errata_ic_trap_handler
+
        /* ---------------------------------------------
         * This function provides neoverse_n1 specific
         * register information for crash reporting.
@@ -497,6 +579,7 @@ func neoverse_n1_cpu_reg_dump
        ret
 endfunc neoverse_n1_cpu_reg_dump
 
-declare_cpu_ops neoverse_n1, NEOVERSE_N1_MIDR, \
+declare_cpu_ops_eh neoverse_n1, NEOVERSE_N1_MIDR, \
        neoverse_n1_reset_func, \
+       neoverse_n1_errata_ic_trap_handler, \
        neoverse_n1_core_pwr_dwn