xtensa: save/restore scompare1 during context switch

Xtensa uses two instructions to perform atomic compare-and-set
instruction: first the comparison register, then the actual
instruction to do compare-and-set. There is a potential that
context switching is performed before these two instructions.
A restored context may have the wrong value in the comparison
register. So we need to save and restore the comparison
register during context switching.

Fixes #21800

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
Daniel Leung 2020-02-12 00:48:19 -08:00 committed by Johan Hedberg
commit bf50aae693
3 changed files with 30 additions and 2 deletions

View file

@ -163,6 +163,10 @@ _restore_context:
wsr.LEND a0 wsr.LEND a0
l32i a0, a1, BSA_LCOUNT_OFF l32i a0, a1, BSA_LCOUNT_OFF
wsr.LCOUNT a0 wsr.LCOUNT a0
#endif
#if XCHAL_HAVE_S32C1I
l32i a0, a1, BSA_SCOMPARE1_OFF
wsr.SCOMPARE1 a0
#endif #endif
rsync rsync

View file

@ -34,6 +34,8 @@
* SP-52 Saved LEND special register (if loops enabled) * SP-52 Saved LEND special register (if loops enabled)
* SP-56 Saved LCOUNT special register (if loops enabled) * SP-56 Saved LCOUNT special register (if loops enabled)
* *
* SP-60 Saved SCOMPARE special register (if S32C1I enabled)
*
* (The above fixed-size region is known as the "base save area" in the * (The above fixed-size region is known as the "base save area" in the
* code below) * code below)
* *
@ -62,12 +64,25 @@
* original/interrupted stack pointer. * original/interrupted stack pointer.
*/ */
#define BASE_SAVE_AREA_SIZE_COMMON 44
#if XCHAL_HAVE_LOOPS #if XCHAL_HAVE_LOOPS
#define BASE_SAVE_AREA_SIZE 56 #define BASE_SAVE_AREA_SIZE_LOOPS 12
#else #else
#define BASE_SAVE_AREA_SIZE 44 #define BASE_SAVE_AREA_SIZE_LOOPS 0
#endif #endif
#if XCHAL_HAVE_S32C1I
#define BASE_SAVE_AREA_SIZE_SCOMPARE 4
#else
#define BASE_SAVE_AREA_SIZE_SCOMPARE 0
#endif
#define BASE_SAVE_AREA_SIZE \
(BASE_SAVE_AREA_SIZE_COMMON + \
BASE_SAVE_AREA_SIZE_LOOPS + \
BASE_SAVE_AREA_SIZE_SCOMPARE)
#define BSA_A3_OFF (BASE_SAVE_AREA_SIZE - 20) #define BSA_A3_OFF (BASE_SAVE_AREA_SIZE - 20)
#define BSA_A2_OFF (BASE_SAVE_AREA_SIZE - 24) #define BSA_A2_OFF (BASE_SAVE_AREA_SIZE - 24)
#define BSA_SCRATCH_OFF (BASE_SAVE_AREA_SIZE - 28) #define BSA_SCRATCH_OFF (BASE_SAVE_AREA_SIZE - 28)
@ -79,4 +94,9 @@
#define BSA_LEND_OFF (BASE_SAVE_AREA_SIZE - 52) #define BSA_LEND_OFF (BASE_SAVE_AREA_SIZE - 52)
#define BSA_LCOUNT_OFF (BASE_SAVE_AREA_SIZE - 56) #define BSA_LCOUNT_OFF (BASE_SAVE_AREA_SIZE - 56)
#define BSA_SCOMPARE1_OFF \
(BASE_SAVE_AREA_SIZE - \
(BASE_SAVE_AREA_SIZE_COMMON + \
BASE_SAVE_AREA_SIZE_LOOPS + 4))
#endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_ASM2_CONTEXT_H_ */ #endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_ASM2_CONTEXT_H_ */

View file

@ -110,6 +110,10 @@
rsr.LCOUNT a0 rsr.LCOUNT a0
s32i a0, a1, BSA_LCOUNT_OFF s32i a0, a1, BSA_LCOUNT_OFF
#endif #endif
#if XCHAL_HAVE_S32C1I
rsr.SCOMPARE1 a0
s32i a0, a1, BSA_SCOMPARE1_OFF
#endif
.endm .endm
/* /*