mirror of
https://github.com/apache/nuttx.git
synced 2025-01-12 22:08:35 +08:00
xtensa: change write intset register to syscall instruction
Signed-off-by: chenxiaoyi <chenxiaoyi@xiaomi.com>
This commit is contained in:
parent
1757ecc5c1
commit
aa426d1edb
7 changed files with 62 additions and 84 deletions
|
@ -44,43 +44,6 @@
|
|||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Select software interrupt number for context-switch.
|
||||
* The SW interrupt level must be greater than XCHAL_SYSCALL_LEVEL
|
||||
* and less than XCHAL_EXCM_LEVEL.
|
||||
* So that we can generate an interrupt when up_irq_save is called.
|
||||
* and not generate interrupt when up_irq_disable is called.
|
||||
* Return an error if no suitable software interrupt was found.
|
||||
*/
|
||||
|
||||
#ifndef XTENSA_SWINT
|
||||
# ifdef XCHAL_SOFTWARE2_INTERRUPT
|
||||
# if XCHAL_INT_LEVEL(XCHAL_SOFTWARE2_INTERRUPT) > XCHAL_SYSCALL_LEVEL && \
|
||||
XCHAL_INT_LEVEL(XCHAL_SOFTWARE2_INTERRUPT) <= XCHAL_EXCM_LEVEL
|
||||
# undef XTENSA_SWINT
|
||||
# define XTENSA_SWINT XCHAL_SOFTWARE2_INTERRUPT
|
||||
# endif
|
||||
# endif
|
||||
# ifdef XCHAL_SOFTWARE1_INTERRUPT
|
||||
# if XCHAL_INT_LEVEL(XCHAL_SOFTWARE1_INTERRUPT) > XCHAL_SYSCALL_LEVEL && \
|
||||
XCHAL_INT_LEVEL(XCHAL_SOFTWARE1_INTERRUPT) <= XCHAL_EXCM_LEVEL
|
||||
# undef XTENSA_SWINT
|
||||
# define XTENSA_SWINT XCHAL_SOFTWARE1_INTERRUPT
|
||||
# endif
|
||||
# endif
|
||||
# ifdef XCHAL_SOFTWARE0_INTERRUPT
|
||||
# if XCHAL_INT_LEVEL(XCHAL_SOFTWARE0_INTERRUPT) > XCHAL_SYSCALL_LEVEL && \
|
||||
XCHAL_INT_LEVEL(XCHAL_SOFTWARE0_INTERRUPT) <= XCHAL_EXCM_LEVEL
|
||||
# undef XTENSA_SWINT
|
||||
# define XTENSA_SWINT XCHAL_SOFTWARE0_INTERRUPT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#ifndef XTENSA_SWINT
|
||||
# error "There is no suitable sw interrupt in this Xtensa configuration."
|
||||
#endif
|
||||
|
||||
#define XCHAL_SWINT_CALL (1 << XTENSA_SWINT)
|
||||
|
||||
#define SYS_syscall 0x00
|
||||
|
||||
/* This logic uses three system calls {0,1,2} for context switching and one
|
||||
|
@ -209,12 +172,10 @@ static inline uintptr_t sys_call0(unsigned int nbr)
|
|||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movi a3, %1\n"
|
||||
"wsr a3, intset\n"
|
||||
"rsync\n"
|
||||
"syscall\n"
|
||||
: "=r"(reg0)
|
||||
: "i"(XCHAL_SWINT_CALL), "r"(reg0)
|
||||
: "a3", "memory"
|
||||
: "r"(reg0)
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return reg0;
|
||||
|
@ -235,12 +196,10 @@ static inline uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1)
|
|||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movi a4, %1\n"
|
||||
"wsr a4, intset\n"
|
||||
"rsync\n"
|
||||
"syscall\n"
|
||||
: "=r"(reg0)
|
||||
: "i"(XCHAL_SWINT_CALL), "r"(reg0), "r"(reg1)
|
||||
: "a4", "memory"
|
||||
: "r"(reg0), "r"(reg1)
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return reg0;
|
||||
|
@ -263,12 +222,10 @@ static inline uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1,
|
|||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movi a5, %1\n"
|
||||
"wsr a5, intset\n"
|
||||
"rsync\n"
|
||||
"syscall\n"
|
||||
: "=r"(reg0)
|
||||
: "i"(XCHAL_SWINT_CALL), "r"(reg0), "r"(reg1), "r"(reg2)
|
||||
: "a5", "memory"
|
||||
: "r"(reg0), "r"(reg1), "r"(reg2)
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return reg0;
|
||||
|
@ -292,13 +249,11 @@ static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1,
|
|||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movi a6, %1\n"
|
||||
"wsr a6, intset\n"
|
||||
"rsync\n"
|
||||
"syscall\n"
|
||||
: "=r"(reg0)
|
||||
: "i"(XCHAL_SWINT_CALL), "r"(reg0), "r"(reg1), "r"(reg2),
|
||||
: "r"(reg0), "r"(reg1), "r"(reg2),
|
||||
"r"(reg3)
|
||||
: "a6", "memory"
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return reg0;
|
||||
|
@ -324,13 +279,11 @@ static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1,
|
|||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movi a7, %1\n"
|
||||
"wsr a7, intset\n"
|
||||
"rsync\n"
|
||||
"syscall\n"
|
||||
: "=r"(reg0)
|
||||
: "i"(XCHAL_SWINT_CALL), "r"(reg0), "r"(reg1), "r"(reg2),
|
||||
: "r"(reg0), "r"(reg1), "r"(reg2),
|
||||
"r"(reg3), "r"(reg4)
|
||||
: "a7", "memory"
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return reg0;
|
||||
|
@ -357,13 +310,11 @@ static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1,
|
|||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movi a8, %1\n"
|
||||
"wsr a8, intset\n"
|
||||
"rsync\n"
|
||||
"syscall\n"
|
||||
: "=r"(reg0)
|
||||
: "i"(XCHAL_SWINT_CALL), "r"(reg0), "r"(reg1), "r"(reg2),
|
||||
: "r"(reg0), "r"(reg1), "r"(reg2),
|
||||
"r"(reg3), "r"(reg4), "r"(reg5)
|
||||
: "a8", "memory"
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return reg0;
|
||||
|
@ -392,13 +343,11 @@ static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1,
|
|||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"movi a9, %1\n"
|
||||
"wsr a9, intset\n"
|
||||
"rsync\n"
|
||||
"syscall\n"
|
||||
: "=r"(reg0)
|
||||
: "i"(XCHAL_SWINT_CALL), "r"(reg0), "r"(reg1), "r"(reg2),
|
||||
: "r"(reg0), "r"(reg1), "r"(reg2),
|
||||
"r"(reg3), "r"(reg4), "r"(reg5), "r"(reg6)
|
||||
: "a9", "memory"
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return reg0;
|
||||
|
|
|
@ -97,9 +97,7 @@ xtensa_dispatch_syscall:
|
|||
/* Execute the SYS_signal_handler_return syscall (will not return) */
|
||||
|
||||
movi a2, SYS_syscall_return
|
||||
movi a4, XCHAL_SWINT_CALL
|
||||
wsr a4, INTSET
|
||||
rsync
|
||||
syscall
|
||||
|
||||
.size xtensa_dispatch_syscall, .-xtensa_dispatch_syscall
|
||||
|
||||
|
|
|
@ -193,6 +193,13 @@ _xtensa_level1_handler:
|
|||
|
||||
call0 _xtensa_context_save
|
||||
|
||||
/* Overwrite the PS saved by the exception entry. */
|
||||
|
||||
movi a2, ~PS_EXCM_MASK
|
||||
l32i a3, sp, (4 * REG_PS)
|
||||
and a3, a3, a2
|
||||
s32i a3, sp, (4 * REG_PS)
|
||||
|
||||
/* 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.
|
||||
|
@ -214,6 +221,13 @@ _xtensa_level1_handler:
|
|||
|
||||
dispatch_c_isr 1 XCHAL_INTLEVEL1_MASK a0
|
||||
|
||||
/* Set PS.EXCM to 1 */
|
||||
|
||||
movi a3, PS_EXCM_MASK
|
||||
l32i a4, a2, (4 * REG_PS)
|
||||
or a4, a3, a4
|
||||
s32i a4, a2, (4 * REG_PS)
|
||||
|
||||
/* Restore registers in preparation to return from interrupt */
|
||||
|
||||
call0 _xtensa_context_restore /* Preserves a2 */
|
||||
|
|
|
@ -69,7 +69,7 @@ uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs)
|
|||
* is invalid, and we can safely overwrite it.
|
||||
*/
|
||||
|
||||
if (!(XTENSA_IRQ_SWINT == irq && regs[REG_A2] == SYS_restore_context))
|
||||
if (!(XTENSA_IRQ_SYSCALL == irq && regs[REG_A2] == SYS_restore_context))
|
||||
{
|
||||
(*running_task)->xcp.regs = regs;
|
||||
}
|
||||
|
|
|
@ -79,9 +79,7 @@ up_signal_handler:
|
|||
/* Execute the SYS_signal_handler_return syscall (will not return) */
|
||||
|
||||
movi a2, SYS_signal_handler_return
|
||||
movi a3, XCHAL_SWINT_CALL
|
||||
wsr a3, INTSET
|
||||
rsync
|
||||
syscall
|
||||
|
||||
.size up_signal_handler, .-up_signal_handler
|
||||
|
||||
|
|
|
@ -189,6 +189,13 @@ _xtensa_user_handler:
|
|||
|
||||
mov a2, RETVAL /* a2 = address of new state save area */
|
||||
|
||||
/* Set PS.EXCM to 1 */
|
||||
|
||||
movi a3, PS_EXCM_MASK
|
||||
l32i a4, a2, (4 * REG_PS)
|
||||
or a4, a3, a4
|
||||
s32i a4, a2, (4 * REG_PS)
|
||||
|
||||
/* Restore registers in preparation to return from interrupt */
|
||||
|
||||
call0 _xtensa_context_restore /* (Preserves a2) */
|
||||
|
@ -231,6 +238,13 @@ _xtensa_syscall_handler:
|
|||
|
||||
call0 _xtensa_context_save
|
||||
|
||||
/* Overwrite the PS saved by the exception entry. */
|
||||
|
||||
movi a2, ~PS_EXCM_MASK
|
||||
l32i a3, sp, (4 * REG_PS)
|
||||
and a3, a3, a2
|
||||
s32i a3, sp, (4 * REG_PS)
|
||||
|
||||
/* Save EPC (note that this will overwrite the PC saved by the exception
|
||||
* entry with the correct value skipping the syscall instruction.)
|
||||
*/
|
||||
|
@ -261,8 +275,8 @@ _xtensa_syscall_handler:
|
|||
#else
|
||||
/* Get the interruptee's PC and skip over the 'syscall' instruction. */
|
||||
|
||||
rsr a1, EPC_1 /* a2 = PC of 'syscall' */
|
||||
addi a0, a1, 3 /* ++PC */
|
||||
rsr a2, EPC_1 /* a2 = PC of 'syscall' */
|
||||
addi a0, a2, 3 /* ++PC */
|
||||
|
||||
wsr a0, EPC_1 /* Update PC */
|
||||
s32i a0, sp, (4 * REG_PC)
|
||||
|
@ -300,6 +314,13 @@ _xtensa_syscall_handler:
|
|||
|
||||
mov a2, RETVAL /* Switch to the new register save area */
|
||||
|
||||
/* Set PS.EXCM to 1 */
|
||||
|
||||
movi a3, PS_EXCM_MASK
|
||||
l32i a4, a2, (4 * REG_PS)
|
||||
or a4, a3, a4
|
||||
s32i a4, a2, (4 * REG_PS)
|
||||
|
||||
/* Restore registers in preparation to return from interrupt */
|
||||
|
||||
call0 _xtensa_context_restore /* (Preserves a2) */
|
||||
|
|
|
@ -132,9 +132,7 @@ setjmp:
|
|||
/* Flush registers. */
|
||||
mov a4, a2 # save a2 (jmp_buf)
|
||||
movi a2, SYS_flush_context
|
||||
movi a3, XCHAL_SWINT_CALL
|
||||
wsr a3, intset
|
||||
isync
|
||||
syscall
|
||||
mov a2, a4 # restore a2
|
||||
|
||||
/* Copy the register save area at (sp - 16). */
|
||||
|
|
Loading…
Reference in a new issue