diff options
Diffstat (limited to 'arch/xtensa/include')
-rw-r--r-- | arch/xtensa/include/asm/asmmacro.h | 65 | ||||
-rw-r--r-- | arch/xtensa/include/asm/atomic.h | 26 | ||||
-rw-r--r-- | arch/xtensa/include/asm/cmpxchg.h | 16 | ||||
-rw-r--r-- | arch/xtensa/include/asm/core.h | 11 | ||||
-rw-r--r-- | arch/xtensa/include/asm/processor.h | 32 | ||||
-rw-r--r-- | arch/xtensa/include/asm/sections.h | 41 | ||||
-rw-r--r-- | arch/xtensa/include/asm/traps.h | 2 |
7 files changed, 166 insertions, 27 deletions
diff --git a/arch/xtensa/include/asm/asmmacro.h b/arch/xtensa/include/asm/asmmacro.h index bfc89e11f469..809c507d1825 100644 --- a/arch/xtensa/include/asm/asmmacro.h +++ b/arch/xtensa/include/asm/asmmacro.h @@ -194,6 +194,12 @@ #define XTENSA_STACK_ALIGNMENT 16 #if defined(__XTENSA_WINDOWED_ABI__) + +/* Assembly instructions for windowed kernel ABI. */ +#define KABI_W +/* Assembly instructions for call0 kernel ABI (will be ignored). */ +#define KABI_C0 # + #define XTENSA_FRAME_SIZE_RESERVE 16 #define XTENSA_SPILL_STACK_RESERVE 32 @@ -206,8 +212,34 @@ #define abi_ret(frame_size) retw #define abi_ret_default retw + /* direct call */ +#define abi_call call4 + /* indirect call */ +#define abi_callx callx4 + /* outgoing call argument registers */ +#define abi_arg0 a6 +#define abi_arg1 a7 +#define abi_arg2 a8 +#define abi_arg3 a9 +#define abi_arg4 a10 +#define abi_arg5 a11 + /* return value */ +#define abi_rv a6 + /* registers preserved across call */ +#define abi_saved0 a2 +#define abi_saved1 a3 + + /* none of the above */ +#define abi_tmp0 a4 +#define abi_tmp1 a5 + #elif defined(__XTENSA_CALL0_ABI__) +/* Assembly instructions for windowed kernel ABI (will be ignored). */ +#define KABI_W # +/* Assembly instructions for call0 kernel ABI. */ +#define KABI_C0 + #define XTENSA_SPILL_STACK_RESERVE 0 #define abi_entry(frame_size) __abi_entry (frame_size) @@ -233,10 +265,43 @@ #define abi_ret_default ret + /* direct call */ +#define abi_call call0 + /* indirect call */ +#define abi_callx callx0 + /* outgoing call argument registers */ +#define abi_arg0 a2 +#define abi_arg1 a3 +#define abi_arg2 a4 +#define abi_arg3 a5 +#define abi_arg4 a6 +#define abi_arg5 a7 + /* return value */ +#define abi_rv a2 + /* registers preserved across call */ +#define abi_saved0 a12 +#define abi_saved1 a13 + + /* none of the above */ +#define abi_tmp0 a8 +#define abi_tmp1 a9 + #else #error Unsupported Xtensa ABI #endif +#if defined(USER_SUPPORT_WINDOWED) +/* Assembly instructions for windowed user ABI. */ +#define UABI_W +/* Assembly instructions for call0 user ABI (will be ignored). */ +#define UABI_C0 # +#else +/* Assembly instructions for windowed user ABI (will be ignored). */ +#define UABI_W # +/* Assembly instructions for call0 user ABI. */ +#define UABI_C0 +#endif + #define __XTENSA_HANDLER .section ".exception.text", "ax" #endif /* _XTENSA_ASMMACRO_H */ diff --git a/arch/xtensa/include/asm/atomic.h b/arch/xtensa/include/asm/atomic.h index 4361fe4247e3..52da614f953c 100644 --- a/arch/xtensa/include/asm/atomic.h +++ b/arch/xtensa/include/asm/atomic.h @@ -25,15 +25,15 @@ * * Locking interrupts looks like this: * - * rsil a15, TOPLEVEL + * rsil a14, TOPLEVEL * <code> - * wsr a15, PS + * wsr a14, PS * rsync * - * Note that a15 is used here because the register allocation + * Note that a14 is used here because the register allocation * done by the compiler is not guaranteed and a window overflow * may not occur between the rsil and wsr instructions. By using - * a15 in the rsil, the machine is guaranteed to be in a state + * a14 in the rsil, the machine is guaranteed to be in a state * where no register reference will cause an overflow. */ @@ -185,15 +185,15 @@ static inline void arch_atomic_##op(int i, atomic_t * v) \ unsigned int vval; \ \ __asm__ __volatile__( \ - " rsil a15, "__stringify(TOPLEVEL)"\n" \ + " rsil a14, "__stringify(TOPLEVEL)"\n" \ " l32i %[result], %[mem]\n" \ " " #op " %[result], %[result], %[i]\n" \ " s32i %[result], %[mem]\n" \ - " wsr a15, ps\n" \ + " wsr a14, ps\n" \ " rsync\n" \ : [result] "=&a" (vval), [mem] "+m" (*v) \ : [i] "a" (i) \ - : "a15", "memory" \ + : "a14", "memory" \ ); \ } \ @@ -203,15 +203,15 @@ static inline int arch_atomic_##op##_return(int i, atomic_t * v) \ unsigned int vval; \ \ __asm__ __volatile__( \ - " rsil a15,"__stringify(TOPLEVEL)"\n" \ + " rsil a14,"__stringify(TOPLEVEL)"\n" \ " l32i %[result], %[mem]\n" \ " " #op " %[result], %[result], %[i]\n" \ " s32i %[result], %[mem]\n" \ - " wsr a15, ps\n" \ + " wsr a14, ps\n" \ " rsync\n" \ : [result] "=&a" (vval), [mem] "+m" (*v) \ : [i] "a" (i) \ - : "a15", "memory" \ + : "a14", "memory" \ ); \ \ return vval; \ @@ -223,16 +223,16 @@ static inline int arch_atomic_fetch_##op(int i, atomic_t * v) \ unsigned int tmp, vval; \ \ __asm__ __volatile__( \ - " rsil a15,"__stringify(TOPLEVEL)"\n" \ + " rsil a14,"__stringify(TOPLEVEL)"\n" \ " l32i %[result], %[mem]\n" \ " " #op " %[tmp], %[result], %[i]\n" \ " s32i %[tmp], %[mem]\n" \ - " wsr a15, ps\n" \ + " wsr a14, ps\n" \ " rsync\n" \ : [result] "=&a" (vval), [tmp] "=&a" (tmp), \ [mem] "+m" (*v) \ : [i] "a" (i) \ - : "a15", "memory" \ + : "a14", "memory" \ ); \ \ return vval; \ diff --git a/arch/xtensa/include/asm/cmpxchg.h b/arch/xtensa/include/asm/cmpxchg.h index 3699e2818efb..eb87810357ad 100644 --- a/arch/xtensa/include/asm/cmpxchg.h +++ b/arch/xtensa/include/asm/cmpxchg.h @@ -52,16 +52,16 @@ __cmpxchg_u32(volatile int *p, int old, int new) return new; #else __asm__ __volatile__( - " rsil a15, "__stringify(TOPLEVEL)"\n" + " rsil a14, "__stringify(TOPLEVEL)"\n" " l32i %[old], %[mem]\n" " bne %[old], %[cmp], 1f\n" " s32i %[new], %[mem]\n" "1:\n" - " wsr a15, ps\n" + " wsr a14, ps\n" " rsync\n" : [old] "=&a" (old), [mem] "+m" (*p) : [cmp] "a" (old), [new] "r" (new) - : "a15", "memory"); + : "a14", "memory"); return old; #endif } @@ -116,10 +116,10 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, /* * xchg_u32 * - * Note that a15 is used here because the register allocation + * Note that a14 is used here because the register allocation * done by the compiler is not guaranteed and a window overflow * may not occur between the rsil and wsr instructions. By using - * a15 in the rsil, the machine is guaranteed to be in a state + * a14 in the rsil, the machine is guaranteed to be in a state * where no register reference will cause an overflow. */ @@ -157,14 +157,14 @@ static inline unsigned long xchg_u32(volatile int * m, unsigned long val) #else unsigned long tmp; __asm__ __volatile__( - " rsil a15, "__stringify(TOPLEVEL)"\n" + " rsil a14, "__stringify(TOPLEVEL)"\n" " l32i %[tmp], %[mem]\n" " s32i %[val], %[mem]\n" - " wsr a15, ps\n" + " wsr a14, ps\n" " rsync\n" : [tmp] "=&a" (tmp), [mem] "+m" (*m) : [val] "a" (val) - : "a15", "memory"); + : "a14", "memory"); return tmp; #endif } diff --git a/arch/xtensa/include/asm/core.h b/arch/xtensa/include/asm/core.h index 5590b0f68837..9138077e567d 100644 --- a/arch/xtensa/include/asm/core.h +++ b/arch/xtensa/include/asm/core.h @@ -26,4 +26,15 @@ #define XCHAL_SPANNING_WAY 0 #endif +#if XCHAL_HAVE_WINDOWED +#if defined(CONFIG_USER_ABI_DEFAULT) || defined(CONFIG_USER_ABI_CALL0_PROBE) +/* Whether windowed ABI is supported in userspace. */ +#define USER_SUPPORT_WINDOWED +#endif +#if defined(__XTENSA_WINDOWED_ABI__) || defined(USER_SUPPORT_WINDOWED) +/* Whether windowed ABI is supported either in userspace or in the kernel. */ +#define SUPPORT_WINDOWED +#endif +#endif + #endif diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index ad15fbc57283..37d3e9887fe7 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h @@ -18,12 +18,6 @@ #include <asm/types.h> #include <asm/regs.h> -/* Assertions. */ - -#if (XCHAL_HAVE_WINDOWED != 1) -# error Linux requires the Xtensa Windowed Registers Option. -#endif - /* Xtensa ABI requires stack alignment to be at least 16 */ #define STACK_ALIGN (XCHAL_DATA_WIDTH > 16 ? XCHAL_DATA_WIDTH : 16) @@ -105,8 +99,18 @@ #define WSBITS (XCHAL_NUM_AREGS / 4) /* width of WINDOWSTART in bits */ #define WBBITS (XCHAL_NUM_AREGS_LOG2 - 2) /* width of WINDOWBASE in bits */ +#if defined(__XTENSA_WINDOWED_ABI__) +#define KERNEL_PS_WOE_MASK PS_WOE_MASK +#elif defined(__XTENSA_CALL0_ABI__) +#define KERNEL_PS_WOE_MASK 0 +#else +#error Unsupported xtensa ABI +#endif + #ifndef __ASSEMBLY__ +#if defined(__XTENSA_WINDOWED_ABI__) + /* Build a valid return address for the specified call winsize. * winsize must be 1 (call4), 2 (call8), or 3 (call12) */ @@ -117,6 +121,22 @@ */ #define MAKE_PC_FROM_RA(ra,sp) (((ra) & 0x3fffffff) | ((sp) & 0xc0000000)) +#elif defined(__XTENSA_CALL0_ABI__) + +/* Build a valid return address for the specified call winsize. + * winsize must be 1 (call4), 2 (call8), or 3 (call12) + */ +#define MAKE_RA_FOR_CALL(ra, ws) (ra) + +/* Convert return address to a valid pc + * Note: We assume that the stack pointer is in the same 1GB ranges as the ra + */ +#define MAKE_PC_FROM_RA(ra, sp) (ra) + +#else +#error Unsupported Xtensa ABI +#endif + /* Spill slot location for the register reg in the spill area under the stack * pointer sp. reg must be in the range [0..4). */ diff --git a/arch/xtensa/include/asm/sections.h b/arch/xtensa/include/asm/sections.h new file mode 100644 index 000000000000..a8c42d08e281 --- /dev/null +++ b/arch/xtensa/include/asm/sections.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _XTENSA_SECTIONS_H +#define _XTENSA_SECTIONS_H + +#include <asm-generic/sections.h> + +#ifdef CONFIG_VECTORS_ADDR +extern char _WindowVectors_text_start[]; +extern char _WindowVectors_text_end[]; +extern char _DebugInterruptVector_text_start[]; +extern char _DebugInterruptVector_text_end[]; +extern char _KernelExceptionVector_text_start[]; +extern char _KernelExceptionVector_text_end[]; +extern char _UserExceptionVector_text_start[]; +extern char _UserExceptionVector_text_end[]; +extern char _DoubleExceptionVector_text_start[]; +extern char _DoubleExceptionVector_text_end[]; +extern char _exception_text_start[]; +extern char _exception_text_end[]; +extern char _Level2InterruptVector_text_start[]; +extern char _Level2InterruptVector_text_end[]; +extern char _Level3InterruptVector_text_start[]; +extern char _Level3InterruptVector_text_end[]; +extern char _Level4InterruptVector_text_start[]; +extern char _Level4InterruptVector_text_end[]; +extern char _Level5InterruptVector_text_start[]; +extern char _Level5InterruptVector_text_end[]; +extern char _Level6InterruptVector_text_start[]; +extern char _Level6InterruptVector_text_end[]; +#endif +#ifdef CONFIG_SMP +extern char _SecondaryResetVector_text_start[]; +extern char _SecondaryResetVector_text_end[]; +#endif +#ifdef CONFIG_XIP_KERNEL +extern char _xip_start[]; +extern char _xip_end[]; +#endif + +#endif diff --git a/arch/xtensa/include/asm/traps.h b/arch/xtensa/include/asm/traps.h index f720a57d0a5b..6fa47cd8e02d 100644 --- a/arch/xtensa/include/asm/traps.h +++ b/arch/xtensa/include/asm/traps.h @@ -56,6 +56,7 @@ void secondary_trap_init(void); static inline void spill_registers(void) { +#if defined(__XTENSA_WINDOWED_ABI__) #if XCHAL_NUM_AREGS > 16 __asm__ __volatile__ ( " call8 1f\n" @@ -96,6 +97,7 @@ static inline void spill_registers(void) " mov a12, a12\n" : : : "memory"); #endif +#endif } struct debug_table { |