From 43438ad1ad6651964e9ae75d35f40aed8d86d088 Mon Sep 17 00:00:00 2001 From: Boyan Karatotev Date: Mon, 3 Oct 2022 14:07:08 +0100 Subject: [PATCH] fix(cpus): workaround for Neoverse-N2 erratum 2326639 Neoverse-N2 erratum 2326639 is a Cat B erratum that applies to revision r0p0 and is fixed in r0p1. The workaround is to set CPUACTLR2_EL1[36] to 1 before the power down sequence that sets CORE_PWRDN_EN. This allows the cpu to retry the power down and prevents the deadlock. TF-A never clears this bit even if it wakes up from the wfi in the sequence since it is not expected to do anything but retry to power down after and the bit is cleared on reset. SDEN can be found here: https://developer.arm.com/documentation/SDEN1982442/latest/ Signed-off-by: Boyan Karatotev Change-Id: I9a325c5b9b498798e5efd5c79a4a6d5bed97c619 --- docs/design/cpu-specific-build-macros.rst | 4 +++ include/lib/cpus/aarch64/neoverse_n2.h | 1 + lib/cpus/aarch64/neoverse_n2.S | 36 +++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 8 +++++ 4 files changed, 49 insertions(+) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 721c399a0..f4d32c9b0 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -535,6 +535,10 @@ For Neoverse N2, the following errata build flags are defined : - ``ERRATA_N2_2280757``: This applies errata 2280757 workaround to Neoverse-N2 CPU. This needs to be enabled for revision r0p0 of the CPU and is still open. +- ``ERRATA_N2_2326639``: This applies errata 2326639 workaround to Neoverse-N2 + CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in + r0p1. + - ``ERRATA_N2_2376738``: This applies errata 2376738 workaround to Neoverse-N2 CPU. This needs to be enabled for revision r0p0 of the CPU, it is fixed in r0p1. diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h index 3ff817c0b..cb1be5b26 100644 --- a/include/lib/cpus/aarch64/neoverse_n2.h +++ b/include/lib/cpus/aarch64/neoverse_n2.h @@ -39,6 +39,7 @@ #define NEOVERSE_N2_CPUACTLR2_EL1 S3_0_C15_C1_1 #define NEOVERSE_N2_CPUACTLR2_EL1_BIT_0 (ULL(1) << 0) #define NEOVERSE_N2_CPUACTLR2_EL1_BIT_2 (ULL(1) << 2) +#define NEOVERSE_N2_CPUACTLR2_EL1_BIT_36 (ULL(1) << 36) #define NEOVERSE_N2_CPUACTLR2_EL1_BIT_40 (ULL(1) << 40) /******************************************************************************* diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S index 72e5ca816..5861decbb 100644 --- a/lib/cpus/aarch64/neoverse_n2.S +++ b/lib/cpus/aarch64/neoverse_n2.S @@ -338,6 +338,34 @@ func check_errata_2280757 b cpu_rev_var_ls endfunc check_errata_2280757 +/* -------------------------------------------------- + * Errata Workaround for Neoverse N2 Erratum 2326639. + * This applies to revision r0p0 of Neoverse N2, + * fixed in r0p1. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x1, x17 + * -------------------------------------------------- + */ +func errata_n2_2326639_wa + /* Check revision. */ + mov x17, x30 + bl check_errata_2326639 + cbz x0, 1f + + /* Set bit 36 in ACTLR2_EL1 */ + mrs x1, NEOVERSE_N2_CPUACTLR2_EL1 + orr x1, x1, #NEOVERSE_N2_CPUACTLR2_EL1_BIT_36 + msr NEOVERSE_N2_CPUACTLR2_EL1, x1 +1: + ret x17 +endfunc errata_n2_2326639_wa + +func check_errata_2326639 + /* Applies to r0p0, fixed in r0p1 */ + mov x1, #0x00 + b cpu_rev_var_ls +endfunc check_errata_2326639 /* -------------------------------------------------- * Errata Workaround for Neoverse N2 Erratum 2376738. @@ -533,6 +561,13 @@ func neoverse_n2_reset_func endfunc neoverse_n2_reset_func func neoverse_n2_core_pwr_dwn +#if ERRATA_N2_2326639 + mov x15, x30 + bl cpu_get_rev_var + bl errata_n2_2326639_wa + mov x30, x15 +#endif /* ERRATA_N2_2326639 */ + /* --------------------------------------------------- * Enable CPU power down bit in power control register * No need to do cache maintenance here. @@ -569,6 +604,7 @@ func neoverse_n2_errata_report report_errata ERRATA_N2_2138958, neoverse_n2, 2138958 report_errata ERRATA_N2_2242400, neoverse_n2, 2242400 report_errata ERRATA_N2_2280757, neoverse_n2, 2280757 + report_errata ERRATA_N2_2326639, neoverse_n2, 2326639 report_errata ERRATA_N2_2376738, neoverse_n2, 2376738 report_errata ERRATA_N2_2388450, neoverse_n2, 2388450 report_errata WORKAROUND_CVE_2022_23960, neoverse_n2, cve_2022_23960 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index ec0d95e7d..2c42ad082 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -592,6 +592,10 @@ ERRATA_N2_2242400 ?=0 # to revision r0p0 of the Neoverse N2 cpu and is still open. ERRATA_N2_2280757 ?=0 +# Flag to apply erraturm 2326639 workaroud during powerdown. This erratum +# applies to revision r0p0 of the Neoverse N2 cpu and is fixed in r0p1. +ERRATA_N2_2326639 ?=0 + # Flag to apply erratum 2376738 workaround during reset. This erratum applies # to revision r0p0 of the Neoverse N2 cpu, it is fixed in r0p1. ERRATA_N2_2376738 ?=0 @@ -1200,6 +1204,10 @@ $(eval $(call add_define,ERRATA_N2_2242400)) $(eval $(call assert_boolean,ERRATA_N2_2280757)) $(eval $(call add_define,ERRATA_N2_2280757)) +# Process ERRATA_N2_2326639 flag +$(eval $(call assert_boolean,ERRATA_N2_2326639)) +$(eval $(call add_define,ERRATA_N2_2326639)) + # Process ERRATA_N2_2376738 flag $(eval $(call assert_boolean,ERRATA_N2_2376738)) $(eval $(call add_define,ERRATA_N2_2376738)) -- 2.39.5