This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 3942f4d13348e5034f50f694448d4e594fba3b65 Author: Abdelatif Guettouche <[email protected]> AuthorDate: Fri Apr 22 18:37:42 2022 +0200 arch/xtensa: No need to save SP in EXCSAVE_1 when linking the interrupt frame with the previous frame. The SP is already saved in A12. Signed-off-by: Abdelatif Guettouche <[email protected]> --- arch/xtensa/src/common/xtensa_int_handlers.S | 60 +++++++++------------------- arch/xtensa/src/common/xtensa_user_handler.S | 30 ++++++-------- 2 files changed, 31 insertions(+), 59 deletions(-) diff --git a/arch/xtensa/src/common/xtensa_int_handlers.S b/arch/xtensa/src/common/xtensa_int_handlers.S index fbcf025baf..0b40e4e3ab 100644 --- a/arch/xtensa/src/common/xtensa_int_handlers.S +++ b/arch/xtensa/src/common/xtensa_int_handlers.S @@ -188,27 +188,27 @@ g_intstacktop: and a6, a6, a3 /* a6 = Set of pending, enabled interrupts for this level */ beqz a6, 1f /* Nothing to do */ - /* At this point, the exception frame should have been allocated and filled, - * and current sp points to the interrupt stack (if enabled). Copy the - * pre-exception's base save area below the current SP. - */ + /* At this point, the exception frame should have been allocated and filled, + * and current sp points to the interrupt stack (if enabled). Copy the + * pre-exception's base save area below the current SP. We saved the SP in A12 + * before getting here. + */ #ifdef CONFIG_XTENSA_INTBACKTRACE - rsr a0, EXCSAVE_1 + \level - 1 /* Get exception frame pointer stored in EXCSAVE_x */ - l32i a3, a0, (4 * REG_A0) /* Copy pre-exception a0 (return address) */ - s32e a3, sp, -16 - l32i a3, a0, (4 * REG_A1) /* Copy pre-exception a1 (stack pointer) */ - s32e a3, sp, -12 - - /* Backtracing only needs a0 and a1, no need to create full base save area. - * Also need to change current frame's return address to point to pre-exception's - * last run instruction. - */ + l32i a3, a12, (4 * REG_A0) /* Copy pre-exception a0 (return address) */ + s32e a3, sp, -16 + l32i a3, a12, (4 * REG_A1) /* Copy pre-exception a1 (stack pointer) */ + s32e a3, sp, -12 + + /* Backtracing only needs a0 and a1, no need to create full base save area. + * Also need to change current frame's return address to point to pre-exception's + * last run instruction. + */ - rsr a0, EPC_1 + \level - 1 /* return address */ - movi a4, 0xc0000000 /* constant with top 2 bits set (call size) */ - or a0, a0, a4 /* set top 2 bits */ - addx2 a0, a4, a0 /* clear top bit -- simulating call4 size */ + rsr a0, EPC_1 + \level - 1 /* return address */ + movi a4, 0xc0000000 /* constant with top 2 bits set (call size) */ + or a0, a0, a4 /* set top 2 bits */ + addx2 a0, a4, a0 /* clear top bit -- simulating call4 size */ #endif /* Call xtensa_int_decode passing the address of the register save area @@ -305,10 +305,6 @@ _xtensa_level1_handler: s32i a0, sp, (4 * REG_A0) s32i a2, sp, (4 * REG_A2) -#ifdef CONFIG_XTENSA_INTBACKTRACE - wsr sp, EXCSAVE_1 -#endif - /* Save rest of interrupt context. */ call0 _xtensa_context_save @@ -407,10 +403,6 @@ _xtensa_level2_handler: s32i a0, sp, (4 * REG_A0) s32i a2, sp, (4 * REG_A2) -#ifdef CONFIG_XTENSA_INTBACKTRACE - wsr sp, EXCSAVE_2 -#endif - /* Save rest of interrupt context. */ call0 _xtensa_context_save @@ -484,10 +476,6 @@ _xtensa_level3_handler: s32i a0, sp, (4 * REG_A0) s32i a2, sp, (4 * REG_A2) -#ifdef CONFIG_XTENSA_INTBACKTRACE - wsr sp, EXCSAVE_3 -#endif - /* Save rest of interrupt context. */ call0 _xtensa_context_save @@ -561,10 +549,6 @@ _xtensa_level4_handler: s32i a0, sp, (4 * REG_A0) s32i a2, sp, (4 * REG_A2) -#ifdef CONFIG_XTENSA_INTBACKTRACE - wsr sp, EXCSAVE_4 -#endif - /* Save rest of interrupt context. */ call0 _xtensa_context_save @@ -638,10 +622,6 @@ _xtensa_level5_handler: s32i a0, sp, (4 * REG_A0) s32i a2, sp, (4 * REG_A2) -#ifdef CONFIG_XTENSA_INTBACKTRACE - wsr sp, EXCSAVE_5 -#endif - /* Save rest of interrupt context. */ call0 _xtensa_context_save @@ -715,10 +695,6 @@ _xtensa_level6_handler: s32i a0, sp, (4 * REG_A0) s32i a2, sp, (4 * REG_A2) -#ifdef CONFIG_XTENSA_INTBACKTRACE - wsr sp, EXCSAVE_6 -#endif - /* Save rest of interrupt context. */ call0 _xtensa_context_save /* Save full register state */ diff --git a/arch/xtensa/src/common/xtensa_user_handler.S b/arch/xtensa/src/common/xtensa_user_handler.S index 432c18ce06..61ef9c1742 100644 --- a/arch/xtensa/src/common/xtensa_user_handler.S +++ b/arch/xtensa/src/common/xtensa_user_handler.S @@ -220,10 +220,6 @@ _xtensa_user_handler: s32i a0, sp, (4 * REG_A0) s32i a2, sp, (4 * REG_A2) -#ifdef CONFIG_XTENSA_INTBACKTRACE - wsr sp, EXCSAVE_1 -#endif - /* Save EXCCAUSE and EXCVADDR into the user frame */ rsr a0, EXCCAUSE @@ -251,21 +247,21 @@ _xtensa_user_handler: ps_setup 1 a0 - /* Create pseudo base save area. At this point, sp is still pointing to the - * allocated and filled exception stack frame. - */ + /* Create pseudo base save area. At this point, a12 points to the + * allocated and filled exception stack frame (old value of SP in case of + * an interrupt stack). + */ #ifdef CONFIG_XTENSA_INTBACKTRACE - rsr a0, EXCSAVE_1 /* Get exception frame pointer stored in EXCSAVE_1 */ - l32i a3, a0, (4 * REG_A0) /* Copy pre-exception a0 (return address) */ - s32e a3, sp, -16 - l32i a3, a0, (4 * REG_A1) /* Copy pre-exception a1 (stack pointer) */ - s32e a3, sp, -12 - - rsr a0, EPC_1 /* return address for debug backtrace */ - movi a4, 0xc0000000 /* constant with top 2 bits set (call size) */ - or a0, a0, a4 /* set top 2 bits */ - addx2 a0, a4, a0 /* clear top bit -- thus simulating call4 size */ + l32i a3, a12, (4 * REG_A0) /* Copy pre-exception a0 (return address) */ + s32e a3, sp, -16 + l32i a3, a12, (4 * REG_A1) /* Copy pre-exception a1 (stack pointer) */ + s32e a3, sp, -12 + + rsr a0, EPC_1 /* return address for debug backtrace */ + movi a4, 0xc0000000 /* constant with top 2 bits set (call size) */ + or a0, a0, a4 /* set top 2 bits */ + addx2 a0, a4, a0 /* clear top bit -- thus simulating call4 size */ #endif /* Call xtensa_user, passing both the EXCCAUSE and a pointer to the
