Add workaround for ARM Cortex-A53 erratum 855873
authorAndre Przywara <andre.przywara@arm.com>
Thu, 6 Oct 2016 15:54:53 +0000 (16:54 +0100)
committerAndre Przywara <andre.przywara@arm.com>
Mon, 20 Mar 2017 10:57:46 +0000 (10:57 +0000)
ARM erratum 855873 applies to all Cortex-A53 CPUs.
The recommended workaround is to promote "data cache clean"
instructions to "data cache clean and invalidate" instructions.
For core revisions of r0p3 and later this can be done by setting a bit
in the CPUACTLR_EL1 register, so that hardware takes care of the promotion.
As CPUACTLR_EL1 is both IMPLEMENTATION DEFINED and can be trapped to EL3,
we set the bit in firmware.
Also we dump this register upon crashing to provide more debug
information.

Enable the workaround for the Juno boards.

Change-Id: I3840114291958a406574ab6c49b01a9d9847fec8
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
docs/cpu-specific-build-macros.md
include/lib/cpus/aarch64/cortex_a53.h
lib/cpus/aarch64/cortex_a53.S
lib/cpus/aarch64/cpu_helpers.S
lib/cpus/cpu-ops.mk
plat/arm/board/juno/platform.mk

index 0a575f72cd21a9d7fec172d80a269066f79561ed..eb23bcd421d8b1c918332367b06c35e1abcec984 100644 (file)
@@ -60,6 +60,13 @@ For Cortex-A53, following errata build flags are defined :
      CPU. This needs to be enabled only for revision <= r0p3 of the CPU. From
      r0p4 and onwards, this errata is enabled by default in hardware.
 
+*   `ERRATA_A53_855873`: This applies errata 855873 workaround to Cortex-A53
+     CPUs. Though the erratum is present in every revision of the CPU,
+     this workaround is only applied to CPUs from r0p3 onwards, which feature
+     a chicken bit in CPUACTLR_EL1 to enable a hardware workaround.
+     Earlier revisions of the CPU have other errata which require the same
+     workaround in software, so they should be covered anyway.
+
 For Cortex-A57, following errata build flags are defined :
 
 *   `ERRATA_A57_806969`: This applies errata 806969 workaround to Cortex-A57
index 6976b809aad5a73404737aa12b65bfe56abccc0d..484eb63c39425ab83fbd5921b9e24723bf5d6a9b 100644 (file)
@@ -67,6 +67,7 @@
 #define CPUACTLR_EL1                   S3_1_C15_C2_0   /* Instruction def. */
 
 #define CPUACTLR_DTAH                  (1 << 24)
+#define CPUACTLR_ENDCCASCI             (1 << 44)
 
 /*******************************************************************************
  * L2 Auxiliary Control register specific definitions.
index 1dd8a8650d52be36a15b68456565fa08b86b621d..a36666bc3e2c1cf9063de6d798b18b2232a09153 100644 (file)
@@ -129,6 +129,39 @@ func check_errata_disable_non_temporal_hint
        b       cpu_rev_var_ls
 endfunc check_errata_disable_non_temporal_hint
 
+       /* --------------------------------------------------
+        * Errata Workaround for Cortex A53 Errata #855873.
+        *
+        * This applies only to revisions >= r0p3 of Cortex A53.
+        * Earlier revisions of the core are affected as well, but don't
+        * have the chicken bit in the CPUACTLR register. It is expected that
+        * the rich OS takes care of that, especially as the workaround is
+        * shared with other erratas in those revisions of the CPU.
+        * Inputs:
+        * x0: variant[4:7] and revision[0:3] of current cpu.
+        * Shall clobber: x0-x17
+        * --------------------------------------------------
+        */
+func errata_a53_855873_wa
+       /*
+        * Compare x0 against revision r0p3 and higher
+        */
+        mov     x17, x30
+        bl      check_errata_855873
+        cbz     x0, 1f
+
+       mrs     x1, CPUACTLR_EL1
+       orr     x1, x1, #CPUACTLR_ENDCCASCI
+       msr     CPUACTLR_EL1, x1
+1:
+       ret     x17
+endfunc errata_a53_855873_wa
+
+func check_errata_855873
+       mov     x1, #0x03
+       b       cpu_rev_var_hs
+endfunc check_errata_855873
+
        /* -------------------------------------------------
         * The CPU Ops reset function for Cortex-A53.
         * Shall clobber: x0-x19
@@ -150,6 +183,11 @@ func cortex_a53_reset_func
        bl      a53_disable_non_temporal_hint
 #endif
 
+#if ERRATA_A53_855873
+       mov     x0, x18
+       bl      errata_a53_855873_wa
+#endif
+
        /* ---------------------------------------------
         * Enable the SMP bit.
         * ---------------------------------------------
@@ -238,6 +276,7 @@ func cortex_a53_errata_report
         */
        report_errata ERRATA_A53_826319, cortex_a53, 826319
        report_errata ERRATA_A53_836870, cortex_a53, disable_non_temporal_hint
