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 <Ioannis.Glaropoulos@nordicsemi.no>
Signed-off-by: Stephanos Ioannidis <root@stephanos.io>
This commit is contained in:
Stephanos Ioannidis 2020-03-17 12:23:58 +09:00 committed by Ioannis Glaropoulos
commit 3f395f5698

View file

@ -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