arch/xtensa: Refactor the differences in ABI calls.
Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
This commit is contained in:
parent
48f20af8bc
commit
1c94cb5324
@ -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.
|
||||
|
@ -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 ARG2, a12 /* Argument 2: Top of stack = register save area */
|
||||
CALL xtensa_int_decode
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
/* 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 */
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
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.
|
||||
*/
|
||||
/* 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
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
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 */
|
||||
|
||||
/* 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.
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#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.
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user