Răsfoiți Sursa

GCC: add WFI/WFE compiler barriers

Add "memory" clobber to __WFI and __WFE. Architecturally these should
always be immediately preceded by a __DSB (eg to ensure the write buffer
is drained). Without a barrier on WFI, the following compiler reordering
would be permitted:

     __DSB();             __DSB();
     __WFI();       ->    val_in_ram = 3;
     val_in_ram = 3;      __WFI();

This could cause some power issues with the external bus not being
idle.

The added barrier should have no impact on code size, assuming these
instructions are always accompanied by DSB, as DSB does have its own
memory clobber already.

SEV not modified as there are no issues with the equivalent reordering;
we only need the SEV to not be reordered before the DSB, which is
ensured by volatile.
Kevin Bracey 7 ani în urmă
părinte
comite
a693d677a9
2 a modificat fișierele cu 4 adăugiri și 4 ștergeri
  1. 2 2
      CMSIS/Core/Include/cmsis_gcc.h
  2. 2 2
      CMSIS/Core_A/Include/cmsis_gcc.h

+ 2 - 2
CMSIS/Core/Include/cmsis_gcc.h

@@ -906,7 +906,7 @@ __STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr)
   \brief   Wait For Interrupt
   \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
  */
-#define __WFI()                             __ASM volatile ("wfi")
+#define __WFI()                             __ASM volatile ("wfi":::"memory")
 
 
 /**
@@ -914,7 +914,7 @@ __STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr)
   \details Wait For Event is a hint instruction that permits the processor to enter
            a low-power state until one of a number of events occurs.
  */
-#define __WFE()                             __ASM volatile ("wfe")
+#define __WFE()                             __ASM volatile ("wfe":::"memory")
 
 
 /**

+ 2 - 2
CMSIS/Core_A/Include/cmsis_gcc.h

@@ -234,12 +234,12 @@ __STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
 /**
   \brief   Wait For Interrupt
  */
-#define __WFI()                             __ASM volatile ("wfi")
+#define __WFI()                             __ASM volatile ("wfi":::"memory")
 
 /**
   \brief   Wait For Event
  */
-#define __WFE()                             __ASM volatile ("wfe")
+#define __WFE()                             __ASM volatile ("wfe":::"memory")
 
 /**
   \brief   Send Event