From abd90085ac24dcb6e4e6ce3bd84d7692de76cbbc Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Thu, 6 Jul 2023 13:32:27 +0200 Subject: [PATCH] soc: arm: nrf53: workaround pop lr after wfi crash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On nRF5340 net core it was observed that when `wfi` instruction was followed by `pop {r0, lr}` in the `arch_cpu_idle` function, the value of `lr` sometimes got read as 0 from memory despite having correct value stored in the memory. This commit inserts additional `nop` instruction after waking up to delay access to the memory. Signed-off-by: Andrzej KuroĊ› --- arch/arm/Kconfig | 16 ++++++++++++++++ arch/arm/core/aarch32/cpu_idle.S | 9 +++++++++ soc/arm/nordic_nrf/nrf53/Kconfig.soc | 1 + soc/arm/nordic_nrf/nrf53/soc_cpu_idle.h | 20 ++++++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 soc/arm/nordic_nrf/nrf53/soc_cpu_idle.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ec82b1e50ee..e17cf3f9b31 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -53,6 +53,22 @@ config ARM_ON_ENTER_CPU_IDLE_HOOK If needed, this hook can be used to prevent the CPU from actually entering sleep by skipping the WFE/WFI instruction. +config ARM_ON_EXIT_CPU_IDLE + bool + help + Enables a possibility to inject SoC-specific code just after WFI/WFE + instructions of the cpu idle implementation. + + Enabling this option requires that the SoC provides a soc_cpu_idle.h + header file which defines SOC_ON_EXIT_CPU_IDLE macro guarded by + _ASMLANGUAGE. + + The SOC_ON_EXIT_CPU_IDLE macro is expanded just after + WFI/WFE instructions before any memory access is performed. The purpose + of the SOC_ON_EXIT_CPU_IDLE is to perform an action that mitigate issues + observed on some SoCs caused by a memory access following WFI/WFE + instructions. + rsource "core/aarch32/Kconfig" rsource "core/aarch32/Kconfig.vfp" diff --git a/arch/arm/core/aarch32/cpu_idle.S b/arch/arm/core/aarch32/cpu_idle.S index 90f51f476b5..8164959ab29 100644 --- a/arch/arm/core/aarch32/cpu_idle.S +++ b/arch/arm/core/aarch32/cpu_idle.S @@ -13,6 +13,10 @@ #include #include +#if defined(CONFIG_ARM_ON_EXIT_CPU_IDLE) +#include +#endif + _ASM_FILE_PROLOGUE GTEXT(z_arm_cpu_idle_init) @@ -64,6 +68,11 @@ SECTION_FUNC(TEXT, z_arm_cpu_idle_init) dsb \wait_instruction +#if defined(CONFIG_ARM_ON_EXIT_CPU_IDLE) + /* Inline the macro provided by SoC-specific code */ + SOC_ON_EXIT_CPU_IDLE +#endif /* CONFIG_ARM_ON_EXIT_CPU_IDLE */ + #if defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK) _skip_\@: #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 96737608800..67cb8a08a6f 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -13,6 +13,7 @@ config SOC_NRF5340_CPUAPP config SOC_NRF5340_CPUNET bool select HAS_NO_PM + select ARM_ON_EXIT_CPU_IDLE imply SOC_NRF53_ANOMALY_160_WORKAROUND_NEEDED choice diff --git a/soc/arm/nordic_nrf/nrf53/soc_cpu_idle.h b/soc/arm/nordic_nrf/nrf53/soc_cpu_idle.h new file mode 100644 index 00000000000..b6cd92ca092 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf53/soc_cpu_idle.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC extensions of cpu_idle.S for the Nordic Semiconductor nRF53 processors family. + */ + + +#if defined(_ASMLANGUAGE) + +#define SOC_ON_EXIT_CPU_IDLE \ + nop; \ + nop; \ + nop; \ + nop; + +#endif /* _ASMLANGUAGE */