From 3a2710dcab0dc6dc625f0a4956a44bace1788618 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Wed, 7 Oct 2020 15:08:01 -0500 Subject: [PATCH 1/2] Workaround for Cortex A78 erratum 1951500 Cortex A78 erratum 1951500 is a Cat B erratum that applies to revisions r0p0, r1p0, and r1p1. The workaround is to insert a DMB ST before acquire atomic instructions without release semantics. This workaround works on revisions r1p0 and r1p1, in r0p0 there is no workaround. SDEN can be found here: https://documentation-service.arm.com/static/5fb66157ca04df4095c1cc2e Signed-off-by: John Powell Change-Id: I47610cee75af6a127ea65edc4d5cffc7e6a2d0a3 --- docs/design/cpu-specific-build-macros.rst | 4 ++ include/lib/cpus/errata_report.h | 3 ++ lib/cpus/aarch64/cortex_a78.S | 60 +++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 9 ++++ 4 files changed, 76 insertions(+) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 09aa3017f..be7096cd3 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -268,6 +268,10 @@ For Cortex-A78, the following errata build flags are defined : - ``ERRATA_A78_1941498``: This applies errata 1941498 workaround to Cortex-A78 CPU. This needs to be enabled for revisions r0p0, r1p0, and r1p1 of the CPU. +- ``ERRATA_A78_1951500``: This applies errata 1951500 workaround to Cortex-A78 + CPU. This needs to be enabled for revisions r1p0 and r1p1, r0p0 has the same + issue but there is no workaround for that revision. + For Neoverse N1, the following errata build flags are defined : - ``ERRATA_N1_1073348``: This applies errata 1073348 workaround to Neoverse-N1 diff --git a/include/lib/cpus/errata_report.h b/include/lib/cpus/errata_report.h index 7cac77ebe..efdedf0aa 100644 --- a/include/lib/cpus/errata_report.h +++ b/include/lib/cpus/errata_report.h @@ -30,4 +30,7 @@ int errata_needs_reporting(spinlock_t *lock, uint32_t *reported); #define ERRATA_APPLIES 1 #define ERRATA_MISSING 2 +/* Macro to get CPU revision code for checking errata version compatibility. */ +#define CPU_REV(r, p) ((r << 4) | p) + #endif /* ERRATA_REPORT_H */ diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S index ef760ed8a..f61726b46 100644 --- a/lib/cpus/aarch64/cortex_a78.S +++ b/lib/cpus/aarch64/cortex_a78.S @@ -72,6 +72,60 @@ func check_errata_1941498 b cpu_rev_var_ls endfunc check_errata_1941498 + /* -------------------------------------------------- + * Errata Workaround for A78 Erratum 1951500. + * This applies to revisions r1p0 and r1p1 of A78. + * The issue also exists in r0p0 but there is no fix + * in that revision. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_a78_1951500_wa + /* Compare x0 against revisions r1p0 - r1p1 */ + mov x17, x30 + bl check_errata_1951500 + cbz x0, 1f + + msr S3_6_c15_c8_0, xzr + ldr x0, =0x10E3900002 + msr S3_6_c15_c8_2, x0 + ldr x0, =0x10FFF00083 + msr S3_6_c15_c8_3, x0 + ldr x0, =0x2001003FF + msr S3_6_c15_c8_1, x0 + + mov x0, #1 + msr S3_6_c15_c8_0, x0 + ldr x0, =0x10E3800082 + msr S3_6_c15_c8_2, x0 + ldr x0, =0x10FFF00083 + msr S3_6_c15_c8_3, x0 + ldr x0, =0x2001003FF + msr S3_6_c15_c8_1, x0 + + mov x0, #2 + msr S3_6_c15_c8_0, x0 + ldr x0, =0x10E3800200 + msr S3_6_c15_c8_2, x0 + ldr x0, =0x10FFF003E0 + msr S3_6_c15_c8_3, x0 + ldr x0, =0x2001003FF + msr S3_6_c15_c8_1, x0 + + isb +1: + ret x17 +endfunc errata_a78_1951500_wa + +func check_errata_1951500 + /* Applies to revisions r1p0 and r1p1. */ + mov x1, #CPU_REV(1, 0) + mov x2, #CPU_REV(1, 1) + b cpu_rev_var_range +endfunc check_errata_1951500 + /* ------------------------------------------------- * The CPU Ops reset function for Cortex-A78 * ------------------------------------------------- @@ -91,6 +145,11 @@ func cortex_a78_reset_func bl errata_a78_1941498_wa #endif +#if ERRATA_A78_1951500 + mov x0, x18 + bl errata_a78_1951500_wa +#endif + #if ENABLE_AMU /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, actlr_el3 @@ -147,6 +206,7 @@ func cortex_a78_errata_report */ report_errata ERRATA_A78_1688305, cortex_a78, 1688305 report_errata ERRATA_A78_1941498, cortex_a78, 1941498 + report_errata ERRATA_A78_1951500, cortex_a78, 1951500 ldp x8, x30, [sp], #16 ret diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index b7dec0b77..93b538c58 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -298,6 +298,11 @@ ERRATA_A78_1688305 ?=0 # to revisions r0p0, r1p0, and r1p1 of the A78 cpu. ERRATA_A78_1941498 ?=0 +# Flag to apply erratum 1951500 workaround during reset. This erratum applies +# to revisions r1p0 and r1p1 of the A78 cpu. The issue is present in r0p0 as +# well but there is no workaround for that revision. +ERRATA_A78_1951500 ?=0 + # Flag to apply T32 CLREX workaround during reset. This erratum applies # only to r0p0 and r1p0 of the Neoverse N1 cpu. ERRATA_N1_1043202 ?=0 @@ -583,6 +588,10 @@ $(eval $(call add_define,ERRATA_A78_1688305)) $(eval $(call assert_boolean,ERRATA_A78_1941498)) $(eval $(call add_define,ERRATA_A78_1941498)) +# Process ERRATA_A78_1951500 flag +$(eval $(call assert_boolean,ERRATA_A78_1951500)) +$(eval $(call add_define,ERRATA_A78_1951500)) + # Process ERRATA_N1_1043202 flag $(eval $(call assert_boolean,ERRATA_N1_1043202)) $(eval $(call add_define,ERRATA_N1_1043202)) From 263ee781c6805172386686b65d012d188a842f05 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Wed, 7 Oct 2020 14:33:15 -0500 Subject: [PATCH 2/2] Workaround for Cortex N1 erratum 1946160 Cortex N1 erratum 1946160 is a Cat B erratum present in r0p0, r1p0, r2p0, r3p0, r3p1, r4p0, and r4p1. The workaround is to insert a DMB ST before acquire atomic instructions without release semantics. This issue is present starting from r0p0 but this workaround applies to revisions r3p0, r3p1, r4p0, and r4p1, for previous revisions there is no workaround. SDEN can be found here: https://documentation-service.arm.com/static/5fa9304cd8dacc30eded464f Signed-off-by: John Powell Change-Id: I36e4d6728c275f1c2477dcee9b351077cf7c53e4 --- docs/design/cpu-specific-build-macros.rst | 4 ++ lib/cpus/aarch64/neoverse_n1.S | 65 ++++++++++++++++++++++- lib/cpus/cpu-ops.mk | 9 ++++ 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index be7096cd3..7c142d132 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -310,6 +310,10 @@ For Neoverse N1, the following errata build flags are defined : - ``ERRATA_N1_1868343``: This applies errata 1868343 workaround to Neoverse-N1 CPU. This needs to be enabled only for revision <= r4p0 of the CPU. +- ``ERRATA_N1_1946160``: This applies errata 1946160 workaround to Neoverse-N1 + CPU. This needs to be enabled for revisions r3p0, r3p1, r4p0, and r4p1, for + revisions r0p0, r1p0, and r2p0 there is no workaround. + DSU Errata Workarounds ---------------------- diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S index 96891be1d..9c97cf60a 100644 --- a/lib/cpus/aarch64/neoverse_n1.S +++ b/lib/cpus/aarch64/neoverse_n1.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -407,6 +407,63 @@ func check_errata_1868343 b cpu_rev_var_ls endfunc check_errata_1868343 + /* -------------------------------------------------- + * Errata Workaround for Neoverse N1 Errata #1946160. + * This applies to revisions r3p0, r3p1, r4p0, and + * r4p1 of Neoverse N1. It also exists in r0p0, r1p0, + * and r2p0 but there is no fix in these revisions. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_n1_1946160_wa + /* + * Compare x0 against r3p0 - r4p1 + */ + mov x17, x30 + bl check_errata_1946160 + cbz x0, 1f + + mov x0, #3 + msr S3_6_C15_C8_0, x0 + ldr x0, =0x10E3900002 + msr S3_6_C15_C8_2, x0 + ldr x0, =0x10FFF00083 + msr S3_6_C15_C8_3, x0 + ldr x0, =0x2001003FF + msr S3_6_C15_C8_1, x0 + + mov x0, #4 + msr S3_6_C15_C8_0, x0 + ldr x0, =0x10E3800082 + msr S3_6_C15_C8_2, x0 + ldr x0, =0x10FFF00083 + msr S3_6_C15_C8_3, x0 + ldr x0, =0x2001003FF + msr S3_6_C15_C8_1, x0 + + mov x0, #5 + msr S3_6_C15_C8_0, x0 + ldr x0, =0x10E3800200 + msr S3_6_C15_C8_2, x0 + ldr x0, =0x10FFF003E0 + msr S3_6_C15_C8_3, x0 + ldr x0, =0x2001003FF + msr S3_6_C15_C8_1, x0 + + isb +1: + ret x17 +endfunc errata_n1_1946160_wa + +func check_errata_1946160 + /* Applies to r3p0 - r4p1. */ + mov x1, #0x30 + mov x2, #0x41 + b cpu_rev_var_range +endfunc check_errata_1946160 + func neoverse_n1_reset_func mov x19, x30 @@ -486,6 +543,11 @@ func neoverse_n1_reset_func bl errata_n1_1868343_wa #endif +#if ERRATA_N1_1946160 + mov x0, x18 + bl errata_n1_1946160_wa +#endif + #if ENABLE_AMU /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, actlr_el3 @@ -560,6 +622,7 @@ func neoverse_n1_errata_report report_errata ERRATA_N1_1315703, neoverse_n1, 1315703 report_errata ERRATA_N1_1542419, neoverse_n1, 1542419 report_errata ERRATA_N1_1868343, neoverse_n1, 1868343 + report_errata ERRATA_N1_1946160, neoverse_n1, 1946160 report_errata ERRATA_DSU_936184, neoverse_n1, dsu_936184 ldp x8, x30, [sp], #16 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 93b538c58..64a4b4d47 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -355,6 +355,11 @@ ERRATA_N1_1542419 ?=0 # to revision <= r4p0 of the Neoverse N1 cpu. ERRATA_N1_1868343 ?=0 +# Flag to apply erratum 1946160 workaround during reset. This erratum applies +# to revisions r3p0, r3p1, r4p0, and r4p1 of the Neoverse N1 cpu. The issue +# exists in revisions r0p0, r1p0, and r2p0 as well but there is no workaround. +ERRATA_N1_1946160 ?=0 + # Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0. # Applying the workaround results in higher DSU power consumption on idle. ERRATA_DSU_798953 ?=0 @@ -644,6 +649,10 @@ $(eval $(call add_define,ERRATA_N1_1542419)) $(eval $(call assert_boolean,ERRATA_N1_1868343)) $(eval $(call add_define,ERRATA_N1_1868343)) +# Process ERRATA_N1_1946160 flag +$(eval $(call assert_boolean,ERRATA_N1_1946160)) +$(eval $(call add_define,ERRATA_N1_1946160)) + # Process ERRATA_DSU_798953 flag $(eval $(call assert_boolean,ERRATA_DSU_798953)) $(eval $(call add_define,ERRATA_DSU_798953))