void PendSV_Handler()

in device_firmware/freertos_kernel/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c [242:417]


void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
{
	__asm volatile
	(
	"	.syntax unified									\n"
	"	.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. */
	"													\n"
	"	cbz r0, save_ns_context							\n" /* No secure context to save. */
	"	push {r0-r2, r14}								\n"
	"	bl SecureContext_SaveContext					\n"
	"	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. */
	"	ldr r3, pxCurrentTCBConst						\n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
	"	ldr r2, [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. */
	#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. */
	#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. */
	#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. */
	#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. */
	#endif /* configENABLE_MPU */
	"													\n"
	" select_next_task:									\n"
	"	cpsid i											\n"
	"	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. */
	"													\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. */
	#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"
	#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"
	#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. */
	"	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. */
	"	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"
	#endif /* configENABLE_MPU */
	);
}