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