From bf50aae69316095490f4da828b1c2cf93842d967 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Wed, 12 Feb 2020 00:48:19 -0800 Subject: [PATCH] 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 --- arch/xtensa/core/xtensa-asm2-util.S | 4 ++++ arch/xtensa/include/xtensa-asm2-context.h | 24 +++++++++++++++++++++-- arch/xtensa/include/xtensa-asm2-s.h | 4 ++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/arch/xtensa/core/xtensa-asm2-util.S b/arch/xtensa/core/xtensa-asm2-util.S index 1ee56a33c43..e14d4cf970a 100644 --- a/arch/xtensa/core/xtensa-asm2-util.S +++ b/arch/xtensa/core/xtensa-asm2-util.S @@ -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 diff --git a/arch/xtensa/include/xtensa-asm2-context.h b/arch/xtensa/include/xtensa-asm2-context.h index 2860b7198c7..620e256a916 100644 --- a/arch/xtensa/include/xtensa-asm2-context.h +++ b/arch/xtensa/include/xtensa-asm2-context.h @@ -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_ */ diff --git a/arch/xtensa/include/xtensa-asm2-s.h b/arch/xtensa/include/xtensa-asm2-s.h index 7361efae4ef..9f85e7d0cae 100644 --- a/arch/xtensa/include/xtensa-asm2-s.h +++ b/arch/xtensa/include/xtensa-asm2-s.h @@ -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 /*