Skip to content

Commit c84fc72

Browse files
committed
armv8-m: Modify ARMv8-M registers stacking procedure
ARMv8-M TrustZone variant registers stacking procedure is modified to be consistent with the NTZ port variant where one `stmdb` instruction is used instead of using 'subs' instruction along with `stmia` instruction, also, this result in more efficient context switching handling (lower latency). Signed-off-by: Ahmed Ismail <Ahmed.Ismail@arm.com>
1 parent 3a7b308 commit c84fc72

File tree

10 files changed

+60
-130
lines changed

10 files changed

+60
-130
lines changed

portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -419,31 +419,24 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
419419
" 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. */
420420
" 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. */
421421
" \n"
422-
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
423-
" ldr r1, [r3] \n" /* Read pxCurrentTCB.*/
424-
" subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */
425-
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
426422
" mrs r1, psplim \n" /* r1 = PSPLIM. */
427423
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
428-
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
424+
" stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
429425
" b select_next_task \n"
430426
" \n"
431427
" save_ns_context: \n"
432-
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
433-
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
434428
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
435429
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
436430
" it eq \n"
437431
" vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
438432
#endif /* configENABLE_FPU || configENABLE_MVE */
439-
" subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
440-
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
441-
" adds r2, r2, #12 \n" /* r2 = r2 + 12. */
442-
" stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */
433+
" stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */
443434
" mrs r1, psplim \n" /* r1 = PSPLIM. */
444435
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
445-
" subs r2, r2, #12 \n" /* r2 = r2 - 12. */
446-
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
436+
" stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
437+
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
438+
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
439+
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
447440
" \n"
448441
" select_next_task: \n"
449442
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */

portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -381,31 +381,24 @@ PendSV_Handler:
381381
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. */
382382
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. */
383383

384-
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
385-
ldr r1, [r3] /* Read pxCurrentTCB. */
386-
subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */
387-
str r2, [r1] /* Save the new top of stack in TCB. */
388384
mrs r1, psplim /* r1 = PSPLIM. */
389385
mov r3, lr /* r3 = LR/EXC_RETURN. */
390-
stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */
386+
stmdb r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */
391387
b select_next_task
392388

393389
save_ns_context:
394-
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
395-
ldr r1, [r3] /* Read pxCurrentTCB. */
396390
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
397391
tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
398392
it eq
399393
vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */
400394
#endif /* configENABLE_FPU || configENABLE_MVE */
401-
subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
402-
str r2, [r1] /* Save the new top of stack in TCB. */
403-
adds r2, r2, #12 /* r2 = r2 + 12. */
404-
stm r2, {r4-r11} /* Store the registers that are not saved automatically. */
395+
stmdb r2!, {r4-r11} /* Store the registers that are not saved automatically. */
405396
mrs r1, psplim /* r1 = PSPLIM. */
406397
mov r3, lr /* r3 = LR/EXC_RETURN. */
407-
subs r2, r2, #12 /* r2 = r2 - 12. */
408-
stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */
398+
stmdb r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */
399+
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
400+
ldr r1, [r3] /* Read pxCurrentTCB. */
401+
str r2, [r1] /* Save the new top of stack in TCB. */
409402

410403
select_next_task:
411404
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY

portable/GCC/ARM_CM33/non_secure/portasm.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -419,31 +419,24 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
419419
" 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. */
420420
" 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. */
421421
" \n"
422-
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
423-
" ldr r1, [r3] \n" /* Read pxCurrentTCB.*/
424-
" subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */
425-
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
426422
" mrs r1, psplim \n" /* r1 = PSPLIM. */
427423
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
428-
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
424+
" stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
429425
" b select_next_task \n"
430426
" \n"
431427
" save_ns_context: \n"
432-
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
433-
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
434428
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
435429
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
436430
" it eq \n"
437431
" vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
438432
#endif /* configENABLE_FPU || configENABLE_MVE */
439-
" subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
440-
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
441-
" adds r2, r2, #12 \n" /* r2 = r2 + 12. */
442-
" stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */
433+
" stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */
443434
" mrs r1, psplim \n" /* r1 = PSPLIM. */
444435
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
445-
" subs r2, r2, #12 \n" /* r2 = r2 - 12. */
446-
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
436+
" stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
437+
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
438+
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
439+
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
447440
" \n"
448441
" select_next_task: \n"
449442
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */

portable/GCC/ARM_CM35P/non_secure/portasm.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -419,31 +419,24 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
419419
" 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. */
420420
" 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. */
421421
" \n"
422-
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
423-
" ldr r1, [r3] \n" /* Read pxCurrentTCB.*/
424-
" subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */
425-
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
426422
" mrs r1, psplim \n" /* r1 = PSPLIM. */
427423
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
428-
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
424+
" stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
429425
" b select_next_task \n"
430426
" \n"
431427
" save_ns_context: \n"
432-
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
433-
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
434428
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
435429
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
436430
" it eq \n"
437431
" vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
438432
#endif /* configENABLE_FPU || configENABLE_MVE */
439-
" subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
440-
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
441-
" adds r2, r2, #12 \n" /* r2 = r2 + 12. */
442-
" stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */
433+
" stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */
443434
" mrs r1, psplim \n" /* r1 = PSPLIM. */
444435
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
445-
" subs r2, r2, #12 \n" /* r2 = r2 - 12. */
446-
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
436+
" stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
437+
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
438+
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
439+
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
447440
" \n"
448441
" select_next_task: \n"
449442
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */

portable/GCC/ARM_CM55/non_secure/portasm.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -419,31 +419,24 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
419419
" 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. */
420420
" 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. */
421421
" \n"
422-
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
423-
" ldr r1, [r3] \n" /* Read pxCurrentTCB.*/
424-
" subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */
425-
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
426422
" mrs r1, psplim \n" /* r1 = PSPLIM. */
427423
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
428-
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
424+
" stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
429425
" b select_next_task \n"
430426
" \n"
431427
" save_ns_context: \n"
432-
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
433-
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
434428
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
435429
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
436430
" it eq \n"
437431
" vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
438432
#endif /* configENABLE_FPU || configENABLE_MVE */
439-
" subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
440-
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
441-
" adds r2, r2, #12 \n" /* r2 = r2 + 12. */
442-
" stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */
433+
" stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */
443434
" mrs r1, psplim \n" /* r1 = PSPLIM. */
444435
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
445-
" subs r2, r2, #12 \n" /* r2 = r2 - 12. */
446-
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
436+
" stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
437+
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
438+
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
439+
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
447440
" \n"
448441
" select_next_task: \n"
449442
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */

0 commit comments

Comments
 (0)