Skip to content

Commit

Permalink
Merge tag 'xtensa-20211105' of git://github.com/jcmvbkbc/linux-xtensa
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Linus Torvalds committed Nov 6, 2021
2 parents 0b707e5 + bd47cdb commit 00f178e
Show file tree
Hide file tree
Showing 21 changed files with 541 additions and 265 deletions.
2 changes: 2 additions & 0 deletions arch/xtensa/boot/boot-elf/bootstrap.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
72 changes: 38 additions & 34 deletions arch/xtensa/boot/boot-redboot/bootstrap.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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 */
Expand All @@ -230,6 +233,7 @@ _reloc:

# a2 Boot parameter list

KABI_C0 mov abi_arg0, abi_saved0
movi a0, _image_start
jx a0

Expand Down
65 changes: 65 additions & 0 deletions arch/xtensa/include/asm/asmmacro.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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)
Expand All @@ -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 */
26 changes: 13 additions & 13 deletions arch/xtensa/include/asm/atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/

Expand Down Expand Up @@ -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" \
); \
} \

Expand All @@ -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; \
Expand All @@ -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; \
Expand Down
16 changes: 8 additions & 8 deletions arch/xtensa/include/asm/cmpxchg.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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.
*/

Expand Down Expand Up @@ -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
}
Expand Down
11 changes: 11 additions & 0 deletions arch/xtensa/include/asm/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading

0 comments on commit 00f178e

Please sign in to comment.