This is an automated email from the ASF dual-hosted git repository. pkarashchenko pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 1c94cb5324e9d91e0ed4611bf21ff4cff3230041 Author: Abdelatif Guettouche <[email protected]> AuthorDate: Sat Jun 11 16:05:19 2022 +0200 arch/xtensa: Refactor the differences in ABI calls. Signed-off-by: Abdelatif Guettouche <[email protected]> --- arch/xtensa/include/xtensa/xtensa_abi.h | 27 +++++++++- arch/xtensa/src/common/xtensa_int_handlers.S | 78 ++++++++-------------------- arch/xtensa/src/common/xtensa_panic.S | 20 +++---- arch/xtensa/src/common/xtensa_user_handler.S | 56 ++++++-------------- 4 files changed, 71 insertions(+), 110 deletions(-) diff --git a/arch/xtensa/include/xtensa/xtensa_abi.h b/arch/xtensa/include/xtensa/xtensa_abi.h index 123b003326..e3b7177a86 100644 --- a/arch/xtensa/include/xtensa/xtensa_abi.h +++ b/arch/xtensa/include/xtensa/xtensa_abi.h @@ -112,9 +112,10 @@ * Pre-processor Definitions ****************************************************************************/ -/* MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN +/* MACROS TO HANDLE ABI SPECIFICS OF FUNCTION CALL, ENTRY AND RETURN * * Convenient where the frame size requirements are the same for both ABIs. + * CALL, ARGx are used to make a call to a C function. * ENTRY(sz), RET(sz) are for framed functions (have locals or make calls). * ENTRY0, RET0 are for frameless functions (no locals, no calls). * @@ -149,6 +150,15 @@ # define RET(sz) ret1 sz # define RET0 ret +# define CALL call0 +# define ARG1 a2 +# define ARG2 a3 +# define ARG3 a4 +# define ARG4 a5 +# define ARG5 a6 +# define ARG6 a7 +# define RETVAL a2 + #else /* Windowed */ @@ -157,6 +167,21 @@ # define RET(sz) retw # define RET0 retw +/* These macros are used only in assembly code when calling C functions + * with CALL4. This is to help refactor common code with the CALL0 ABI. + * call0 can still be used to call assembly function not conforming to the + * windowed ABI. + */ + +# define CALL call4 +# define ARG1 a6 +# define ARG2 a7 +# define ARG3 a8 +# define ARG4 a9 +# define ARG5 a10 +# define ARG6 a11 +# define RETVAL a6 + #endif /* Index into stack frame. diff --git a/arch/xtensa/src/common/xtensa_int_handlers.S b/arch/xtensa/src/common/xtensa_int_handlers.S index 28946006f9..052cce6e0c 100644 --- a/arch/xtensa/src/common/xtensa_int_handlers.S +++ b/arch/xtensa/src/common/xtensa_int_handlers.S @@ -131,66 +131,32 @@ g_intstacktop: ps_setup \level \tmp -#ifdef __XTENSA_CALL0_ABI__ /* Get mask of pending, enabled interrupts at this level into a2. */ - rsr a2, INTENABLE + rsr ARG1, INTENABLE rsr a3, INTERRUPT movi a4, \mask - and a2, a2, a3 - and a2, a2, a4 /* a2 = Set of pending, enabled interrupts for this level */ - beqz a2, 1f /* Nothing to do */ + and ARG1, ARG1, a3 + and ARG1, ARG1, a4 /* Set of pending, enabled interrupts for this level */ + beqz ARG1, 1f /* Nothing to do */ - /* Call xtensa_int_decode passing the address of the register save area - * as a parameter (A3). - */ - - /* Argument 1: Set of CPU interrupt to dispatch */ - mov a3, a12 /* Argument 2: Top of stack = register save area */ - call0 xtensa_int_decode /* Call xtensa_int_decode */ - - /* On return from xtensa_int_decode, a2 will contain the address of the new - * register save area. Usually this would be the same as the current SP. - * But in the event of a context switch, a2 will instead refer to the TCB - * register save area. This may or may not reside on a stack. - */ - - mov a12, a2 /* Switch to the save area of the new thread */ - -#else - /* Get mask of pending, enabled interrupts at this level into a6. */ - - rsr a6, INTENABLE - rsr a2, INTERRUPT - movi a3, \mask - and a6, a6, a2 - 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. We saved the SP in A12 - * before getting here. + /* Link the pre-exception frame for debugging. At this point, a12 points to the + * allocated and filled exception stack frame (old value of SP in case of + * an interrupt stack). */ exception_backtrace a12 \level - /* Call xtensa_int_decode passing the address of the register save area - * as a parameter (A7). - */ - - /* Argument 1: Set of CPU interrupt to dispatch */ - mov a7, a12 /* Argument 2: Top of stack = register save area */ - call4 xtensa_int_decode /* Call xtensa_int_decode */ + /* Argument 1: Set of CPU interrupt to dispatch */ + mov ARG2, a12 /* Argument 2: Top of stack = register save area */ + CALL xtensa_int_decode - /* On return from xtensa_int_decode, a6 will contain the address of the new - * register save area. Usually this would be the same as the current SP. - * But in the event of a context switch, a6 will instead refer to the TCB - * register save area. This may or may not reside on a stack. + /* xtensa_int_decode returns the address of the new register save area. + * Usually this would be the same as the current SP. But in the event of + * a context switch, it will instead refer to the TCB register save area. */ - mov a12, a6 /* Switch to the save area of the new thread */ -#endif + mov a12, RETVAL /* Switch to the save area of the new thread */ #if CONFIG_ARCH_INTERRUPTSTACK < 15 addi sp, sp, XCPTCONTEXT_SIZE @@ -232,17 +198,17 @@ _xtensa_level1_handler: call0 _xtensa_context_save - /* Save current SP before (possibly) overwriting it, it's the register save - * area. This value will be used later by dispatch_c_isr to retrieve the - * register save area. - */ - - mov a12, sp + /* Save current SP before (possibly) overwriting it, it's the register save + * area. This value will be used later by dispatch_c_isr to retrieve the + * register save area. + */ + + mov a12, sp - /* Switch to an interrupt stack if we have one */ + /* Switch to an interrupt stack if we have one */ #if CONFIG_ARCH_INTERRUPTSTACK > 15 - setintstack a13 a14 + setintstack a13 a14 #endif /* Decode and dispatch the interrupt. In the event of an interrupt diff --git a/arch/xtensa/src/common/xtensa_panic.S b/arch/xtensa/src/common/xtensa_panic.S index dbd2ce7099..05eef85e6e 100644 --- a/arch/xtensa/src/common/xtensa_panic.S +++ b/arch/xtensa/src/common/xtensa_panic.S @@ -62,6 +62,7 @@ #include <arch/irq.h> #include <arch/xtensa/core.h> +#include <arch/xtensa/xtensa_abi.h> #include <arch/xtensa/xtensa_specregs.h> #include "xtensa_macros.S" @@ -129,21 +130,16 @@ _xtensa_panic: /* Set up PS for C, re-enable hi-pri interrupts, and clear EXCM. */ - ps_setup XCHAL_EXCM_LEVEL a0 + ps_setup XCHAL_EXCM_LEVEL a0 - /* Call C panic handler: Arg1 (A2) = Exception code; Arg 2 (A3) = start - * of the register save area. + /* Call C panic handler: + * Arg1 = Exception code. + * Arg 2 = Start of the register save area. */ -#ifdef __XTENSA_CALL0_ABI__ - rsr a2, EXCSAVE_1 - mov a3, a12 - call0 xtensa_panic /* Call xtensa_panic. Should not return */ -#else - rsr a6, EXCSAVE_1 - mov a7, a12 - call4 xtensa_panic /* Call xtensa_panic. Should not return */ -#endif + rsr ARG1, EXCSAVE_1 + mov ARG2, a12 + CALL xtensa_panic /* Call xtensa_panic. Should not return */ 1: j 1b /* loop infinitely */ retw diff --git a/arch/xtensa/src/common/xtensa_user_handler.S b/arch/xtensa/src/common/xtensa_user_handler.S index 47adb53634..dd5cd26da1 100644 --- a/arch/xtensa/src/common/xtensa_user_handler.S +++ b/arch/xtensa/src/common/xtensa_user_handler.S @@ -62,6 +62,7 @@ #include <arch/irq.h> #include <arch/xtensa/core.h> +#include <arch/xtensa/xtensa_abi.h> #include <arch/xtensa/xtensa_specregs.h> #include "xtensa_macros.S" @@ -184,7 +185,7 @@ _xtensa_user_handler: ps_setup 1 a0 - /* Create pseudo base save area. At this point, a12 points to the + /* Link the pre-exception frame for debugging. At this point, a12 points to the * allocated and filled exception stack frame (old value of SP in case of * an interrupt stack). */ @@ -195,16 +196,9 @@ _xtensa_user_handler: * beginning of the register save area. */ -#ifdef __XTENSA_CALL0_ABI__ - rsr a2, EXCCAUSE /* Argument 1 (a2) = EXCCAUSE */ - mov a3, a12 /* Argument 2 (a3) = pointer to register save area */ - calx0 xtensa_user /* Call xtensa_user */ -#else - rsr a6, EXCCAUSE /* Argument 1 (a6) = EXCCAUSE */ - mov a7, a12 /* Argument 2 (a7) = pointer to register save area */ - call4 xtensa_user /* Call xtensa_user */ - mov a12, a6 -#endif + rsr ARG1, EXCCAUSE /* Argument 1 = EXCCAUSE */ + mov ARG2, a12 /* Argument 2 = pointer to register save area */ + CALL xtensa_user /* Call xtensa_user */ /* Restore registers in preparation to return from interrupt */ @@ -312,30 +306,16 @@ _xtensa_syscall_handler: ps_setup 1 a0 -#ifdef __XTENSA_CALL0_ABI__ - movi a2, XTENSA_IRQ_SYSCALL /* Argument 1: IRQ number */ - mov a3, a12 /* Argument 2: Top of stack = register save area */ - call0 xtensa_irq_dispatch /* Call xtensa_int_decode */ - - /* On return from xtensa_irq_dispatch, A2 will contain the address of the new - * register save area. Usually this would be the same as the current SP. - * But in the event of a context switch, A2 will instead refer to the TCB - * register save area. - */ + movi ARG1, XTENSA_IRQ_SYSCALL /* Argument 1: IRQ number */ + mov ARG2, a12 /* Argument 2: Top of stack = register save area */ + CALL xtensa_irq_dispatch /* Call xtensa_int_decode */ -#else - movi a6, XTENSA_IRQ_SYSCALL /* Argument 1: IRQ number */ - mov a7, a12 /* Argument 2: Top of stack = register save area */ - call4 xtensa_irq_dispatch /* Call xtensa_int_decode */ - - /* On return from xtensa_irq_dispatch, A6 will contain the address of the new - * register save area. Usually this would be the same as the current SP. - * But in the event of a context switch, A6 will instead refer to the TCB - * register save area. + /* xtensa_irq_dispatch returns the address of the new register save area. + * Usually this would be the same as the current SP. But in the event of + * a context switch, it will instead refer to the TCB register save area. */ - mov a2, a6 /* Switch to the new register save area */ -#endif + mov a2, RETVAL /* Switch to the new register save area */ /* Restore registers in preparation to return from interrupt */ @@ -447,15 +427,9 @@ _xtensa_coproc_handler: * beginning of the register save area. */ -#ifdef __XTENSA_CALL0_ABI__ - rsr a2, EXCCAUSE /* Argument 1 (a2) = EXCCAUSE */ - mov a3, sp /* Argument 2 (a2) = pointer to register save area */ - calx0 xtensa_user_panic /* Call xtensa_user_panic */ -#else - rsr a6, EXCCAUSE /* Argument 1 (a2) = EXCCAUSE */ - mov a7, sp /* Argument 2 (a2) = pointer to register save area */ - call4 xtensa_user_panic /* Call xtensa_user_panic */ -#endif + rsr ARG1, EXCCAUSE /* Argument 1 = EXCCAUSE */ + mov ARG2, sp /* Argument 2 = pointer to register save area */ + CALL xtensa_user_panic /* Call xtensa_user_panic */ /* xtensa_user_panic should not return */
