From bb801857eaf21365402a4748296c05cb3c6e861f Mon Sep 17 00:00:00 2001 From: Boyan Karatotev Date: Tue, 21 Jan 2025 11:41:46 +0000 Subject: [PATCH] feat(cpus): add sysreg_bit_toggle Introduce a new helper to toggle bits in assembly. This allows us to call the workaround twice, with the first call setting the workaround and second undoing it. This allows the (errata) workaround functions to be used to both apply and undo the mitigation. This is applied to functions where the undo part will be required in follow-up patches. Change-Id: I058bad58f5949b2d5fe058101410e33b6be1b8ba Signed-off-by: Boyan Karatotev --- include/lib/cpus/aarch64/cpu_macros.S | 14 +++++++++++++- lib/cpus/aarch64/cortex_a710.S | 7 ++++--- lib/cpus/aarch64/cortex_gelas.S | 7 ++++--- lib/cpus/aarch64/cortex_x3.S | 4 +++- lib/cpus/aarch64/neoverse_n2.S | 7 ++++--- lib/cpus/aarch64/travis.S | 7 ++++--- 6 files changed, 32 insertions(+), 14 deletions(-) diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S index 0ce9c3cbc..ab6041289 100644 --- a/include/lib/cpus/aarch64/cpu_macros.S +++ b/include/lib/cpus/aarch64/cpu_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -402,6 +402,18 @@ msr \_reg, x1 .endm +/* + * Toggle a bit in a system register. Can toggle multiple bits but is limited by + * the way the EOR instrucion encodes them. + * + * see sysreg_bit_set for usage + */ +.macro sysreg_bit_toggle _reg:req, _bit:req, _assert=1 + mrs x1, \_reg + eor x1, x1, #\_bit + msr \_reg, x1 +.endm + .macro override_vector_table _table:req adr x1, \_table msr vbar_el3, x1 diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S index dce9c7354..830771aa7 100644 --- a/lib/cpus/aarch64/cortex_a710.S +++ b/lib/cpus/aarch64/cortex_a710.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024, Arm Limited. All rights reserved. + * Copyright (c) 2021-2025, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -163,8 +163,9 @@ workaround_reset_end cortex_a710, ERRATUM(2282622) check_erratum_ls cortex_a710, ERRATUM(2282622), CPU_REV(2, 1) workaround_runtime_start cortex_a710, ERRATUM(2291219), ERRATA_A710_2291219 - /* Set bit 36 in ACTLR2_EL1 */ - sysreg_bit_set CORTEX_A710_CPUACTLR2_EL1, CORTEX_A710_CPUACTLR2_EL1_BIT_36 + /* Set/unset bit 36 in ACTLR2_EL1. The first call will set it, applying + * the workaround. Second call clears it to undo it. */ + sysreg_bit_toggle CORTEX_A710_CPUACTLR2_EL1, CORTEX_A710_CPUACTLR2_EL1_BIT_36 workaround_runtime_end cortex_a710, ERRATUM(2291219), NO_ISB check_erratum_ls cortex_a710, ERRATUM(2291219), CPU_REV(2, 0) diff --git a/lib/cpus/aarch64/cortex_gelas.S b/lib/cpus/aarch64/cortex_gelas.S index 891e9a653..43608e4fb 100644 --- a/lib/cpus/aarch64/cortex_gelas.S +++ b/lib/cpus/aarch64/cortex_gelas.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024, Arm Limited. All rights reserved. + * Copyright (c) 2023-2025, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -49,10 +49,11 @@ func cortex_gelas_core_pwr_dwn 1: #endif /* --------------------------------------------------- - * Enable CPU power down bit in power control register + * Flip CPU power down bit in power control register. + * It will be set on powerdown and cleared on wakeup * --------------------------------------------------- */ - sysreg_bit_set CORTEX_GELAS_CPUPWRCTLR_EL1, \ + sysreg_bit_toggle CORTEX_GELAS_CPUPWRCTLR_EL1, \ CORTEX_GELAS_CPUPWRCTLR_EL1_CORE_PWRDN_BIT isb ret diff --git a/lib/cpus/aarch64/cortex_x3.S b/lib/cpus/aarch64/cortex_x3.S index 4a0212e20..7a339b489 100644 --- a/lib/cpus/aarch64/cortex_x3.S +++ b/lib/cpus/aarch64/cortex_x3.S @@ -53,7 +53,9 @@ workaround_runtime_end cortex_x3, ERRATUM(2302506), NO_ISB check_erratum_ls cortex_x3, ERRATUM(2302506), CPU_REV(1, 1) workaround_runtime_start cortex_x3, ERRATUM(2313909), ERRATA_X3_2313909 - sysreg_bit_set CORTEX_X3_CPUACTLR2_EL1, CORTEX_X3_CPUACTLR2_EL1_BIT_36 + /* Set/unset bit 36 in ACTLR2_EL1. The first call will set it, applying + * the workaround. Second call clears it to undo it. */ + sysreg_bit_toggle CORTEX_X3_CPUACTLR2_EL1, CORTEX_X3_CPUACTLR2_EL1_BIT_36 workaround_runtime_end cortex_x3, ERRATUM(2313909), NO_ISB check_erratum_ls cortex_x3, ERRATUM(2313909), CPU_REV(1, 0) diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S index 69aa8abbc..5cccff311 100644 --- a/lib/cpus/aarch64/neoverse_n2.S +++ b/lib/cpus/aarch64/neoverse_n2.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2024, Arm Limited. All rights reserved. + * Copyright (c) 2020-2025, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -166,8 +166,9 @@ workaround_reset_end neoverse_n2, ERRATUM(2280757) check_erratum_ls neoverse_n2, ERRATUM(2280757), CPU_REV(0, 0) workaround_runtime_start neoverse_n2, ERRATUM(2326639), ERRATA_N2_2326639 - /* Set bit 36 in ACTLR2_EL1 */ - sysreg_bit_set NEOVERSE_N2_CPUACTLR2_EL1, NEOVERSE_N2_CPUACTLR2_EL1_BIT_36 + /* Set/unset bit 36 in ACTLR2_EL1. The first call will set it, applying + * the workaround. Second call clears it to undo it. */ + sysreg_bit_toggle NEOVERSE_N2_CPUACTLR2_EL1, NEOVERSE_N2_CPUACTLR2_EL1_BIT_36 workaround_runtime_end neoverse_n2, ERRATUM(2326639) check_erratum_ls neoverse_n2, ERRATUM(2326639), CPU_REV(0, 0) diff --git a/lib/cpus/aarch64/travis.S b/lib/cpus/aarch64/travis.S index e8b3860b0..695e7d86b 100644 --- a/lib/cpus/aarch64/travis.S +++ b/lib/cpus/aarch64/travis.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024, Arm Limited. All rights reserved. + * Copyright (c) 2023-2025, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -45,10 +45,11 @@ func travis_core_pwr_dwn 1: #endif /* --------------------------------------------------- - * Enable CPU power down bit in power control register + * Flip CPU power down bit in power control register. + * It will be set on powerdown and cleared on wakeup * --------------------------------------------------- */ - sysreg_bit_set TRAVIS_IMP_CPUPWRCTLR_EL1, \ + sysreg_bit_toggle TRAVIS_IMP_CPUPWRCTLR_EL1, \ TRAVIS_IMP_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT isb ret