From 3f395f569851ee3ac9c71a599ad562fbd6b4b993 Mon Sep 17 00:00:00 2001 From: Stephanos Ioannidis Date: Tue, 17 Mar 2020 12:23:58 +0900 Subject: [PATCH] arch: arm: aarch32: Add memory barriers to arch_cpu_idle This commit adds the required memory barriers to the `arch_cpu_idle` function in order to ensure proper idle operation in all cases. 1. Add ISB after setting BASEPRI to ensure that the new wake-up interrupt priority is visible to the WFI instruction. 2. Add DSB before WFI to ensure that all memory transactions are completed before going to sleep. 3. Add ISB after CPSIE to ensure that the pending wake-up interrupt is serviced immediately. Co-authored-by: Ioannis Glaropoulos Signed-off-by: Stephanos Ioannidis --- arch/arm/core/aarch32/cpu_idle.S | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/arch/arm/core/aarch32/cpu_idle.S b/arch/arm/core/aarch32/cpu_idle.S index ca5ff63c638..79fd796f294 100644 --- a/arch/arm/core/aarch32/cpu_idle.S +++ b/arch/arm/core/aarch32/cpu_idle.S @@ -74,9 +74,13 @@ SECTION_FUNC(TEXT, arch_cpu_idle) */ cpsid i - /* Set wake-up interrupt priority to the lowest */ + /* + * Set wake-up interrupt priority to the lowest and synchronise to + * ensure that this is visible to the WFI instruction. + */ eors.n r0, r0 msr BASEPRI, r0 + isb #else /* * For all the other ARM architectures that do not implement BASEPRI, @@ -87,10 +91,21 @@ SECTION_FUNC(TEXT, arch_cpu_idle) */ #endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */ + /* + * Wait for all memory transactions to complete before entering low + * power state. + */ + dsb + + /* Enter low power state */ wfi - /* Clear PRIMASK to service any pending interrupt */ + /* + * Clear PRIMASK and flush instruction buffer to immediately service + * the wake-up interrupt. + */ cpsie i + isb bx lr