tests: arm thread swap: save and restore callee-saved in subroutine

Temporarily save and restore all callee-saved registers
in the sub-routine, not only the frame pointer, to avoid
errors if compiler chooses to use them in the alternative
thread function. The callee-saved regs are restored after
the alternative thread switches back in.

Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
This commit is contained in:
Ioannis Glaropoulos 2021-02-16 20:42:58 +01:00
commit 407c76d54f

View file

@ -319,6 +319,14 @@ static void alt_thread_entry(void)
*/ */
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
__asm__ volatile ( __asm__ volatile (
"push {r4,r5,r6,r7};\n\t"
"mov r4, r8;\n\t"
"mov r5, r9;\n\t"
"push {r4, r5};\n\t"
"mov r4, r10;\n\t"
"mov r5, r11;\n\t"
"push {r4, r5};\n\t"
"push {r0, r1};\n\t"
"mov r1, r7;\n\t" "mov r1, r7;\n\t"
"mov r0, %0;\n\t" "mov r0, %0;\n\t"
"ldmia r0!, {r4-r7};\n\t" "ldmia r0!, {r4-r7};\n\t"
@ -328,14 +336,18 @@ static void alt_thread_entry(void)
"mov r10, r6;\n\t" "mov r10, r6;\n\t"
"mov r11, r7;\n\t" "mov r11, r7;\n\t"
"mov r7, r1;\n\t" "mov r7, r1;\n\t"
"pop {r0, r1};\n\t"
: : "r" (&ztest_thread_callee_saved_regs_container) : : "r" (&ztest_thread_callee_saved_regs_container)
: "memory" : "memory"
); );
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
__asm__ volatile ( __asm__ volatile (
"push {v1-v8};\n\t"
"push {r0, r1};\n\t"
"mov r0, r7;\n\t" "mov r0, r7;\n\t"
"ldmia %0, {v1-v8};\n\t" "ldmia %0, {v1-v8};\n\t"
"mov r7, r0;\n\t" "mov r7, r0;\n\t"
"pop {r0, r1};\n\t"
: : "r" (&ztest_thread_callee_saved_regs_container) : : "r" (&ztest_thread_callee_saved_regs_container)
: "memory" : "memory"
); );
@ -348,6 +360,24 @@ static void alt_thread_entry(void)
SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
irq_unlock(0); irq_unlock(0);
/* Restore stacked callee-saved registers */
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
__asm__ volatile (
"pop {r4, r5, r6, r7};\n\t"
"mov r8, r4;\n\t"
"mov r9, r5;\n\t"
"mov r10, r6;\n\t"
"mov r11, r7;\n\t"
"pop {r4, r5, r6, r7};\n\t"
: : :
);
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
__asm__ volatile (
"pop {v1-v8};\n\t"
: : :
);
#endif
/* Verify that the main test thread has managed to resume, before /* Verify that the main test thread has managed to resume, before
* we return to the alternative thread (we verify this by checking * we return to the alternative thread (we verify this by checking
* the status of the switch flag; the main test thread will clear * the status of the switch flag; the main test thread will clear