Add additional memory barriers into ARM GCC asm code to ensure no re-ordering across asm code as optimisers get more aggressive.

This commit is contained in:
Richard Barry 2017-03-07 04:06:10 +00:00
parent c3acc441ac
commit b9fe24962e
16 changed files with 100 additions and 98 deletions

View file

@ -448,7 +448,7 @@ void FreeRTOS_Tick_Handler( void )
{ {
uint32_t ulMaskBits; uint32_t ulMaskBits;
__asm volatile( "mrs %0, daif" : "=r"( ulMaskBits ) ); __asm volatile( "mrs %0, daif" : "=r"( ulMaskBits ) :: "memory" );
configASSERT( ( ulMaskBits & portDAIF_I ) != 0 ); configASSERT( ( ulMaskBits & portDAIF_I ) != 0 );
} }
#endif /* configASSERT_DEFINED */ #endif /* configASSERT_DEFINED */
@ -460,7 +460,7 @@ void FreeRTOS_Tick_Handler( void )
updated. */ updated. */
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
__asm volatile ( "dsb sy \n" __asm volatile ( "dsb sy \n"
"isb sy \n" ); "isb sy \n" ::: "memory" );
/* Ok to enable interrupts after the interrupt source has been cleared. */ /* Ok to enable interrupts after the interrupt source has been cleared. */
configCLEAR_TICK_INTERRUPT(); configCLEAR_TICK_INTERRUPT();
@ -514,7 +514,7 @@ uint32_t ulReturn;
ulReturn = pdFALSE; ulReturn = pdFALSE;
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
__asm volatile ( "dsb sy \n" __asm volatile ( "dsb sy \n"
"isb sy \n" ); "isb sy \n" ::: "memory" );
} }
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();

View file

@ -129,9 +129,9 @@ extern uint64_t ullPortYieldRequired; \
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
#if defined( GUEST ) #if defined( GUEST )
#define portYIELD() __asm volatile ( "SVC 0" ) #define portYIELD() __asm volatile ( "SVC 0" ::: "memory" )
#else #else
#define portYIELD() __asm volatile ( "SMC 0" ) #define portYIELD() __asm volatile ( "SMC 0" ::: "memory" )
#endif #endif
/*----------------------------------------------------------- /*-----------------------------------------------------------
* Critical section control * Critical section control
@ -144,12 +144,12 @@ extern void vPortClearInterruptMask( UBaseType_t uxNewMaskValue );
extern void vPortInstallFreeRTOSVectorTable( void ); extern void vPortInstallFreeRTOSVectorTable( void );
#define portDISABLE_INTERRUPTS() \ #define portDISABLE_INTERRUPTS() \
__asm volatile ( "MSR DAIFSET, #2" ); \ __asm volatile ( "MSR DAIFSET, #2" ::: "memory" ); \
__asm volatile ( "DSB SY" ); \ __asm volatile ( "DSB SY" ); \
__asm volatile ( "ISB SY" ); __asm volatile ( "ISB SY" );
#define portENABLE_INTERRUPTS() \ #define portENABLE_INTERRUPTS() \
__asm volatile ( "MSR DAIFCLR, #2" ); \ __asm volatile ( "MSR DAIFCLR, #2" ::: "memory" ); \
__asm volatile ( "DSB SY" ); \ __asm volatile ( "DSB SY" ); \
__asm volatile ( "ISB SY" ); __asm volatile ( "ISB SY" );

View file

@ -156,12 +156,12 @@ mode. */
determined priority level. Sometimes it is necessary to turn interrupt off in determined priority level. Sometimes it is necessary to turn interrupt off in
the CPU itself before modifying certain hardware registers. */ the CPU itself before modifying certain hardware registers. */
#define portCPU_IRQ_DISABLE() \ #define portCPU_IRQ_DISABLE() \
__asm volatile ( "CPSID i" ); \ __asm volatile ( "CPSID i" ::: "memory" ); \
__asm volatile ( "DSB" ); \ __asm volatile ( "DSB" ); \
__asm volatile ( "ISB" ); __asm volatile ( "ISB" );
#define portCPU_IRQ_ENABLE() \ #define portCPU_IRQ_ENABLE() \
__asm volatile ( "CPSIE i" ); \ __asm volatile ( "CPSIE i" ::: "memory" ); \
__asm volatile ( "DSB" ); \ __asm volatile ( "DSB" ); \
__asm volatile ( "ISB" ); __asm volatile ( "ISB" );
@ -404,7 +404,7 @@ uint32_t ulAPSR;
/* Only continue if the CPU is not in User mode. The CPU must be in a /* Only continue if the CPU is not in User mode. The CPU must be in a
Privileged mode for the scheduler to start. */ Privileged mode for the scheduler to start. */
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) ); __asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) :: "memory" );
ulAPSR &= portAPSR_MODE_BITS_MASK; ulAPSR &= portAPSR_MODE_BITS_MASK;
configASSERT( ulAPSR != portAPSR_USER_MODE ); configASSERT( ulAPSR != portAPSR_USER_MODE );
@ -501,7 +501,7 @@ void FreeRTOS_Tick_Handler( void )
portCPU_IRQ_DISABLE(); portCPU_IRQ_DISABLE();
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
__asm volatile ( "dsb \n" __asm volatile ( "dsb \n"
"isb \n" ); "isb \n" ::: "memory" );
portCPU_IRQ_ENABLE(); portCPU_IRQ_ENABLE();
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
@ -527,7 +527,7 @@ void FreeRTOS_Tick_Handler( void )
ulPortTaskHasFPUContext = pdTRUE; ulPortTaskHasFPUContext = pdTRUE;
/* Initialise the floating point status register. */ /* Initialise the floating point status register. */
__asm volatile ( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) ); __asm volatile ( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) : "memory" );
} }
#endif /* configUSE_TASK_FPU_SUPPORT */ #endif /* configUSE_TASK_FPU_SUPPORT */
@ -559,7 +559,7 @@ uint32_t ulReturn;
ulReturn = pdFALSE; ulReturn = pdFALSE;
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
__asm volatile ( "dsb \n" __asm volatile ( "dsb \n"
"isb \n" ); "isb \n" ::: "memory" );
} }
portCPU_IRQ_ENABLE(); portCPU_IRQ_ENABLE();

