aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanh-arm <dan.handley@arm.com>2016-04-22 10:13:16 +0100
committerdanh-arm <dan.handley@arm.com>2016-04-22 10:13:16 +0100
commit7607204c0d9aa2d996bd02794ce6f5bbb2b96152 (patch)
tree57b04ac4825de32cf0e609f011d26634108b4d7f
parent7ee532a1eeba8effed836c496c0b14311e6a8b52 (diff)
parent86d8948c781404ec7091538588c1403664603649 (diff)
downloadtrusted-firmware-a-7607204c0d9aa2d996bd02794ce6f5bbb2b96152.tar.gz
Merge pull request #601 from sandrine-bailleux-arm/sb/a57-errata-workarounds
Cortex-A57 errata workarounds
-rw-r--r--docs/cpu-specific-build-macros.md30
-rw-r--r--include/lib/cpus/aarch64/cortex_a57.h6
-rw-r--r--lib/cpus/aarch64/cortex_a57.S161
-rw-r--r--lib/cpus/cpu-ops.mk63
4 files changed, 245 insertions, 15 deletions
diff --git a/docs/cpu-specific-build-macros.md b/docs/cpu-specific-build-macros.md
index c57dc7ee54..df2fbd86d0 100644
--- a/docs/cpu-specific-build-macros.md
+++ b/docs/cpu-specific-build-macros.md
@@ -22,14 +22,19 @@ for a specific CPU on a platform.
ARM Trusted Firmware exports a series of build flags which control the
errata workarounds that are applied to each CPU by the reset handler. The
errata details can be found in the CPU specific errata documents published
-by ARM. The errata workarounds are implemented for a particular revision
-or a set of processor revisions. This is checked by reset handler at runtime.
-Each errata workaround is identified by its `ID` as specified in the processor's
+by ARM:
+
+* [Cortex-A53 MPCore Software Developers Errata Notice][A53 Errata Notice]
+* [Cortex-A57 MPCore Software Developers Errata Notice][A57 Errata Notice]
+
+The errata workarounds are implemented for a particular revision or a set of
+processor revisions. This is checked by the reset handler at runtime. Each
+errata workaround is identified by its `ID` as specified in the processor's
errata notice document. The format of the define used to enable/disable the
errata workaround is `ERRATA_<Processor name>_<ID>`, where the `Processor name`
is for example `A57` for the `Cortex_A57` CPU.
-All workarounds are disabled by default. The platform is reponsible for
+All workarounds are disabled by default. The platform is responsible for
enabling these workarounds according to its requirement by defining the
errata workaround build flags in the platform specific makefile. In case
these workarounds are enabled for the wrong CPU revision then the errata
@@ -60,6 +65,21 @@ For Cortex-A57, following errata build flags are defined :
* `ERRATA_A57_813420`: This applies errata 813420 workaround to Cortex-A57
CPU. This needs to be enabled only for revision r0p0 of the CPU.
+* `ERRATA_A57_826974`: This applies errata 826974 workaround to Cortex-A57
+ CPU. This needs to be enabled only for revision <= r1p1 of the CPU.
+
+* `ERRATA_A57_826977`: This applies errata 826977 workaround to Cortex-A57
+ CPU. This needs to be enabled only for revision <= r1p1 of the CPU.
+
+* `ERRATA_A57_828024`: This applies errata 828024 workaround to Cortex-A57
+ CPU. This needs to be enabled only for revision <= r1p1 of the CPU.
+
+* `ERRATA_A57_829520`: This applies errata 829520 workaround to Cortex-A57
+ CPU. This needs to be enabled only for revision <= r1p2 of the CPU.
+
+* `ERRATA_A57_833471`: This applies errata 833471 workaround to Cortex-A57
+ CPU. This needs to be enabled only for revision <= r1p2 of the CPU.
+
3. CPU Specific optimizations
------------------------------
@@ -94,3 +114,5 @@ architecture that can be enabled by the platform as desired.
_Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved._
[A57 SW Optimization Guide]: http://infocenter.arm.com/help/topic/com.arm.doc.uan0015b/Cortex_A57_Software_Optimization_Guide_external.pdf
+[A53 Errata Notice]: http://infocenter.arm.com/help/topic/com.arm.doc.epm048406/index.html
+[A57 Errata Notice]: http://infocenter.arm.com/help/topic/com.arm.doc.epm049219/cortex_a57_mpcore_software_developers_errata_notice.pdf
diff --git a/include/lib/cpus/aarch64/cortex_a57.h b/include/lib/cpus/aarch64/cortex_a57.h
index c512129a17..ac4ae57017 100644
--- a/include/lib/cpus/aarch64/cortex_a57.h
+++ b/include/lib/cpus/aarch64/cortex_a57.h
@@ -61,9 +61,15 @@
******************************************************************************/
#define CPUACTLR_EL1 S3_1_C15_C2_0 /* Instruction def. */
+#define CPUACTLR_DIS_LOAD_PASS_DMB (1 << 59)
+#define CPUACTLR_GRE_NGRE_AS_NGNRE (1 << 54)
#define CPUACTLR_DIS_OVERREAD (1 << 52)
#define CPUACTLR_NO_ALLOC_WBWA (1 << 49)
#define CPUACTLR_DCC_AS_DCCI (1 << 44)
+#define CPUACTLR_FORCE_FPSCR_FLUSH (1 << 38)
+#define CPUACTLR_DIS_STREAMING (3 << 27)
+#define CPUACTLR_DIS_L1_STREAMING (3 << 25)
+#define CPUACTLR_DIS_INDIRECT_PREDICTOR (1 << 4)
/*******************************************************************************
* L2 Control register specific definitions.
diff --git a/lib/cpus/aarch64/cortex_a57.S b/lib/cpus/aarch64/cortex_a57.S
index 4c0b8ce381..60929a0506 100644
--- a/lib/cpus/aarch64/cortex_a57.S
+++ b/lib/cpus/aarch64/cortex_a57.S
@@ -167,6 +167,142 @@ disable_hint:
ret
endfunc a57_disable_ldnp_overread
+ /* ---------------------------------------------------
+ * Errata Workaround for Cortex A57 Errata #826974.
+ * This applies only to revision <= r1p1 of Cortex A57.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Clobbers : x0 - x5
+ * ---------------------------------------------------
+ */
+func errata_a57_826974_wa
+ /*
+ * Compare x0 against revision r1p1
+ */
+ cmp x0, #0x11
+ b.ls apply_826974
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+ b print_revision_warning
+#else
+ ret
+#endif
+apply_826974:
+ mrs x1, CPUACTLR_EL1
+ orr x1, x1, #CPUACTLR_DIS_LOAD_PASS_DMB
+ msr CPUACTLR_EL1, x1
+ ret
+endfunc errata_a57_826974_wa
+
+ /* ---------------------------------------------------
+ * Errata Workaround for Cortex A57 Errata #826977.
+ * This applies only to revision <= r1p1 of Cortex A57.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Clobbers : x0 - x5
+ * ---------------------------------------------------
+ */
+func errata_a57_826977_wa
+ /*
+ * Compare x0 against revision r1p1
+ */
+ cmp x0, #0x11
+ b.ls apply_826977
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+ b print_revision_warning
+#else
+ ret
+#endif
+apply_826977:
+ mrs x1, CPUACTLR_EL1
+ orr x1, x1, #CPUACTLR_GRE_NGRE_AS_NGNRE
+ msr CPUACTLR_EL1, x1
+ ret
+endfunc errata_a57_826977_wa
+
+ /* ---------------------------------------------------
+ * Errata Workaround for Cortex A57 Errata #828024.
+ * This applies only to revision <= r1p1 of Cortex A57.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Clobbers : x0 - x5
+ * ---------------------------------------------------
+ */
+func errata_a57_828024_wa
+ /*
+ * Compare x0 against revision r1p1
+ */
+ cmp x0, #0x11
+ b.ls apply_828024
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+ b print_revision_warning
+#else
+ ret
+#endif
+apply_828024:
+ mrs x1, CPUACTLR_EL1
+ /*
+ * Setting the relevant bits in CPUACTLR_EL1 has to be done in 2
+ * instructions here because the resulting bitmask doesn't fit in a
+ * 16-bit value so it cannot be encoded in a single instruction.
+ */
+ orr x1, x1, #CPUACTLR_NO_ALLOC_WBWA
+ orr x1, x1, #(CPUACTLR_DIS_L1_STREAMING | CPUACTLR_DIS_STREAMING)
+ msr CPUACTLR_EL1, x1
+ ret
+endfunc errata_a57_828024_wa
+
+ /* ---------------------------------------------------
+ * Errata Workaround for Cortex A57 Errata #829520.
+ * This applies only to revision <= r1p2 of Cortex A57.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Clobbers : x0 - x5
+ * ---------------------------------------------------
+ */
+func errata_a57_829520_wa
+ /*
+ * Compare x0 against revision r1p2
+ */
+ cmp x0, #0x12
+ b.ls apply_829520
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+ b print_revision_warning
+#else
+ ret
+#endif
+apply_829520:
+ mrs x1, CPUACTLR_EL1
+ orr x1, x1, #CPUACTLR_DIS_INDIRECT_PREDICTOR
+ msr CPUACTLR_EL1, x1
+ ret
+endfunc errata_a57_829520_wa
+
+ /* ---------------------------------------------------
+ * Errata Workaround for Cortex A57 Errata #833471.
+ * This applies only to revision <= r1p2 of Cortex A57.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Clobbers : x0 - x5
+ * ---------------------------------------------------
+ */
+func errata_a57_833471_wa
+ /*
+ * Compare x0 against revision r1p2
+ */
+ cmp x0, #0x12
+ b.ls apply_833471
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+ b print_revision_warning
+#else
+ ret
+#endif
+apply_833471:
+ mrs x1, CPUACTLR_EL1
+ orr x1, x1, #CPUACTLR_FORCE_FPSCR_FLUSH
+ msr CPUACTLR_EL1, x1
+ ret
+endfunc errata_a57_833471_wa
+
/* -------------------------------------------------
* The CPU Ops reset function for Cortex-A57.
* Clobbers: x0-x5, x15, x19, x30
@@ -200,6 +336,31 @@ func cortex_a57_reset_func
bl a57_disable_ldnp_overread
#endif
+#if ERRATA_A57_826974
+ mov x0, x15
+ bl errata_a57_826974_wa
+#endif
+
+#if ERRATA_A57_826977
+ mov x0, x15
+ bl errata_a57_826977_wa
+#endif
+
+#if ERRATA_A57_828024
+ mov x0, x15
+ bl errata_a57_828024_wa
+#endif
+
+#if ERRATA_A57_829520
+ mov x0, x15
+ bl errata_a57_829520_wa
+#endif
+
+#if ERRATA_A57_833471
+ mov x0, x15
+ bl errata_a57_833471_wa
+#endif
+
/* ---------------------------------------------
* Enable the SMP bit.
* ---------------------------------------------
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index a3a08e155f..0659bff9c6 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -53,26 +53,47 @@ $(eval $(call assert_boolean,A57_DISABLE_NON_TEMPORAL_HINT))
$(eval $(call add_define,A57_DISABLE_NON_TEMPORAL_HINT))
-# CPU Errata Build flags. These should be enabled by the
-# platform if the errata needs to be applied.
+# CPU Errata Build flags.
+# These should be enabled by the platform if the erratum workaround needs to be
+# applied.
-# Flag to apply errata 826319 during reset. This errata applies only to
-# revision <= r0p2 of the Cortex A53 cpu.
+# Flag to apply erratum 826319 workaround during reset. This erratum applies
+# only to revision <= r0p2 of the Cortex A53 cpu.
ERRATA_A53_826319 ?=0
-# Flag to apply errata 836870 during reset. This errata applies only to
-# revision <= r0p3 of the Cortex A53 cpu. From r0p4 and onwards, this
-# errata is enabled by default.
+# Flag to apply erratum 836870 workaround during reset. This erratum applies
+# only to revision <= r0p3 of the Cortex A53 cpu. From r0p4 and onwards, this
+# erratum workaround is enabled by default.
ERRATA_A53_836870 ?=0
-# Flag to apply errata 806969 during reset. This errata applies only to
-# revision r0p0 of the Cortex A57 cpu.
+# Flag to apply erratum 806969 workaround during reset. This erratum applies
+# only to revision r0p0 of the Cortex A57 cpu.
ERRATA_A57_806969 ?=0
-# Flag to apply errata 813420 during reset. This errata applies only to
-# revision r0p0 of the Cortex A57 cpu.
+# Flag to apply erratum 813420 workaround during reset. This erratum applies
+# only to revision r0p0 of the Cortex A57 cpu.
ERRATA_A57_813420 ?=0
+# Flag to apply erratum 826974 workaround during reset. This erratum applies
+# only to revision <= r1p1 of the Cortex A57 cpu.
+ERRATA_A57_826974 ?=0
+
+# Flag to apply erratum 826977 workaround during reset. This erratum applies
+# only to revision <= r1p1 of the Cortex A57 cpu.
+ERRATA_A57_826977 ?=0
+
+# Flag to apply erratum 828024 workaround during reset. This erratum applies
+# only to revision <= r1p1 of the Cortex A57 cpu.
+ERRATA_A57_828024 ?=0
+
+# Flag to apply erratum 829520 workaround during reset. This erratum applies
+# only to revision <= r1p2 of the Cortex A57 cpu.
+ERRATA_A57_829520 ?=0
+
+# Flag to apply erratum 833471 workaround during reset. This erratum applies
+# only to revision <= r1p2 of the Cortex A57 cpu.
+ERRATA_A57_833471 ?=0
+
# Process ERRATA_A53_826319 flag
$(eval $(call assert_boolean,ERRATA_A53_826319))
$(eval $(call add_define,ERRATA_A53_826319))
@@ -88,3 +109,23 @@ $(eval $(call add_define,ERRATA_A57_806969))
# Process ERRATA_A57_813420 flag
$(eval $(call assert_boolean,ERRATA_A57_813420))
$(eval $(call add_define,ERRATA_A57_813420))
+
+# Process ERRATA_A57_826974 flag
+$(eval $(call assert_boolean,ERRATA_A57_826974))
+$(eval $(call add_define,ERRATA_A57_826974))
+
+# Process ERRATA_A57_826977 flag
+$(eval $(call assert_boolean,ERRATA_A57_826977))
+$(eval $(call add_define,ERRATA_A57_826977))
+
+# Process ERRATA_A57_828024 flag
+$(eval $(call assert_boolean,ERRATA_A57_828024))
+$(eval $(call add_define,ERRATA_A57_828024))
+
+# Process ERRATA_A57_829520 flag
+$(eval $(call assert_boolean,ERRATA_A57_829520))
+$(eval $(call add_define,ERRATA_A57_829520))
+
+# Process ERRATA_A57_833471 flag
+$(eval $(call assert_boolean,ERRATA_A57_833471))
+$(eval $(call add_define,ERRATA_A57_833471))