Associate secure context with task handle

The secure side context management code now checks that the secure
context being saved or restored belongs to the task being switched-out
or switched-in respectively.

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c
index 0d8294e..0b81637 100644
--- a/portable/ARMv8M/non_secure/port.c
+++ b/portable/ARMv8M/non_secure/port.c
@@ -781,7 +781,8 @@
     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 @@
                         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 e32c631..9dab039 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 @@
         "	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 @@
         "	.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 @@
         "	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 @@
 {

     __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 6dc125e..8ed6c5e 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 @@
         "	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 @@
         "	.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 @@
         "	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 @@
 {

     __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 ffaf87e..0f2c838 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 @@
 /*-----------------------------------------------------------*/

 

 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 @@
 		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 @@
 /*-----------------------------------------------------------*/

 

 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 e7dc5f3..6ab1aef 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 6ba01ff..f8fd04f 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 @@
 /*-----------------------------------------------------------*/

 

 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 @@
 		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 @@
 

 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 8677b22..0c87199 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 0731abe..a6bf54c 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 cf245b9..1124e82 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 0df0a1b..52dbe45 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 96a5662..a51d1c1 100644
--- a/portable/ARMv8M/secure/context/secure_context.c
+++ b/portable/ARMv8M/secure/context/secure_context.c
@@ -52,11 +52,6 @@
 #define securecontextCONTROL_VALUE_UNPRIVILEGED    0x03

 

 /**

- * @brief Invalid context ID.

- */

-#define securecontextINVALID_CONTEXT_ID            0UL

-

-/**

  * @brief Maximum number of secure contexts.

  */

 #ifndef secureconfigMAX_SECURE_CONTEXTS

@@ -71,11 +66,15 @@
 /*-----------------------------------------------------------*/

 

 /**

- * @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_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 @@
     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 @@
             xSecureContexts[ i ].pucCurrentStackPointer = NULL;

             xSecureContexts[ i ].pucStackLimit = NULL;

             xSecureContexts[ i ].pucStackStart = NULL;

+            xSecureContexts[ i ].pvTaskHandle = NULL;

         }

 

         #if ( configENABLE_MPU == 1 )

@@ -155,28 +170,35 @@
 

 #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 @@
                  * 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 @@
                 /* 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_FreeContext( SecureContextHandle_t xSecureContextHandle )

+secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )

 {

     uint32_t ulIPSR, ulSecureContextIndex;

 

@@ -257,38 +277,61 @@
         {

             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 b7a3ba5..57e390c 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 @@
     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 @@
  */

 #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 @@
  * @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 @@
  * @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 @@
  * @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 099b01f..b3a7378 100644
--- a/portable/ARMv8M/secure/heap/secure_heap.c
+++ b/portable/ARMv8M/secure/heap/secure_heap.c
@@ -449,9 +449,3 @@
     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 f08c092..bd42ff9 100644
--- a/portable/ARMv8M/secure/heap/secure_heap.h
+++ b/portable/ARMv8M/secure/heap/secure_heap.h
@@ -49,4 +49,18 @@
  */

 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 955ef75..5499054 100644
--- a/portable/ARMv8M/secure/macros/secure_port_macros.h
+++ b/portable/ARMv8M/secure/macros/secure_port_macros.h
@@ -69,6 +69,12 @@
     __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.

  */

 #define secureportSET_PSPLIM( pucStackLimit ) \

diff --git a/portable/Common/mpu_wrappers.c b/portable/Common/mpu_wrappers.c
index e9ed25f..7a04fb8 100644
--- a/portable/Common/mpu_wrappers.c
+++ b/portable/Common/mpu_wrappers.c
@@ -936,33 +936,6 @@
 }

 /*-----------------------------------------------------------*/

 

-#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 c1185d8..393e21e 100644
--- a/portable/GCC/ARM_CM23/non_secure/port.c
+++ b/portable/GCC/ARM_CM23/non_secure/port.c
@@ -781,7 +781,8 @@
     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 @@
                         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 e32c631..9dab039 100644
--- a/portable/GCC/ARM_CM23/non_secure/portasm.c
+++ b/portable/GCC/ARM_CM23/non_secure/portasm.c
@@ -55,79 +55,79 @@
         "	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 @@
         "	.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 @@
         "	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 @@
 {

     __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 96a5662..a51d1c1 100644
--- a/portable/GCC/ARM_CM23/secure/secure_context.c
+++ b/portable/GCC/ARM_CM23/secure/secure_context.c
@@ -52,11 +52,6 @@
 #define securecontextCONTROL_VALUE_UNPRIVILEGED    0x03

 

 /**

- * @brief Invalid context ID.

- */

-#define securecontextINVALID_CONTEXT_ID            0UL

-

-/**

  * @brief Maximum number of secure contexts.

  */

 #ifndef secureconfigMAX_SECURE_CONTEXTS

@@ -71,11 +66,15 @@
 /*-----------------------------------------------------------*/

 

 /**

- * @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_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 @@
     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 @@
             xSecureContexts[ i ].pucCurrentStackPointer = NULL;

             xSecureContexts[ i ].pucStackLimit = NULL;

             xSecureContexts[ i ].pucStackStart = NULL;

+            xSecureContexts[ i ].pvTaskHandle = NULL;

         }

 

         #if ( configENABLE_MPU == 1 )

@@ -155,28 +170,35 @@
 

 #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 @@
                  * 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 @@
                 /* 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_FreeContext( SecureContextHandle_t xSecureContextHandle )

+secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )

 {

     uint32_t ulIPSR, ulSecureContextIndex;

 

@@ -257,38 +277,61 @@
         {

             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 b7a3ba5..57e390c 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 @@
     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 @@
  */

 #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 @@
  * @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 @@
  * @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 @@
  * @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 8677b22..0c87199 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 099b01f..b3a7378 100644
--- a/portable/GCC/ARM_CM23/secure/secure_heap.c
+++ b/portable/GCC/ARM_CM23/secure/secure_heap.c
@@ -449,9 +449,3 @@
     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 f08c092..bd42ff9 100644
--- a/portable/GCC/ARM_CM23/secure/secure_heap.h
+++ b/portable/GCC/ARM_CM23/secure/secure_heap.h
@@ -49,4 +49,18 @@
  */

 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 955ef75..5499054 100644
--- a/portable/GCC/ARM_CM23/secure/secure_port_macros.h
+++ b/portable/GCC/ARM_CM23/secure/secure_port_macros.h
@@ -69,6 +69,12 @@
     __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.

  */

 #define secureportSET_PSPLIM( pucStackLimit ) \

diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c
index 0d8294e..0b81637 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 @@
     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 @@
                         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 0d8294e..0b81637 100644
--- a/portable/GCC/ARM_CM33/non_secure/port.c
+++ b/portable/GCC/ARM_CM33/non_secure/port.c
@@ -781,7 +781,8 @@
     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 @@
                         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 6dc125e..8ed6c5e 100644
--- a/portable/GCC/ARM_CM33/non_secure/portasm.c
+++ b/portable/GCC/ARM_CM33/non_secure/portasm.c
@@ -51,66 +51,66 @@
         "	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 @@
         "	.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 @@
         "	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 @@
 {

     __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 96a5662..a51d1c1 100644
--- a/portable/GCC/ARM_CM33/secure/secure_context.c
+++ b/portable/GCC/ARM_CM33/secure/secure_context.c
@@ -52,11 +52,6 @@
 #define securecontextCONTROL_VALUE_UNPRIVILEGED    0x03

 

 /**

- * @brief Invalid context ID.

- */

-#define securecontextINVALID_CONTEXT_ID            0UL

-

-/**

  * @brief Maximum number of secure contexts.

  */

 #ifndef secureconfigMAX_SECURE_CONTEXTS

@@ -71,11 +66,15 @@
 /*-----------------------------------------------------------*/

 

 /**

- * @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_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 @@
     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 @@
             xSecureContexts[ i ].pucCurrentStackPointer = NULL;

             xSecureContexts[ i ].pucStackLimit = NULL;

             xSecureContexts[ i ].pucStackStart = NULL;

+            xSecureContexts[ i ].pvTaskHandle = NULL;

         }

 

         #if ( configENABLE_MPU == 1 )

@@ -155,28 +170,35 @@
 

 #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 @@
                  * 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 @@
                 /* 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_FreeContext( SecureContextHandle_t xSecureContextHandle )

+secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )

 {

     uint32_t ulIPSR, ulSecureContextIndex;

 

@@ -257,38 +277,61 @@
         {

             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 b7a3ba5..57e390c 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 @@
     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 @@
  */

 #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 @@
  * @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 @@
  * @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 @@
  * @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 0731abe..a6bf54c 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 099b01f..b3a7378 100644
--- a/portable/GCC/ARM_CM33/secure/secure_heap.c
+++ b/portable/GCC/ARM_CM33/secure/secure_heap.c
@@ -449,9 +449,3 @@
     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 f08c092..bd42ff9 100644
--- a/portable/GCC/ARM_CM33/secure/secure_heap.h
+++ b/portable/GCC/ARM_CM33/secure/secure_heap.h
@@ -49,4 +49,18 @@
  */

 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 955ef75..5499054 100644
--- a/portable/GCC/ARM_CM33/secure/secure_port_macros.h
+++ b/portable/GCC/ARM_CM33/secure/secure_port_macros.h
@@ -69,6 +69,12 @@
     __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.

  */

 #define secureportSET_PSPLIM( pucStackLimit ) \

diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c
index c1185d8..393e21e 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 @@
     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 @@
                         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 c1185d8..393e21e 100644
--- a/portable/IAR/ARM_CM23/non_secure/port.c
+++ b/portable/IAR/ARM_CM23/non_secure/port.c
@@ -781,7 +781,8 @@
     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 @@
                         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 ffaf87e..0f2c838 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 @@
 /*-----------------------------------------------------------*/

 

 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 @@
 		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 @@
 /*-----------------------------------------------------------*/

 

 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 96a5662..a51d1c1 100644
--- a/portable/IAR/ARM_CM23/secure/secure_context.c
+++ b/portable/IAR/ARM_CM23/secure/secure_context.c
@@ -52,11 +52,6 @@
 #define securecontextCONTROL_VALUE_UNPRIVILEGED    0x03

 

 /**

- * @brief Invalid context ID.

- */

-#define securecontextINVALID_CONTEXT_ID            0UL

-

-/**

  * @brief Maximum number of secure contexts.

  */

 #ifndef secureconfigMAX_SECURE_CONTEXTS

@@ -71,11 +66,15 @@
 /*-----------------------------------------------------------*/

 

 /**

- * @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_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 @@
     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 @@
             xSecureContexts[ i ].pucCurrentStackPointer = NULL;

             xSecureContexts[ i ].pucStackLimit = NULL;

             xSecureContexts[ i ].pucStackStart = NULL;

+            xSecureContexts[ i ].pvTaskHandle = NULL;

         }

 

         #if ( configENABLE_MPU == 1 )

@@ -155,28 +170,35 @@
 

 #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 @@
                  * 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 @@
                 /* 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_FreeContext( SecureContextHandle_t xSecureContextHandle )

+secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )

 {

     uint32_t ulIPSR, ulSecureContextIndex;

 

@@ -257,38 +277,61 @@
         {

             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 b7a3ba5..57e390c 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 @@
     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 @@
  */

 #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 @@
  * @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 @@
  * @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 @@
  * @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 cf245b9..1124e82 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 099b01f..b3a7378 100644
--- a/portable/IAR/ARM_CM23/secure/secure_heap.c
+++ b/portable/IAR/ARM_CM23/secure/secure_heap.c
@@ -449,9 +449,3 @@
     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 f08c092..bd42ff9 100644
--- a/portable/IAR/ARM_CM23/secure/secure_heap.h
+++ b/portable/IAR/ARM_CM23/secure/secure_heap.h
@@ -49,4 +49,18 @@
  */

 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 955ef75..5499054 100644
--- a/portable/IAR/ARM_CM23/secure/secure_port_macros.h
+++ b/portable/IAR/ARM_CM23/secure/secure_port_macros.h
@@ -69,6 +69,12 @@
     __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.

  */

 #define secureportSET_PSPLIM( pucStackLimit ) \

diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c
index c1185d8..393e21e 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 @@
     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 @@
                         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 e7dc5f3..6ab1aef 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 c1185d8..393e21e 100644
--- a/portable/IAR/ARM_CM33/non_secure/port.c
+++ b/portable/IAR/ARM_CM33/non_secure/port.c
@@ -781,7 +781,8 @@
     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 @@
                         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 6ba01ff..f8fd04f 100644
--- a/portable/IAR/ARM_CM33/non_secure/portasm.s
+++ b/portable/IAR/ARM_CM33/non_secure/portasm.s
@@ -184,62 +184,65 @@
 /*-----------------------------------------------------------*/

 

 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 @@
 		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 @@
 

 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 96a5662..a51d1c1 100644
--- a/portable/IAR/ARM_CM33/secure/secure_context.c
+++ b/portable/IAR/ARM_CM33/secure/secure_context.c
@@ -52,11 +52,6 @@
 #define securecontextCONTROL_VALUE_UNPRIVILEGED    0x03

 

 /**

- * @brief Invalid context ID.

- */

-#define securecontextINVALID_CONTEXT_ID            0UL

-

-/**

  * @brief Maximum number of secure contexts.

  */

 #ifndef secureconfigMAX_SECURE_CONTEXTS

@@ -71,11 +66,15 @@
 /*-----------------------------------------------------------*/

 

 /**

- * @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_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 @@
     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 @@
             xSecureContexts[ i ].pucCurrentStackPointer = NULL;

             xSecureContexts[ i ].pucStackLimit = NULL;

             xSecureContexts[ i ].pucStackStart = NULL;

+            xSecureContexts[ i ].pvTaskHandle = NULL;

         }

 

         #if ( configENABLE_MPU == 1 )

@@ -155,28 +170,35 @@
 

 #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 @@
                  * 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 @@
                 /* 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_FreeContext( SecureContextHandle_t xSecureContextHandle )

+secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle, void * pvTaskHandle )

 {

     uint32_t ulIPSR, ulSecureContextIndex;

 

@@ -257,38 +277,61 @@
         {

             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 b7a3ba5..57e390c 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 @@
     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 @@
  */

 #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 @@
  * @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 @@
  * @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 @@
  * @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 0df0a1b..52dbe45 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 099b01f..b3a7378 100644
--- a/portable/IAR/ARM_CM33/secure/secure_heap.c
+++ b/portable/IAR/ARM_CM33/secure/secure_heap.c
@@ -449,9 +449,3 @@
     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 f08c092..bd42ff9 100644
--- a/portable/IAR/ARM_CM33/secure/secure_heap.h
+++ b/portable/IAR/ARM_CM33/secure/secure_heap.h
@@ -49,4 +49,18 @@
  */

 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 955ef75..5499054 100644
--- a/portable/IAR/ARM_CM33/secure/secure_port_macros.h
+++ b/portable/IAR/ARM_CM33/secure/secure_port_macros.h
@@ -69,6 +69,12 @@
     __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.

  */

 #define secureportSET_PSPLIM( pucStackLimit ) \

diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c
index c1185d8..393e21e 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 @@
     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 @@
                         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 */