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
l32i a0, a1, BSA_LCOUNT_OFF
wsr.LCOUNT a0
#endif
#if XCHAL_HAVE_S32C1I
l32i a0, a1, BSA_SCOMPARE1_OFF
wsr.SCOMPARE1 a0
#endif
rsync

View file

@ -34,6 +34,8 @@
* SP-52 Saved LEND 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
* code below)
*
@ -62,12 +64,25 @@
* original/interrupted stack pointer.
*/
#define BASE_SAVE_AREA_SIZE_COMMON 44
#if XCHAL_HAVE_LOOPS
#define BASE_SAVE_AREA_SIZE 56
#define BASE_SAVE_AREA_SIZE_LOOPS 12
#else
#define BASE_SAVE_AREA_SIZE 44
#define BASE_SAVE_AREA_SIZE_LOOPS 0
#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_A2_OFF (BASE_SAVE_AREA_SIZE - 24)
#define BSA_SCRATCH_OFF (BASE_SAVE_AREA_SIZE - 28)
@ -79,4 +94,9 @@
#define BSA_LEND_OFF (BASE_SAVE_AREA_SIZE - 52)
#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_ */

View file

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