View file

@ -127,7 +127,7 @@ extern uint32_t ulPortYieldRequired; \
} }
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
#define portYIELD() __asm volatile ( "SWI 0" ); #define portYIELD() __asm volatile ( "SWI 0" ::: "memory" );
/*----------------------------------------------------------- /*-----------------------------------------------------------

View file

@ -79,15 +79,15 @@
#define portNVIC_SYSTICK_CTRL ( ( volatile uint32_t * ) 0xe000e010 ) #define portNVIC_SYSTICK_CTRL ( ( volatile uint32_t * ) 0xe000e010 )
#define portNVIC_SYSTICK_LOAD ( ( volatile uint32_t * ) 0xe000e014 ) #define portNVIC_SYSTICK_LOAD ( ( volatile uint32_t * ) 0xe000e014 )
#define portNVIC_SYSTICK_CURRENT_VALUE ( ( volatile uint32_t * ) 0xe000e018 ) #define portNVIC_SYSTICK_CURRENT_VALUE ( ( volatile uint32_t * ) 0xe000e018 )
#define portNVIC_INT_CTRL ( ( volatile uint32_t *) 0xe000ed04 ) #define portNVIC_INT_CTRL ( ( volatile uint32_t *) 0xe000ed04 )
#define portNVIC_SYSPRI2 ( ( volatile uint32_t *) 0xe000ed20 ) #define portNVIC_SYSPRI2 ( ( volatile uint32_t *) 0xe000ed20 )
#define portNVIC_SYSTICK_CLK 0x00000004 #define portNVIC_SYSTICK_CLK 0x00000004
#define portNVIC_SYSTICK_INT 0x00000002 #define portNVIC_SYSTICK_INT 0x00000002
#define portNVIC_SYSTICK_ENABLE 0x00000001 #define portNVIC_SYSTICK_ENABLE 0x00000001
#define portNVIC_PENDSVSET 0x10000000 #define portNVIC_PENDSVSET 0x10000000
#define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portMIN_INTERRUPT_PRIORITY ( 255UL )
#define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL )
#define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL )
/* Constants required to set up the initial stack. */ /* Constants required to set up the initial stack. */
#define portINITIAL_XPSR ( 0x01000000 ) #define portINITIAL_XPSR ( 0x01000000 )
@ -243,7 +243,7 @@ void vPortYield( void )
/* Barriers are normally not required but do ensure the code is completely /* Barriers are normally not required but do ensure the code is completely
within the specified behaviour for the architecture. */ within the specified behaviour for the architecture. */
__asm volatile( "dsb" ); __asm volatile( "dsb" ::: "memory" );
__asm volatile( "isb" ); __asm volatile( "isb" );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -252,7 +252,7 @@ void vPortEnterCritical( void )
{ {
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
uxCriticalNesting++; uxCriticalNesting++;
__asm volatile( "dsb" ); __asm volatile( "dsb" ::: "memory" );
__asm volatile( "isb" ); __asm volatile( "isb" );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -274,6 +274,7 @@ uint32_t ulSetInterruptMaskFromISR( void )
" mrs r0, PRIMASK \n" " mrs r0, PRIMASK \n"
" cpsid i \n" " cpsid i \n"
" bx lr " " bx lr "
::: "memory"
); );
/* To avoid compiler warnings. This line will never be reached. */ /* To avoid compiler warnings. This line will never be reached. */
@ -286,6 +287,7 @@ void vClearInterruptMaskFromISR( uint32_t ulMask )
__asm volatile( __asm volatile(
" msr PRIMASK, r0 \n" " msr PRIMASK, r0 \n"
" bx lr " " bx lr "
::: "memory"
); );
/* Just to avoid compiler warning. */ /* Just to avoid compiler warning. */

