Commit 00f178e1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'xtensa-20211105' of git://github.com/jcmvbkbc/linux-xtensa

Pull xtensa updates from Max Filippov:

 - add support for xtensa cores without windowed registers option

* tag 'xtensa-20211105' of git://github.com/jcmvbkbc/linux-xtensa:
  xtensa: move section symbols to asm/sections.h
  xtensa: remove unused variable wmask
  xtensa: only build windowed register support code when needed
  xtensa: use register window specific opcodes only when present
  xtensa: implement call0 ABI support in assembly
  xtensa: definitions for call0 ABI
  xtensa: don't use a12 in __xtensa_copy_user in call0 ABI
  xtensa: don't use a12 in strncpy_user
  xtensa: use a14 instead of a15 in inline assembly
  xtensa: move _SimulateUserKernelVectorException out of WindowVectors
parents 0b707e57 bd47cdb7
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -42,12 +42,14 @@ _bootparam:

	.align  4
_SetupMMU:
#if XCHAL_HAVE_WINDOWED
	movi	a0, 0
	wsr	a0, windowbase
	rsync
	movi	a0, 1
	wsr	a0, windowstart
	rsync
#endif
	movi	a0, 0x1F
	wsr	a0, ps
	rsync
+38 −34
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
#include <asm/regs.h>
#include <asm/asmmacro.h>
#include <asm/cacheasm.h>
#include <asm/processor.h>
	/*
	 * RB-Data: RedBoot data/bss
	 * P:	    Boot-Parameters
@@ -36,7 +37,7 @@
	.globl __start
	/* this must be the first byte of the loader! */
__start:
	entry	sp, 32		# we do not intend to return
	abi_entry(32)		# we do not intend to return
	_call0	_start
__start_a0:
	.align 4
@@ -55,17 +56,19 @@ _start:
	movi	a4, 1
	wsr	a4, ps
	rsync

#if XCHAL_HAVE_WINDOWED
	rsr	a5, windowbase
	ssl	a5
	sll	a4, a4
	wsr	a4, windowstart
	rsync

	movi	a4, 0x00040000
#endif
	movi	a4, KERNEL_PS_WOE_MASK
	wsr	a4, ps
	rsync

KABI_C0	mov	abi_saved0, abi_arg0

	/* copy the loader to its address
	 * Note: The loader itself is a very small piece, so we assume we
	 *       don't partially overlap. We also assume (even more important)
@@ -168,52 +171,52 @@ _reloc:

	movi	a3, __image_load
	sub	a4, a3, a4
	add	a8, a0, a4
	add	abi_arg2, a0, a4

	# a1  Stack
	# a8(a4)  Load address of the image

	movi	a6, _image_start
	movi	a10, _image_end
	movi	a7, 0x1000000
	sub	a11, a10, a6
	movi	a9, complen
	s32i	a11, a9, 0
	movi	abi_arg0, _image_start
	movi	abi_arg4, _image_end
	movi	abi_arg1, 0x1000000
	sub	abi_tmp0, abi_arg4, abi_arg0
	movi	abi_arg3, complen
	s32i	abi_tmp0, abi_arg3, 0

	movi	a0, 0

	# a6 destination
	# a7 maximum size of destination
	# a8 source
	# a9 ptr to length
	# abi_arg0 destination
	# abi_arg1 maximum size of destination
	# abi_arg2 source
	# abi_arg3 ptr to length

	.extern gunzip
	movi	a4, gunzip
	beqz	a4, 1f
	movi	abi_tmp0, gunzip
	beqz	abi_tmp0, 1f

	callx4	a4
	abi_callx	abi_tmp0

	j	2f


	# a6 destination start
	# a7 maximum size of destination
	# a8 source start
	# a9 ptr to length
	# a10 destination end
	# abi_arg0 destination start
	# abi_arg1 maximum size of destination
	# abi_arg2 source start
	# abi_arg3 ptr to length
	# abi_arg4 destination end

1:
        l32i    a9, a8, 0
        l32i    a11, a8, 4
        s32i    a9, a6, 0
        s32i    a11, a6, 4
        l32i    a9, a8, 8
        l32i    a11, a8, 12
        s32i    a9, a6, 8
        s32i    a11, a6, 12
        addi    a6, a6, 16
        addi    a8, a8, 16
        blt     a6, a10, 1b
        l32i    abi_tmp0, abi_arg2, 0
        l32i    abi_tmp1, abi_arg2, 4
        s32i    abi_tmp0, abi_arg0, 0
        s32i    abi_tmp1, abi_arg0, 4
        l32i    abi_tmp0, abi_arg2, 8
        l32i    abi_tmp1, abi_arg2, 12
        s32i    abi_tmp0, abi_arg0, 8
        s32i    abi_tmp1, abi_arg0, 12
        addi    abi_arg0, abi_arg0, 16
        addi    abi_arg2, abi_arg2, 16
        blt     abi_arg0, abi_arg4, 1b


	/* jump to the kernel */
@@ -230,6 +233,7 @@ _reloc:

	# a2  Boot parameter list

KABI_C0	mov	abi_arg0, abi_saved0
	movi	a0, _image_start
	jx	a0

+65 −0
Original line number Diff line number Diff line
@@ -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 */
+13 −13
Original line number Diff line number Diff line
@@ -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;							\
+8 −8
Original line number Diff line number Diff line
@@ -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
}
Loading