diff --git a/arch/xtensa/include/syscall.h b/arch/xtensa/include/syscall.h index 1d7326fa5b..07b81d4a5f 100644 --- a/arch/xtensa/include/syscall.h +++ b/arch/xtensa/include/syscall.h @@ -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; diff --git a/arch/xtensa/src/common/xtensa_dispatch_syscall.S b/arch/xtensa/src/common/xtensa_dispatch_syscall.S index 705e21fafa..46024fc162 100644 --- a/arch/xtensa/src/common/xtensa_dispatch_syscall.S +++ b/arch/xtensa/src/common/xtensa_dispatch_syscall.S @@ -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 diff --git a/arch/xtensa/src/common/xtensa_int_handlers.S b/arch/xtensa/src/common/xtensa_int_handlers.S index be6e407bf7..c63848d66c 100644 --- a/arch/xtensa/src/common/xtensa_int_handlers.S +++ b/arch/xtensa/src/common/xtensa_int_handlers.S @@ -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 */ diff --git a/arch/xtensa/src/common/xtensa_irqdispatch.c b/arch/xtensa/src/common/xtensa_irqdispatch.c index c1d28e49c5..0b3b26d17b 100644 --- a/arch/xtensa/src/common/xtensa_irqdispatch.c +++ b/arch/xtensa/src/common/xtensa_irqdispatch.c @@ -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; } diff --git a/arch/xtensa/src/common/xtensa_signal_handler.S b/arch/xtensa/src/common/xtensa_signal_handler.S index f5990a6b0b..935da317be 100644 --- a/arch/xtensa/src/common/xtensa_signal_handler.S +++ b/arch/xtensa/src/common/xtensa_signal_handler.S @@ -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 diff --git a/arch/xtensa/src/common/xtensa_user_handler.S b/arch/xtensa/src/common/xtensa_user_handler.S index ad5936f2d0..a178bd05a2 100644 --- a/arch/xtensa/src/common/xtensa_user_handler.S +++ b/arch/xtensa/src/common/xtensa_user_handler.S @@ -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) */ diff --git a/libs/libc/machine/xtensa/arch_setjmp.S b/libs/libc/machine/xtensa/arch_setjmp.S index 8f085fc22d..32217cfa60 100644 --- a/libs/libc/machine/xtensa/arch_setjmp.S +++ b/libs/libc/machine/xtensa/arch_setjmp.S @@ -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). */