diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c index 0d8294e79..0b81637ef 100644 --- a/portable/ARMv8M/non_secure/port.c +++ b/portable/ARMv8M/non_secure/port.c @@ -781,7 +781,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) - uint32_t ulR0; + uint32_t ulR0, ulR1; + extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ @@ -812,25 +813,27 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged ); + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0 ); + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != NULL ); - SecureContext_LoadContext( xSecureContext ); + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains the secure context handle to be freed. */ + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 ); + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c index e32c63104..9dab039d8 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c @@ -55,79 +55,79 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_ " ldr r0, [r3] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r5, #1 \n"/* r5 = 1. */ - " bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - " movs r5, #4 \n"/* r5 = 4. */ - " str r5, [r2] \n"/* Program RNR = 4. */ - " ldmia r3!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */ - " movs r5, #5 \n"/* r5 = 5. */ - " str r5, [r2] \n"/* Program RNR = 5. */ - " ldmia r3!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */ - " movs r5, #6 \n"/* r5 = 6. */ - " str r5, [r2] \n"/* Program RNR = 6. */ - " ldmia r3!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */ - " movs r5, #7 \n"/* r5 = 7. */ - " str r5, [r2] \n"/* Program RNR = 7. */ - " ldmia r3!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r5, #1 \n"/* r5 = 1. */ - " orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ + " dmb \n"/* Complete outstanding transfers before disabling MPU. */ + " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ + " movs r5, #1 \n"/* r5 = 1. */ + " bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ + " str r4, [r2] \n"/* Disable MPU. */ + " \n" + " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ + " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r4, [r2] \n"/* Program MAIR0. */ + " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ + " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ + " movs r5, #4 \n"/* r5 = 4. */ + " str r5, [r2] \n"/* Program RNR = 4. */ + " ldmia r3!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */ + " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ + " stmia r4!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */ + " movs r5, #5 \n"/* r5 = 5. */ + " str r5, [r2] \n"/* Program RNR = 5. */ + " ldmia r3!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */ + " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ + " stmia r4!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */ + " movs r5, #6 \n"/* r5 = 6. */ + " str r5, [r2] \n"/* Program RNR = 6. */ + " ldmia r3!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */ + " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ + " stmia r4!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */ + " movs r5, #7 \n"/* r5 = 7. */ + " str r5, [r2] \n"/* Program RNR = 7. */ + " ldmia r3!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */ + " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ + " stmia r4!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */ + " \n" + " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ + " movs r5, #1 \n"/* r5 = 1. */ + " orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ + " str r4, [r2] \n"/* Enable MPU. */ + " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - " ldr r5, xSecureContextConst2 \n" - " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " msr control, r3 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " bx r4 \n"/* Finally, branch to EXC_RETURN. */ + " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ + " ldr r5, xSecureContextConst2 \n" + " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ + " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ + " msr control, r3 \n"/* Set this task's CONTROL value. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " bx r4 \n"/* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" - " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ + " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ + " ldr r4, xSecureContextConst2 \n" + " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ + " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ + " movs r1, #2 \n"/* r1 = 2. */ + " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " bx r3 \n"/* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" "xSecureContextConst2: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" + "xMPUCTRLConst2: .word 0xe000ed94 \n" + "xMAIR0Const2: .word 0xe000edc0 \n" + "xRNRConst2: .word 0xe000ed98 \n" + "xRBARConst2: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } @@ -233,64 +233,66 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" - " mrs r1, psp \n"/* Read PSP in r1. */ - " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " ldr r0, [r2] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later.*/ + " mrs r2, psp \n"/* Read PSP in r2. */ " \n" " cbz r0, save_ns_context \n"/* No secure context to save. */ " push {r0-r2, r14} \n" - " bl SecureContext_SaveContext \n" + " bl SecureContext_SaveContext \n"/* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r0-r3} \n"/* LR is now in r3. */ " mov lr, r3 \n"/* LR = r3. */ - " lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl save_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " lsls r1, r3, #25 \n"/* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl save_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r2, [r3] \n"/* Read pxCurrentTCB. */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) - " subs r1, r1, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - " str r1, [r2] \n"/* Save the new top of stack in TCB. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " stmia r1!, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mrs r3, control \n"/* r3 = CONTROL. */ + " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ - " subs r1, r1, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r1, [r2] \n"/* Save the new top of stack in TCB. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r1!, {r0, r2-r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ + " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ " b select_next_task \n" " \n" " save_ns_context: \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r2, [r3] \n"/* Read pxCurrentTCB. */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) - " subs r1, r1, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - " str r1, [r2] \n"/* Save the new top of stack in TCB. */ - " adds r1, r1, #16 \n"/* r1 = r1 + 16. */ - " stmia r1!, {r4-r7} \n"/* Store the low registers that are not saved automatically. */ - " mov r4, r8 \n"/* r4 = r8. */ - " mov r5, r9 \n"/* r5 = r9. */ - " mov r6, r10 \n"/* r6 = r10. */ - " mov r7, r11 \n"/* r7 = r11. */ - " stmia r1!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " subs r1, r1, #48 \n"/* r1 = r1 - 48. */ - " stmia r1!, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ + " stmia r2!, {r4-r7} \n"/* Store the low registers that are not saved automatically. */ + " mov r4, r8 \n"/* r4 = r8. */ + " mov r5, r9 \n"/* r5 = r9. */ + " mov r6, r10 \n"/* r6 = r10. */ + " mov r7, r11 \n"/* r7 = r11. */ + " stmia r2!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mrs r3, control \n"/* r3 = CONTROL. */ + " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ + " subs r2, r2, #48 \n"/* r2 = r2 - 48. */ + " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ - " subs r1, r1, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r1, [r2] \n"/* Save the new top of stack in TCB. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r1!, {r0, r2-r7} \n"/* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ - " mov r4, r8 \n"/* r4 = r8. */ - " mov r5, r9 \n"/* r5 = r9. */ - " mov r6, r10 \n"/* r6 = r10. */ - " mov r7, r11 \n"/* r7 = r11. */ - " stmia r1!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ + " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3-r7} \n"/* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ + " mov r4, r8 \n"/* r4 = r8. */ + " mov r5, r9 \n"/* r5 = r9. */ + " mov r6, r10 \n"/* r6 = r10. */ + " mov r7, r11 \n"/* r7 = r11. */ + " stmia r2!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ #endif /* configENABLE_MPU */ " \n" " select_next_task: \n" @@ -298,106 +300,110 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " bl vTaskSwitchContext \n" " cpsie i \n" " \n" - " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r3, [r2] \n"/* Read pxCurrentTCB. */ - " ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " ldr r2, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r5, #1 \n"/* r5 = 1. */ - " bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - " movs r5, #4 \n"/* r5 = 4. */ - " str r5, [r2] \n"/* Program RNR = 4. */ - " ldmia r3!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */ - " movs r5, #5 \n"/* r5 = 5. */ - " str r5, [r2] \n"/* Program RNR = 5. */ - " ldmia r3!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */ - " movs r5, #6 \n"/* r5 = 6. */ - " str r5, [r2] \n"/* Program RNR = 6. */ - " ldmia r3!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */ - " movs r5, #7 \n"/* r5 = 7. */ - " str r5, [r2] \n"/* Program RNR = 7. */ - " ldmia r3!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */ - " \n" - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r5, #1 \n"/* r5 = 1. */ - " orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ + " dmb \n"/* Complete outstanding transfers before disabling MPU. */ + " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ + " movs r5, #1 \n"/* r5 = 1. */ + " bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ + " str r4, [r3] \n"/* Disable MPU. */ + " \n" + " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ + " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ + " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ + " str r4, [r3] \n"/* Program MAIR0. */ + " ldr r4, xRNRConst \n"/* r4 = 0xe000ed98 [Location of RNR]. */ + " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ + " movs r5, #4 \n"/* r5 = 4. */ + " str r5, [r4] \n"/* Program RNR = 4. */ + " ldmia r1!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */ + " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ + " stmia r3!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */ + " movs r5, #5 \n"/* r5 = 5. */ + " str r5, [r4] \n"/* Program RNR = 5. */ + " ldmia r1!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */ + " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ + " stmia r3!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */ + " movs r5, #6 \n"/* r5 = 6. */ + " str r5, [r4] \n"/* Program RNR = 6. */ + " ldmia r1!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */ + " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ + " stmia r3!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */ + " movs r5, #7 \n"/* r5 = 7. */ + " str r5, [r4] \n"/* Program RNR = 7. */ + " ldmia r1!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */ + " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ + " stmia r3!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */ + " \n" + " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ + " movs r5, #1 \n"/* r5 = 1. */ + " orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ + " str r4, [r3] \n"/* Enable MPU. */ + " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) - " ldmia r1!, {r0, r2-r4} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */ - " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r2] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " push {r1,r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. */ - " pop {r1,r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r2, r4, #25 \n"/* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r1 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" + " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ + " mov lr, r4 \n"/* LR = r4. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n"/* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " push {r2, r4} \n" + " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r2, r4} \n" + " mov lr, r4 \n"/* LR = r4. */ + " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" #else /* configENABLE_MPU */ - " ldmia r1!, {r0, r2-r3} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */ - " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ - " mov lr, r3 \n"/* LR = r3. */ - " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r2] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " push {r1,r3} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. */ - " pop {r1,r3} \n" - " mov lr, r3 \n"/* LR = r3. */ - " lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r1 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" + " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " mov lr, r4 \n"/* LR = r4. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n"/* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " push {r2, r4} \n" + " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r2, r4} \n" + " mov lr, r4 \n"/* LR = r4. */ + " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" #endif /* configENABLE_MPU */ " \n" " restore_ns_context: \n" - " adds r1, r1, #16 \n"/* Move to the high registers. */ - " ldmia r1!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ + " adds r2, r2, #16 \n"/* Move to the high registers. */ + " ldmia r2!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ " mov r8, r4 \n"/* r8 = r4. */ " mov r9, r5 \n"/* r9 = r5. */ " mov r10, r6 \n"/* r10 = r6. */ " mov r11, r7 \n"/* r11 = r7. */ - " msr psp, r1 \n"/* Remember the new top of stack for the task. */ - " subs r1, r1, #32 \n"/* Go back to the low registers. */ - " ldmia r1!, {r4-r7} \n"/* Restore the low registers that are not automatically restored. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " subs r2, r2, #32 \n"/* Go back to the low registers. */ + " ldmia r2!, {r4-r7} \n"/* Restore the low registers that are not automatically restored. */ " bx lr \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" "xSecureContextConst: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" + "xMPUCTRLConst: .word 0xe000ed94 \n" + "xMAIR0Const: .word 0xe000edc0 \n" + "xRNRConst: .word 0xe000ed98 \n" + "xRBARConst: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } @@ -440,9 +446,9 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR { __asm volatile ( - " ldr r1, [r0] \n"/* The first item in the TCB is the top of the stack. */ - " ldr r0, [r1] \n"/* The first item on the stack is the task's xSecureContext. */ - " cmp r0, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */ + " ldr r2, [r0] \n"/* The first item in the TCB is the top of the stack. */ + " ldr r1, [r2] \n"/* The first item on the stack is the task's xSecureContext. */ + " cmp r1, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */ " beq free_secure_context \n" " bx lr \n"/* There is no secure context (xSecureContext is NULL). */ " free_secure_context: \n" diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c index 6dc125e00..8ed6c5eab 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c @@ -51,66 +51,66 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_ " ldr r0, [r3] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r2] \n"/* Program RNR = 4. */ - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ + " dmb \n"/* Complete outstanding transfers before disabling MPU. */ + " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ + " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ + " str r4, [r2] \n"/* Disable MPU. */ + " \n" + " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ + " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r4, [r2] \n"/* Program MAIR0. */ + " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ + " movs r4, #4 \n"/* r4 = 4. */ + " str r4, [r2] \n"/* Program RNR = 4. */ + " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ + " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ + " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ + " str r4, [r2] \n"/* Enable MPU. */ + " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - " ldr r5, xSecureContextConst2 \n" - " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " msr control, r3 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r4 \n"/* Finally, branch to EXC_RETURN. */ + " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ + " ldr r5, xSecureContextConst2 \n" + " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ + " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ + " msr control, r3 \n"/* Set this task's CONTROL value. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ + " bx r4 \n"/* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" - " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ + " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ + " ldr r4, xSecureContextConst2 \n" + " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ + " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ + " movs r1, #2 \n"/* r1 = 2. */ + " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ + " bx r3 \n"/* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" "xSecureContextConst2: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" + "xMPUCTRLConst2: .word 0xe000ed94 \n" + "xMAIR0Const2: .word 0xe000edc0 \n" + "xRNRConst2: .word 0xe000ed98 \n" + "xRBARConst2: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } @@ -217,62 +217,65 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" - " mrs r1, psp \n"/* Read PSP in r1. */ - " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " ldr r0, [r2] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " mrs r2, psp \n"/* Read PSP in r2. */ " \n" " cbz r0, save_ns_context \n"/* No secure context to save. */ " push {r0-r2, r14} \n" - " bl SecureContext_SaveContext \n" + " bl SecureContext_SaveContext \n"/* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r0-r3} \n"/* LR is now in r3. */ " mov lr, r3 \n"/* LR = r3. */ - " lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl save_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " lsls r1, r3, #25 \n"/* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl save_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r2, [r3] \n"/* Read pxCurrentTCB. */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB.*/ #if ( configENABLE_MPU == 1 ) - " subs r1, r1, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - " str r1, [r2] \n"/* Save the new top of stack in TCB. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " stmia r1!, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mrs r3, control \n"/* r3 = CONTROL. */ + " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ - " subs r1, r1, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r1, [r2] \n"/* Save the new top of stack in TCB. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r1!, {r0, r2-r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ + " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ " b select_next_task \n" " \n" " save_ns_context: \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r2, [r3] \n"/* Read pxCurrentTCB. */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ #if ( configENABLE_FPU == 1 ) - " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ - " it eq \n" - " vstmdbeq r1!, {s16-s31} \n"/* Store the FPU registers which are not saved automatically. */ + " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ + " it eq \n" + " vstmdbeq r2!, {s16-s31} \n"/* Store the FPU registers which are not saved automatically. */ #endif /* configENABLE_FPU */ #if ( configENABLE_MPU == 1 ) - " subs r1, r1, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - " str r1, [r2] \n"/* Save the new top of stack in TCB. */ - " adds r1, r1, #16 \n"/* r1 = r1 + 16. */ - " stm r1, {r4-r11} \n"/* Store the registers that are not saved automatically. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " subs r1, r1, #16 \n"/* r1 = r1 - 16. */ - " stm r1, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ + " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mrs r3, control \n"/* r3 = CONTROL. */ + " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ + " subs r2, r2, #16 \n"/* r2 = r2 - 16. */ + " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ - " subs r1, r1, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r1, [r2] \n"/* Save the new top of stack in TCB. */ - " adds r1, r1, #12 \n"/* r1 = r1 + 12. */ - " stm r1, {r4-r11} \n"/* Store the registers that are not saved automatically. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " subs r1, r1, #12 \n"/* r1 = r1 - 12. */ - " stmia r1!, {r0, r2-r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ + " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " adds r2, r2, #12 \n"/* r2 = r2 + 12. */ + " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " subs r2, r2, #12 \n"/* r2 = r2 - 12. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ " \n" " select_next_task: \n" @@ -284,87 +287,91 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " mov r0, #0 \n"/* r0 = 0. */ " msr basepri, r0 \n"/* Enable interrupts. */ " \n" - " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r3, [r2] \n"/* Read pxCurrentTCB. */ - " ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " ldr r2, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r2] \n"/* Program RNR = 4. */ - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ + " dmb \n"/* Complete outstanding transfers before disabling MPU. */ + " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ + " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ + " str r4, [r3] \n"/* Disable MPU. */ + " \n" + " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ + " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ + " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ + " str r4, [r3] \n"/* Program MAIR0. */ + " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ + " movs r4, #4 \n"/* r4 = 4. */ + " str r4, [r3] \n"/* Program RNR = 4. */ + " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ + " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ + " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ + " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ + " str r4, [r3] \n"/* Enable MPU. */ + " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) - " ldmia r1!, {r0, r2-r4} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */ - " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r2] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " push {r1,r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. */ - " pop {r1,r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r2, r4, #25 \n"/* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r1 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" + " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ + " mov lr, r4 \n"/* LR = r4. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n"/* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " push {r2, r4} \n" + " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r2, r4} \n" + " mov lr, r4 \n"/* LR = r4. */ + " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" #else /* configENABLE_MPU */ - " ldmia r1!, {r0, r2-r3} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */ - " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ - " mov lr, r3 \n"/* LR = r3. */ - " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r2] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " push {r1,r3} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. */ - " pop {r1,r3} \n" - " mov lr, r3 \n"/* LR = r3. */ - " lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r1 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" + " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " mov lr, r4 \n"/* LR = r4. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n"/* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " push {r2, r4} \n" + " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r2, r4} \n" + " mov lr, r4 \n"/* LR = r4. */ + " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" #endif /* configENABLE_MPU */ " \n" " restore_ns_context: \n" - " ldmia r1!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */ + " ldmia r2!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */ #if ( configENABLE_FPU == 1 ) - " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ - " it eq \n" - " vldmiaeq r1!, {s16-s31} \n"/* Restore the FPU registers which are not restored automatically. */ + " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ + " it eq \n" + " vldmiaeq r2!, {s16-s31} \n"/* Restore the FPU registers which are not restored automatically. */ #endif /* configENABLE_FPU */ - " msr psp, r1 \n"/* Remember the new top of stack for the task. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ " bx lr \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" "xSecureContextConst: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" + "xMPUCTRLConst: .word 0xe000ed94 \n" + "xMAIR0Const: .word 0xe000edc0 \n" + "xRNRConst: .word 0xe000ed98 \n" + "xRBARConst: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); @@ -403,9 +410,9 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR { __asm volatile ( - " ldr r1, [r0] \n"/* The first item in the TCB is the top of the stack. */ - " ldr r0, [r1] \n"/* The first item on the stack is the task's xSecureContext. */ - " cmp r0, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */ + " ldr r2, [r0] \n"/* The first item in the TCB is the top of the stack. */ + " ldr r1, [r2] \n"/* The first item on the stack is the task's xSecureContext. */ + " cmp r1, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */ " it ne \n" " svcne %0 \n"/* Secure context is freed in the supervisor call. */ " bx lr \n"/* Return. */ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s index ffaf87e26..0f2c8387c 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s @@ -26,6 +26,13 @@ * */ +/* Including FreeRTOSConfig.h here will cause build errors if the header file +contains code not understood by the assembler - for example the 'extern' keyword. +To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +the code is included in C files but excluded by the preprocessor in assembly +files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ +#include "FreeRTOSConfig.h" + EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext @@ -194,64 +201,66 @@ vClearInterruptMask: /*-----------------------------------------------------------*/ PendSV_Handler: - mrs r1, psp /* Read PSP in r1. */ - ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - ldr r0, [r2] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ push {r0-r2, r14} - bl SecureContext_SaveContext + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r0-r3} /* LR is now in r3. */ mov lr, r3 /* LR = r3. */ - lsls r2, r3, #25 /* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl save_ns_context /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + lsls r1, r3, #25 /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r2, [r3] /* Read pxCurrentTCB. */ + ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) - subs r1, r1, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - str r1, [r2] /* Save the new top of stack in TCB. */ - mrs r2, psplim /* r2 = PSPLIM. */ + subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ - stmia r1!, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ - subs r1, r1, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - str r1, [r2] /* Save the new top of stack in TCB. */ - mrs r2, psplim /* r2 = PSPLIM. */ + subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r1!, {r0, r2-r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ b select_next_task save_ns_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r2, [r3] /* Read pxCurrentTCB. */ + ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) - subs r1, r1, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - str r1, [r2] /* Save the new top of stack in TCB. */ - adds r1, r1, #16 /* r1 = r1 + 16. */ - stmia r1!, {r4-r7} /* Store the low registers that are not saved automatically. */ + subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + adds r2, r2, #16 /* r2 = r2 + 16. */ + stmia r2!, {r4-r7} /* Store the low registers that are not saved automatically. */ mov r4, r8 /* r4 = r8. */ mov r5, r9 /* r5 = r9. */ mov r6, r10 /* r6 = r10. */ mov r7, r11 /* r7 = r11. */ - stmia r1!, {r4-r7} /* Store the high registers that are not saved automatically. */ - mrs r2, psplim /* r2 = PSPLIM. */ + stmia r2!, {r4-r7} /* Store the high registers that are not saved automatically. */ + mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ - subs r1, r1, #48 /* r1 = r1 - 48. */ - stmia r1!, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + subs r2, r2, #48 /* r2 = r2 - 48. */ + stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ - subs r1, r1, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - str r1, [r2] /* Save the new top of stack in TCB. */ - mrs r2, psplim /* r2 = PSPLIM. */ + subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r1!, {r0, r2-r7} /* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ + stmia r2!, {r0, r1, r3-r7} /* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ mov r4, r8 /* r4 = r8. */ mov r5, r9 /* r5 = r9. */ mov r6, r10 /* r6 = r10. */ mov r7, r11 /* r7 = r11. */ - stmia r1!, {r4-r7} /* Store the high registers that are not saved automatically. */ + stmia r2!, {r4-r7} /* Store the high registers that are not saved automatically. */ #endif /* configENABLE_MPU */ select_next_task: @@ -259,96 +268,100 @@ PendSV_Handler: bl vTaskSwitchContext cpsie i - ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r3, [r2] /* Read pxCurrentTCB. */ - ldr r1, [r3] /* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ + ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r4, [r3] /* Read the value of MPU_CTRL. */ movs r5, #1 /* r5 = 1. */ bics r4, r5 /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ + str r4, [r3] /* Disable MPU. */ - adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ + adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ + ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ + ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ + str r4, [r3] /* Program MAIR0. */ + ldr r4, =0xe000ed98 /* r4 = 0xe000ed98 [Location of RNR]. */ + adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ movs r5, #4 /* r5 = 4. */ - str r5, [r2] /* Program RNR = 4. */ - ldmia r3!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */ - ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ - stmia r4!, {r6,r7} /* Write first set of RBAR/RLAR registers. */ + str r5, [r4] /* Program RNR = 4. */ + ldmia r1!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */ + ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ + stmia r3!, {r6,r7} /* Write first set of RBAR/RLAR registers. */ movs r5, #5 /* r5 = 5. */ - str r5, [r2] /* Program RNR = 5. */ - ldmia r3!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */ - ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ - stmia r4!, {r6,r7} /* Write second set of RBAR/RLAR registers. */ + str r5, [r4] /* Program RNR = 5. */ + ldmia r1!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */ + ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ + stmia r3!, {r6,r7} /* Write second set of RBAR/RLAR registers. */ movs r5, #6 /* r5 = 6. */ - str r5, [r2] /* Program RNR = 6. */ - ldmia r3!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */ - ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ - stmia r4!, {r6,r7} /* Write third set of RBAR/RLAR registers. */ + str r5, [r4] /* Program RNR = 6. */ + ldmia r1!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */ + ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ + stmia r3!, {r6,r7} /* Write third set of RBAR/RLAR registers. */ movs r5, #7 /* r5 = 7. */ - str r5, [r2] /* Program RNR = 7. */ - ldmia r3!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */ - ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ - stmia r4!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */ + str r5, [r4] /* Program RNR = 7. */ + ldmia r1!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */ + ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ + stmia r3!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ + ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r4, [r3] /* Read the value of MPU_CTRL. */ movs r5, #1 /* r5 = 1. */ orrs r4, r5 /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ + str r4, [r3] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) - ldmia r1!, {r0, r2-r4} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */ - msr psplim, r2 /* Restore the PSPLIM register value for the task. */ + ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ + msr psplim, r1 /* Restore the PSPLIM register value for the task. */ msr control, r3 /* Restore the CONTROL register value for the task. */ mov lr, r4 /* LR = r4. */ - ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - str r0, [r2] /* Restore the task's xSecureContext. */ + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - push {r1,r4} - bl SecureContext_LoadContext /* Restore the secure context. */ - pop {r1,r4} + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + push {r2, r4} + bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r2, r4} mov lr, r4 /* LR = r4. */ - lsls r2, r4, #25 /* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r1 /* Remember the new top of stack for the task. */ + lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + msr psp, r2 /* Remember the new top of stack for the task. */ bx lr #else /* configENABLE_MPU */ - ldmia r1!, {r0, r2-r3} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */ - msr psplim, r2 /* Restore the PSPLIM register value for the task. */ - mov lr, r3 /* LR = r3. */ - ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - str r0, [r2] /* Restore the task's xSecureContext. */ + ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ + msr psplim, r1 /* Restore the PSPLIM register value for the task. */ + mov lr, r4 /* LR = r4. */ + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - push {r1,r3} - bl SecureContext_LoadContext /* Restore the secure context. */ - pop {r1,r3} - mov lr, r3 /* LR = r3. */ - lsls r2, r3, #25 /* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r1 /* Remember the new top of stack for the task. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + push {r2, r4} + bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r2, r4} + mov lr, r4 /* LR = r4. */ + lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + msr psp, r2 /* Remember the new top of stack for the task. */ bx lr #endif /* configENABLE_MPU */ restore_ns_context: - adds r1, r1, #16 /* Move to the high registers. */ - ldmia r1!, {r4-r7} /* Restore the high registers that are not automatically restored. */ + adds r2, r2, #16 /* Move to the high registers. */ + ldmia r2!, {r4-r7} /* Restore the high registers that are not automatically restored. */ mov r8, r4 /* r8 = r4. */ mov r9, r5 /* r9 = r5. */ mov r10, r6 /* r10 = r6. */ mov r11, r7 /* r11 = r7. */ - msr psp, r1 /* Remember the new top of stack for the task. */ - subs r1, r1, #32 /* Go back to the low registers. */ - ldmia r1!, {r4-r7} /* Restore the low registers that are not automatically restored. */ + msr psp, r2 /* Remember the new top of stack for the task. */ + subs r2, r2, #32 /* Go back to the low registers. */ + ldmia r2!, {r4-r7} /* Restore the low registers that are not automatically restored. */ bx lr /*-----------------------------------------------------------*/ @@ -365,9 +378,9 @@ SVC_Handler: /*-----------------------------------------------------------*/ vPortFreeSecureContext: - ldr r1, [r0] /* The first item in the TCB is the top of the stack. */ - ldr r0, [r1] /* The first item on the stack is the task's xSecureContext. */ - cmp r0, #0 /* Raise svc if task's xSecureContext is not NULL. */ + ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ + ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ + cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ beq free_secure_context bx lr /* There is no secure context (xSecureContext is NULL). */ free_secure_context: diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portasm.s b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portasm.s index e7dc5f307..6ab1aefcc 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portasm.s @@ -25,6 +25,12 @@ * https://github.com/FreeRTOS * */ +/* Including FreeRTOSConfig.h here will cause build errors if the header file +contains code not understood by the assembler - for example the 'extern' keyword. +To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +the code is included in C files but excluded by the preprocessor in assembly +files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ +#include "FreeRTOSConfig.h" EXTERN pxCurrentTCB EXTERN vTaskSwitchContext diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s index 6ba01ffc5..f8fd04f9f 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s @@ -184,62 +184,65 @@ vClearInterruptMask: /*-----------------------------------------------------------*/ PendSV_Handler: - mrs r1, psp /* Read PSP in r1. */ - ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - ldr r0, [r2] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ push {r0-r2, r14} - bl SecureContext_SaveContext + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r0-r3} /* LR is now in r3. */ mov lr, r3 /* LR = r3. */ - lsls r2, r3, #25 /* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl save_ns_context /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + lsls r1, r3, #25 /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r2, [r3] /* Read pxCurrentTCB. */ + ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) - subs r1, r1, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - str r1, [r2] /* Save the new top of stack in TCB. */ - mrs r2, psplim /* r2 = PSPLIM. */ + subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ - stmia r1!, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ - subs r1, r1, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - str r1, [r2] /* Save the new top of stack in TCB. */ - mrs r2, psplim /* r2 = PSPLIM. */ + subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r1!, {r0, r2-r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ b select_next_task save_ns_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r2, [r3] /* Read pxCurrentTCB. */ + ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( configENABLE_FPU == 1 ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ it eq - vstmdbeq r1!, {s16-s31} /* Store the FPU registers which are not saved automatically. */ + vstmdbeq r2!, {s16-s31} /* Store the FPU registers which are not saved automatically. */ #endif /* configENABLE_FPU */ #if ( configENABLE_MPU == 1 ) - subs r1, r1, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - str r1, [r2] /* Save the new top of stack in TCB. */ - adds r1, r1, #16 /* r1 = r1 + 16. */ - stm r1, {r4-r11} /* Store the registers that are not saved automatically. */ - mrs r2, psplim /* r2 = PSPLIM. */ + subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + adds r2, r2, #16 /* r2 = r2 + 16. */ + stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ + mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ - subs r1, r1, #16 /* r1 = r1 - 16. */ - stm r1, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + subs r2, r2, #16 /* r2 = r2 - 16. */ + stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ - subs r1, r1, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - str r1, [r2] /* Save the new top of stack in TCB. */ - adds r1, r1, #12 /* r1 = r1 + 12. */ - stm r1, {r4-r11} /* Store the registers that are not saved automatically. */ - mrs r2, psplim /* r2 = PSPLIM. */ + subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + adds r2, r2, #12 /* r2 = r2 + 12. */ + stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ + mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - subs r1, r1, #12 /* r1 = r1 - 12. */ - stmia r1!, {r0, r2-r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + subs r2, r2, #12 /* r2 = r2 - 12. */ + stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ select_next_task: @@ -251,77 +254,81 @@ PendSV_Handler: mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ - ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r3, [r2] /* Read pxCurrentTCB. */ - ldr r1, [r3] /* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ + ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r4, [r3] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ + str r4, [r3] /* Disable MPU. */ - adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ + adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ + ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ + ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ + str r4, [r3] /* Program MAIR0. */ + ldr r3, =0xe000ed98 /* r3 = 0xe000ed98 [Location of RNR]. */ movs r4, #4 /* r4 = 4. */ - str r4, [r2] /* Program RNR = 4. */ - adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ - ldmia r3!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ - stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + str r4, [r3] /* Program RNR = 4. */ + adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ + ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ + ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r3!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ + ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r4, [r3] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ + str r4, [r3] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) - ldmia r1!, {r0, r2-r4} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */ - msr psplim, r2 /* Restore the PSPLIM register value for the task. */ + ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ + msr psplim, r1 /* Restore the PSPLIM register value for the task. */ msr control, r3 /* Restore the CONTROL register value for the task. */ mov lr, r4 /* LR = r4. */ - ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - str r0, [r2] /* Restore the task's xSecureContext. */ + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - push {r1,r4} - bl SecureContext_LoadContext /* Restore the secure context. */ - pop {r1,r4} + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + push {r2, r4} + bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r2, r4} mov lr, r4 /* LR = r4. */ - lsls r2, r4, #25 /* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r1 /* Remember the new top of stack for the task. */ + lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + msr psp, r2 /* Remember the new top of stack for the task. */ bx lr #else /* configENABLE_MPU */ - ldmia r1!, {r0, r2-r3} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */ - msr psplim, r2 /* Restore the PSPLIM register value for the task. */ - mov lr, r3 /* LR = r3. */ - ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - str r0, [r2] /* Restore the task's xSecureContext. */ + ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ + msr psplim, r1 /* Restore the PSPLIM register value for the task. */ + mov lr, r4 /* LR = r4. */ + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - push {r1,r3} - bl SecureContext_LoadContext /* Restore the secure context. */ - pop {r1,r3} - mov lr, r3 /* LR = r3. */ - lsls r2, r3, #25 /* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r1 /* Remember the new top of stack for the task. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + push {r2, r4} + bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r2, r4} + mov lr, r4 /* LR = r4. */ + lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + msr psp, r2 /* Remember the new top of stack for the task. */ bx lr #endif /* configENABLE_MPU */ restore_ns_context: - ldmia r1!, {r4-r11} /* Restore the registers that are not automatically restored. */ + ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ #if ( configENABLE_FPU == 1 ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ it eq - vldmiaeq r1!, {s16-s31} /* Restore the FPU registers which are not restored automatically. */ + vldmiaeq r2!, {s16-s31} /* Restore the FPU registers which are not restored automatically. */ #endif /* configENABLE_FPU */ - msr psp, r1 /* Remember the new top of stack for the task. */ + msr psp, r2 /* Remember the new top of stack for the task. */ bx lr /*-----------------------------------------------------------*/ @@ -335,9 +342,9 @@ SVC_Handler: vPortFreeSecureContext: /* r0 = uint32_t *pulTCB. */ - ldr r1, [r0] /* The first item in the TCB is the top of the stack. */ - ldr r0, [r1] /* The first item on the stack is the task's xSecureContext. */ - cmp r0, #0 /* Raise svc if task's xSecureContext is not NULL. */ + ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ + ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ + cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ it ne svcne 1 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 1. */ bx lr /* Return. */ diff --git a/portable/ARMv8M/secure/context/portable/GCC/ARM_CM23/secure_context_port.c b/portable/ARMv8M/secure/context/portable/GCC/ARM_CM23/secure_context_port.c index 8677b2297..0c871990c 100644 --- a/portable/ARMv8M/secure/context/portable/GCC/ARM_CM23/secure_context_port.c +++ b/portable/ARMv8M/secure/context/portable/GCC/ARM_CM23/secure_context_port.c @@ -36,6 +36,9 @@ #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif +void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); +void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); + void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) { /* pxSecureContext value is in r0. */ diff --git a/portable/ARMv8M/secure/context/portable/GCC/ARM_CM33/secure_context_port.c b/portable/ARMv8M/secure/context/portable/GCC/ARM_CM33/secure_context_port.c index 0731abe1f..a6bf54cae 100644 --- a/portable/ARMv8M/secure/context/portable/GCC/ARM_CM33/secure_context_port.c +++ b/portable/ARMv8M/secure/context/portable/GCC/ARM_CM33/secure_context_port.c @@ -32,6 +32,9 @@ /* Secure port macros. */ #include "secure_port_macros.h" +void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); +void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); + void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) { /* pxSecureContext value is in r0. */ diff --git a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM23/secure_context_port_asm.s b/portable/ARMv8M/secure/context/portable/IAR/ARM_CM23/secure_context_port_asm.s index cf245b915..1124e82bb 100644 --- a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM23/secure_context_port_asm.s +++ b/portable/ARMv8M/secure/context/portable/IAR/ARM_CM23/secure_context_port_asm.s @@ -29,6 +29,13 @@ SECTION .text:CODE:NOROOT(2) THUMB +/* Including FreeRTOSConfig.h here will cause build errors if the header file +contains code not understood by the assembler - for example the 'extern' keyword. +To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +the code is included in C files but excluded by the preprocessor in assembly +files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ +#include "FreeRTOSConfig.h" + PUBLIC SecureContext_LoadContextAsm PUBLIC SecureContext_SaveContextAsm diff --git a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM33/secure_context_port_asm.s b/portable/ARMv8M/secure/context/portable/IAR/ARM_CM33/secure_context_port_asm.s index 0df0a1b40..52dbe4563 100644 --- a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM33/secure_context_port_asm.s +++ b/portable/ARMv8M/secure/context/portable/IAR/ARM_CM33/secure_context_port_asm.s @@ -29,6 +29,13 @@ SECTION .text:CODE:NOROOT(2) THUMB +/* Including FreeRTOSConfig.h here will cause build errors if the header file +contains code not understood by the assembler - for example the 'extern' keyword. +To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +the code is included in C files but excluded by the preprocessor in assembly +files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ +#include "FreeRTOSConfig.h" + PUBLIC SecureContext_LoadContextAsm PUBLIC SecureContext_SaveContextAsm /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/secure/context/secure_context.c b/portable/ARMv8M/secure/context/secure_context.c index 96a566211..a51d1c17c 100644 --- a/portable/ARMv8M/secure/context/secure_context.c +++ b/portable/ARMv8M/secure/context/secure_context.c @@ -51,11 +51,6 @@ */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 -/** - * @brief Invalid context ID. - */ -#define securecontextINVALID_CONTEXT_ID 0UL - /** * @brief Maximum number of secure contexts. */ @@ -71,11 +66,15 @@ SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ]; /*-----------------------------------------------------------*/ /** - * @brief Get a free context from the secure context pool (xSecureContexts). + * @brief Get a free secure context for a task from the secure context pool (xSecureContexts). * - * @return Index of a free context in the xSecureContexts array. + * This function ensures that only one secure context is allocated for a task. + * + * @param[in] pvTaskHandle The task handle for which the secure context is allocated. + * + * @return Index of a free secure context in the xSecureContexts array. */ -static uint32_t ulGetSecureContext( void ); +static uint32_t ulGetSecureContext( void * pvTaskHandle ); /** * @brief Return the secure context to the secure context pool (xSecureContexts). @@ -89,16 +88,26 @@ extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ); extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ); /*-----------------------------------------------------------*/ -static uint32_t ulGetSecureContext( void ) +static uint32_t ulGetSecureContext( void * pvTaskHandle ) { - uint32_t ulSecureContextIndex; + /* Start with invalid index. */ + uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; - for( ulSecureContextIndex = 0; ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS; ulSecureContextIndex++ ) + for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { - if( ( xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer == NULL ) && - ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == NULL ) && - ( xSecureContexts[ ulSecureContextIndex ].pucStackStart == NULL ) ) + if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) && + ( xSecureContexts[ i ].pucStackLimit == NULL ) && + ( xSecureContexts[ i ].pucStackStart == NULL ) && + ( xSecureContexts[ i ].pvTaskHandle == NULL ) && + ( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) ) { + ulSecureContextIndex = i; + } + else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle ) + { + /* A task can only have one secure context. Do not allocate a second + * context for the same task. */ + ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; break; } } @@ -112,20 +121,25 @@ static void vReturnSecureContext( uint32_t ulSecureContextIndex ) xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL; + xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) { uint32_t ulIPSR, i; + static uint32_t ulSecureContextsInitialized = 0; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ - if( ulIPSR != 0 ) + if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) ) { + /* Ensure to initialize secure contexts only once. */ + ulSecureContextsInitialized = 1; + /* No stack for thread mode until a task's context is loaded. */ secureportSET_PSPLIM( securecontextNO_STACK ); secureportSET_PSP( securecontextNO_STACK ); @@ -136,6 +150,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) xSecureContexts[ i ].pucCurrentStackPointer = NULL; xSecureContexts[ i ].pucStackLimit = NULL; xSecureContexts[ i ].pucStackStart = NULL; + xSecureContexts[ i ].pvTaskHandle = NULL; } #if ( configENABLE_MPU == 1 ) @@ -155,28 +170,35 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) #if ( configENABLE_MPU == 1 ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, - uint32_t ulIsTaskPrivileged ) + uint32_t ulIsTaskPrivileged, + void * pvTaskHandle ) #else /* configENABLE_MPU */ - secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize ) + secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + void * pvTaskHandle ) #endif /* configENABLE_MPU */ { uint8_t * pucStackMemory = NULL; + uint8_t * pucStackLimit; uint32_t ulIPSR, ulSecureContextIndex; - SecureContextHandle_t xSecureContextHandle; + SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID; #if ( configENABLE_MPU == 1 ) uint32_t * pulCurrentStackPointer = NULL; #endif /* configENABLE_MPU */ - /* Read the Interrupt Program Status Register (IPSR) value. */ + /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit + * Register (PSPLIM) value. */ secureportREAD_IPSR( ulIPSR ); + secureportREAD_PSPLIM( pucStackLimit ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero - * when the processor is running in the Thread Mode. */ - if( ulIPSR != 0 ) + * when the processor is running in the Thread Mode. + * Also do nothing, if a secure context us already loaded. PSPLIM is set to + * securecontextNO_STACK when no secure context is loaded. */ + if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { /* Ontain a free secure context. */ - ulSecureContextIndex = ulGetSecureContext(); + ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) @@ -198,6 +220,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; + xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle; + #if ( configENABLE_MPU == 1 ) { /* Store the correct CONTROL value for the task on the stack. @@ -230,10 +254,6 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) /* Ensure to never return 0 as a valid context handle. */ xSecureContextHandle = ulSecureContextIndex + 1UL; } - else - { - xSecureContextHandle = securecontextINVALID_CONTEXT_ID; - } } } @@ -241,7 +261,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) } /*-----------------------------------------------------------*/ -secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle ) +secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint32_t ulIPSR, ulSecureContextIndex; @@ -257,38 +277,61 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl { ulSecureContextIndex = xSecureContextHandle - 1UL; - /* Free the stack space. */ - vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); + /* Ensure that the secure context being deleted is associated with + * the task. */ + if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) + { + /* Free the stack space. */ + vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); - /* Return the context back to the free contexts pool. */ - vReturnSecureContext( ulSecureContextIndex ); + /* Return the secure context back to the free secure contexts pool. */ + vReturnSecureContext( ulSecureContextIndex ); + } } } } /*-----------------------------------------------------------*/ -secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ) +secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { + uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; - SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + secureportREAD_PSPLIM( pucStackLimit ); + + /* Ensure that no secure context is loaded and the task is loading it's + * own context. */ + if( ( pucStackLimit == securecontextNO_STACK ) && + ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) + { + SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + } } } /*-----------------------------------------------------------*/ -secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle ) +secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { + uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; - SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + secureportREAD_PSPLIM( pucStackLimit ); + + /* Ensure that task's context is loaded and the task is saving it's own + * context. */ + if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && + ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) + { + SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + } } } /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/secure/context/secure_context.h b/portable/ARMv8M/secure/context/secure_context.h index b7a3ba50e..57e390c26 100644 --- a/portable/ARMv8M/secure/context/secure_context.h +++ b/portable/ARMv8M/secure/context/secure_context.h @@ -38,7 +38,12 @@ /** * @brief PSP value when no secure context is loaded. */ -#define securecontextNO_STACK 0x0 +#define securecontextNO_STACK 0x0 + +/** + * @brief Invalid context ID. + */ +#define securecontextINVALID_CONTEXT_ID 0UL /*-----------------------------------------------------------*/ /** @@ -52,6 +57,7 @@ typedef struct SecureContext uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */ uint8_t * pucStackStart; /**< First location of the stack memory. */ + void * pvTaskHandle; /**< Task handle of the task this context is associated with. */ } SecureContext_t; /*-----------------------------------------------------------*/ @@ -86,9 +92,11 @@ void SecureContext_Init( void ); */ #if ( configENABLE_MPU == 1 ) SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, - uint32_t ulIsTaskPrivileged ); + uint32_t ulIsTaskPrivileged, + void * pvTaskHandle ); #else /* configENABLE_MPU */ - SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize ); + SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + void * pvTaskHandle ); #endif /* configENABLE_MPU */ /** @@ -100,7 +108,7 @@ void SecureContext_Init( void ); * @param[in] xSecureContextHandle Context handle corresponding to the * context to be freed. */ -void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle ); +void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Loads the given context. @@ -111,7 +119,7 @@ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle ); * @param[in] xSecureContextHandle Context handle corresponding to the context * to be loaded. */ -void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ); +void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Saves the given context. @@ -122,6 +130,6 @@ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ); * @param[in] xSecureContextHandle Context handle corresponding to the context * to be saved. */ -void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle ); +void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); #endif /* __SECURE_CONTEXT_H__ */ diff --git a/portable/ARMv8M/secure/heap/secure_heap.c b/portable/ARMv8M/secure/heap/secure_heap.c index 099b01f1f..b3a737818 100644 --- a/portable/ARMv8M/secure/heap/secure_heap.c +++ b/portable/ARMv8M/secure/heap/secure_heap.c @@ -449,9 +449,3 @@ size_t xPortGetMinimumEverFreeHeapSize( void ) return xMinimumEverFreeBytesRemaining; } /*-----------------------------------------------------------*/ - -void vPortInitialiseBlocks( void ) -{ - /* This just exists to keep the linker quiet. */ -} -/*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/secure/heap/secure_heap.h b/portable/ARMv8M/secure/heap/secure_heap.h index f08c092f2..bd42ff9ba 100644 --- a/portable/ARMv8M/secure/heap/secure_heap.h +++ b/portable/ARMv8M/secure/heap/secure_heap.h @@ -49,4 +49,18 @@ void * pvPortMalloc( size_t xWantedSize ); */ void vPortFree( void * pv ); +/** + * @brief Get the free heap size. + * + * @return Free heap size. + */ +size_t xPortGetFreeHeapSize( void ); + +/** + * @brief Get the minimum ever free heap size. + * + * @return Minimum ever free heap size. + */ +size_t xPortGetMinimumEverFreeHeapSize( void ); + #endif /* __SECURE_HEAP_H__ */ diff --git a/portable/ARMv8M/secure/macros/secure_port_macros.h b/portable/ARMv8M/secure/macros/secure_port_macros.h index 955ef75c6..54990549a 100644 --- a/portable/ARMv8M/secure/macros/secure_port_macros.h +++ b/portable/ARMv8M/secure/macros/secure_port_macros.h @@ -68,6 +68,12 @@ #define secureportSET_PSP( pucCurrentStackPointer ) \ __asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) ) +/** + * @brief Read the PSPLIM value in the given variable. + */ +#define secureportREAD_PSPLIM( pucOutStackLimit ) \ + __asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) ) + /** * @brief Set the PSPLIM to the given value. */ diff --git a/portable/Common/mpu_wrappers.c b/portable/Common/mpu_wrappers.c index e9ed25f29..7a04fb8a7 100644 --- a/portable/Common/mpu_wrappers.c +++ b/portable/Common/mpu_wrappers.c @@ -936,33 +936,6 @@ void MPU_vQueueDelete( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ } /*-----------------------------------------------------------*/ -#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - void MPU_vPortInitialiseBlocks( void ) /* FREERTOS_SYSTEM_CALL */ - { - BaseType_t xRunningPrivileged = xPortRaisePrivilege(); - - vPortInitialiseBlocks(); - - vPortResetPrivilege( xRunningPrivileged ); - } -#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ -/*-----------------------------------------------------------*/ - -#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - size_t MPU_xPortGetFreeHeapSize( void ) /* FREERTOS_SYSTEM_CALL */ - { - size_t xReturn; - BaseType_t xRunningPrivileged = xPortRaisePrivilege(); - - xReturn = xPortGetFreeHeapSize(); - - vPortResetPrivilege( xRunningPrivileged ); - - return xReturn; - } -#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ -/*-----------------------------------------------------------*/ - #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) ) TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, diff --git a/portable/GCC/ARM_CM23/non_secure/port.c b/portable/GCC/ARM_CM23/non_secure/port.c index c1185d811..393e21e9f 100644 --- a/portable/GCC/ARM_CM23/non_secure/port.c +++ b/portable/GCC/ARM_CM23/non_secure/port.c @@ -781,7 +781,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) - uint32_t ulR0; + uint32_t ulR0, ulR1; + extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ @@ -812,25 +813,27 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged ); + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0 ); + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != NULL ); - SecureContext_LoadContext( xSecureContext ); + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains the secure context handle to be freed. */ + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 ); + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ diff --git a/portable/GCC/ARM_CM23/non_secure/portasm.c b/portable/GCC/ARM_CM23/non_secure/portasm.c index e32c63104..9dab039d8 100644 --- a/portable/GCC/ARM_CM23/non_secure/portasm.c +++ b/portable/GCC/ARM_CM23/non_secure/portasm.c @@ -55,79 +55,79 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_ " ldr r0, [r3] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r5, #1 \n"/* r5 = 1. */ - " bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - " movs r5, #4 \n"/* r5 = 4. */ - " str r5, [r2] \n"/* Program RNR = 4. */ - " ldmia r3!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */ - " movs r5, #5 \n"/* r5 = 5. */ - " str r5, [r2] \n"/* Program RNR = 5. */ - " ldmia r3!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */ - " movs r5, #6 \n"/* r5 = 6. */ - " str r5, [r2] \n"/* Program RNR = 6. */ - " ldmia r3!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */ - " movs r5, #7 \n"/* r5 = 7. */ - " str r5, [r2] \n"/* Program RNR = 7. */ - " ldmia r3!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r5, #1 \n"/* r5 = 1. */ - " orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ + " dmb \n"/* Complete outstanding transfers before disabling MPU. */ + " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ + " movs r5, #1 \n"/* r5 = 1. */ + " bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ + " str r4, [r2] \n"/* Disable MPU. */ + " \n" + " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ + " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r4, [r2] \n"/* Program MAIR0. */ + " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ + " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ + " movs r5, #4 \n"/* r5 = 4. */ + " str r5, [r2] \n"/* Program RNR = 4. */ + " ldmia r3!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */ + " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ + " stmia r4!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */ + " movs r5, #5 \n"/* r5 = 5. */ + " str r5, [r2] \n"/* Program RNR = 5. */ + " ldmia r3!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */ + " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ + " stmia r4!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */ + " movs r5, #6 \n"/* r5 = 6. */ + " str r5, [r2] \n"/* Program RNR = 6. */ + " ldmia r3!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */ + " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ + " stmia r4!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */ + " movs r5, #7 \n"/* r5 = 7. */ + " str r5, [r2] \n"/* Program RNR = 7. */ + " ldmia r3!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */ + " ldr r4, xRBARConst2 \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ + " stmia r4!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */ + " \n" + " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ + " movs r5, #1 \n"/* r5 = 1. */ + " orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ + " str r4, [r2] \n"/* Enable MPU. */ + " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - " ldr r5, xSecureContextConst2 \n" - " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " msr control, r3 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " bx r4 \n"/* Finally, branch to EXC_RETURN. */ + " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ + " ldr r5, xSecureContextConst2 \n" + " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ + " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ + " msr control, r3 \n"/* Set this task's CONTROL value. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " bx r4 \n"/* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" - " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ + " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ + " ldr r4, xSecureContextConst2 \n" + " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ + " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ + " movs r1, #2 \n"/* r1 = 2. */ + " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " bx r3 \n"/* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" "xSecureContextConst2: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" + "xMPUCTRLConst2: .word 0xe000ed94 \n" + "xMAIR0Const2: .word 0xe000edc0 \n" + "xRNRConst2: .word 0xe000ed98 \n" + "xRBARConst2: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } @@ -233,64 +233,66 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" - " mrs r1, psp \n"/* Read PSP in r1. */ - " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " ldr r0, [r2] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later.*/ + " mrs r2, psp \n"/* Read PSP in r2. */ " \n" " cbz r0, save_ns_context \n"/* No secure context to save. */ " push {r0-r2, r14} \n" - " bl SecureContext_SaveContext \n" + " bl SecureContext_SaveContext \n"/* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r0-r3} \n"/* LR is now in r3. */ " mov lr, r3 \n"/* LR = r3. */ - " lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl save_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " lsls r1, r3, #25 \n"/* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl save_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r2, [r3] \n"/* Read pxCurrentTCB. */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) - " subs r1, r1, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - " str r1, [r2] \n"/* Save the new top of stack in TCB. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " stmia r1!, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mrs r3, control \n"/* r3 = CONTROL. */ + " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ - " subs r1, r1, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r1, [r2] \n"/* Save the new top of stack in TCB. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r1!, {r0, r2-r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ + " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ " b select_next_task \n" " \n" " save_ns_context: \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r2, [r3] \n"/* Read pxCurrentTCB. */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) - " subs r1, r1, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - " str r1, [r2] \n"/* Save the new top of stack in TCB. */ - " adds r1, r1, #16 \n"/* r1 = r1 + 16. */ - " stmia r1!, {r4-r7} \n"/* Store the low registers that are not saved automatically. */ - " mov r4, r8 \n"/* r4 = r8. */ - " mov r5, r9 \n"/* r5 = r9. */ - " mov r6, r10 \n"/* r6 = r10. */ - " mov r7, r11 \n"/* r7 = r11. */ - " stmia r1!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " subs r1, r1, #48 \n"/* r1 = r1 - 48. */ - " stmia r1!, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ + " stmia r2!, {r4-r7} \n"/* Store the low registers that are not saved automatically. */ + " mov r4, r8 \n"/* r4 = r8. */ + " mov r5, r9 \n"/* r5 = r9. */ + " mov r6, r10 \n"/* r6 = r10. */ + " mov r7, r11 \n"/* r7 = r11. */ + " stmia r2!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mrs r3, control \n"/* r3 = CONTROL. */ + " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ + " subs r2, r2, #48 \n"/* r2 = r2 - 48. */ + " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ - " subs r1, r1, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r1, [r2] \n"/* Save the new top of stack in TCB. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r1!, {r0, r2-r7} \n"/* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ - " mov r4, r8 \n"/* r4 = r8. */ - " mov r5, r9 \n"/* r5 = r9. */ - " mov r6, r10 \n"/* r6 = r10. */ - " mov r7, r11 \n"/* r7 = r11. */ - " stmia r1!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ + " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3-r7} \n"/* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ + " mov r4, r8 \n"/* r4 = r8. */ + " mov r5, r9 \n"/* r5 = r9. */ + " mov r6, r10 \n"/* r6 = r10. */ + " mov r7, r11 \n"/* r7 = r11. */ + " stmia r2!, {r4-r7} \n"/* Store the high registers that are not saved automatically. */ #endif /* configENABLE_MPU */ " \n" " select_next_task: \n" @@ -298,106 +300,110 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " bl vTaskSwitchContext \n" " cpsie i \n" " \n" - " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r3, [r2] \n"/* Read pxCurrentTCB. */ - " ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " ldr r2, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r5, #1 \n"/* r5 = 1. */ - " bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - " movs r5, #4 \n"/* r5 = 4. */ - " str r5, [r2] \n"/* Program RNR = 4. */ - " ldmia r3!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */ - " movs r5, #5 \n"/* r5 = 5. */ - " str r5, [r2] \n"/* Program RNR = 5. */ - " ldmia r3!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */ - " movs r5, #6 \n"/* r5 = 6. */ - " str r5, [r2] \n"/* Program RNR = 6. */ - " ldmia r3!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */ - " movs r5, #7 \n"/* r5 = 7. */ - " str r5, [r2] \n"/* Program RNR = 7. */ - " ldmia r3!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */ - " ldr r4, xRBARConst \n"/* r4 = 0xe000ed9c [Location of RBAR]. */ - " stmia r4!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */ - " \n" - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " movs r5, #1 \n"/* r5 = 1. */ - " orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ + " dmb \n"/* Complete outstanding transfers before disabling MPU. */ + " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ + " movs r5, #1 \n"/* r5 = 1. */ + " bics r4, r5 \n"/* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ + " str r4, [r3] \n"/* Disable MPU. */ + " \n" + " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ + " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ + " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ + " str r4, [r3] \n"/* Program MAIR0. */ + " ldr r4, xRNRConst \n"/* r4 = 0xe000ed98 [Location of RNR]. */ + " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ + " movs r5, #4 \n"/* r5 = 4. */ + " str r5, [r4] \n"/* Program RNR = 4. */ + " ldmia r1!, {r6,r7} \n"/* Read first set of RBAR/RLAR from TCB. */ + " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ + " stmia r3!, {r6,r7} \n"/* Write first set of RBAR/RLAR registers. */ + " movs r5, #5 \n"/* r5 = 5. */ + " str r5, [r4] \n"/* Program RNR = 5. */ + " ldmia r1!, {r6,r7} \n"/* Read second set of RBAR/RLAR from TCB. */ + " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ + " stmia r3!, {r6,r7} \n"/* Write second set of RBAR/RLAR registers. */ + " movs r5, #6 \n"/* r5 = 6. */ + " str r5, [r4] \n"/* Program RNR = 6. */ + " ldmia r1!, {r6,r7} \n"/* Read third set of RBAR/RLAR from TCB. */ + " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ + " stmia r3!, {r6,r7} \n"/* Write third set of RBAR/RLAR registers. */ + " movs r5, #7 \n"/* r5 = 7. */ + " str r5, [r4] \n"/* Program RNR = 7. */ + " ldmia r1!, {r6,r7} \n"/* Read fourth set of RBAR/RLAR from TCB. */ + " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ + " stmia r3!, {r6,r7} \n"/* Write fourth set of RBAR/RLAR registers. */ + " \n" + " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ + " movs r5, #1 \n"/* r5 = 1. */ + " orrs r4, r5 \n"/* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ + " str r4, [r3] \n"/* Enable MPU. */ + " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) - " ldmia r1!, {r0, r2-r4} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */ - " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r2] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " push {r1,r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. */ - " pop {r1,r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r2, r4, #25 \n"/* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r1 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" + " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ + " mov lr, r4 \n"/* LR = r4. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n"/* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " push {r2, r4} \n" + " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r2, r4} \n" + " mov lr, r4 \n"/* LR = r4. */ + " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" #else /* configENABLE_MPU */ - " ldmia r1!, {r0, r2-r3} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */ - " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ - " mov lr, r3 \n"/* LR = r3. */ - " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r2] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " push {r1,r3} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. */ - " pop {r1,r3} \n" - " mov lr, r3 \n"/* LR = r3. */ - " lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r1 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" + " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " mov lr, r4 \n"/* LR = r4. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n"/* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " push {r2, r4} \n" + " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r2, r4} \n" + " mov lr, r4 \n"/* LR = r4. */ + " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" #endif /* configENABLE_MPU */ " \n" " restore_ns_context: \n" - " adds r1, r1, #16 \n"/* Move to the high registers. */ - " ldmia r1!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ + " adds r2, r2, #16 \n"/* Move to the high registers. */ + " ldmia r2!, {r4-r7} \n"/* Restore the high registers that are not automatically restored. */ " mov r8, r4 \n"/* r8 = r4. */ " mov r9, r5 \n"/* r9 = r5. */ " mov r10, r6 \n"/* r10 = r6. */ " mov r11, r7 \n"/* r11 = r7. */ - " msr psp, r1 \n"/* Remember the new top of stack for the task. */ - " subs r1, r1, #32 \n"/* Go back to the low registers. */ - " ldmia r1!, {r4-r7} \n"/* Restore the low registers that are not automatically restored. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " subs r2, r2, #32 \n"/* Go back to the low registers. */ + " ldmia r2!, {r4-r7} \n"/* Restore the low registers that are not automatically restored. */ " bx lr \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" "xSecureContextConst: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" + "xMPUCTRLConst: .word 0xe000ed94 \n" + "xMAIR0Const: .word 0xe000edc0 \n" + "xRNRConst: .word 0xe000ed98 \n" + "xRBARConst: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } @@ -440,9 +446,9 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR { __asm volatile ( - " ldr r1, [r0] \n"/* The first item in the TCB is the top of the stack. */ - " ldr r0, [r1] \n"/* The first item on the stack is the task's xSecureContext. */ - " cmp r0, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */ + " ldr r2, [r0] \n"/* The first item in the TCB is the top of the stack. */ + " ldr r1, [r2] \n"/* The first item on the stack is the task's xSecureContext. */ + " cmp r1, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */ " beq free_secure_context \n" " bx lr \n"/* There is no secure context (xSecureContext is NULL). */ " free_secure_context: \n" diff --git a/portable/GCC/ARM_CM23/secure/secure_context.c b/portable/GCC/ARM_CM23/secure/secure_context.c index 96a566211..a51d1c17c 100644 --- a/portable/GCC/ARM_CM23/secure/secure_context.c +++ b/portable/GCC/ARM_CM23/secure/secure_context.c @@ -51,11 +51,6 @@ */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 -/** - * @brief Invalid context ID. - */ -#define securecontextINVALID_CONTEXT_ID 0UL - /** * @brief Maximum number of secure contexts. */ @@ -71,11 +66,15 @@ SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ]; /*-----------------------------------------------------------*/ /** - * @brief Get a free context from the secure context pool (xSecureContexts). + * @brief Get a free secure context for a task from the secure context pool (xSecureContexts). * - * @return Index of a free context in the xSecureContexts array. + * This function ensures that only one secure context is allocated for a task. + * + * @param[in] pvTaskHandle The task handle for which the secure context is allocated. + * + * @return Index of a free secure context in the xSecureContexts array. */ -static uint32_t ulGetSecureContext( void ); +static uint32_t ulGetSecureContext( void * pvTaskHandle ); /** * @brief Return the secure context to the secure context pool (xSecureContexts). @@ -89,16 +88,26 @@ extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ); extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ); /*-----------------------------------------------------------*/ -static uint32_t ulGetSecureContext( void ) +static uint32_t ulGetSecureContext( void * pvTaskHandle ) { - uint32_t ulSecureContextIndex; + /* Start with invalid index. */ + uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; - for( ulSecureContextIndex = 0; ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS; ulSecureContextIndex++ ) + for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { - if( ( xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer == NULL ) && - ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == NULL ) && - ( xSecureContexts[ ulSecureContextIndex ].pucStackStart == NULL ) ) + if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) && + ( xSecureContexts[ i ].pucStackLimit == NULL ) && + ( xSecureContexts[ i ].pucStackStart == NULL ) && + ( xSecureContexts[ i ].pvTaskHandle == NULL ) && + ( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) ) { + ulSecureContextIndex = i; + } + else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle ) + { + /* A task can only have one secure context. Do not allocate a second + * context for the same task. */ + ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; break; } } @@ -112,20 +121,25 @@ static void vReturnSecureContext( uint32_t ulSecureContextIndex ) xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL; + xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) { uint32_t ulIPSR, i; + static uint32_t ulSecureContextsInitialized = 0; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ - if( ulIPSR != 0 ) + if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) ) { + /* Ensure to initialize secure contexts only once. */ + ulSecureContextsInitialized = 1; + /* No stack for thread mode until a task's context is loaded. */ secureportSET_PSPLIM( securecontextNO_STACK ); secureportSET_PSP( securecontextNO_STACK ); @@ -136,6 +150,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) xSecureContexts[ i ].pucCurrentStackPointer = NULL; xSecureContexts[ i ].pucStackLimit = NULL; xSecureContexts[ i ].pucStackStart = NULL; + xSecureContexts[ i ].pvTaskHandle = NULL; } #if ( configENABLE_MPU == 1 ) @@ -155,28 +170,35 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) #if ( configENABLE_MPU == 1 ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, - uint32_t ulIsTaskPrivileged ) + uint32_t ulIsTaskPrivileged, + void * pvTaskHandle ) #else /* configENABLE_MPU */ - secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize ) + secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + void * pvTaskHandle ) #endif /* configENABLE_MPU */ { uint8_t * pucStackMemory = NULL; + uint8_t * pucStackLimit; uint32_t ulIPSR, ulSecureContextIndex; - SecureContextHandle_t xSecureContextHandle; + SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID; #if ( configENABLE_MPU == 1 ) uint32_t * pulCurrentStackPointer = NULL; #endif /* configENABLE_MPU */ - /* Read the Interrupt Program Status Register (IPSR) value. */ + /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit + * Register (PSPLIM) value. */ secureportREAD_IPSR( ulIPSR ); + secureportREAD_PSPLIM( pucStackLimit ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero - * when the processor is running in the Thread Mode. */ - if( ulIPSR != 0 ) + * when the processor is running in the Thread Mode. + * Also do nothing, if a secure context us already loaded. PSPLIM is set to + * securecontextNO_STACK when no secure context is loaded. */ + if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { /* Ontain a free secure context. */ - ulSecureContextIndex = ulGetSecureContext(); + ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) @@ -198,6 +220,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; + xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle; + #if ( configENABLE_MPU == 1 ) { /* Store the correct CONTROL value for the task on the stack. @@ -230,10 +254,6 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) /* Ensure to never return 0 as a valid context handle. */ xSecureContextHandle = ulSecureContextIndex + 1UL; } - else - { - xSecureContextHandle = securecontextINVALID_CONTEXT_ID; - } } } @@ -241,7 +261,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) } /*-----------------------------------------------------------*/ -secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle ) +secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint32_t ulIPSR, ulSecureContextIndex; @@ -257,38 +277,61 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl { ulSecureContextIndex = xSecureContextHandle - 1UL; - /* Free the stack space. */ - vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); + /* Ensure that the secure context being deleted is associated with + * the task. */ + if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) + { + /* Free the stack space. */ + vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); - /* Return the context back to the free contexts pool. */ - vReturnSecureContext( ulSecureContextIndex ); + /* Return the secure context back to the free secure contexts pool. */ + vReturnSecureContext( ulSecureContextIndex ); + } } } } /*-----------------------------------------------------------*/ -secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ) +secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { + uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; - SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + secureportREAD_PSPLIM( pucStackLimit ); + + /* Ensure that no secure context is loaded and the task is loading it's + * own context. */ + if( ( pucStackLimit == securecontextNO_STACK ) && + ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) + { + SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + } } } /*-----------------------------------------------------------*/ -secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle ) +secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { + uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; - SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + secureportREAD_PSPLIM( pucStackLimit ); + + /* Ensure that task's context is loaded and the task is saving it's own + * context. */ + if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && + ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) + { + SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + } } } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23/secure/secure_context.h b/portable/GCC/ARM_CM23/secure/secure_context.h index b7a3ba50e..57e390c26 100644 --- a/portable/GCC/ARM_CM23/secure/secure_context.h +++ b/portable/GCC/ARM_CM23/secure/secure_context.h @@ -38,7 +38,12 @@ /** * @brief PSP value when no secure context is loaded. */ -#define securecontextNO_STACK 0x0 +#define securecontextNO_STACK 0x0 + +/** + * @brief Invalid context ID. + */ +#define securecontextINVALID_CONTEXT_ID 0UL /*-----------------------------------------------------------*/ /** @@ -52,6 +57,7 @@ typedef struct SecureContext uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */ uint8_t * pucStackStart; /**< First location of the stack memory. */ + void * pvTaskHandle; /**< Task handle of the task this context is associated with. */ } SecureContext_t; /*-----------------------------------------------------------*/ @@ -86,9 +92,11 @@ void SecureContext_Init( void ); */ #if ( configENABLE_MPU == 1 ) SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, - uint32_t ulIsTaskPrivileged ); + uint32_t ulIsTaskPrivileged, + void * pvTaskHandle ); #else /* configENABLE_MPU */ - SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize ); + SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + void * pvTaskHandle ); #endif /* configENABLE_MPU */ /** @@ -100,7 +108,7 @@ void SecureContext_Init( void ); * @param[in] xSecureContextHandle Context handle corresponding to the * context to be freed. */ -void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle ); +void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Loads the given context. @@ -111,7 +119,7 @@ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle ); * @param[in] xSecureContextHandle Context handle corresponding to the context * to be loaded. */ -void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ); +void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Saves the given context. @@ -122,6 +130,6 @@ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ); * @param[in] xSecureContextHandle Context handle corresponding to the context * to be saved. */ -void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle ); +void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); #endif /* __SECURE_CONTEXT_H__ */ diff --git a/portable/GCC/ARM_CM23/secure/secure_context_port.c b/portable/GCC/ARM_CM23/secure/secure_context_port.c index 8677b2297..0c871990c 100644 --- a/portable/GCC/ARM_CM23/secure/secure_context_port.c +++ b/portable/GCC/ARM_CM23/secure/secure_context_port.c @@ -36,6 +36,9 @@ #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif +void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); +void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); + void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) { /* pxSecureContext value is in r0. */ diff --git a/portable/GCC/ARM_CM23/secure/secure_heap.c b/portable/GCC/ARM_CM23/secure/secure_heap.c index 099b01f1f..b3a737818 100644 --- a/portable/GCC/ARM_CM23/secure/secure_heap.c +++ b/portable/GCC/ARM_CM23/secure/secure_heap.c @@ -449,9 +449,3 @@ size_t xPortGetMinimumEverFreeHeapSize( void ) return xMinimumEverFreeBytesRemaining; } /*-----------------------------------------------------------*/ - -void vPortInitialiseBlocks( void ) -{ - /* This just exists to keep the linker quiet. */ -} -/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23/secure/secure_heap.h b/portable/GCC/ARM_CM23/secure/secure_heap.h index f08c092f2..bd42ff9ba 100644 --- a/portable/GCC/ARM_CM23/secure/secure_heap.h +++ b/portable/GCC/ARM_CM23/secure/secure_heap.h @@ -49,4 +49,18 @@ void * pvPortMalloc( size_t xWantedSize ); */ void vPortFree( void * pv ); +/** + * @brief Get the free heap size. + * + * @return Free heap size. + */ +size_t xPortGetFreeHeapSize( void ); + +/** + * @brief Get the minimum ever free heap size. + * + * @return Minimum ever free heap size. + */ +size_t xPortGetMinimumEverFreeHeapSize( void ); + #endif /* __SECURE_HEAP_H__ */ diff --git a/portable/GCC/ARM_CM23/secure/secure_port_macros.h b/portable/GCC/ARM_CM23/secure/secure_port_macros.h index 955ef75c6..54990549a 100644 --- a/portable/GCC/ARM_CM23/secure/secure_port_macros.h +++ b/portable/GCC/ARM_CM23/secure/secure_port_macros.h @@ -68,6 +68,12 @@ #define secureportSET_PSP( pucCurrentStackPointer ) \ __asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) ) +/** + * @brief Read the PSPLIM value in the given variable. + */ +#define secureportREAD_PSPLIM( pucOutStackLimit ) \ + __asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) ) + /** * @brief Set the PSPLIM to the given value. */ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c index 0d8294e79..0b81637ef 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c @@ -781,7 +781,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) - uint32_t ulR0; + uint32_t ulR0, ulR1; + extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ @@ -812,25 +813,27 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged ); + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0 ); + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != NULL ); - SecureContext_LoadContext( xSecureContext ); + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains the secure context handle to be freed. */ + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 ); + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ diff --git a/portable/GCC/ARM_CM33/non_secure/port.c b/portable/GCC/ARM_CM33/non_secure/port.c index 0d8294e79..0b81637ef 100644 --- a/portable/GCC/ARM_CM33/non_secure/port.c +++ b/portable/GCC/ARM_CM33/non_secure/port.c @@ -781,7 +781,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) - uint32_t ulR0; + uint32_t ulR0, ulR1; + extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ @@ -812,25 +813,27 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged ); + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0 ); + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != NULL ); - SecureContext_LoadContext( xSecureContext ); + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains the secure context handle to be freed. */ + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 ); + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ diff --git a/portable/GCC/ARM_CM33/non_secure/portasm.c b/portable/GCC/ARM_CM33/non_secure/portasm.c index 6dc125e00..8ed6c5eab 100644 --- a/portable/GCC/ARM_CM33/non_secure/portasm.c +++ b/portable/GCC/ARM_CM33/non_secure/portasm.c @@ -51,66 +51,66 @@ void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_ " ldr r0, [r3] \n"/* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r2] \n"/* Program RNR = 4. */ - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ + " dmb \n"/* Complete outstanding transfers before disabling MPU. */ + " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ + " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ + " str r4, [r2] \n"/* Disable MPU. */ + " \n" + " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ + " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ + " ldr r2, xMAIR0Const2 \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ + " str r4, [r2] \n"/* Program MAIR0. */ + " ldr r2, xRNRConst2 \n"/* r2 = 0xe000ed98 [Location of RNR]. */ + " movs r4, #4 \n"/* r4 = 4. */ + " str r4, [r2] \n"/* Program RNR = 4. */ + " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ + " ldr r2, xRBARConst2 \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ + " ldmia r3!, {r4-r11} \n"/* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + " ldr r2, xMPUCTRLConst2 \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ + " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ + " str r4, [r2] \n"/* Enable MPU. */ + " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) - " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ - " ldr r5, xSecureContextConst2 \n" - " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " msr control, r3 \n"/* Set this task's CONTROL value. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r4 \n"/* Finally, branch to EXC_RETURN. */ + " ldm r0!, {r1-r4} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = EXC_RETURN. */ + " ldr r5, xSecureContextConst2 \n" + " str r1, [r5] \n"/* Set xSecureContext to this task's value for the same. */ + " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ + " msr control, r3 \n"/* Set this task's CONTROL value. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ + " bx r4 \n"/* Finally, branch to EXC_RETURN. */ #else /* configENABLE_MPU */ - " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ - " ldr r4, xSecureContextConst2 \n" - " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ - " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ - " movs r1, #2 \n"/* r1 = 2. */ - " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ - " adds r0, #32 \n"/* Discard everything up to r0. */ - " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ - " isb \n" - " mov r0, #0 \n" - " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ - " bx r3 \n"/* Finally, branch to EXC_RETURN. */ + " ldm r0!, {r1-r3} \n"/* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ + " ldr r4, xSecureContextConst2 \n" + " str r1, [r4] \n"/* Set xSecureContext to this task's value for the same. */ + " msr psplim, r2 \n"/* Set this task's PSPLIM value. */ + " movs r1, #2 \n"/* r1 = 2. */ + " msr CONTROL, r1 \n"/* Switch to use PSP in the thread mode. */ + " adds r0, #32 \n"/* Discard everything up to r0. */ + " msr psp, r0 \n"/* This is now the new top of stack to use in the task. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n"/* Ensure that interrupts are enabled when the first task starts. */ + " bx r3 \n"/* Finally, branch to EXC_RETURN. */ #endif /* configENABLE_MPU */ " \n" " .align 4 \n" "pxCurrentTCBConst2: .word pxCurrentTCB \n" "xSecureContextConst2: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst2: .word 0xe000ed94 \n" - "xMAIR0Const2: .word 0xe000edc0 \n" - "xRNRConst2: .word 0xe000ed98 \n" - "xRBARConst2: .word 0xe000ed9c \n" + "xMPUCTRLConst2: .word 0xe000ed94 \n" + "xMAIR0Const2: .word 0xe000edc0 \n" + "xRNRConst2: .word 0xe000ed98 \n" + "xRBARConst2: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ); } @@ -217,62 +217,65 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " .extern SecureContext_SaveContext \n" " .extern SecureContext_LoadContext \n" " \n" - " mrs r1, psp \n"/* Read PSP in r1. */ - " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " ldr r0, [r2] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n"/* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " mrs r2, psp \n"/* Read PSP in r2. */ " \n" " cbz r0, save_ns_context \n"/* No secure context to save. */ " push {r0-r2, r14} \n" - " bl SecureContext_SaveContext \n" + " bl SecureContext_SaveContext \n"/* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " pop {r0-r3} \n"/* LR is now in r3. */ " mov lr, r3 \n"/* LR = r3. */ - " lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl save_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " lsls r1, r3, #25 \n"/* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl save_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r2, [r3] \n"/* Read pxCurrentTCB. */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB.*/ #if ( configENABLE_MPU == 1 ) - " subs r1, r1, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - " str r1, [r2] \n"/* Save the new top of stack in TCB. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " stmia r1!, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + " subs r2, r2, #16 \n"/* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mrs r3, control \n"/* r3 = CONTROL. */ + " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ - " subs r1, r1, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r1, [r2] \n"/* Save the new top of stack in TCB. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " stmia r1!, {r0, r2-r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ + " subs r2, r2, #12 \n"/* Make space for xSecureContext, PSPLIM and LR on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ " b select_next_task \n" " \n" " save_ns_context: \n" " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r2, [r3] \n"/* Read pxCurrentTCB. */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ #if ( configENABLE_FPU == 1 ) - " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ - " it eq \n" - " vstmdbeq r1!, {s16-s31} \n"/* Store the FPU registers which are not saved automatically. */ + " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ + " it eq \n" + " vstmdbeq r2!, {s16-s31} \n"/* Store the FPU registers which are not saved automatically. */ #endif /* configENABLE_FPU */ #if ( configENABLE_MPU == 1 ) - " subs r1, r1, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - " str r1, [r2] \n"/* Save the new top of stack in TCB. */ - " adds r1, r1, #16 \n"/* r1 = r1 + 16. */ - " stm r1, {r4-r11} \n"/* Store the registers that are not saved automatically. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mrs r3, control \n"/* r3 = CONTROL. */ - " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ - " subs r1, r1, #16 \n"/* r1 = r1 - 16. */ - " stm r1, {r0, r2-r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + " subs r2, r2, #48 \n"/* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " adds r2, r2, #16 \n"/* r2 = r2 + 16. */ + " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mrs r3, control \n"/* r3 = CONTROL. */ + " mov r4, lr \n"/* r4 = LR/EXC_RETURN. */ + " subs r2, r2, #16 \n"/* r2 = r2 - 16. */ + " stmia r2!, {r0, r1, r3, r4} \n"/* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ - " subs r1, r1, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r1, [r2] \n"/* Save the new top of stack in TCB. */ - " adds r1, r1, #12 \n"/* r1 = r1 + 12. */ - " stm r1, {r4-r11} \n"/* Store the registers that are not saved automatically. */ - " mrs r2, psplim \n"/* r2 = PSPLIM. */ - " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ - " subs r1, r1, #12 \n"/* r1 = r1 - 12. */ - " stmia r1!, {r0, r2-r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ + " subs r2, r2, #44 \n"/* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ + " str r2, [r1] \n"/* Save the new top of stack in TCB. */ + " adds r2, r2, #12 \n"/* r2 = r2 + 12. */ + " stm r2, {r4-r11} \n"/* Store the registers that are not saved automatically. */ + " mrs r1, psplim \n"/* r1 = PSPLIM. */ + " mov r3, lr \n"/* r3 = LR/EXC_RETURN. */ + " subs r2, r2, #12 \n"/* r2 = r2 - 12. */ + " stmia r2!, {r0, r1, r3} \n"/* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ " \n" " select_next_task: \n" @@ -284,87 +287,91 @@ void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ " mov r0, #0 \n"/* r0 = 0. */ " msr basepri, r0 \n"/* Enable interrupts. */ " \n" - " ldr r2, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r3, [r2] \n"/* Read pxCurrentTCB. */ - " ldr r1, [r3] \n"/* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " ldr r2, [r1] \n"/* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" #if ( configENABLE_MPU == 1 ) - " dmb \n"/* Complete outstanding transfers before disabling MPU. */ - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - " str r4, [r2] \n"/* Disable MPU. */ - " \n" - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - " ldr r4, [r3] \n"/* r4 = *r3 i.e. r4 = MAIR0. */ - " ldr r2, xMAIR0Const \n"/* r2 = 0xe000edc0 [Location of MAIR0]. */ - " str r4, [r2] \n"/* Program MAIR0. */ - " ldr r2, xRNRConst \n"/* r2 = 0xe000ed98 [Location of RNR]. */ - " movs r4, #4 \n"/* r4 = 4. */ - " str r4, [r2] \n"/* Program RNR = 4. */ - " adds r3, #4 \n"/* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - " ldr r2, xRBARConst \n"/* r2 = 0xe000ed9c [Location of RBAR]. */ - " ldmia r3!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ - " \n" - " ldr r2, xMPUCTRLConst \n"/* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - " ldr r4, [r2] \n"/* Read the value of MPU_CTRL. */ - " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - " str r4, [r2] \n"/* Enable MPU. */ - " dsb \n"/* Force memory writes before continuing. */ + " dmb \n"/* Complete outstanding transfers before disabling MPU. */ + " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ + " bic r4, #1 \n"/* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ + " str r4, [r3] \n"/* Disable MPU. */ + " \n" + " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ + " ldr r4, [r1] \n"/* r4 = *r1 i.e. r4 = MAIR0. */ + " ldr r3, xMAIR0Const \n"/* r3 = 0xe000edc0 [Location of MAIR0]. */ + " str r4, [r3] \n"/* Program MAIR0. */ + " ldr r3, xRNRConst \n"/* r3 = 0xe000ed98 [Location of RNR]. */ + " movs r4, #4 \n"/* r4 = 4. */ + " str r4, [r3] \n"/* Program RNR = 4. */ + " adds r1, #4 \n"/* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ + " ldr r3, xRBARConst \n"/* r3 = 0xe000ed9c [Location of RBAR]. */ + " ldmia r1!, {r4-r11} \n"/* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r3!, {r4-r11} \n"/* Write 4 set of RBAR/RLAR registers using alias registers. */ + " \n" + " ldr r3, xMPUCTRLConst \n"/* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + " ldr r4, [r3] \n"/* Read the value of MPU_CTRL. */ + " orr r4, #1 \n"/* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ + " str r4, [r3] \n"/* Enable MPU. */ + " dsb \n"/* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ " \n" #if ( configENABLE_MPU == 1 ) - " ldmia r1!, {r0, r2-r4} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */ - " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ - " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ - " mov lr, r4 \n"/* LR = r4. */ - " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r2] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " push {r1,r4} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. */ - " pop {r1,r4} \n" - " mov lr, r4 \n"/* LR = r4. */ - " lsls r2, r4, #25 \n"/* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r1 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" + " ldmia r2!, {r0, r1, r3, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " msr control, r3 \n"/* Restore the CONTROL register value for the task. */ + " mov lr, r4 \n"/* LR = r4. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n"/* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " push {r2, r4} \n" + " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r2, r4} \n" + " mov lr, r4 \n"/* LR = r4. */ + " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" #else /* configENABLE_MPU */ - " ldmia r1!, {r0, r2-r3} \n"/* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */ - " msr psplim, r2 \n"/* Restore the PSPLIM register value for the task. */ - " mov lr, r3 \n"/* LR = r3. */ - " ldr r2, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r2] \n"/* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ - " push {r1,r3} \n" - " bl SecureContext_LoadContext \n"/* Restore the secure context. */ - " pop {r1,r3} \n" - " mov lr, r3 \n"/* LR = r3. */ - " lsls r2, r3, #25 \n"/* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - " msr psp, r1 \n"/* Remember the new top of stack for the task. */ - " bx lr \n" + " ldmia r2!, {r0, r1, r4} \n"/* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ + " msr psplim, r1 \n"/* Restore the PSPLIM register value for the task. */ + " mov lr, r4 \n"/* LR = r4. */ + " ldr r3, xSecureContextConst \n"/* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n"/* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n"/* If there is no secure context for the task, restore the non-secure context. */ + " ldr r3, pxCurrentTCBConst \n"/* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n"/* Read pxCurrentTCB. */ + " push {r2, r4} \n" + " bl SecureContext_LoadContext \n"/* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r2, r4} \n" + " mov lr, r4 \n"/* LR = r4. */ + " lsls r1, r4, #25 \n"/* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bpl restore_ns_context \n"/* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ + " bx lr \n" #endif /* configENABLE_MPU */ " \n" " restore_ns_context: \n" - " ldmia r1!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */ + " ldmia r2!, {r4-r11} \n"/* Restore the registers that are not automatically restored. */ #if ( configENABLE_FPU == 1 ) - " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ - " it eq \n" - " vldmiaeq r1!, {s16-s31} \n"/* Restore the FPU registers which are not restored automatically. */ + " tst lr, #0x10 \n"/* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ + " it eq \n" + " vldmiaeq r2!, {s16-s31} \n"/* Restore the FPU registers which are not restored automatically. */ #endif /* configENABLE_FPU */ - " msr psp, r1 \n"/* Remember the new top of stack for the task. */ + " msr psp, r2 \n"/* Remember the new top of stack for the task. */ " bx lr \n" " \n" " .align 4 \n" "pxCurrentTCBConst: .word pxCurrentTCB \n" "xSecureContextConst: .word xSecureContext \n" #if ( configENABLE_MPU == 1 ) - "xMPUCTRLConst: .word 0xe000ed94 \n" - "xMAIR0Const: .word 0xe000edc0 \n" - "xRNRConst: .word 0xe000ed98 \n" - "xRBARConst: .word 0xe000ed9c \n" + "xMPUCTRLConst: .word 0xe000ed94 \n" + "xMAIR0Const: .word 0xe000edc0 \n" + "xRNRConst: .word 0xe000ed98 \n" + "xRBARConst: .word 0xe000ed9c \n" #endif /* configENABLE_MPU */ ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); @@ -403,9 +410,9 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR { __asm volatile ( - " ldr r1, [r0] \n"/* The first item in the TCB is the top of the stack. */ - " ldr r0, [r1] \n"/* The first item on the stack is the task's xSecureContext. */ - " cmp r0, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */ + " ldr r2, [r0] \n"/* The first item in the TCB is the top of the stack. */ + " ldr r1, [r2] \n"/* The first item on the stack is the task's xSecureContext. */ + " cmp r1, #0 \n"/* Raise svc if task's xSecureContext is not NULL. */ " it ne \n" " svcne %0 \n"/* Secure context is freed in the supervisor call. */ " bx lr \n"/* Return. */ diff --git a/portable/GCC/ARM_CM33/secure/secure_context.c b/portable/GCC/ARM_CM33/secure/secure_context.c index 96a566211..a51d1c17c 100644 --- a/portable/GCC/ARM_CM33/secure/secure_context.c +++ b/portable/GCC/ARM_CM33/secure/secure_context.c @@ -51,11 +51,6 @@ */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 -/** - * @brief Invalid context ID. - */ -#define securecontextINVALID_CONTEXT_ID 0UL - /** * @brief Maximum number of secure contexts. */ @@ -71,11 +66,15 @@ SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ]; /*-----------------------------------------------------------*/ /** - * @brief Get a free context from the secure context pool (xSecureContexts). + * @brief Get a free secure context for a task from the secure context pool (xSecureContexts). * - * @return Index of a free context in the xSecureContexts array. + * This function ensures that only one secure context is allocated for a task. + * + * @param[in] pvTaskHandle The task handle for which the secure context is allocated. + * + * @return Index of a free secure context in the xSecureContexts array. */ -static uint32_t ulGetSecureContext( void ); +static uint32_t ulGetSecureContext( void * pvTaskHandle ); /** * @brief Return the secure context to the secure context pool (xSecureContexts). @@ -89,16 +88,26 @@ extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ); extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ); /*-----------------------------------------------------------*/ -static uint32_t ulGetSecureContext( void ) +static uint32_t ulGetSecureContext( void * pvTaskHandle ) { - uint32_t ulSecureContextIndex; + /* Start with invalid index. */ + uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; - for( ulSecureContextIndex = 0; ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS; ulSecureContextIndex++ ) + for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { - if( ( xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer == NULL ) && - ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == NULL ) && - ( xSecureContexts[ ulSecureContextIndex ].pucStackStart == NULL ) ) + if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) && + ( xSecureContexts[ i ].pucStackLimit == NULL ) && + ( xSecureContexts[ i ].pucStackStart == NULL ) && + ( xSecureContexts[ i ].pvTaskHandle == NULL ) && + ( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) ) { + ulSecureContextIndex = i; + } + else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle ) + { + /* A task can only have one secure context. Do not allocate a second + * context for the same task. */ + ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; break; } } @@ -112,20 +121,25 @@ static void vReturnSecureContext( uint32_t ulSecureContextIndex ) xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL; + xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) { uint32_t ulIPSR, i; + static uint32_t ulSecureContextsInitialized = 0; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ - if( ulIPSR != 0 ) + if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) ) { + /* Ensure to initialize secure contexts only once. */ + ulSecureContextsInitialized = 1; + /* No stack for thread mode until a task's context is loaded. */ secureportSET_PSPLIM( securecontextNO_STACK ); secureportSET_PSP( securecontextNO_STACK ); @@ -136,6 +150,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) xSecureContexts[ i ].pucCurrentStackPointer = NULL; xSecureContexts[ i ].pucStackLimit = NULL; xSecureContexts[ i ].pucStackStart = NULL; + xSecureContexts[ i ].pvTaskHandle = NULL; } #if ( configENABLE_MPU == 1 ) @@ -155,28 +170,35 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) #if ( configENABLE_MPU == 1 ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, - uint32_t ulIsTaskPrivileged ) + uint32_t ulIsTaskPrivileged, + void * pvTaskHandle ) #else /* configENABLE_MPU */ - secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize ) + secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + void * pvTaskHandle ) #endif /* configENABLE_MPU */ { uint8_t * pucStackMemory = NULL; + uint8_t * pucStackLimit; uint32_t ulIPSR, ulSecureContextIndex; - SecureContextHandle_t xSecureContextHandle; + SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID; #if ( configENABLE_MPU == 1 ) uint32_t * pulCurrentStackPointer = NULL; #endif /* configENABLE_MPU */ - /* Read the Interrupt Program Status Register (IPSR) value. */ + /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit + * Register (PSPLIM) value. */ secureportREAD_IPSR( ulIPSR ); + secureportREAD_PSPLIM( pucStackLimit ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero - * when the processor is running in the Thread Mode. */ - if( ulIPSR != 0 ) + * when the processor is running in the Thread Mode. + * Also do nothing, if a secure context us already loaded. PSPLIM is set to + * securecontextNO_STACK when no secure context is loaded. */ + if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { /* Ontain a free secure context. */ - ulSecureContextIndex = ulGetSecureContext(); + ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) @@ -198,6 +220,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; + xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle; + #if ( configENABLE_MPU == 1 ) { /* Store the correct CONTROL value for the task on the stack. @@ -230,10 +254,6 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) /* Ensure to never return 0 as a valid context handle. */ xSecureContextHandle = ulSecureContextIndex + 1UL; } - else - { - xSecureContextHandle = securecontextINVALID_CONTEXT_ID; - } } } @@ -241,7 +261,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) } /*-----------------------------------------------------------*/ -secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle ) +secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint32_t ulIPSR, ulSecureContextIndex; @@ -257,38 +277,61 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl { ulSecureContextIndex = xSecureContextHandle - 1UL; - /* Free the stack space. */ - vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); + /* Ensure that the secure context being deleted is associated with + * the task. */ + if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) + { + /* Free the stack space. */ + vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); - /* Return the context back to the free contexts pool. */ - vReturnSecureContext( ulSecureContextIndex ); + /* Return the secure context back to the free secure contexts pool. */ + vReturnSecureContext( ulSecureContextIndex ); + } } } } /*-----------------------------------------------------------*/ -secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ) +secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { + uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; - SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + secureportREAD_PSPLIM( pucStackLimit ); + + /* Ensure that no secure context is loaded and the task is loading it's + * own context. */ + if( ( pucStackLimit == securecontextNO_STACK ) && + ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) + { + SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + } } } /*-----------------------------------------------------------*/ -secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle ) +secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { + uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; - SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + secureportREAD_PSPLIM( pucStackLimit ); + + /* Ensure that task's context is loaded and the task is saving it's own + * context. */ + if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && + ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) + { + SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + } } } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33/secure/secure_context.h b/portable/GCC/ARM_CM33/secure/secure_context.h index b7a3ba50e..57e390c26 100644 --- a/portable/GCC/ARM_CM33/secure/secure_context.h +++ b/portable/GCC/ARM_CM33/secure/secure_context.h @@ -38,7 +38,12 @@ /** * @brief PSP value when no secure context is loaded. */ -#define securecontextNO_STACK 0x0 +#define securecontextNO_STACK 0x0 + +/** + * @brief Invalid context ID. + */ +#define securecontextINVALID_CONTEXT_ID 0UL /*-----------------------------------------------------------*/ /** @@ -52,6 +57,7 @@ typedef struct SecureContext uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */ uint8_t * pucStackStart; /**< First location of the stack memory. */ + void * pvTaskHandle; /**< Task handle of the task this context is associated with. */ } SecureContext_t; /*-----------------------------------------------------------*/ @@ -86,9 +92,11 @@ void SecureContext_Init( void ); */ #if ( configENABLE_MPU == 1 ) SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, - uint32_t ulIsTaskPrivileged ); + uint32_t ulIsTaskPrivileged, + void * pvTaskHandle ); #else /* configENABLE_MPU */ - SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize ); + SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + void * pvTaskHandle ); #endif /* configENABLE_MPU */ /** @@ -100,7 +108,7 @@ void SecureContext_Init( void ); * @param[in] xSecureContextHandle Context handle corresponding to the * context to be freed. */ -void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle ); +void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Loads the given context. @@ -111,7 +119,7 @@ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle ); * @param[in] xSecureContextHandle Context handle corresponding to the context * to be loaded. */ -void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ); +void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Saves the given context. @@ -122,6 +130,6 @@ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ); * @param[in] xSecureContextHandle Context handle corresponding to the context * to be saved. */ -void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle ); +void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); #endif /* __SECURE_CONTEXT_H__ */ diff --git a/portable/GCC/ARM_CM33/secure/secure_context_port.c b/portable/GCC/ARM_CM33/secure/secure_context_port.c index 0731abe1f..a6bf54cae 100644 --- a/portable/GCC/ARM_CM33/secure/secure_context_port.c +++ b/portable/GCC/ARM_CM33/secure/secure_context_port.c @@ -32,6 +32,9 @@ /* Secure port macros. */ #include "secure_port_macros.h" +void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); +void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) ); + void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) { /* pxSecureContext value is in r0. */ diff --git a/portable/GCC/ARM_CM33/secure/secure_heap.c b/portable/GCC/ARM_CM33/secure/secure_heap.c index 099b01f1f..b3a737818 100644 --- a/portable/GCC/ARM_CM33/secure/secure_heap.c +++ b/portable/GCC/ARM_CM33/secure/secure_heap.c @@ -449,9 +449,3 @@ size_t xPortGetMinimumEverFreeHeapSize( void ) return xMinimumEverFreeBytesRemaining; } /*-----------------------------------------------------------*/ - -void vPortInitialiseBlocks( void ) -{ - /* This just exists to keep the linker quiet. */ -} -/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33/secure/secure_heap.h b/portable/GCC/ARM_CM33/secure/secure_heap.h index f08c092f2..bd42ff9ba 100644 --- a/portable/GCC/ARM_CM33/secure/secure_heap.h +++ b/portable/GCC/ARM_CM33/secure/secure_heap.h @@ -49,4 +49,18 @@ void * pvPortMalloc( size_t xWantedSize ); */ void vPortFree( void * pv ); +/** + * @brief Get the free heap size. + * + * @return Free heap size. + */ +size_t xPortGetFreeHeapSize( void ); + +/** + * @brief Get the minimum ever free heap size. + * + * @return Minimum ever free heap size. + */ +size_t xPortGetMinimumEverFreeHeapSize( void ); + #endif /* __SECURE_HEAP_H__ */ diff --git a/portable/GCC/ARM_CM33/secure/secure_port_macros.h b/portable/GCC/ARM_CM33/secure/secure_port_macros.h index 955ef75c6..54990549a 100644 --- a/portable/GCC/ARM_CM33/secure/secure_port_macros.h +++ b/portable/GCC/ARM_CM33/secure/secure_port_macros.h @@ -68,6 +68,12 @@ #define secureportSET_PSP( pucCurrentStackPointer ) \ __asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) ) +/** + * @brief Read the PSPLIM value in the given variable. + */ +#define secureportREAD_PSPLIM( pucOutStackLimit ) \ + __asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) ) + /** * @brief Set the PSPLIM to the given value. */ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c index c1185d811..393e21e9f 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c @@ -781,7 +781,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) - uint32_t ulR0; + uint32_t ulR0, ulR1; + extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ @@ -812,25 +813,27 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged ); + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0 ); + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != NULL ); - SecureContext_LoadContext( xSecureContext ); + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains the secure context handle to be freed. */ + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 ); + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ diff --git a/portable/IAR/ARM_CM23/non_secure/port.c b/portable/IAR/ARM_CM23/non_secure/port.c index c1185d811..393e21e9f 100644 --- a/portable/IAR/ARM_CM23/non_secure/port.c +++ b/portable/IAR/ARM_CM23/non_secure/port.c @@ -781,7 +781,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) - uint32_t ulR0; + uint32_t ulR0, ulR1; + extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ @@ -812,25 +813,27 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged ); + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0 ); + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != NULL ); - SecureContext_LoadContext( xSecureContext ); + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains the secure context handle to be freed. */ + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 ); + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ diff --git a/portable/IAR/ARM_CM23/non_secure/portasm.s b/portable/IAR/ARM_CM23/non_secure/portasm.s index ffaf87e26..0f2c8387c 100644 --- a/portable/IAR/ARM_CM23/non_secure/portasm.s +++ b/portable/IAR/ARM_CM23/non_secure/portasm.s @@ -26,6 +26,13 @@ * */ +/* Including FreeRTOSConfig.h here will cause build errors if the header file +contains code not understood by the assembler - for example the 'extern' keyword. +To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +the code is included in C files but excluded by the preprocessor in assembly +files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ +#include "FreeRTOSConfig.h" + EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext @@ -194,64 +201,66 @@ vClearInterruptMask: /*-----------------------------------------------------------*/ PendSV_Handler: - mrs r1, psp /* Read PSP in r1. */ - ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - ldr r0, [r2] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ push {r0-r2, r14} - bl SecureContext_SaveContext + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r0-r3} /* LR is now in r3. */ mov lr, r3 /* LR = r3. */ - lsls r2, r3, #25 /* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl save_ns_context /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + lsls r1, r3, #25 /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r2, [r3] /* Read pxCurrentTCB. */ + ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) - subs r1, r1, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - str r1, [r2] /* Save the new top of stack in TCB. */ - mrs r2, psplim /* r2 = PSPLIM. */ + subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ - stmia r1!, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ - subs r1, r1, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - str r1, [r2] /* Save the new top of stack in TCB. */ - mrs r2, psplim /* r2 = PSPLIM. */ + subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r1!, {r0, r2-r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ b select_next_task save_ns_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r2, [r3] /* Read pxCurrentTCB. */ + ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) - subs r1, r1, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - str r1, [r2] /* Save the new top of stack in TCB. */ - adds r1, r1, #16 /* r1 = r1 + 16. */ - stmia r1!, {r4-r7} /* Store the low registers that are not saved automatically. */ + subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + adds r2, r2, #16 /* r2 = r2 + 16. */ + stmia r2!, {r4-r7} /* Store the low registers that are not saved automatically. */ mov r4, r8 /* r4 = r8. */ mov r5, r9 /* r5 = r9. */ mov r6, r10 /* r6 = r10. */ mov r7, r11 /* r7 = r11. */ - stmia r1!, {r4-r7} /* Store the high registers that are not saved automatically. */ - mrs r2, psplim /* r2 = PSPLIM. */ + stmia r2!, {r4-r7} /* Store the high registers that are not saved automatically. */ + mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ - subs r1, r1, #48 /* r1 = r1 - 48. */ - stmia r1!, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + subs r2, r2, #48 /* r2 = r2 - 48. */ + stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ - subs r1, r1, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - str r1, [r2] /* Save the new top of stack in TCB. */ - mrs r2, psplim /* r2 = PSPLIM. */ + subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r1!, {r0, r2-r7} /* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ + stmia r2!, {r0, r1, r3-r7} /* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */ mov r4, r8 /* r4 = r8. */ mov r5, r9 /* r5 = r9. */ mov r6, r10 /* r6 = r10. */ mov r7, r11 /* r7 = r11. */ - stmia r1!, {r4-r7} /* Store the high registers that are not saved automatically. */ + stmia r2!, {r4-r7} /* Store the high registers that are not saved automatically. */ #endif /* configENABLE_MPU */ select_next_task: @@ -259,96 +268,100 @@ PendSV_Handler: bl vTaskSwitchContext cpsie i - ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r3, [r2] /* Read pxCurrentTCB. */ - ldr r1, [r3] /* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ + ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r4, [r3] /* Read the value of MPU_CTRL. */ movs r5, #1 /* r5 = 1. */ bics r4, r5 /* r4 = r4 & ~r5 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ + str r4, [r3] /* Disable MPU. */ - adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ - adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ + adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ + ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ + ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ + str r4, [r3] /* Program MAIR0. */ + ldr r4, =0xe000ed98 /* r4 = 0xe000ed98 [Location of RNR]. */ + adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ movs r5, #4 /* r5 = 4. */ - str r5, [r2] /* Program RNR = 4. */ - ldmia r3!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */ - ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ - stmia r4!, {r6,r7} /* Write first set of RBAR/RLAR registers. */ + str r5, [r4] /* Program RNR = 4. */ + ldmia r1!, {r6,r7} /* Read first set of RBAR/RLAR from TCB. */ + ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ + stmia r3!, {r6,r7} /* Write first set of RBAR/RLAR registers. */ movs r5, #5 /* r5 = 5. */ - str r5, [r2] /* Program RNR = 5. */ - ldmia r3!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */ - ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ - stmia r4!, {r6,r7} /* Write second set of RBAR/RLAR registers. */ + str r5, [r4] /* Program RNR = 5. */ + ldmia r1!, {r6,r7} /* Read second set of RBAR/RLAR from TCB. */ + ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ + stmia r3!, {r6,r7} /* Write second set of RBAR/RLAR registers. */ movs r5, #6 /* r5 = 6. */ - str r5, [r2] /* Program RNR = 6. */ - ldmia r3!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */ - ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ - stmia r4!, {r6,r7} /* Write third set of RBAR/RLAR registers. */ + str r5, [r4] /* Program RNR = 6. */ + ldmia r1!, {r6,r7} /* Read third set of RBAR/RLAR from TCB. */ + ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ + stmia r3!, {r6,r7} /* Write third set of RBAR/RLAR registers. */ movs r5, #7 /* r5 = 7. */ - str r5, [r2] /* Program RNR = 7. */ - ldmia r3!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */ - ldr r4, =0xe000ed9c /* r4 = 0xe000ed9c [Location of RBAR]. */ - stmia r4!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */ + str r5, [r4] /* Program RNR = 7. */ + ldmia r1!, {r6,r7} /* Read fourth set of RBAR/RLAR from TCB. */ + ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ + stmia r3!, {r6,r7} /* Write fourth set of RBAR/RLAR registers. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ + ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r4, [r3] /* Read the value of MPU_CTRL. */ movs r5, #1 /* r5 = 1. */ orrs r4, r5 /* r4 = r4 | r5 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ + str r4, [r3] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) - ldmia r1!, {r0, r2-r4} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */ - msr psplim, r2 /* Restore the PSPLIM register value for the task. */ + ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ + msr psplim, r1 /* Restore the PSPLIM register value for the task. */ msr control, r3 /* Restore the CONTROL register value for the task. */ mov lr, r4 /* LR = r4. */ - ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - str r0, [r2] /* Restore the task's xSecureContext. */ + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - push {r1,r4} - bl SecureContext_LoadContext /* Restore the secure context. */ - pop {r1,r4} + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + push {r2, r4} + bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r2, r4} mov lr, r4 /* LR = r4. */ - lsls r2, r4, #25 /* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r1 /* Remember the new top of stack for the task. */ + lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + msr psp, r2 /* Remember the new top of stack for the task. */ bx lr #else /* configENABLE_MPU */ - ldmia r1!, {r0, r2-r3} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */ - msr psplim, r2 /* Restore the PSPLIM register value for the task. */ - mov lr, r3 /* LR = r3. */ - ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - str r0, [r2] /* Restore the task's xSecureContext. */ + ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ + msr psplim, r1 /* Restore the PSPLIM register value for the task. */ + mov lr, r4 /* LR = r4. */ + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - push {r1,r3} - bl SecureContext_LoadContext /* Restore the secure context. */ - pop {r1,r3} - mov lr, r3 /* LR = r3. */ - lsls r2, r3, #25 /* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r1 /* Remember the new top of stack for the task. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + push {r2, r4} + bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r2, r4} + mov lr, r4 /* LR = r4. */ + lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + msr psp, r2 /* Remember the new top of stack for the task. */ bx lr #endif /* configENABLE_MPU */ restore_ns_context: - adds r1, r1, #16 /* Move to the high registers. */ - ldmia r1!, {r4-r7} /* Restore the high registers that are not automatically restored. */ + adds r2, r2, #16 /* Move to the high registers. */ + ldmia r2!, {r4-r7} /* Restore the high registers that are not automatically restored. */ mov r8, r4 /* r8 = r4. */ mov r9, r5 /* r9 = r5. */ mov r10, r6 /* r10 = r6. */ mov r11, r7 /* r11 = r7. */ - msr psp, r1 /* Remember the new top of stack for the task. */ - subs r1, r1, #32 /* Go back to the low registers. */ - ldmia r1!, {r4-r7} /* Restore the low registers that are not automatically restored. */ + msr psp, r2 /* Remember the new top of stack for the task. */ + subs r2, r2, #32 /* Go back to the low registers. */ + ldmia r2!, {r4-r7} /* Restore the low registers that are not automatically restored. */ bx lr /*-----------------------------------------------------------*/ @@ -365,9 +378,9 @@ SVC_Handler: /*-----------------------------------------------------------*/ vPortFreeSecureContext: - ldr r1, [r0] /* The first item in the TCB is the top of the stack. */ - ldr r0, [r1] /* The first item on the stack is the task's xSecureContext. */ - cmp r0, #0 /* Raise svc if task's xSecureContext is not NULL. */ + ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ + ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ + cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ beq free_secure_context bx lr /* There is no secure context (xSecureContext is NULL). */ free_secure_context: diff --git a/portable/IAR/ARM_CM23/secure/secure_context.c b/portable/IAR/ARM_CM23/secure/secure_context.c index 96a566211..a51d1c17c 100644 --- a/portable/IAR/ARM_CM23/secure/secure_context.c +++ b/portable/IAR/ARM_CM23/secure/secure_context.c @@ -51,11 +51,6 @@ */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 -/** - * @brief Invalid context ID. - */ -#define securecontextINVALID_CONTEXT_ID 0UL - /** * @brief Maximum number of secure contexts. */ @@ -71,11 +66,15 @@ SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ]; /*-----------------------------------------------------------*/ /** - * @brief Get a free context from the secure context pool (xSecureContexts). + * @brief Get a free secure context for a task from the secure context pool (xSecureContexts). * - * @return Index of a free context in the xSecureContexts array. + * This function ensures that only one secure context is allocated for a task. + * + * @param[in] pvTaskHandle The task handle for which the secure context is allocated. + * + * @return Index of a free secure context in the xSecureContexts array. */ -static uint32_t ulGetSecureContext( void ); +static uint32_t ulGetSecureContext( void * pvTaskHandle ); /** * @brief Return the secure context to the secure context pool (xSecureContexts). @@ -89,16 +88,26 @@ extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ); extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ); /*-----------------------------------------------------------*/ -static uint32_t ulGetSecureContext( void ) +static uint32_t ulGetSecureContext( void * pvTaskHandle ) { - uint32_t ulSecureContextIndex; + /* Start with invalid index. */ + uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; - for( ulSecureContextIndex = 0; ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS; ulSecureContextIndex++ ) + for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { - if( ( xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer == NULL ) && - ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == NULL ) && - ( xSecureContexts[ ulSecureContextIndex ].pucStackStart == NULL ) ) + if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) && + ( xSecureContexts[ i ].pucStackLimit == NULL ) && + ( xSecureContexts[ i ].pucStackStart == NULL ) && + ( xSecureContexts[ i ].pvTaskHandle == NULL ) && + ( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) ) { + ulSecureContextIndex = i; + } + else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle ) + { + /* A task can only have one secure context. Do not allocate a second + * context for the same task. */ + ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; break; } } @@ -112,20 +121,25 @@ static void vReturnSecureContext( uint32_t ulSecureContextIndex ) xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL; + xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) { uint32_t ulIPSR, i; + static uint32_t ulSecureContextsInitialized = 0; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ - if( ulIPSR != 0 ) + if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) ) { + /* Ensure to initialize secure contexts only once. */ + ulSecureContextsInitialized = 1; + /* No stack for thread mode until a task's context is loaded. */ secureportSET_PSPLIM( securecontextNO_STACK ); secureportSET_PSP( securecontextNO_STACK ); @@ -136,6 +150,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) xSecureContexts[ i ].pucCurrentStackPointer = NULL; xSecureContexts[ i ].pucStackLimit = NULL; xSecureContexts[ i ].pucStackStart = NULL; + xSecureContexts[ i ].pvTaskHandle = NULL; } #if ( configENABLE_MPU == 1 ) @@ -155,28 +170,35 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) #if ( configENABLE_MPU == 1 ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, - uint32_t ulIsTaskPrivileged ) + uint32_t ulIsTaskPrivileged, + void * pvTaskHandle ) #else /* configENABLE_MPU */ - secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize ) + secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + void * pvTaskHandle ) #endif /* configENABLE_MPU */ { uint8_t * pucStackMemory = NULL; + uint8_t * pucStackLimit; uint32_t ulIPSR, ulSecureContextIndex; - SecureContextHandle_t xSecureContextHandle; + SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID; #if ( configENABLE_MPU == 1 ) uint32_t * pulCurrentStackPointer = NULL; #endif /* configENABLE_MPU */ - /* Read the Interrupt Program Status Register (IPSR) value. */ + /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit + * Register (PSPLIM) value. */ secureportREAD_IPSR( ulIPSR ); + secureportREAD_PSPLIM( pucStackLimit ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero - * when the processor is running in the Thread Mode. */ - if( ulIPSR != 0 ) + * when the processor is running in the Thread Mode. + * Also do nothing, if a secure context us already loaded. PSPLIM is set to + * securecontextNO_STACK when no secure context is loaded. */ + if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { /* Ontain a free secure context. */ - ulSecureContextIndex = ulGetSecureContext(); + ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) @@ -198,6 +220,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; + xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle; + #if ( configENABLE_MPU == 1 ) { /* Store the correct CONTROL value for the task on the stack. @@ -230,10 +254,6 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) /* Ensure to never return 0 as a valid context handle. */ xSecureContextHandle = ulSecureContextIndex + 1UL; } - else - { - xSecureContextHandle = securecontextINVALID_CONTEXT_ID; - } } } @@ -241,7 +261,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) } /*-----------------------------------------------------------*/ -secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle ) +secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint32_t ulIPSR, ulSecureContextIndex; @@ -257,38 +277,61 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl { ulSecureContextIndex = xSecureContextHandle - 1UL; - /* Free the stack space. */ - vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); + /* Ensure that the secure context being deleted is associated with + * the task. */ + if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) + { + /* Free the stack space. */ + vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); - /* Return the context back to the free contexts pool. */ - vReturnSecureContext( ulSecureContextIndex ); + /* Return the secure context back to the free secure contexts pool. */ + vReturnSecureContext( ulSecureContextIndex ); + } } } } /*-----------------------------------------------------------*/ -secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ) +secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { + uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; - SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + secureportREAD_PSPLIM( pucStackLimit ); + + /* Ensure that no secure context is loaded and the task is loading it's + * own context. */ + if( ( pucStackLimit == securecontextNO_STACK ) && + ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) + { + SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + } } } /*-----------------------------------------------------------*/ -secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle ) +secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { + uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; - SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + secureportREAD_PSPLIM( pucStackLimit ); + + /* Ensure that task's context is loaded and the task is saving it's own + * context. */ + if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && + ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) + { + SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + } } } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23/secure/secure_context.h b/portable/IAR/ARM_CM23/secure/secure_context.h index b7a3ba50e..57e390c26 100644 --- a/portable/IAR/ARM_CM23/secure/secure_context.h +++ b/portable/IAR/ARM_CM23/secure/secure_context.h @@ -38,7 +38,12 @@ /** * @brief PSP value when no secure context is loaded. */ -#define securecontextNO_STACK 0x0 +#define securecontextNO_STACK 0x0 + +/** + * @brief Invalid context ID. + */ +#define securecontextINVALID_CONTEXT_ID 0UL /*-----------------------------------------------------------*/ /** @@ -52,6 +57,7 @@ typedef struct SecureContext uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */ uint8_t * pucStackStart; /**< First location of the stack memory. */ + void * pvTaskHandle; /**< Task handle of the task this context is associated with. */ } SecureContext_t; /*-----------------------------------------------------------*/ @@ -86,9 +92,11 @@ void SecureContext_Init( void ); */ #if ( configENABLE_MPU == 1 ) SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, - uint32_t ulIsTaskPrivileged ); + uint32_t ulIsTaskPrivileged, + void * pvTaskHandle ); #else /* configENABLE_MPU */ - SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize ); + SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + void * pvTaskHandle ); #endif /* configENABLE_MPU */ /** @@ -100,7 +108,7 @@ void SecureContext_Init( void ); * @param[in] xSecureContextHandle Context handle corresponding to the * context to be freed. */ -void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle ); +void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Loads the given context. @@ -111,7 +119,7 @@ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle ); * @param[in] xSecureContextHandle Context handle corresponding to the context * to be loaded. */ -void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ); +void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Saves the given context. @@ -122,6 +130,6 @@ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ); * @param[in] xSecureContextHandle Context handle corresponding to the context * to be saved. */ -void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle ); +void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); #endif /* __SECURE_CONTEXT_H__ */ diff --git a/portable/IAR/ARM_CM23/secure/secure_context_port_asm.s b/portable/IAR/ARM_CM23/secure/secure_context_port_asm.s index cf245b915..1124e82bb 100644 --- a/portable/IAR/ARM_CM23/secure/secure_context_port_asm.s +++ b/portable/IAR/ARM_CM23/secure/secure_context_port_asm.s @@ -29,6 +29,13 @@ SECTION .text:CODE:NOROOT(2) THUMB +/* Including FreeRTOSConfig.h here will cause build errors if the header file +contains code not understood by the assembler - for example the 'extern' keyword. +To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +the code is included in C files but excluded by the preprocessor in assembly +files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ +#include "FreeRTOSConfig.h" + PUBLIC SecureContext_LoadContextAsm PUBLIC SecureContext_SaveContextAsm diff --git a/portable/IAR/ARM_CM23/secure/secure_heap.c b/portable/IAR/ARM_CM23/secure/secure_heap.c index 099b01f1f..b3a737818 100644 --- a/portable/IAR/ARM_CM23/secure/secure_heap.c +++ b/portable/IAR/ARM_CM23/secure/secure_heap.c @@ -449,9 +449,3 @@ size_t xPortGetMinimumEverFreeHeapSize( void ) return xMinimumEverFreeBytesRemaining; } /*-----------------------------------------------------------*/ - -void vPortInitialiseBlocks( void ) -{ - /* This just exists to keep the linker quiet. */ -} -/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23/secure/secure_heap.h b/portable/IAR/ARM_CM23/secure/secure_heap.h index f08c092f2..bd42ff9ba 100644 --- a/portable/IAR/ARM_CM23/secure/secure_heap.h +++ b/portable/IAR/ARM_CM23/secure/secure_heap.h @@ -49,4 +49,18 @@ void * pvPortMalloc( size_t xWantedSize ); */ void vPortFree( void * pv ); +/** + * @brief Get the free heap size. + * + * @return Free heap size. + */ +size_t xPortGetFreeHeapSize( void ); + +/** + * @brief Get the minimum ever free heap size. + * + * @return Minimum ever free heap size. + */ +size_t xPortGetMinimumEverFreeHeapSize( void ); + #endif /* __SECURE_HEAP_H__ */ diff --git a/portable/IAR/ARM_CM23/secure/secure_port_macros.h b/portable/IAR/ARM_CM23/secure/secure_port_macros.h index 955ef75c6..54990549a 100644 --- a/portable/IAR/ARM_CM23/secure/secure_port_macros.h +++ b/portable/IAR/ARM_CM23/secure/secure_port_macros.h @@ -68,6 +68,12 @@ #define secureportSET_PSP( pucCurrentStackPointer ) \ __asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) ) +/** + * @brief Read the PSPLIM value in the given variable. + */ +#define secureportREAD_PSPLIM( pucOutStackLimit ) \ + __asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) ) + /** * @brief Set the PSPLIM to the given value. */ diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c index c1185d811..393e21e9f 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c @@ -781,7 +781,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) - uint32_t ulR0; + uint32_t ulR0, ulR1; + extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ @@ -812,25 +813,27 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged ); + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0 ); + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != NULL ); - SecureContext_LoadContext( xSecureContext ); + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains the secure context handle to be freed. */ + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 ); + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.s index e7dc5f307..6ab1aefcc 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.s @@ -25,6 +25,12 @@ * https://github.com/FreeRTOS * */ +/* Including FreeRTOSConfig.h here will cause build errors if the header file +contains code not understood by the assembler - for example the 'extern' keyword. +To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +the code is included in C files but excluded by the preprocessor in assembly +files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ +#include "FreeRTOSConfig.h" EXTERN pxCurrentTCB EXTERN vTaskSwitchContext diff --git a/portable/IAR/ARM_CM33/non_secure/port.c b/portable/IAR/ARM_CM33/non_secure/port.c index c1185d811..393e21e9f 100644 --- a/portable/IAR/ARM_CM33/non_secure/port.c +++ b/portable/IAR/ARM_CM33/non_secure/port.c @@ -781,7 +781,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) - uint32_t ulR0; + uint32_t ulR0, ulR1; + extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ @@ -812,25 +813,27 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged ); + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0 ); + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != NULL ); - SecureContext_LoadContext( xSecureContext ); + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains the secure context handle to be freed. */ + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 ); + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */ diff --git a/portable/IAR/ARM_CM33/non_secure/portasm.s b/portable/IAR/ARM_CM33/non_secure/portasm.s index 6ba01ffc5..f8fd04f9f 100644 --- a/portable/IAR/ARM_CM33/non_secure/portasm.s +++ b/portable/IAR/ARM_CM33/non_secure/portasm.s @@ -184,62 +184,65 @@ vClearInterruptMask: /*-----------------------------------------------------------*/ PendSV_Handler: - mrs r1, psp /* Read PSP in r1. */ - ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - ldr r0, [r2] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ push {r0-r2, r14} - bl SecureContext_SaveContext + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ pop {r0-r3} /* LR is now in r3. */ mov lr, r3 /* LR = r3. */ - lsls r2, r3, #25 /* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl save_ns_context /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + lsls r1, r3, #25 /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r2, [r3] /* Read pxCurrentTCB. */ + ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( configENABLE_MPU == 1 ) - subs r1, r1, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ - str r1, [r2] /* Save the new top of stack in TCB. */ - mrs r2, psplim /* r2 = PSPLIM. */ + subs r2, r2, #16 /* Make space for xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ - stmia r1!, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ - subs r1, r1, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - str r1, [r2] /* Save the new top of stack in TCB. */ - mrs r2, psplim /* r2 = PSPLIM. */ + subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r1!, {r0, r2-r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ b select_next_task save_ns_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r2, [r3] /* Read pxCurrentTCB. */ + ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( configENABLE_FPU == 1 ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ it eq - vstmdbeq r1!, {s16-s31} /* Store the FPU registers which are not saved automatically. */ + vstmdbeq r2!, {s16-s31} /* Store the FPU registers which are not saved automatically. */ #endif /* configENABLE_FPU */ #if ( configENABLE_MPU == 1 ) - subs r1, r1, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ - str r1, [r2] /* Save the new top of stack in TCB. */ - adds r1, r1, #16 /* r1 = r1 + 16. */ - stm r1, {r4-r11} /* Store the registers that are not saved automatically. */ - mrs r2, psplim /* r2 = PSPLIM. */ + subs r2, r2, #48 /* Make space for xSecureContext, PSPLIM, CONTROL, LR and the remaining registers on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + adds r2, r2, #16 /* r2 = r2 + 16. */ + stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ + mrs r1, psplim /* r1 = PSPLIM. */ mrs r3, control /* r3 = CONTROL. */ mov r4, lr /* r4 = LR/EXC_RETURN. */ - subs r1, r1, #16 /* r1 = r1 - 16. */ - stm r1, {r0, r2-r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ + subs r2, r2, #16 /* r2 = r2 - 16. */ + stmia r2!, {r0, r1, r3, r4} /* Store xSecureContext, PSPLIM, CONTROL and LR on the stack. */ #else /* configENABLE_MPU */ - subs r1, r1, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - str r1, [r2] /* Save the new top of stack in TCB. */ - adds r1, r1, #12 /* r1 = r1 + 12. */ - stm r1, {r4-r11} /* Store the registers that are not saved automatically. */ - mrs r2, psplim /* r2 = PSPLIM. */ + subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ + str r2, [r1] /* Save the new top of stack in TCB. */ + adds r2, r2, #12 /* r2 = r2 + 12. */ + stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ + mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - subs r1, r1, #12 /* r1 = r1 - 12. */ - stmia r1!, {r0, r2-r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + subs r2, r2, #12 /* r2 = r2 - 12. */ + stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ #endif /* configENABLE_MPU */ select_next_task: @@ -251,77 +254,81 @@ PendSV_Handler: mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ - ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r3, [r2] /* Read pxCurrentTCB. */ - ldr r1, [r3] /* The first item in pxCurrentTCB is the task top of stack. r1 now points to the top of stack. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ #if ( configENABLE_MPU == 1 ) dmb /* Complete outstanding transfers before disabling MPU. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ + ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r4, [r3] /* Read the value of MPU_CTRL. */ bic r4, r4, #1 /* r4 = r4 & ~1 i.e. Clear the bit 0 in r4. */ - str r4, [r2] /* Disable MPU. */ + str r4, [r3] /* Disable MPU. */ - adds r3, #4 /* r3 = r3 + 4. r3 now points to MAIR0 in TCB. */ - ldr r4, [r3] /* r4 = *r3 i.e. r4 = MAIR0. */ - ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */ - str r4, [r2] /* Program MAIR0. */ - ldr r2, =0xe000ed98 /* r2 = 0xe000ed98 [Location of RNR]. */ + adds r1, #4 /* r1 = r1 + 4. r1 now points to MAIR0 in TCB. */ + ldr r4, [r1] /* r4 = *r1 i.e. r4 = MAIR0. */ + ldr r3, =0xe000edc0 /* r3 = 0xe000edc0 [Location of MAIR0]. */ + str r4, [r3] /* Program MAIR0. */ + ldr r3, =0xe000ed98 /* r3 = 0xe000ed98 [Location of RNR]. */ movs r4, #4 /* r4 = 4. */ - str r4, [r2] /* Program RNR = 4. */ - adds r3, #4 /* r3 = r3 + 4. r3 now points to first RBAR in TCB. */ - ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */ - ldmia r3!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ - stmia r2!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ + str r4, [r3] /* Program RNR = 4. */ + adds r1, #4 /* r1 = r1 + 4. r1 now points to first RBAR in TCB. */ + ldr r3, =0xe000ed9c /* r3 = 0xe000ed9c [Location of RBAR]. */ + ldmia r1!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */ + stmia r3!, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */ - ldr r2, =0xe000ed94 /* r2 = 0xe000ed94 [Location of MPU_CTRL]. */ - ldr r4, [r2] /* Read the value of MPU_CTRL. */ + ldr r3, =0xe000ed94 /* r3 = 0xe000ed94 [Location of MPU_CTRL]. */ + ldr r4, [r3] /* Read the value of MPU_CTRL. */ orr r4, r4, #1 /* r4 = r4 | 1 i.e. Set the bit 0 in r4. */ - str r4, [r2] /* Enable MPU. */ + str r4, [r3] /* Enable MPU. */ dsb /* Force memory writes before continuing. */ #endif /* configENABLE_MPU */ #if ( configENABLE_MPU == 1 ) - ldmia r1!, {r0, r2-r4} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM, r3 = CONTROL and r4 = LR. */ - msr psplim, r2 /* Restore the PSPLIM register value for the task. */ + ldmia r2!, {r0, r1, r3, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM, r3 = CONTROL and r4 = LR. */ + msr psplim, r1 /* Restore the PSPLIM register value for the task. */ msr control, r3 /* Restore the CONTROL register value for the task. */ mov lr, r4 /* LR = r4. */ - ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - str r0, [r2] /* Restore the task's xSecureContext. */ + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - push {r1,r4} - bl SecureContext_LoadContext /* Restore the secure context. */ - pop {r1,r4} + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + push {r2, r4} + bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r2, r4} mov lr, r4 /* LR = r4. */ - lsls r2, r4, #25 /* r2 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r1 /* Remember the new top of stack for the task. */ + lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + msr psp, r2 /* Remember the new top of stack for the task. */ bx lr #else /* configENABLE_MPU */ - ldmia r1!, {r0, r2-r3} /* Read from stack - r0 = xSecureContext, r2 = PSPLIM and r3 = LR. */ - msr psplim, r2 /* Restore the PSPLIM register value for the task. */ - mov lr, r3 /* LR = r3. */ - ldr r2, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - str r0, [r2] /* Restore the task's xSecureContext. */ + ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ + msr psplim, r1 /* Restore the PSPLIM register value for the task. */ + mov lr, r4 /* LR = r4. */ + ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - push {r1,r3} - bl SecureContext_LoadContext /* Restore the secure context. */ - pop {r1,r3} - mov lr, r3 /* LR = r3. */ - lsls r2, r3, #25 /* r2 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ - bpl restore_ns_context /* bpl - branch if positive or zero. If r2 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - msr psp, r1 /* Remember the new top of stack for the task. */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + push {r2, r4} + bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r2, r4} + mov lr, r4 /* LR = r4. */ + lsls r1, r4, #25 /* r1 = r4 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bpl restore_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ + msr psp, r2 /* Remember the new top of stack for the task. */ bx lr #endif /* configENABLE_MPU */ restore_ns_context: - ldmia r1!, {r4-r11} /* Restore the registers that are not automatically restored. */ + ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ #if ( configENABLE_FPU == 1 ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the FPU is in use. */ it eq - vldmiaeq r1!, {s16-s31} /* Restore the FPU registers which are not restored automatically. */ + vldmiaeq r2!, {s16-s31} /* Restore the FPU registers which are not restored automatically. */ #endif /* configENABLE_FPU */ - msr psp, r1 /* Remember the new top of stack for the task. */ + msr psp, r2 /* Remember the new top of stack for the task. */ bx lr /*-----------------------------------------------------------*/ @@ -335,9 +342,9 @@ SVC_Handler: vPortFreeSecureContext: /* r0 = uint32_t *pulTCB. */ - ldr r1, [r0] /* The first item in the TCB is the top of the stack. */ - ldr r0, [r1] /* The first item on the stack is the task's xSecureContext. */ - cmp r0, #0 /* Raise svc if task's xSecureContext is not NULL. */ + ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ + ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ + cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ it ne svcne 1 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 1. */ bx lr /* Return. */ diff --git a/portable/IAR/ARM_CM33/secure/secure_context.c b/portable/IAR/ARM_CM33/secure/secure_context.c index 96a566211..a51d1c17c 100644 --- a/portable/IAR/ARM_CM33/secure/secure_context.c +++ b/portable/IAR/ARM_CM33/secure/secure_context.c @@ -51,11 +51,6 @@ */ #define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03 -/** - * @brief Invalid context ID. - */ -#define securecontextINVALID_CONTEXT_ID 0UL - /** * @brief Maximum number of secure contexts. */ @@ -71,11 +66,15 @@ SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ]; /*-----------------------------------------------------------*/ /** - * @brief Get a free context from the secure context pool (xSecureContexts). + * @brief Get a free secure context for a task from the secure context pool (xSecureContexts). * - * @return Index of a free context in the xSecureContexts array. + * This function ensures that only one secure context is allocated for a task. + * + * @param[in] pvTaskHandle The task handle for which the secure context is allocated. + * + * @return Index of a free secure context in the xSecureContexts array. */ -static uint32_t ulGetSecureContext( void ); +static uint32_t ulGetSecureContext( void * pvTaskHandle ); /** * @brief Return the secure context to the secure context pool (xSecureContexts). @@ -89,16 +88,26 @@ extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ); extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ); /*-----------------------------------------------------------*/ -static uint32_t ulGetSecureContext( void ) +static uint32_t ulGetSecureContext( void * pvTaskHandle ) { - uint32_t ulSecureContextIndex; + /* Start with invalid index. */ + uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; - for( ulSecureContextIndex = 0; ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS; ulSecureContextIndex++ ) + for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ ) { - if( ( xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer == NULL ) && - ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == NULL ) && - ( xSecureContexts[ ulSecureContextIndex ].pucStackStart == NULL ) ) + if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) && + ( xSecureContexts[ i ].pucStackLimit == NULL ) && + ( xSecureContexts[ i ].pucStackStart == NULL ) && + ( xSecureContexts[ i ].pvTaskHandle == NULL ) && + ( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) ) { + ulSecureContextIndex = i; + } + else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle ) + { + /* A task can only have one secure context. Do not allocate a second + * context for the same task. */ + ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS; break; } } @@ -112,20 +121,25 @@ static void vReturnSecureContext( uint32_t ulSecureContextIndex ) xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL; xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL; + xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL; } /*-----------------------------------------------------------*/ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) { uint32_t ulIPSR, i; + static uint32_t ulSecureContextsInitialized = 0; /* Read the Interrupt Program Status Register (IPSR) value. */ secureportREAD_IPSR( ulIPSR ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero * when the processor is running in the Thread Mode. */ - if( ulIPSR != 0 ) + if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) ) { + /* Ensure to initialize secure contexts only once. */ + ulSecureContextsInitialized = 1; + /* No stack for thread mode until a task's context is loaded. */ secureportSET_PSPLIM( securecontextNO_STACK ); secureportSET_PSP( securecontextNO_STACK ); @@ -136,6 +150,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) xSecureContexts[ i ].pucCurrentStackPointer = NULL; xSecureContexts[ i ].pucStackLimit = NULL; xSecureContexts[ i ].pucStackStart = NULL; + xSecureContexts[ i ].pvTaskHandle = NULL; } #if ( configENABLE_MPU == 1 ) @@ -155,28 +170,35 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) #if ( configENABLE_MPU == 1 ) secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, - uint32_t ulIsTaskPrivileged ) + uint32_t ulIsTaskPrivileged, + void * pvTaskHandle ) #else /* configENABLE_MPU */ - secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize ) + secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + void * pvTaskHandle ) #endif /* configENABLE_MPU */ { uint8_t * pucStackMemory = NULL; + uint8_t * pucStackLimit; uint32_t ulIPSR, ulSecureContextIndex; - SecureContextHandle_t xSecureContextHandle; + SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID; #if ( configENABLE_MPU == 1 ) uint32_t * pulCurrentStackPointer = NULL; #endif /* configENABLE_MPU */ - /* Read the Interrupt Program Status Register (IPSR) value. */ + /* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit + * Register (PSPLIM) value. */ secureportREAD_IPSR( ulIPSR ); + secureportREAD_PSPLIM( pucStackLimit ); /* Do nothing if the processor is running in the Thread Mode. IPSR is zero - * when the processor is running in the Thread Mode. */ - if( ulIPSR != 0 ) + * when the processor is running in the Thread Mode. + * Also do nothing, if a secure context us already loaded. PSPLIM is set to + * securecontextNO_STACK when no secure context is loaded. */ + if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { /* Ontain a free secure context. */ - ulSecureContextIndex = ulGetSecureContext(); + ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS ) @@ -198,6 +220,8 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * programmed in the PSPLIM register on context switch.*/ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory; + xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle; + #if ( configENABLE_MPU == 1 ) { /* Store the correct CONTROL value for the task on the stack. @@ -230,10 +254,6 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) /* Ensure to never return 0 as a valid context handle. */ xSecureContextHandle = ulSecureContextIndex + 1UL; } - else - { - xSecureContextHandle = securecontextINVALID_CONTEXT_ID; - } } } @@ -241,7 +261,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) } /*-----------------------------------------------------------*/ -secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle ) +secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { uint32_t ulIPSR, ulSecureContextIndex; @@ -257,38 +277,61 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl { ulSecureContextIndex = xSecureContextHandle - 1UL; - /* Free the stack space. */ - vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); + /* Ensure that the secure context being deleted is associated with + * the task. */ + if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) + { + /* Free the stack space. */ + vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit ); - /* Return the context back to the free contexts pool. */ - vReturnSecureContext( ulSecureContextIndex ); + /* Return the secure context back to the free secure contexts pool. */ + vReturnSecureContext( ulSecureContextIndex ); + } } } } /*-----------------------------------------------------------*/ -secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ) +secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { + uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; - SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + secureportREAD_PSPLIM( pucStackLimit ); + + /* Ensure that no secure context is loaded and the task is loading it's + * own context. */ + if( ( pucStackLimit == securecontextNO_STACK ) && + ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) + { + SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + } } } /*-----------------------------------------------------------*/ -secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle ) +secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ) { + uint8_t * pucStackLimit; uint32_t ulSecureContextIndex; if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) ) { ulSecureContextIndex = xSecureContextHandle - 1UL; - SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + secureportREAD_PSPLIM( pucStackLimit ); + + /* Ensure that task's context is loaded and the task is saving it's own + * context. */ + if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) && + ( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) ) + { + SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) ); + } } } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33/secure/secure_context.h b/portable/IAR/ARM_CM33/secure/secure_context.h index b7a3ba50e..57e390c26 100644 --- a/portable/IAR/ARM_CM33/secure/secure_context.h +++ b/portable/IAR/ARM_CM33/secure/secure_context.h @@ -38,7 +38,12 @@ /** * @brief PSP value when no secure context is loaded. */ -#define securecontextNO_STACK 0x0 +#define securecontextNO_STACK 0x0 + +/** + * @brief Invalid context ID. + */ +#define securecontextINVALID_CONTEXT_ID 0UL /*-----------------------------------------------------------*/ /** @@ -52,6 +57,7 @@ typedef struct SecureContext uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */ uint8_t * pucStackStart; /**< First location of the stack memory. */ + void * pvTaskHandle; /**< Task handle of the task this context is associated with. */ } SecureContext_t; /*-----------------------------------------------------------*/ @@ -86,9 +92,11 @@ void SecureContext_Init( void ); */ #if ( configENABLE_MPU == 1 ) SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, - uint32_t ulIsTaskPrivileged ); + uint32_t ulIsTaskPrivileged, + void * pvTaskHandle ); #else /* configENABLE_MPU */ - SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize ); + SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, + void * pvTaskHandle ); #endif /* configENABLE_MPU */ /** @@ -100,7 +108,7 @@ void SecureContext_Init( void ); * @param[in] xSecureContextHandle Context handle corresponding to the * context to be freed. */ -void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle ); +void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Loads the given context. @@ -111,7 +119,7 @@ void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle ); * @param[in] xSecureContextHandle Context handle corresponding to the context * to be loaded. */ -void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ); +void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); /** * @brief Saves the given context. @@ -122,6 +130,6 @@ void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle ); * @param[in] xSecureContextHandle Context handle corresponding to the context * to be saved. */ -void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle ); +void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle ); #endif /* __SECURE_CONTEXT_H__ */ diff --git a/portable/IAR/ARM_CM33/secure/secure_context_port_asm.s b/portable/IAR/ARM_CM33/secure/secure_context_port_asm.s index 0df0a1b40..52dbe4563 100644 --- a/portable/IAR/ARM_CM33/secure/secure_context_port_asm.s +++ b/portable/IAR/ARM_CM33/secure/secure_context_port_asm.s @@ -29,6 +29,13 @@ SECTION .text:CODE:NOROOT(2) THUMB +/* Including FreeRTOSConfig.h here will cause build errors if the header file +contains code not understood by the assembler - for example the 'extern' keyword. +To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +the code is included in C files but excluded by the preprocessor in assembly +files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ +#include "FreeRTOSConfig.h" + PUBLIC SecureContext_LoadContextAsm PUBLIC SecureContext_SaveContextAsm /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33/secure/secure_heap.c b/portable/IAR/ARM_CM33/secure/secure_heap.c index 099b01f1f..b3a737818 100644 --- a/portable/IAR/ARM_CM33/secure/secure_heap.c +++ b/portable/IAR/ARM_CM33/secure/secure_heap.c @@ -449,9 +449,3 @@ size_t xPortGetMinimumEverFreeHeapSize( void ) return xMinimumEverFreeBytesRemaining; } /*-----------------------------------------------------------*/ - -void vPortInitialiseBlocks( void ) -{ - /* This just exists to keep the linker quiet. */ -} -/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33/secure/secure_heap.h b/portable/IAR/ARM_CM33/secure/secure_heap.h index f08c092f2..bd42ff9ba 100644 --- a/portable/IAR/ARM_CM33/secure/secure_heap.h +++ b/portable/IAR/ARM_CM33/secure/secure_heap.h @@ -49,4 +49,18 @@ void * pvPortMalloc( size_t xWantedSize ); */ void vPortFree( void * pv ); +/** + * @brief Get the free heap size. + * + * @return Free heap size. + */ +size_t xPortGetFreeHeapSize( void ); + +/** + * @brief Get the minimum ever free heap size. + * + * @return Minimum ever free heap size. + */ +size_t xPortGetMinimumEverFreeHeapSize( void ); + #endif /* __SECURE_HEAP_H__ */ diff --git a/portable/IAR/ARM_CM33/secure/secure_port_macros.h b/portable/IAR/ARM_CM33/secure/secure_port_macros.h index 955ef75c6..54990549a 100644 --- a/portable/IAR/ARM_CM33/secure/secure_port_macros.h +++ b/portable/IAR/ARM_CM33/secure/secure_port_macros.h @@ -68,6 +68,12 @@ #define secureportSET_PSP( pucCurrentStackPointer ) \ __asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) ) +/** + * @brief Read the PSPLIM value in the given variable. + */ +#define secureportREAD_PSPLIM( pucOutStackLimit ) \ + __asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) ) + /** * @brief Set the PSPLIM to the given value. */ diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c index c1185d811..393e21e9f 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c @@ -781,7 +781,8 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulPC; #if ( configENABLE_TRUSTZONE == 1 ) - uint32_t ulR0; + uint32_t ulR0, ulR1; + extern TaskHandle_t pxCurrentTCB; #if ( configENABLE_MPU == 1 ) uint32_t ulControl, ulIsTaskPrivileged; #endif /* configENABLE_MPU */ @@ -812,25 +813,27 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged ); + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); } #else /* if ( configENABLE_MPU == 1 ) */ { /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0 ); + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); } #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != NULL ); - SecureContext_LoadContext( xSecureContext ); + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); break; case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains the secure context handle to be freed. */ + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR0 ); + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); break; #endif /* configENABLE_TRUSTZONE */