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 * 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 #define SYS_syscall 0x00
/* This logic uses three system calls {0,1,2} for context switching and one /* 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__ __asm__ __volatile__
( (
"movi a3, %1\n" "syscall\n"
"wsr a3, intset\n"
"rsync\n"
: "=r"(reg0) : "=r"(reg0)
: "i"(XCHAL_SWINT_CALL), "r"(reg0) : "r"(reg0)
: "a3", "memory" : "memory"
); );
return reg0; return reg0;
@ -235,12 +196,10 @@ static inline uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1)
__asm__ __volatile__ __asm__ __volatile__
( (
"movi a4, %1\n" "syscall\n"
"wsr a4, intset\n"
"rsync\n"
: "=r"(reg0) : "=r"(reg0)
: "i"(XCHAL_SWINT_CALL), "r"(reg0), "r"(reg1) : "r"(reg0), "r"(reg1)
: "a4", "memory" : "memory"
); );
return reg0; return reg0;
@ -263,12 +222,10 @@ static inline uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1,
__asm__ __volatile__ __asm__ __volatile__
( (
"movi a5, %1\n" "syscall\n"
"wsr a5, intset\n"
"rsync\n"
: "=r"(reg0) : "=r"(reg0)
: "i"(XCHAL_SWINT_CALL), "r"(reg0), "r"(reg1), "r"(reg2) : "r"(reg0), "r"(reg1), "r"(reg2)
: "a5", "memory" : "memory"
); );
return reg0; return reg0;
@ -292,13 +249,11 @@ static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1,
__asm__ __volatile__ __asm__ __volatile__
( (
"movi a6, %1\n" "syscall\n"
"wsr a6, intset\n"
"rsync\n"
: "=r"(reg0) : "=r"(reg0)
: "i"(XCHAL_SWINT_CALL), "r"(reg0), "r"(reg1), "r"(reg2), : "r"(reg0), "r"(reg1), "r"(reg2),
"r"(reg3) "r"(reg3)
: "a6", "memory" : "memory"
); );
return reg0; return reg0;
@ -324,13 +279,11 @@ static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1,
__asm__ __volatile__ __asm__ __volatile__
( (
"movi a7, %1\n" "syscall\n"
"wsr a7, intset\n"
"rsync\n"
: "=r"(reg0) : "=r"(reg0)
: "i"(XCHAL_SWINT_CALL), "r"(reg0), "r"(reg1), "r"(reg2), : "r"(reg0), "r"(reg1), "r"(reg2),
"r"(reg3), "r"(reg4) "r"(reg3), "r"(reg4)
: "a7", "memory" : "memory"
); );
return reg0; return reg0;
@ -357,13 +310,11 @@ static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1,
__asm__ __volatile__ __asm__ __volatile__
( (
"movi a8, %1\n" "syscall\n"
"wsr a8, intset\n"
"rsync\n"
: "=r"(reg0) : "=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"(reg3), "r"(reg4), "r"(reg5)
: "a8", "memory" : "memory"
); );
return reg0; return reg0;
@ -392,13 +343,11 @@ static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1,
__asm__ __volatile__ __asm__ __volatile__
( (
"movi a9, %1\n" "syscall\n"
"wsr a9, intset\n"
"rsync\n"
: "=r"(reg0) : "=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) "r"(reg3), "r"(reg4), "r"(reg5), "r"(reg6)
: "a9", "memory" : "memory"
); );
return reg0; return reg0;

View file

@ -97,9 +97,7 @@ xtensa_dispatch_syscall:
/* Execute the SYS_signal_handler_return syscall (will not return) */ /* Execute the SYS_signal_handler_return syscall (will not return) */
movi a2, SYS_syscall_return movi a2, SYS_syscall_return
movi a4, XCHAL_SWINT_CALL syscall
wsr a4, INTSET
rsync
.size xtensa_dispatch_syscall, .-xtensa_dispatch_syscall .size xtensa_dispatch_syscall, .-xtensa_dispatch_syscall

View file

@ -193,6 +193,13 @@ _xtensa_level1_handler:
call0 _xtensa_context_save 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 /* 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 * area. This value will be used later by dispatch_c_isr to retrieve the
* register save area. * register save area.
@ -214,6 +221,13 @@ _xtensa_level1_handler:
dispatch_c_isr 1 XCHAL_INTLEVEL1_MASK a0 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 */ /* Restore registers in preparation to return from interrupt */
call0 _xtensa_context_restore /* Preserves a2 */ 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. * 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; (*running_task)->xcp.regs = regs;
} }

View file

@ -79,9 +79,7 @@ up_signal_handler:
/* Execute the SYS_signal_handler_return syscall (will not return) */ /* Execute the SYS_signal_handler_return syscall (will not return) */
movi a2, SYS_signal_handler_return movi a2, SYS_signal_handler_return
movi a3, XCHAL_SWINT_CALL syscall
wsr a3, INTSET
rsync
.size up_signal_handler, .-up_signal_handler .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 */ 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 */ /* Restore registers in preparation to return from interrupt */
call0 _xtensa_context_restore /* (Preserves a2) */ call0 _xtensa_context_restore /* (Preserves a2) */
@ -231,6 +238,13 @@ _xtensa_syscall_handler:
call0 _xtensa_context_save 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 /* Save EPC (note that this will overwrite the PC saved by the exception
* entry with the correct value skipping the syscall instruction.) * entry with the correct value skipping the syscall instruction.)
*/ */
@ -261,8 +275,8 @@ _xtensa_syscall_handler:
#else #else
/* Get the interruptee's PC and skip over the 'syscall' instruction. */ /* Get the interruptee's PC and skip over the 'syscall' instruction. */
rsr a1, EPC_1 /* a2 = PC of 'syscall' */ rsr a2, EPC_1 /* a2 = PC of 'syscall' */
addi a0, a1, 3 /* ++PC */ addi a0, a2, 3 /* ++PC */
wsr a0, EPC_1 /* Update PC */ wsr a0, EPC_1 /* Update PC */
s32i a0, sp, (4 * REG_PC) s32i a0, sp, (4 * REG_PC)
@ -300,6 +314,13 @@ _xtensa_syscall_handler:
mov a2, RETVAL /* Switch to the new register save area */ 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 */ /* Restore registers in preparation to return from interrupt */
call0 _xtensa_context_restore /* (Preserves a2) */ call0 _xtensa_context_restore /* (Preserves a2) */

View file

@ -132,9 +132,7 @@ setjmp:
/* Flush registers. */ /* Flush registers. */
mov a4, a2 # save a2 (jmp_buf) mov a4, a2 # save a2 (jmp_buf)
movi a2, SYS_flush_context movi a2, SYS_flush_context
movi a3, XCHAL_SWINT_CALL syscall
wsr a3, intset
isync
mov a2, a4 # restore a2 mov a2, a4 # restore a2
/* Copy the register save area at (sp - 16). */ /* Copy the register save area at (sp - 16). */