* Standard FreeRTOS exception handlers.\r
*/\r
void xPortPendSVHandler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;\r
-void xPortSysTickHandler( void ) __attribute__ ((optimize("3"))) PRIVILEGED_FUNCTION;\r
+void xPortSysTickHandler( void ) PRIVILEGED_FUNCTION;\r
void vPortSVCHandler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;\r
\r
/*\r
static void prvSVCHandler( uint32_t *pulParam )\r
{\r
uint8_t ucSVCNumber;\r
+uint32_t ulPC;\r
+#if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 )\r
+ #if defined( __ARMCC_VERSION )\r
+ /* Declaration when these variable are defined in code instead of being\r
+ * exported from linker scripts. */\r
+ extern uint32_t * __syscalls_flash_start__;\r
+ extern uint32_t * __syscalls_flash_end__;\r
+ #else\r
+ /* Declaration when these variable are exported from linker scripts. */\r
+ extern uint32_t __syscalls_flash_start__[];\r
+ extern uint32_t __syscalls_flash_end__[];\r
+ #endif /* #if defined( __ARMCC_VERSION ) */\r
+#endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */\r
+\r
+ /* The stack contains: r0, r1, r2, r3, r12, LR, PC and xPSR. The first\r
+ argument (r0) is pulParam[ 0 ]. */\r
+ ulPC = pulParam[ portOFFSET_TO_PC ];\r
+ ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ];\r
\r
- /* The stack contains: r0, r1, r2, r3, r12, r14, the return address and\r
- xPSR. The first argument (r0) is pulParam[ 0 ]. */\r
- ucSVCNumber = ( ( uint8_t * ) pulParam[ portOFFSET_TO_PC ] )[ -2 ];\r
switch( ucSVCNumber )\r
{\r
case portSVC_START_SCHEDULER : portNVIC_SYSPRI1_REG |= portNVIC_SVC_PRI;\r
\r
break;\r
\r
+ #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 )\r
+ case portSVC_RAISE_PRIVILEGE : /* Only raise the privilege, if the\r
+ * svc was raised from any of the\r
+ * system calls. */\r
+ if( ulPC >= ( uint32_t ) __syscalls_flash_start__ &&\r
+ ulPC <= ( uint32_t ) __syscalls_flash_end__ )\r
+ {\r
+ __asm volatile\r
+ (\r
+ " mrs r1, control \n" /* Obtain current control value. */\r
+ " bic r1, #1 \n" /* Set privilege bit. */\r
+ " msr control, r1 \n" /* Write back new control value. */\r
+ ::: "r1", "memory"\r
+ );\r
+ }\r
+ break;\r
+ #else\r
case portSVC_RAISE_PRIVILEGE : __asm volatile\r
(\r
" mrs r1, control \n" /* Obtain current control value. */\r
::: "r1", "memory"\r
);\r
break;\r
+ #endif /* #if( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY == 1 ) */\r
\r
default : /* Unknown SVC call. */\r
break;\r
" ldr r1, [r3] \n"\r
" ldr r0, [r1] \n" /* The first item in the TCB is the task top of stack. */\r
" add r1, r1, #4 \n" /* Move onto the second item in the TCB... */\r
+ " \n"\r
+ " dmb \n" /* Complete outstanding transfers before disabling MPU. */\r
+ " ldr r2, =0xe000ed94 \n" /* MPU_CTRL register. */\r
+ " ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */\r
+ " bic r3, #1 \n" /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */\r
+ " str r3, [r2] \n" /* Disable MPU. */\r
+ " \n"\r
" ldr r2, =0xe000ed9c \n" /* Region Base Address register. */\r
- " ldmia r1!, {r4-r11} \n" /* Read 4 sets of MPU registers. */\r
+ " ldmia r1!, {r4-r11} \n" /* Read 4 sets of MPU registers from TCB. */\r
" stmia r2!, {r4-r11} \n" /* Write 4 sets of MPU registers. */\r
+ " \n"\r
+ " ldr r2, =0xe000ed94 \n" /* MPU_CTRL register. */\r
+ " ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */\r
+ " orr r3, #1 \n" /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */\r
+ " str r3, [r2] \n" /* Enable MPU. */\r
+ " dsb \n" /* Force memory writes before continuing. */\r
+ " \n"\r
" ldmia r0!, {r3-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry. */\r
" msr control, r3 \n"\r
" msr psp, r0 \n" /* Restore the task stack pointer. */\r
" ldr r1, [r3] \n"\r
" ldr r0, [r1] \n" /* The first item in the TCB is the task top of stack. */\r
" add r1, r1, #4 \n" /* Move onto the second item in the TCB... */\r
+ " \n"\r
+ " dmb \n" /* Complete outstanding transfers before disabling MPU. */\r
+ " ldr r2, =0xe000ed94 \n" /* MPU_CTRL register. */\r
+ " ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */\r
+ " bic r3, #1 \n" /* r3 = r3 & ~1 i.e. Clear the bit 0 in r3. */\r
+ " str r3, [r2] \n" /* Disable MPU. */\r
+ " \n"\r
" ldr r2, =0xe000ed9c \n" /* Region Base Address register. */\r
- " ldmia r1!, {r4-r11} \n" /* Read 4 sets of MPU registers. */\r
+ " ldmia r1!, {r4-r11} \n" /* Read 4 sets of MPU registers from TCB. */\r
" stmia r2!, {r4-r11} \n" /* Write 4 sets of MPU registers. */\r
+ " \n"\r
+ " ldr r2, =0xe000ed94 \n" /* MPU_CTRL register. */\r
+ " ldr r3, [r2] \n" /* Read the value of MPU_CTRL. */\r
+ " orr r3, #1 \n" /* r3 = r3 | 1 i.e. Set the bit 0 in r3. */\r
+ " str r3, [r2] \n" /* Enable MPU. */\r
+ " dsb \n" /* Force memory writes before continuing. */\r
+ " \n"\r
" ldmia r0!, {r3-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry. */\r
" msr control, r3 \n"\r
" \n"\r
\r
static void prvSetupMPU( void )\r
{\r
-extern uint32_t __privileged_functions_end__[];\r
-extern uint32_t __FLASH_segment_start__[];\r
-extern uint32_t __FLASH_segment_end__[];\r
-extern uint32_t __privileged_data_start__[];\r
-extern uint32_t __privileged_data_end__[];\r
-\r
+#if defined( __ARMCC_VERSION )\r
+ /* Declaration when these variable are defined in code instead of being\r
+ * exported from linker scripts. */\r
+ extern uint32_t * __privileged_functions_end__;\r
+ extern uint32_t * __FLASH_segment_start__;\r
+ extern uint32_t * __FLASH_segment_end__;\r
+ extern uint32_t * __privileged_data_start__;\r
+ extern uint32_t * __privileged_data_end__;\r
+#else\r
+ /* Declaration when these variable are exported from linker scripts. */\r
+ extern uint32_t __privileged_functions_end__[];\r
+ extern uint32_t __FLASH_segment_start__[];\r
+ extern uint32_t __FLASH_segment_end__[];\r
+ extern uint32_t __privileged_data_start__[];\r
+ extern uint32_t __privileged_data_end__[];\r
+#endif\r
/* Check the expected MPU is present. */\r
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )\r
{\r
\r
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth )\r
{\r
-extern uint32_t __SRAM_segment_start__[];\r
-extern uint32_t __SRAM_segment_end__[];\r
-extern uint32_t __privileged_data_start__[];\r
-extern uint32_t __privileged_data_end__[];\r
+#if defined( __ARMCC_VERSION )\r
+ /* Declaration when these variable are defined in code instead of being\r
+ * exported from linker scripts. */\r
+ extern uint32_t * __SRAM_segment_start__;\r
+ extern uint32_t * __SRAM_segment_end__;\r
+ extern uint32_t * __privileged_data_start__;\r
+ extern uint32_t * __privileged_data_end__;\r
+#else\r
+ /* Declaration when these variable are exported from linker scripts. */\r
+ extern uint32_t __SRAM_segment_start__[];\r
+ extern uint32_t __SRAM_segment_end__[];\r
+ extern uint32_t __privileged_data_start__[];\r
+ extern uint32_t __privileged_data_end__[];\r
+#endif\r
+\r
int32_t lIndex;\r
uint32_t ul;\r
\r