Merge branch 'bugfix/xtensa_sol_frame_saves_extra_registers' into 'master'

freertos: Xtensa solicited stack frame should save threadptr register

Closes IDF-5070

See merge request espressif/esp-idf!18468
This commit is contained in:
Darian 2022-06-16 07:13:16 +08:00
commit f6ef3480d1
3 changed files with 34 additions and 2 deletions

View File

@ -468,6 +468,10 @@ _frxt_dispatch:
.L_frxt_dispatch_sol:
/* Solicited stack frame. Restore minimal context and return from vPortYield(). */
#if XCHAL_HAVE_THREADPTR
l32i a2, sp, XT_SOL_THREADPTR
wur.threadptr a2
#endif
l32i a3, sp, XT_SOL_PS
#ifdef __XTENSA_CALL0_ABI__
l32i a12, sp, XT_SOL_A12
@ -555,6 +559,10 @@ vPortYield:
rsr a2, PS
s32i a0, sp, XT_SOL_PC
s32i a2, sp, XT_SOL_PS
#if XCHAL_HAVE_THREADPTR
rur.threadptr a2
s32i a2, sp, XT_SOL_THREADPTR
#endif
#ifdef __XTENSA_CALL0_ABI__
s32i a12, sp, XT_SOL_A12 /* save callee-saved registers */
s32i a13, sp, XT_SOL_A13

View File

@ -446,6 +446,10 @@ _frxt_dispatch:
.L_frxt_dispatch_sol:
/* Solicited stack frame. Restore minimal context and return from vPortYield(). */
#if XCHAL_HAVE_THREADPTR
l32i a2, sp, XT_SOL_THREADPTR
wur.threadptr a2
#endif
l32i a3, sp, XT_SOL_PS
#ifdef __XTENSA_CALL0_ABI__
l32i a12, sp, XT_SOL_A12
@ -533,6 +537,10 @@ vPortYield:
rsr a2, PS
s32i a0, sp, XT_SOL_PC
s32i a2, sp, XT_SOL_PS
#if XCHAL_HAVE_THREADPTR
rur.threadptr a2
s32i a2, sp, XT_SOL_THREADPTR
#endif
#ifdef __XTENSA_CALL0_ABI__
s32i a12, sp, XT_SOL_A12 /* save callee-saved registers */
s32i a13, sp, XT_SOL_A13

View File

@ -193,6 +193,14 @@ STRUCT_END(XtExcFrame)
by the callee according to the compiler's ABI conventions, some space to save
the return address for returning to the caller, and the caller's PS register.
Note: Although the xtensa ABI considers the threadptr as "global" across
functions (meanig it is neither caller or callee saved), it is treated as a
callee-saved register in a solicited stack frame. This omits the need for the
OS to include extra logic to save "global" registers on each context switch.
Only the threadptr register is treated as callee-saved, as all other NCP
(non-coprocessor extra) registers are caller-saved. See "tie.h" for more
details.
For Windowed ABI, this stack frame includes the caller's base save area.
Note on XT_SOL_EXIT field:
@ -209,7 +217,11 @@ STRUCT_BEGIN
STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit)
STRUCT_FIELD (long, 4, XT_SOL_PC, pc)
STRUCT_FIELD (long, 4, XT_SOL_PS, ps)
STRUCT_FIELD (long, 4, XT_SOL_NEXT, next)
#if XCHAL_HAVE_THREADPTR
STRUCT_FIELD (long, 4, XT_SOL_THREADPTR, threadptr)
#else
STRUCT_FIELD (long, 4, XT_SOL_NEXT, next) /* Dummy register for 16-byte alignment */
#endif
STRUCT_FIELD (long, 4, XT_SOL_A12, a12) /* should be on 16-byte alignment */
STRUCT_FIELD (long, 4, XT_SOL_A13, a13)
STRUCT_FIELD (long, 4, XT_SOL_A14, a14)
@ -218,7 +230,11 @@ STRUCT_FIELD (long, 4, XT_SOL_A15, a15)
STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit)
STRUCT_FIELD (long, 4, XT_SOL_PC, pc)
STRUCT_FIELD (long, 4, XT_SOL_PS, ps)
STRUCT_FIELD (long, 4, XT_SOL_NEXT, next)
#if XCHAL_HAVE_THREADPTR
STRUCT_FIELD (long, 4, XT_SOL_THREADPTR, threadptr)
#else
STRUCT_FIELD (long, 4, XT_SOL_NEXT, next) /* Dummy register for 16-byte alignment */
#endif
STRUCT_FIELD (long, 4, XT_SOL_A0, a0) /* should be on 16-byte alignment */
STRUCT_FIELD (long, 4, XT_SOL_A1, a1)
STRUCT_FIELD (long, 4, XT_SOL_A2, a2)