View file

@ -136,8 +136,8 @@ extern void vClearInterruptMaskFromISR( uint32_t ulMask ) __attribute__((naked)
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() #define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ) #define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " ::: "memory" )
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ) #define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " ::: "memory" )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()

View file

@ -436,7 +436,7 @@ void xPortPendSVHandler( void )
" mov r0, #0 \n" " mov r0, #0 \n"
" msr basepri, r0 \n" " msr basepri, r0 \n"
" ldmia sp!, {r3, r14} \n" " ldmia sp!, {r3, r14} \n"
" \n" /* Restore the context, including the critical nesting count. */ " \n" /* Restore the context, including the critical nesting count. */
" ldr r1, [r3] \n" " ldr r1, [r3] \n"
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
" ldmia r0!, {r4-r11} \n" /* Pop the registers. */ " ldmia r0!, {r4-r11} \n" /* Pop the registers. */
@ -501,7 +501,7 @@ void xPortSysTickHandler( void )
/* Enter a critical section but don't use the taskENTER_CRITICAL() /* Enter a critical section but don't use the taskENTER_CRITICAL()
method as that will mask interrupts that should exit sleep mode. */ method as that will mask interrupts that should exit sleep mode. */
__asm volatile( "cpsid i" ); __asm volatile( "cpsid i" ::: "memory" );
__asm volatile( "dsb" ); __asm volatile( "dsb" );
__asm volatile( "isb" ); __asm volatile( "isb" );
@ -522,7 +522,7 @@ void xPortSysTickHandler( void )
/* Re-enable interrupts - see comments above the cpsid instruction() /* Re-enable interrupts - see comments above the cpsid instruction()
above. */ above. */
__asm volatile( "cpsie i" ); __asm volatile( "cpsie i" ::: "memory" );
} }
else else
{ {
@ -545,7 +545,7 @@ void xPortSysTickHandler( void )
configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 ) if( xModifiableIdleTime > 0 )
{ {
__asm volatile( "dsb" ); __asm volatile( "dsb" ::: "memory" );
__asm volatile( "wfi" ); __asm volatile( "wfi" );
__asm volatile( "isb" ); __asm volatile( "isb" );
} }
@ -553,7 +553,7 @@ void xPortSysTickHandler( void )
/* Re-enable interrupts - see comments above the cpsid instruction() /* Re-enable interrupts - see comments above the cpsid instruction()
above. */ above. */
__asm volatile( "cpsie i" ); __asm volatile( "cpsie i" ::: "memory" );
/* Disable the SysTick clock without reading the /* Disable the SysTick clock without reading the
portNVIC_SYSTICK_CTRL_REG register to ensure the portNVIC_SYSTICK_CTRL_REG register to ensure the
@ -661,7 +661,7 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
uint8_t ucCurrentPriority; uint8_t ucCurrentPriority;
/* Obtain the number of the currently executing interrupt. */ /* Obtain the number of the currently executing interrupt. */
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
/* Is the interrupt number a user defined interrupt? */ /* Is the interrupt number a user defined interrupt? */
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )

