From c5c3fdd67bc9b4e598ca35ee9ba0c0304987aaca Mon Sep 17 00:00:00 2001 From: Wayne Ren Date: Wed, 25 Sep 2019 16:21:45 +0800 Subject: [PATCH] arch: arc: fix the bug in _firq_enter * In ARC, pop reg ==> sp=sp-4; *sp= b; The original codes have bug that the save of ilink (st ilink [sp]) will crash the interruptted stack's content. This commit fixes this bug and makes the codes easier to understand Signed-off-by: Wayne Ren --- arch/arc/core/fast_irq.S | 17 +++++++++++------ arch/arc/include/swap_macros.h | 12 ++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/arch/arc/core/fast_irq.S b/arch/arc/core/fast_irq.S index f14a541f5b1..19c83e06bab 100644 --- a/arch/arc/core/fast_irq.S +++ b/arch/arc/core/fast_irq.S @@ -101,20 +101,25 @@ firq_nest: * save original value of _ARC_V2_USER_SP and ilink into * the stack of interrupted context first, then restore them later */ - st ilink, [sp] - lr ilink, [_ARC_V2_USER_SP] - st ilink, [sp, -4] + push ilink + PUSHAX ilink, _ARC_V2_USER_SP + /* sp here is the sp of interrupted context */ sr sp, [_ARC_V2_USER_SP] + /* here, bank 0 sp must go back to the value before push and + * PUSHAX as we will switch to bank1, the pop and POPAX later will + * change bank1's sp, not bank0's sp + */ + add sp, sp, 8 /* switch back to banked reg, only ilink can be used */ lr ilink, [_ARC_V2_STATUS32] or ilink, ilink, _ARC_V2_STATUS32_RB(1) kflag ilink lr sp, [_ARC_V2_USER_SP] - ld ilink, [sp, -4] - sr ilink, [_ARC_V2_USER_SP] - ld ilink, [sp] + + POPAX ilink, _ARC_V2_USER_SP + pop ilink firq_nest_1: #else firq_nest: diff --git a/arch/arc/include/swap_macros.h b/arch/arc/include/swap_macros.h index 491a1af50ef..f92ac12f71c 100644 --- a/arch/arc/include/swap_macros.h +++ b/arch/arc/include/swap_macros.h @@ -365,6 +365,18 @@ #endif .endm +/* macro to push aux reg through reg */ +.macro PUSHAX reg aux + lr \reg, [\aux] + st.a \reg, [sp, -4] +.endm + +/* macro to pop aux reg through reg */ +.macro POPAX reg aux + ld.ab \reg, [sp, 4] + sr \reg, [\aux] +.endm + #endif /* _ASMLANGUAGE */ #endif /* ZEPHYR_ARCH_ARC_INCLUDE_SWAP_MACROS_H_ */