+       report_errata ERRATA_A53_855873, cortex_a53, 855873
 
        ldp     x8, x30, [sp], #16
        ret
@@ -255,13 +294,15 @@ endfunc cortex_a53_errata_report
         */
 .section .rodata.cortex_a53_regs, "aS"
 cortex_a53_regs:  /* The ascii list of register names to be reported */
-       .asciz  "cpuectlr_el1", "cpumerrsr_el1", "l2merrsr_el1", ""
+       .asciz  "cpuectlr_el1", "cpumerrsr_el1", "l2merrsr_el1", \
+               "cpuactlr_el1", ""
 
 func cortex_a53_cpu_reg_dump
        adr     x6, cortex_a53_regs
        mrs     x8, CPUECTLR_EL1
        mrs     x9, CPUMERRSR_EL1
        mrs     x10, L2MERRSR_EL1
+       mrs     x11, CPUACTLR_EL1
        ret
 endfunc cortex_a53_cpu_reg_dump
 
index 6a3669dec20c7b9e57c1bcd5a2b9ba6601c29fe6..47cb6a2deda956e60bd32abe3d7a7339dc62cff2 100644 (file)
@@ -234,6 +234,20 @@ func cpu_rev_var_ls
        ret
 endfunc cpu_rev_var_ls
 
+/*
+ * Compare the CPU's revision-variant (x0) with a given value (x1), for errata
+ * application purposes. If the revision-variant is higher than or same as a
+ * given value, indicates that errata applies; otherwise not.
+ */
+       .globl  cpu_rev_var_hs
+func cpu_rev_var_hs
+       mov     x2, #ERRATA_APPLIES
+       mov     x3, #ERRATA_NOT_APPLIES
+       cmp     x0, x1
+       csel    x0, x2, x3, hs
+       ret
+endfunc cpu_rev_var_hs
+
 #if REPORT_ERRATA
 /*
  * void print_errata_status(void);
index 7d7db2032b451ea6ccaa1ccca84f800c7d9f5743..132ab6f794e9b5a923f458af88df585d1836a83d 100644 (file)
@@ -66,6 +66,12 @@ ERRATA_A53_826319    ?=0
 # erratum workaround is enabled by default in hardware.
 ERRATA_A53_836870      ?=0
 
+# Flag to apply errata 855873 during reset. This errata applies to all
+# revisions of the Cortex A53 CPU, but this firmware workaround only works
+# for revisions r0p3 and higher. Earlier revisions are taken care
+# of by the rich OS.
+ERRATA_A53_855873      ?=0
+
 # Flag to apply erratum 806969 workaround during reset. This erratum applies
 # only to revision r0p0 of the Cortex A57 cpu.
 ERRATA_A57_806969      ?=0
@@ -106,6 +112,10 @@ $(eval $(call add_define,ERRATA_A53_826319))
 $(eval $(call assert_boolean,ERRATA_A53_836870))
 $(eval $(call add_define,ERRATA_A53_836870))
 
+# Process ERRATA_A53_855873 flag
+$(eval $(call assert_boolean,ERRATA_A53_855873))
+$(eval $(call add_define,ERRATA_A53_855873))
+
 # Process ERRATA_A57_806969 flag
 $(eval $(call assert_boolean,ERRATA_A57_806969))
 $(eval $(call add_define,ERRATA_A57_806969))
index 5ba1698a87690c3bcfebf278a9dd2d2d5ab2af82..7571582bcc1d7535ffc3777ffa075f6b9afcab4e 100644 (file)
@@ -67,7 +67,8 @@ BL31_SOURCES          +=      lib/cpus/aarch64/cortex_a53.S           \
                                ${JUNO_INTERCONNECT_SOURCES}            \
                                ${JUNO_SECURITY_SOURCES}
 
-# Enable workarounds for selected Cortex-A57 erratas.
+# Enable workarounds for selected Cortex-A53 and A57 erratas.
+ERRATA_A53_855873              :=      1
 ERRATA_A57_806969              :=      0
 ERRATA_A57_813419              :=      1
 ERRATA_A57_813420              :=      1