View file

@ -125,7 +125,7 @@ typedef unsigned long UBaseType_t;
\ \
/* Barriers are normally not required but do ensure the code is completely \ /* Barriers are normally not required but do ensure the code is completely \
within the specified behaviour for the architecture. */ \ within the specified behaviour for the architecture. */ \
__asm volatile( "dsb" ); \ __asm volatile( "dsb" ::: "memory" ); \
__asm volatile( "isb" ); \ __asm volatile( "isb" ); \
} }
@ -173,7 +173,7 @@ not necessary for to use this port. They are defined so the common demo files
{ {
uint8_t ucReturn; uint8_t ucReturn;
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) ); __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
return ucReturn; return ucReturn;
} }
@ -214,7 +214,7 @@ uint32_t ulCurrentInterrupt;
BaseType_t xReturn; BaseType_t xReturn;
/* Obtain the number of the currently executing interrupt. */ /* Obtain the number of the currently executing interrupt. */
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
if( ulCurrentInterrupt == 0 ) if( ulCurrentInterrupt == 0 )
{ {
@ -236,11 +236,11 @@ uint32_t ulNewBASEPRI;
__asm volatile __asm volatile
( (
" mov %0, %1 \n" \ " mov %0, %1 \n" \
" msr basepri, %0 \n" \ " msr basepri, %0 \n" \
" isb \n" \ " isb \n" \
" dsb \n" \ " dsb \n" \
:"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
} }
@ -253,11 +253,11 @@ uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
__asm volatile __asm volatile
( (
" mrs %0, basepri \n" \ " mrs %0, basepri \n" \
" mov %1, %2 \n" \ " mov %1, %2 \n" \
" msr basepri, %1 \n" \ " msr basepri, %1 \n" \
" isb \n" \ " isb \n" \
" dsb \n" \ " dsb \n" \
:"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) :"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
/* This return will not be reached but is necessary to prevent compiler /* This return will not be reached but is necessary to prevent compiler
@ -270,7 +270,7 @@ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
{ {
__asm volatile __asm volatile
( (
" msr basepri, %0 " :: "r" ( ulNewMaskValue ) " msr basepri, %0 " :: "r" ( ulNewMaskValue ) : "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -132,7 +132,7 @@ typedef unsigned long UBaseType_t;
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
#define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " :::"r0" ) #define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " ::: "r0", "memory" )
typedef struct MPU_REGION_REGISTERS typedef struct MPU_REGION_REGISTERS
{ {
@ -159,7 +159,7 @@ typedef struct MPU_SETTINGS
/* Scheduler utilities. */ /* Scheduler utilities. */
#define portYIELD() __asm volatile ( " SVC %0 \n" :: "i" (portSVC_YIELD) ) #define portYIELD() __asm volatile ( " SVC %0 \n" :: "i" (portSVC_YIELD) : "memory" )
#define portYIELD_WITHIN_API() \ #define portYIELD_WITHIN_API() \
{ \ { \
/* Set a PendSV to request a context switch. */ \ /* Set a PendSV to request a context switch. */ \
@ -167,7 +167,7 @@ typedef struct MPU_SETTINGS
\ \
/* Barriers are normally not required but do ensure the code is completely \ /* Barriers are normally not required but do ensure the code is completely \
within the specified behaviour for the architecture. */ \ within the specified behaviour for the architecture. */ \
__asm volatile( "dsb" ); \ __asm volatile( "dsb" ::: "memory" ); \
__asm volatile( "isb" ); \ __asm volatile( "isb" ); \
} }
@ -208,7 +208,7 @@ not necessary for to use this port. They are defined so the common demo files
{ {
uint8_t ucReturn; uint8_t ucReturn;
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) ); __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
return ucReturn; return ucReturn;
} }
@ -251,7 +251,7 @@ portFORCE_INLINE static void vPortResetPrivilege( BaseType_t xRunningPrivileged
__asm volatile ( " mrs r0, control \n" \ __asm volatile ( " mrs r0, control \n" \
" orr r0, #1 \n" \ " orr r0, #1 \n" \
" msr control, r0 \n" \ " msr control, r0 \n" \
:::"r0" ); :::"r0", "memory" );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -262,7 +262,7 @@ uint32_t ulCurrentInterrupt;
BaseType_t xReturn; BaseType_t xReturn;
/* Obtain the number of the currently executing interrupt. */ /* Obtain the number of the currently executing interrupt. */
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
if( ulCurrentInterrupt == 0 ) if( ulCurrentInterrupt == 0 )
{ {
@ -288,7 +288,7 @@ uint32_t ulNewBASEPRI;
" msr basepri, %0 \n" \ " msr basepri, %0 \n" \
" isb \n" \ " isb \n" \
" dsb \n" \ " dsb \n" \
:"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
} }
@ -305,7 +305,7 @@ uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
" msr basepri, %1 \n" \ " msr basepri, %1 \n" \
" isb \n" \ " isb \n" \
" dsb \n" \ " dsb \n" \
:"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) :"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
/* This return will not be reached but is necessary to prevent compiler /* This return will not be reached but is necessary to prevent compiler
@ -318,7 +318,7 @@ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
{ {
__asm volatile __asm volatile
( (
" msr basepri, %0 " :: "r" ( ulNewMaskValue ) " msr basepri, %0 " :: "r" ( ulNewMaskValue ) : "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -563,7 +563,7 @@ void xPortSysTickHandler( void )
/* Enter a critical section but don't use the taskENTER_CRITICAL() /* Enter a critical section but don't use the taskENTER_CRITICAL()
method as that will mask interrupts that should exit sleep mode. */ method as that will mask interrupts that should exit sleep mode. */
__asm volatile( "cpsid i" ); __asm volatile( "cpsid i" ::: "memory" );
__asm volatile( "dsb" ); __asm volatile( "dsb" );
__asm volatile( "isb" ); __asm volatile( "isb" );
@ -584,7 +584,7 @@ void xPortSysTickHandler( void )
/* Re-enable interrupts - see comments above the cpsid instruction() /* Re-enable interrupts - see comments above the cpsid instruction()
above. */ above. */
__asm volatile( "cpsie i" ); __asm volatile( "cpsie i" ::: "memory" );
} }
else else
{ {
@ -607,7 +607,7 @@ void xPortSysTickHandler( void )
configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 ) if( xModifiableIdleTime > 0 )
{ {
__asm volatile( "dsb" ); __asm volatile( "dsb" ::: "memory" );
__asm volatile( "wfi" ); __asm volatile( "wfi" );
__asm volatile( "isb" ); __asm volatile( "isb" );
} }
@ -622,7 +622,7 @@ void xPortSysTickHandler( void )
/* Re-enable interrupts - see comments above the cpsid instruction() /* Re-enable interrupts - see comments above the cpsid instruction()
above. */ above. */
__asm volatile( "cpsie i" ); __asm volatile( "cpsie i" ::: "memory" );
if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
{ {
@ -735,7 +735,7 @@ static void vPortEnableVFP( void )
uint8_t ucCurrentPriority; uint8_t ucCurrentPriority;
/* Obtain the number of the currently executing interrupt. */ /* Obtain the number of the currently executing interrupt. */
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
/* Is the interrupt number a user defined interrupt? */ /* Is the interrupt number a user defined interrupt? */
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )

View file

@ -125,7 +125,7 @@ typedef unsigned long UBaseType_t;
\ \
/* Barriers are normally not required but do ensure the code is completely \ /* Barriers are normally not required but do ensure the code is completely \
within the specified behaviour for the architecture. */ \ within the specified behaviour for the architecture. */ \
__asm volatile( "dsb" ); \ __asm volatile( "dsb" ::: "memory" ); \
__asm volatile( "isb" ); \ __asm volatile( "isb" ); \
} }
@ -173,7 +173,7 @@ not necessary for to use this port. They are defined so the common demo files
{ {
uint8_t ucReturn; uint8_t ucReturn;
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) ); __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
return ucReturn; return ucReturn;
} }
@ -214,7 +214,7 @@ uint32_t ulCurrentInterrupt;
BaseType_t xReturn; BaseType_t xReturn;
/* Obtain the number of the currently executing interrupt. */ /* Obtain the number of the currently executing interrupt. */
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
if( ulCurrentInterrupt == 0 ) if( ulCurrentInterrupt == 0 )
{ {
@ -240,7 +240,7 @@ uint32_t ulNewBASEPRI;
" msr basepri, %0 \n" \ " msr basepri, %0 \n" \
" isb \n" \ " isb \n" \
" dsb \n" \ " dsb \n" \
:"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
} }
@ -257,7 +257,7 @@ uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
" msr basepri, %1 \n" \ " msr basepri, %1 \n" \
" isb \n" \ " isb \n" \
" dsb \n" \ " dsb \n" \
:"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) :"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
/* This return will not be reached but is necessary to prevent compiler /* This return will not be reached but is necessary to prevent compiler
@ -270,7 +270,7 @@ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
{ {
__asm volatile __asm volatile
( (
" msr basepri, %0 " :: "r" ( ulNewMaskValue ) " msr basepri, %0 " :: "r" ( ulNewMaskValue ) : "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -132,7 +132,7 @@ typedef unsigned long UBaseType_t;
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
#define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " :::"r0" ) #define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " ::: "r0", "memory" )
typedef struct MPU_REGION_REGISTERS typedef struct MPU_REGION_REGISTERS
{ {
@ -159,7 +159,7 @@ typedef struct MPU_SETTINGS
/* Scheduler utilities. */ /* Scheduler utilities. */
#define portYIELD() __asm volatile ( " SVC %0 \n" :: "i" (portSVC_YIELD) ) #define portYIELD() __asm volatile ( " SVC %0 \n" :: "i" (portSVC_YIELD) : "memory" )
#define portYIELD_WITHIN_API() \ #define portYIELD_WITHIN_API() \
{ \ { \
/* Set a PendSV to request a context switch. */ \ /* Set a PendSV to request a context switch. */ \
@ -167,7 +167,7 @@ typedef struct MPU_SETTINGS
\ \
/* Barriers are normally not required but do ensure the code is completely \ /* Barriers are normally not required but do ensure the code is completely \
within the specified behaviour for the architecture. */ \ within the specified behaviour for the architecture. */ \
__asm volatile( "dsb" ); \ __asm volatile( "dsb" ::: "memory" ); \
__asm volatile( "isb" ); \ __asm volatile( "isb" ); \
} }
@ -208,7 +208,7 @@ not necessary for to use this port. They are defined so the common demo files
{ {
uint8_t ucReturn; uint8_t ucReturn;
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) ); __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
return ucReturn; return ucReturn;
} }
@ -251,7 +251,7 @@ portFORCE_INLINE static void vPortResetPrivilege( BaseType_t xRunningPrivileged
__asm volatile ( " mrs r0, control \n" \ __asm volatile ( " mrs r0, control \n" \
" orr r0, #1 \n" \ " orr r0, #1 \n" \
" msr control, r0 \n" \ " msr control, r0 \n" \
:::"r0" ); :::"r0", "memory" );
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -262,7 +262,7 @@ uint32_t ulCurrentInterrupt;
BaseType_t xReturn; BaseType_t xReturn;
/* Obtain the number of the currently executing interrupt. */ /* Obtain the number of the currently executing interrupt. */
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
if( ulCurrentInterrupt == 0 ) if( ulCurrentInterrupt == 0 )
{ {
@ -288,7 +288,7 @@ uint32_t ulNewBASEPRI;
" msr basepri, %0 \n" \ " msr basepri, %0 \n" \
" isb \n" \ " isb \n" \
" dsb \n" \ " dsb \n" \
:"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
} }
@ -305,7 +305,7 @@ uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
" msr basepri, %1 \n" \ " msr basepri, %1 \n" \
" isb \n" \ " isb \n" \
" dsb \n" \ " dsb \n" \
:"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) :"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
/* This return will not be reached but is necessary to prevent compiler /* This return will not be reached but is necessary to prevent compiler
@ -318,7 +318,7 @@ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
{ {
__asm volatile __asm volatile
( (
" msr basepri, %0 " :: "r" ( ulNewMaskValue ) " msr basepri, %0 " :: "r" ( ulNewMaskValue ) : "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -553,7 +553,7 @@ void xPortSysTickHandler( void )
/* Enter a critical section but don't use the taskENTER_CRITICAL() /* Enter a critical section but don't use the taskENTER_CRITICAL()
method as that will mask interrupts that should exit sleep mode. */ method as that will mask interrupts that should exit sleep mode. */
__asm volatile( "cpsid i" ); __asm volatile( "cpsid i" ::: "memory" );
__asm volatile( "dsb" ); __asm volatile( "dsb" );
__asm volatile( "isb" ); __asm volatile( "isb" );
@ -574,7 +574,7 @@ void xPortSysTickHandler( void )
/* Re-enable interrupts - see comments above the cpsid instruction() /* Re-enable interrupts - see comments above the cpsid instruction()
above. */ above. */
__asm volatile( "cpsie i" ); __asm volatile( "cpsie i" ::: "memory" );
} }
else else
{ {
@ -597,7 +597,7 @@ void xPortSysTickHandler( void )
configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 ) if( xModifiableIdleTime > 0 )
{ {
__asm volatile( "dsb" ); __asm volatile( "dsb" ::: "memory" );
__asm volatile( "wfi" ); __asm volatile( "wfi" );
__asm volatile( "isb" ); __asm volatile( "isb" );
} }
@ -612,7 +612,7 @@ void xPortSysTickHandler( void )
/* Re-enable interrupts - see comments above the cpsid instruction() /* Re-enable interrupts - see comments above the cpsid instruction()
above. */ above. */
__asm volatile( "cpsie i" ); __asm volatile( "cpsie i" ::: "memory" );
if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
{ {
@ -725,7 +725,7 @@ static void vPortEnableVFP( void )
uint8_t ucCurrentPriority; uint8_t ucCurrentPriority;
/* Obtain the number of the currently executing interrupt. */ /* Obtain the number of the currently executing interrupt. */
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
/* Is the interrupt number a user defined interrupt? */ /* Is the interrupt number a user defined interrupt? */
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )

View file

@ -125,7 +125,7 @@ typedef unsigned long UBaseType_t;
\ \
/* Barriers are normally not required but do ensure the code is completely \ /* Barriers are normally not required but do ensure the code is completely \
within the specified behaviour for the architecture. */ \ within the specified behaviour for the architecture. */ \
__asm volatile( "dsb" ); \ __asm volatile( "dsb" ::: "memory" ); \
__asm volatile( "isb" ); \ __asm volatile( "isb" ); \
} }
@ -173,7 +173,7 @@ not necessary for to use this port. They are defined so the common demo files
{ {
uint8_t ucReturn; uint8_t ucReturn;
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) ); __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
return ucReturn; return ucReturn;
} }
@ -214,7 +214,7 @@ uint32_t ulCurrentInterrupt;
BaseType_t xReturn; BaseType_t xReturn;
/* Obtain the number of the currently executing interrupt. */ /* Obtain the number of the currently executing interrupt. */
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
if( ulCurrentInterrupt == 0 ) if( ulCurrentInterrupt == 0 )
{ {
@ -242,7 +242,7 @@ uint32_t ulNewBASEPRI;
" isb \n" \ " isb \n" \
" dsb \n" \ " dsb \n" \
" cpsie i \n" \ " cpsie i \n" \
:"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
} }
@ -261,7 +261,7 @@ uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
" isb \n" \ " isb \n" \
" dsb \n" \ " dsb \n" \
" cpsie i \n" \ " cpsie i \n" \
:"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) :"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
/* This return will not be reached but is necessary to prevent compiler /* This return will not be reached but is necessary to prevent compiler
@ -274,7 +274,7 @@ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
{ {
__asm volatile __asm volatile
( (
" msr basepri, %0 " :: "r" ( ulNewMaskValue ) " msr basepri, %0 " :: "r" ( ulNewMaskValue ) : "memory"
); );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -156,12 +156,12 @@ mode. */
determined priority level. Sometimes it is necessary to turn interrupt off in determined priority level. Sometimes it is necessary to turn interrupt off in
the CPU itself before modifying certain hardware registers. */ the CPU itself before modifying certain hardware registers. */
#define portCPU_IRQ_DISABLE() \ #define portCPU_IRQ_DISABLE() \
__asm volatile ( "CPSID i" ); \ __asm volatile ( "CPSID i" ::: "memory" ); \
__asm volatile ( "DSB" ); \ __asm volatile ( "DSB" ); \
__asm volatile ( "ISB" ); __asm volatile ( "ISB" );
#define portCPU_IRQ_ENABLE() \ #define portCPU_IRQ_ENABLE() \
__asm volatile ( "CPSIE i" ); \ __asm volatile ( "CPSIE i" ::: "memory" ); \
__asm volatile ( "DSB" ); \ __asm volatile ( "DSB" ); \
__asm volatile ( "ISB" ); __asm volatile ( "ISB" );
@ -171,8 +171,8 @@ the CPU itself before modifying certain hardware registers. */
{ \ { \
portCPU_IRQ_DISABLE(); \ portCPU_IRQ_DISABLE(); \
portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \ portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE; \
__asm( "DSB \n" \ __asm volatile ( "DSB \n" \
"ISB \n" ); \ "ISB \n" ); \
portCPU_IRQ_ENABLE(); \ portCPU_IRQ_ENABLE(); \
} }
@ -367,7 +367,7 @@ uint32_t ulAPSR, ulCycles = 8; /* 8 bits per byte. */
/* Only continue if the CPU is not in User mode. The CPU must be in a /* Only continue if the CPU is not in User mode. The CPU must be in a
Privileged mode for the scheduler to start. */ Privileged mode for the scheduler to start. */
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) ); __asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR ) :: "memory" );
ulAPSR &= portAPSR_MODE_BITS_MASK; ulAPSR &= portAPSR_MODE_BITS_MASK;
configASSERT( ulAPSR != portAPSR_USER_MODE ); configASSERT( ulAPSR != portAPSR_USER_MODE );
@ -464,7 +464,7 @@ void FreeRTOS_Tick_Handler( void )
portCPU_IRQ_DISABLE(); portCPU_IRQ_DISABLE();
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
__asm volatile ( "dsb \n" __asm volatile ( "dsb \n"
"isb \n" ); "isb \n" ::: "memory" );
portCPU_IRQ_ENABLE(); portCPU_IRQ_ENABLE();
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
@ -488,7 +488,7 @@ uint32_t ulInitialFPSCR = 0;
ulPortTaskHasFPUContext = pdTRUE; ulPortTaskHasFPUContext = pdTRUE;
/* Initialise the floating point status register. */ /* Initialise the floating point status register. */
__asm volatile ( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) ); __asm volatile ( "FMXR FPSCR, %0" :: "r" (ulInitialFPSCR) : "memory" );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -518,7 +518,7 @@ uint32_t ulReturn;
ulReturn = pdFALSE; ulReturn = pdFALSE;
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ); portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
__asm volatile ( "dsb \n" __asm volatile ( "dsb \n"
"isb \n" ); "isb \n" ::: "memory" );
} }
portCPU_IRQ_ENABLE(); portCPU_IRQ_ENABLE();

View file

@ -123,7 +123,7 @@ extern uint32_t ulPortYieldRequired; \
} }
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
#define portYIELD() __asm volatile ( "SWI 0" ); #define portYIELD() __asm volatile ( "SWI 0" ::: "memory" );
/*----------------------------------------------------------- /*-----------------------------------------------------------