mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
freertos: Xtensa FreeRTOS saves threadptr in solicited stack frame
The Xtensa FreeRTOS port does not save the threadptr register when doing a voluntary yield. This can result in a crash when multiple tasks used the threadptr register and call "taskYIELD()". This commit adds the threadptr register to the solicited stack frame.
This commit is contained in:
parent
c9140caf8c
commit
c26d2ad132
@ -449,6 +449,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
|
||||
@ -536,6 +540,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
|
||||
|
@ -188,6 +188,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 (meaning 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:
|
||||
@ -204,7 +212,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)
|
||||
@ -213,7 +225,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)
|
||||
|
Loading…
Reference in New Issue
Block a user