xtensa: change write intset register to syscall instruction

Signed-off-by: chenxiaoyi <chenxiaoyi@xiaomi.com>
This commit is contained in:
chenxiaoyi 2024-09-24 16:46:36 +08:00 committed by Xiang Xiao
parent 1757ecc5c1
commit aa426d1edb
7 changed files with 62 additions and 84 deletions

View file

@ -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;

View file

@ -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

View file

@ -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 */

View file

@ -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;
}

View file

@ -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

View file

@ -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) */

View file

@ -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). */