From 47d6f5ff16d1f2ad009d630a381054b10fa0a06f Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 27 Jul 2021 02:32:29 -0700 Subject: feat(cpus): workaround for Cortex A78 AE erratum 1941500 Cortex A78 AE erratum 1941500 is a Cat B erratum that applies to revisions <= r0p1. It is still open. This erratum is avoided by by setting CPUECTLR_EL1[8] to 1. There is a small performance cost (<0.5%) for setting this bit. SDEN is available at https://developer.arm.com/documentation/SDEN1707912/0900 Change-Id: I2d72666468b146714a0340ba114ccf0f5165b39c Signed-off-by: Varun Wadekar --- lib/cpus/aarch64/cortex_a78_ae.S | 36 ++++++++++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 8 ++++++++ 2 files changed, 44 insertions(+) (limited to 'lib/cpus') diff --git a/lib/cpus/aarch64/cortex_a78_ae.S b/lib/cpus/aarch64/cortex_a78_ae.S index c8cccf278..421c17433 100644 --- a/lib/cpus/aarch64/cortex_a78_ae.S +++ b/lib/cpus/aarch64/cortex_a78_ae.S @@ -17,6 +17,36 @@ #error "cortex_a78_ae must be compiled with HW_ASSISTED_COHERENCY enabled" #endif +/* -------------------------------------------------- + * Errata Workaround for A78 AE Erratum 1941500. + * This applies to revisions r0p0 and r0p1 of A78 AE. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_a78_ae_1941500_wa + /* Compare x0 against revisions r0p0 - r0p1 */ + mov x17, x30 + bl check_errata_1941500 + cbz x0, 1f + + /* Set bit 8 in ECTLR_EL1 */ + mrs x0, CORTEX_A78_AE_CPUECTLR_EL1 + bic x0, x0, #CORTEX_A78_AE_CPUECTLR_EL1_BIT_8 + msr CORTEX_A78_AE_CPUECTLR_EL1, x0 + isb +1: + ret x17 +endfunc errata_a78_ae_1941500_wa + +func check_errata_1941500 + /* Applies to revisions r0p0 and r0p1. */ + mov x1, #CPU_REV(0, 0) + mov x2, #CPU_REV(0, 1) + b cpu_rev_var_range +endfunc check_errata_1941500 + /* -------------------------------------------------- * Errata Workaround for A78 AE Erratum 1951502. * This applies to revisions r0p0 and r0p1 of A78 AE. @@ -78,6 +108,11 @@ func cortex_a78_ae_reset_func bl cpu_get_rev_var mov x18, x0 +#if ERRATA_A78_AE_1941500 + mov x0, x18 + bl errata_a78_ae_1941500_wa +#endif + #if ERRATA_A78_AE_1951502 mov x0, x18 bl errata_a78_ae_1951502_wa @@ -138,6 +173,7 @@ func cortex_a78_ae_errata_report * Report all errata. The revision-variant information is passed to * checking functions of each errata. */ + report_errata ERRATA_A78_AE_1941500, cortex_a78_ae, 1941500 report_errata ERRATA_A78_AE_1951502, cortex_a78_ae, 1951502 ldp x8, x30, [sp], #16 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index b36616760..e81471ec3 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -311,6 +311,10 @@ ERRATA_A78_1941498 ?=0 # well but there is no workaround for that revision. ERRATA_A78_1951500 ?=0 +# Flag to apply erratum 1941500 workaround during reset. This erratum applies +# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open. +ERRATA_A78_AE_1941500 ?=0 + # Flag to apply erratum 1951502 workaround during reset. This erratum applies # to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open. ERRATA_A78_AE_1951502 ?=0 @@ -650,6 +654,10 @@ $(eval $(call add_define,ERRATA_A78_1941498)) $(eval $(call assert_boolean,ERRATA_A78_1951500)) $(eval $(call add_define,ERRATA_A78_1951500)) +# Process ERRATA_A78_AE_1941500 flag +$(eval $(call assert_boolean,ERRATA_A78_AE_1941500)) +$(eval $(call add_define,ERRATA_A78_AE_1941500)) + # Process ERRATA_A78_AE_1951502 flag $(eval $(call assert_boolean,ERRATA_A78_AE_1951502)) $(eval $(call add_define,ERRATA_A78_AE_1951502)) -- cgit v1.2.3