From ad5ec6af085dc8cbe695872f98c2d07eb325fcf6 Mon Sep 17 00:00:00 2001 From: fenugrec Date: Sun, 10 Jan 2016 11:13:25 -0500 Subject: [PATCH] Cortex-M defines : fix potential issue where PRIMASK and FAULTMASK operations could be optimized out by gcc. This adds the "volatile" keyword to all the inline assembly. gcc docs say "You can prevent an asm instruction from being deleted by writing the keyword volatile after the asm.". Testing (see comments of github issue #475) shows that indeed gcc can remove some inline asm, in at least this situation: -multiple calls to cm_is_masked_interrupts() in the same scope/context - -Os or -O2 optimization This is problem because the value of PRIMASK could change between two calls to cm_is_masked_interrupts(). Adding the volatile keyword fixes this, and probably costs less than adding a full barrier (like adding "memory" to the clobber list). --- include/libopencm3/cm3/cortex.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/libopencm3/cm3/cortex.h b/include/libopencm3/cm3/cortex.h index e3aa53c6..66f2cd6f 100644 --- a/include/libopencm3/cm3/cortex.h +++ b/include/libopencm3/cm3/cortex.h @@ -43,7 +43,7 @@ */ static inline void cm_enable_interrupts(void) { - __asm__("CPSIE I\n"); + __asm__ volatile ("CPSIE I\n"); } /*---------------------------------------------------------------------------*/ @@ -53,7 +53,7 @@ static inline void cm_enable_interrupts(void) */ static inline void cm_disable_interrupts(void) { - __asm__("CPSID I\n"); + __asm__ volatile ("CPSID I\n"); } /*---------------------------------------------------------------------------*/ @@ -63,7 +63,7 @@ static inline void cm_disable_interrupts(void) */ static inline void cm_enable_faults(void) { - __asm__("CPSIE F\n"); + __asm__ volatile ("CPSIE F\n"); } /*---------------------------------------------------------------------------*/ @@ -73,7 +73,7 @@ static inline void cm_enable_faults(void) */ static inline void cm_disable_faults(void) { - __asm__("CPSID F\n"); + __asm__ volatile ("CPSID F\n"); } /*---------------------------------------------------------------------------*/ @@ -87,7 +87,7 @@ __attribute__((always_inline)) static inline bool cm_is_masked_interrupts(void) { register uint32_t result; - __asm__ ("MRS %0, PRIMASK" : "=r" (result)); + __asm__ volatile ("MRS %0, PRIMASK" : "=r" (result)); return result; } @@ -102,7 +102,7 @@ __attribute__((always_inline)) static inline bool cm_is_masked_faults(void) { register uint32_t result; - __asm__ ("MRS %0, FAULTMASK" : "=r" (result)); + __asm__ volatile ("MRS %0, FAULTMASK" : "=r" (result)); return result; }