Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+541 -265
+2
arch/xtensa/boot/boot-elf/bootstrap.S
··· 42 42 43 43 .align 4 44 44 _SetupMMU: 45 + #if XCHAL_HAVE_WINDOWED 45 46 movi a0, 0 46 47 wsr a0, windowbase 47 48 rsync 48 49 movi a0, 1 49 50 wsr a0, windowstart 50 51 rsync 52 + #endif 51 53 movi a0, 0x1F 52 54 wsr a0, ps 53 55 rsync
+38 -34
arch/xtensa/boot/boot-redboot/bootstrap.S
··· 3 3 #include <asm/regs.h> 4 4 #include <asm/asmmacro.h> 5 5 #include <asm/cacheasm.h> 6 + #include <asm/processor.h> 6 7 /* 7 8 * RB-Data: RedBoot data/bss 8 9 * P: Boot-Parameters ··· 37 36 .globl __start 38 37 /* this must be the first byte of the loader! */ 39 38 __start: 40 - entry sp, 32 # we do not intend to return 39 + abi_entry(32) # we do not intend to return 41 40 _call0 _start 42 41 __start_a0: 43 42 .align 4 ··· 56 55 movi a4, 1 57 56 wsr a4, ps 58 57 rsync 59 - 58 + #if XCHAL_HAVE_WINDOWED 60 59 rsr a5, windowbase 61 60 ssl a5 62 61 sll a4, a4 63 62 wsr a4, windowstart 64 63 rsync 65 - 66 - movi a4, 0x00040000 64 + #endif 65 + movi a4, KERNEL_PS_WOE_MASK 67 66 wsr a4, ps 68 67 rsync 68 + 69 + KABI_C0 mov abi_saved0, abi_arg0 69 70 70 71 /* copy the loader to its address 71 72 * Note: The loader itself is a very small piece, so we assume we ··· 171 168 172 169 movi a3, __image_load 173 170 sub a4, a3, a4 174 - add a8, a0, a4 171 + add abi_arg2, a0, a4 175 172 176 173 # a1 Stack 177 174 # a8(a4) Load address of the image 178 175 179 - movi a6, _image_start 180 - movi a10, _image_end 181 - movi a7, 0x1000000 182 - sub a11, a10, a6 183 - movi a9, complen 184 - s32i a11, a9, 0 176 + movi abi_arg0, _image_start 177 + movi abi_arg4, _image_end 178 + movi abi_arg1, 0x1000000 179 + sub abi_tmp0, abi_arg4, abi_arg0 180 + movi abi_arg3, complen 181 + s32i abi_tmp0, abi_arg3, 0 185 182 186 183 movi a0, 0 187 184 188 - # a6 destination 189 - # a7 maximum size of destination 190 - # a8 source 191 - # a9 ptr to length 185 + # abi_arg0 destination 186 + # abi_arg1 maximum size of destination 187 + # abi_arg2 source 188 + # abi_arg3 ptr to length 192 189 193 190 .extern gunzip 194 - movi a4, gunzip 195 - beqz a4, 1f 191 + movi abi_tmp0, gunzip 192 + beqz abi_tmp0, 1f 196 193 197 - callx4 a4 194 + abi_callx abi_tmp0 198 195 199 196 j 2f 200 197 201 198 202 - # a6 destination start 203 - # a7 maximum size of destination 204 - # a8 source start 205 - # a9 ptr to length 206 - # a10 destination end 199 + # abi_arg0 destination start 200 + # abi_arg1 maximum size of destination 201 + # abi_arg2 source start 202 + # abi_arg3 ptr to length 203 + # abi_arg4 destination end 207 204 208 205 1: 209 - l32i a9, a8, 0 210 - l32i a11, a8, 4 211 - s32i a9, a6, 0 212 - s32i a11, a6, 4 213 - l32i a9, a8, 8 214 - l32i a11, a8, 12 215 - s32i a9, a6, 8 216 - s32i a11, a6, 12 217 - addi a6, a6, 16 218 - addi a8, a8, 16 219 - blt a6, a10, 1b 206 + l32i abi_tmp0, abi_arg2, 0 207 + l32i abi_tmp1, abi_arg2, 4 208 + s32i abi_tmp0, abi_arg0, 0 209 + s32i abi_tmp1, abi_arg0, 4 210 + l32i abi_tmp0, abi_arg2, 8 211 + l32i abi_tmp1, abi_arg2, 12 212 + s32i abi_tmp0, abi_arg0, 8 213 + s32i abi_tmp1, abi_arg0, 12 214 + addi abi_arg0, abi_arg0, 16 215 + addi abi_arg2, abi_arg2, 16 216 + blt abi_arg0, abi_arg4, 1b 220 217 221 218 222 219 /* jump to the kernel */ ··· 233 230 234 231 # a2 Boot parameter list 235 232 233 + KABI_C0 mov abi_arg0, abi_saved0 236 234 movi a0, _image_start 237 235 jx a0 238 236
+65
arch/xtensa/include/asm/asmmacro.h
··· 194 194 #define XTENSA_STACK_ALIGNMENT 16 195 195 196 196 #if defined(__XTENSA_WINDOWED_ABI__) 197 + 198 + /* Assembly instructions for windowed kernel ABI. */ 199 + #define KABI_W 200 + /* Assembly instructions for call0 kernel ABI (will be ignored). */ 201 + #define KABI_C0 # 202 + 197 203 #define XTENSA_FRAME_SIZE_RESERVE 16 198 204 #define XTENSA_SPILL_STACK_RESERVE 32 199 205 ··· 212 206 #define abi_ret(frame_size) retw 213 207 #define abi_ret_default retw 214 208 209 + /* direct call */ 210 + #define abi_call call4 211 + /* indirect call */ 212 + #define abi_callx callx4 213 + /* outgoing call argument registers */ 214 + #define abi_arg0 a6 215 + #define abi_arg1 a7 216 + #define abi_arg2 a8 217 + #define abi_arg3 a9 218 + #define abi_arg4 a10 219 + #define abi_arg5 a11 220 + /* return value */ 221 + #define abi_rv a6 222 + /* registers preserved across call */ 223 + #define abi_saved0 a2 224 + #define abi_saved1 a3 225 + 226 + /* none of the above */ 227 + #define abi_tmp0 a4 228 + #define abi_tmp1 a5 229 + 215 230 #elif defined(__XTENSA_CALL0_ABI__) 231 + 232 + /* Assembly instructions for windowed kernel ABI (will be ignored). */ 233 + #define KABI_W # 234 + /* Assembly instructions for call0 kernel ABI. */ 235 + #define KABI_C0 216 236 217 237 #define XTENSA_SPILL_STACK_RESERVE 0 218 238 ··· 265 233 266 234 #define abi_ret_default ret 267 235 236 + /* direct call */ 237 + #define abi_call call0 238 + /* indirect call */ 239 + #define abi_callx callx0 240 + /* outgoing call argument registers */ 241 + #define abi_arg0 a2 242 + #define abi_arg1 a3 243 + #define abi_arg2 a4 244 + #define abi_arg3 a5 245 + #define abi_arg4 a6 246 + #define abi_arg5 a7 247 + /* return value */ 248 + #define abi_rv a2 249 + /* registers preserved across call */ 250 + #define abi_saved0 a12 251 + #define abi_saved1 a13 252 + 253 + /* none of the above */ 254 + #define abi_tmp0 a8 255 + #define abi_tmp1 a9 256 + 268 257 #else 269 258 #error Unsupported Xtensa ABI 259 + #endif 260 + 261 + #if defined(USER_SUPPORT_WINDOWED) 262 + /* Assembly instructions for windowed user ABI. */ 263 + #define UABI_W 264 + /* Assembly instructions for call0 user ABI (will be ignored). */ 265 + #define UABI_C0 # 266 + #else 267 + /* Assembly instructions for windowed user ABI (will be ignored). */ 268 + #define UABI_W # 269 + /* Assembly instructions for call0 user ABI. */ 270 + #define UABI_C0 270 271 #endif 271 272 272 273 #define __XTENSA_HANDLER .section ".exception.text", "ax"
+13 -13
arch/xtensa/include/asm/atomic.h
··· 25 25 * 26 26 * Locking interrupts looks like this: 27 27 * 28 - * rsil a15, TOPLEVEL 28 + * rsil a14, TOPLEVEL 29 29 * <code> 30 - * wsr a15, PS 30 + * wsr a14, PS 31 31 * rsync 32 32 * 33 - * Note that a15 is used here because the register allocation 33 + * Note that a14 is used here because the register allocation 34 34 * done by the compiler is not guaranteed and a window overflow 35 35 * may not occur between the rsil and wsr instructions. By using 36 - * a15 in the rsil, the machine is guaranteed to be in a state 36 + * a14 in the rsil, the machine is guaranteed to be in a state 37 37 * where no register reference will cause an overflow. 38 38 */ 39 39 ··· 185 185 unsigned int vval; \ 186 186 \ 187 187 __asm__ __volatile__( \ 188 - " rsil a15, "__stringify(TOPLEVEL)"\n" \ 188 + " rsil a14, "__stringify(TOPLEVEL)"\n" \ 189 189 " l32i %[result], %[mem]\n" \ 190 190 " " #op " %[result], %[result], %[i]\n" \ 191 191 " s32i %[result], %[mem]\n" \ 192 - " wsr a15, ps\n" \ 192 + " wsr a14, ps\n" \ 193 193 " rsync\n" \ 194 194 : [result] "=&a" (vval), [mem] "+m" (*v) \ 195 195 : [i] "a" (i) \ 196 - : "a15", "memory" \ 196 + : "a14", "memory" \ 197 197 ); \ 198 198 } \ 199 199 ··· 203 203 unsigned int vval; \ 204 204 \ 205 205 __asm__ __volatile__( \ 206 - " rsil a15,"__stringify(TOPLEVEL)"\n" \ 206 + " rsil a14,"__stringify(TOPLEVEL)"\n" \ 207 207 " l32i %[result], %[mem]\n" \ 208 208 " " #op " %[result], %[result], %[i]\n" \ 209 209 " s32i %[result], %[mem]\n" \ 210 - " wsr a15, ps\n" \ 210 + " wsr a14, ps\n" \ 211 211 " rsync\n" \ 212 212 : [result] "=&a" (vval), [mem] "+m" (*v) \ 213 213 : [i] "a" (i) \ 214 - : "a15", "memory" \ 214 + : "a14", "memory" \ 215 215 ); \ 216 216 \ 217 217 return vval; \ ··· 223 223 unsigned int tmp, vval; \ 224 224 \ 225 225 __asm__ __volatile__( \ 226 - " rsil a15,"__stringify(TOPLEVEL)"\n" \ 226 + " rsil a14,"__stringify(TOPLEVEL)"\n" \ 227 227 " l32i %[result], %[mem]\n" \ 228 228 " " #op " %[tmp], %[result], %[i]\n" \ 229 229 " s32i %[tmp], %[mem]\n" \ 230 - " wsr a15, ps\n" \ 230 + " wsr a14, ps\n" \ 231 231 " rsync\n" \ 232 232 : [result] "=&a" (vval), [tmp] "=&a" (tmp), \ 233 233 [mem] "+m" (*v) \ 234 234 : [i] "a" (i) \ 235 - : "a15", "memory" \ 235 + : "a14", "memory" \ 236 236 ); \ 237 237 \ 238 238 return vval; \
+8 -8
arch/xtensa/include/asm/cmpxchg.h
··· 52 52 return new; 53 53 #else 54 54 __asm__ __volatile__( 55 - " rsil a15, "__stringify(TOPLEVEL)"\n" 55 + " rsil a14, "__stringify(TOPLEVEL)"\n" 56 56 " l32i %[old], %[mem]\n" 57 57 " bne %[old], %[cmp], 1f\n" 58 58 " s32i %[new], %[mem]\n" 59 59 "1:\n" 60 - " wsr a15, ps\n" 60 + " wsr a14, ps\n" 61 61 " rsync\n" 62 62 : [old] "=&a" (old), [mem] "+m" (*p) 63 63 : [cmp] "a" (old), [new] "r" (new) 64 - : "a15", "memory"); 64 + : "a14", "memory"); 65 65 return old; 66 66 #endif 67 67 } ··· 116 116 /* 117 117 * xchg_u32 118 118 * 119 - * Note that a15 is used here because the register allocation 119 + * Note that a14 is used here because the register allocation 120 120 * done by the compiler is not guaranteed and a window overflow 121 121 * may not occur between the rsil and wsr instructions. By using 122 - * a15 in the rsil, the machine is guaranteed to be in a state 122 + * a14 in the rsil, the machine is guaranteed to be in a state 123 123 * where no register reference will cause an overflow. 124 124 */ 125 125 ··· 157 157 #else 158 158 unsigned long tmp; 159 159 __asm__ __volatile__( 160 - " rsil a15, "__stringify(TOPLEVEL)"\n" 160 + " rsil a14, "__stringify(TOPLEVEL)"\n" 161 161 " l32i %[tmp], %[mem]\n" 162 162 " s32i %[val], %[mem]\n" 163 - " wsr a15, ps\n" 163 + " wsr a14, ps\n" 164 164 " rsync\n" 165 165 : [tmp] "=&a" (tmp), [mem] "+m" (*m) 166 166 : [val] "a" (val) 167 - : "a15", "memory"); 167 + : "a14", "memory"); 168 168 return tmp; 169 169 #endif 170 170 }
+11
arch/xtensa/include/asm/core.h
··· 26 26 #define XCHAL_SPANNING_WAY 0 27 27 #endif 28 28 29 + #if XCHAL_HAVE_WINDOWED 30 + #if defined(CONFIG_USER_ABI_DEFAULT) || defined(CONFIG_USER_ABI_CALL0_PROBE) 31 + /* Whether windowed ABI is supported in userspace. */ 32 + #define USER_SUPPORT_WINDOWED 33 + #endif 34 + #if defined(__XTENSA_WINDOWED_ABI__) || defined(USER_SUPPORT_WINDOWED) 35 + /* Whether windowed ABI is supported either in userspace or in the kernel. */ 36 + #define SUPPORT_WINDOWED 37 + #endif 38 + #endif 39 + 29 40 #endif
+26 -6
arch/xtensa/include/asm/processor.h
··· 18 18 #include <asm/types.h> 19 19 #include <asm/regs.h> 20 20 21 - /* Assertions. */ 22 - 23 - #if (XCHAL_HAVE_WINDOWED != 1) 24 - # error Linux requires the Xtensa Windowed Registers Option. 25 - #endif 26 - 27 21 /* Xtensa ABI requires stack alignment to be at least 16 */ 28 22 29 23 #define STACK_ALIGN (XCHAL_DATA_WIDTH > 16 ? XCHAL_DATA_WIDTH : 16) ··· 99 105 #define WSBITS (XCHAL_NUM_AREGS / 4) /* width of WINDOWSTART in bits */ 100 106 #define WBBITS (XCHAL_NUM_AREGS_LOG2 - 2) /* width of WINDOWBASE in bits */ 101 107 108 + #if defined(__XTENSA_WINDOWED_ABI__) 109 + #define KERNEL_PS_WOE_MASK PS_WOE_MASK 110 + #elif defined(__XTENSA_CALL0_ABI__) 111 + #define KERNEL_PS_WOE_MASK 0 112 + #else 113 + #error Unsupported xtensa ABI 114 + #endif 115 + 102 116 #ifndef __ASSEMBLY__ 117 + 118 + #if defined(__XTENSA_WINDOWED_ABI__) 103 119 104 120 /* Build a valid return address for the specified call winsize. 105 121 * winsize must be 1 (call4), 2 (call8), or 3 (call12) ··· 120 116 * Note: We assume that the stack pointer is in the same 1GB ranges as the ra 121 117 */ 122 118 #define MAKE_PC_FROM_RA(ra,sp) (((ra) & 0x3fffffff) | ((sp) & 0xc0000000)) 119 + 120 + #elif defined(__XTENSA_CALL0_ABI__) 121 + 122 + /* Build a valid return address for the specified call winsize. 123 + * winsize must be 1 (call4), 2 (call8), or 3 (call12) 124 + */ 125 + #define MAKE_RA_FOR_CALL(ra, ws) (ra) 126 + 127 + /* Convert return address to a valid pc 128 + * Note: We assume that the stack pointer is in the same 1GB ranges as the ra 129 + */ 130 + #define MAKE_PC_FROM_RA(ra, sp) (ra) 131 + 132 + #else 133 + #error Unsupported Xtensa ABI 134 + #endif 123 135 124 136 /* Spill slot location for the register reg in the spill area under the stack 125 137 * pointer sp. reg must be in the range [0..4).
+41
arch/xtensa/include/asm/sections.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #ifndef _XTENSA_SECTIONS_H 4 + #define _XTENSA_SECTIONS_H 5 + 6 + #include <asm-generic/sections.h> 7 + 8 + #ifdef CONFIG_VECTORS_ADDR 9 + extern char _WindowVectors_text_start[]; 10 + extern char _WindowVectors_text_end[]; 11 + extern char _DebugInterruptVector_text_start[]; 12 + extern char _DebugInterruptVector_text_end[]; 13 + extern char _KernelExceptionVector_text_start[]; 14 + extern char _KernelExceptionVector_text_end[]; 15 + extern char _UserExceptionVector_text_start[]; 16 + extern char _UserExceptionVector_text_end[]; 17 + extern char _DoubleExceptionVector_text_start[]; 18 + extern char _DoubleExceptionVector_text_end[]; 19 + extern char _exception_text_start[]; 20 + extern char _exception_text_end[]; 21 + extern char _Level2InterruptVector_text_start[]; 22 + extern char _Level2InterruptVector_text_end[]; 23 + extern char _Level3InterruptVector_text_start[]; 24 + extern char _Level3InterruptVector_text_end[]; 25 + extern char _Level4InterruptVector_text_start[]; 26 + extern char _Level4InterruptVector_text_end[]; 27 + extern char _Level5InterruptVector_text_start[]; 28 + extern char _Level5InterruptVector_text_end[]; 29 + extern char _Level6InterruptVector_text_start[]; 30 + extern char _Level6InterruptVector_text_end[]; 31 + #endif 32 + #ifdef CONFIG_SMP 33 + extern char _SecondaryResetVector_text_start[]; 34 + extern char _SecondaryResetVector_text_end[]; 35 + #endif 36 + #ifdef CONFIG_XIP_KERNEL 37 + extern char _xip_start[]; 38 + extern char _xip_end[]; 39 + #endif 40 + 41 + #endif
+2
arch/xtensa/include/asm/traps.h
··· 56 56 57 57 static inline void spill_registers(void) 58 58 { 59 + #if defined(__XTENSA_WINDOWED_ABI__) 59 60 #if XCHAL_NUM_AREGS > 16 60 61 __asm__ __volatile__ ( 61 62 " call8 1f\n" ··· 96 95 __asm__ __volatile__ ( 97 96 " mov a12, a12\n" 98 97 : : : "memory"); 98 + #endif 99 99 #endif 100 100 } 101 101
+2
arch/xtensa/kernel/align.S
··· 58 58 * BE shift left / mask 0 0 X X 59 59 */ 60 60 61 + #if XCHAL_HAVE_WINDOWED 61 62 #define UNALIGNED_USER_EXCEPTION 63 + #endif 62 64 63 65 #if XCHAL_HAVE_BE 64 66
+141 -75
arch/xtensa/kernel/entry.S
··· 158 158 /* Rotate ws so that the current windowbase is at bit0. */ 159 159 /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */ 160 160 161 + #if defined(USER_SUPPORT_WINDOWED) 161 162 rsr a2, windowbase 162 163 rsr a3, windowstart 163 164 ssr a2 ··· 168 167 src a2, a3, a2 169 168 srli a2, a2, 32-WSBITS 170 169 s32i a2, a1, PT_WMASK # needed for restoring registers 170 + #else 171 + movi a2, 0 172 + movi a3, 1 173 + s32i a2, a1, PT_WINDOWBASE 174 + s32i a3, a1, PT_WINDOWSTART 175 + s32i a3, a1, PT_WMASK 176 + #endif 171 177 172 178 /* Save only live registers. */ 173 179 174 - _bbsi.l a2, 1, 1f 180 + UABI_W _bbsi.l a2, 1, 1f 175 181 s32i a4, a1, PT_AREG4 176 182 s32i a5, a1, PT_AREG5 177 183 s32i a6, a1, PT_AREG6 178 184 s32i a7, a1, PT_AREG7 179 - _bbsi.l a2, 2, 1f 185 + UABI_W _bbsi.l a2, 2, 1f 180 186 s32i a8, a1, PT_AREG8 181 187 s32i a9, a1, PT_AREG9 182 188 s32i a10, a1, PT_AREG10 183 189 s32i a11, a1, PT_AREG11 184 - _bbsi.l a2, 3, 1f 190 + UABI_W _bbsi.l a2, 3, 1f 185 191 s32i a12, a1, PT_AREG12 186 192 s32i a13, a1, PT_AREG13 187 193 s32i a14, a1, PT_AREG14 188 194 s32i a15, a1, PT_AREG15 195 + 196 + #if defined(USER_SUPPORT_WINDOWED) 189 197 _bnei a2, 1, 1f # only one valid frame? 190 198 191 199 /* Only one valid frame, skip saving regs. */ ··· 249 239 rsync 250 240 251 241 /* We are back to the original stack pointer (a1) */ 252 - 242 + #endif 253 243 2: /* Now, jump to the common exception handler. */ 254 244 255 245 j common_exception ··· 305 295 s32i a3, a1, PT_SAR 306 296 s32i a2, a1, PT_ICOUNTLEVEL 307 297 298 + #if defined(__XTENSA_WINDOWED_ABI__) 308 299 /* Rotate ws so that the current windowbase is at bit0. */ 309 300 /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */ 310 301 ··· 316 305 src a2, a3, a2 317 306 srli a2, a2, 32-WSBITS 318 307 s32i a2, a1, PT_WMASK # needed for kernel_exception_exit 308 + #endif 319 309 320 310 /* Save only the live window-frame */ 321 311 322 - _bbsi.l a2, 1, 1f 312 + KABI_W _bbsi.l a2, 1, 1f 323 313 s32i a4, a1, PT_AREG4 324 314 s32i a5, a1, PT_AREG5 325 315 s32i a6, a1, PT_AREG6 326 316 s32i a7, a1, PT_AREG7 327 - _bbsi.l a2, 2, 1f 317 + KABI_W _bbsi.l a2, 2, 1f 328 318 s32i a8, a1, PT_AREG8 329 319 s32i a9, a1, PT_AREG9 330 320 s32i a10, a1, PT_AREG10 331 321 s32i a11, a1, PT_AREG11 332 - _bbsi.l a2, 3, 1f 322 + KABI_W _bbsi.l a2, 3, 1f 333 323 s32i a12, a1, PT_AREG12 334 324 s32i a13, a1, PT_AREG13 335 325 s32i a14, a1, PT_AREG14 336 326 s32i a15, a1, PT_AREG15 337 327 328 + #ifdef __XTENSA_WINDOWED_ABI__ 338 329 _bnei a2, 1, 1f 339 - 340 330 /* Copy spill slots of a0 and a1 to imitate movsp 341 331 * in order to keep exception stack continuous 342 332 */ ··· 345 333 l32i a0, a1, PT_SIZE + 4 346 334 s32e a3, a1, -16 347 335 s32e a0, a1, -12 336 + #endif 348 337 1: 349 338 l32i a0, a1, PT_AREG0 # restore saved a0 350 339 wsr a0, depc ··· 432 419 movi a3, LOCKLEVEL 433 420 434 421 .Lexception: 435 - movi a0, PS_WOE_MASK 436 - or a3, a3, a0 422 + KABI_W movi a0, PS_WOE_MASK 423 + KABI_W or a3, a3, a0 437 424 #else 438 425 addi a2, a2, -EXCCAUSE_LEVEL1_INTERRUPT 439 426 movi a0, LOCKLEVEL 440 427 extui a3, a3, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH 441 428 # a3 = PS.INTLEVEL 442 429 moveqz a3, a0, a2 # a3 = LOCKLEVEL iff interrupt 443 - movi a2, PS_WOE_MASK 444 - or a3, a3, a2 430 + KABI_W movi a2, PS_WOE_MASK 431 + KABI_W or a3, a3, a2 445 432 rsr a2, exccause 446 433 #endif 447 434 ··· 474 461 */ 475 462 476 463 rsr a4, excsave1 477 - mov a6, a1 # pass stack frame 478 - mov a7, a2 # pass EXCCAUSE 479 464 addx4 a4, a2, a4 480 465 l32i a4, a4, EXC_TABLE_DEFAULT # load handler 466 + mov abi_arg1, a2 # pass EXCCAUSE 467 + mov abi_arg0, a1 # pass stack frame 481 468 482 469 /* Call the second-level handler */ 483 470 484 - callx4 a4 471 + abi_callx a4 485 472 486 473 /* Jump here for exception exit */ 487 474 .global common_exception_return ··· 495 482 1: 496 483 irq_save a2, a3 497 484 #ifdef CONFIG_TRACE_IRQFLAGS 498 - call4 trace_hardirqs_off 485 + abi_call trace_hardirqs_off 499 486 #endif 500 487 501 488 /* Jump if we are returning from kernel exceptions. */ 502 489 503 - l32i a3, a1, PT_PS 490 + l32i abi_saved1, a1, PT_PS 504 491 GET_THREAD_INFO(a2, a1) 505 492 l32i a4, a2, TI_FLAGS 506 - _bbci.l a3, PS_UM_BIT, 6f 493 + _bbci.l abi_saved1, PS_UM_BIT, 6f 507 494 508 495 /* Specific to a user exception exit: 509 496 * We need to check some flags for signal handling and rescheduling, ··· 522 509 /* Call do_signal() */ 523 510 524 511 #ifdef CONFIG_TRACE_IRQFLAGS 525 - call4 trace_hardirqs_on 512 + abi_call trace_hardirqs_on 526 513 #endif 527 514 rsil a2, 0 528 - mov a6, a1 529 - call4 do_notify_resume # int do_notify_resume(struct pt_regs*) 515 + mov abi_arg0, a1 516 + abi_call do_notify_resume # int do_notify_resume(struct pt_regs*) 530 517 j 1b 531 518 532 519 3: /* Reschedule */ 533 520 534 521 #ifdef CONFIG_TRACE_IRQFLAGS 535 - call4 trace_hardirqs_on 522 + abi_call trace_hardirqs_on 536 523 #endif 537 524 rsil a2, 0 538 - call4 schedule # void schedule (void) 525 + abi_call schedule # void schedule (void) 539 526 j 1b 540 527 541 528 #ifdef CONFIG_PREEMPTION ··· 546 533 547 534 l32i a4, a2, TI_PRE_COUNT 548 535 bnez a4, 4f 549 - call4 preempt_schedule_irq 536 + abi_call preempt_schedule_irq 550 537 j 4f 551 538 #endif 552 539 553 540 #if XTENSA_FAKE_NMI 554 541 .LNMIexit: 555 - l32i a3, a1, PT_PS 556 - _bbci.l a3, PS_UM_BIT, 4f 542 + l32i abi_saved1, a1, PT_PS 543 + _bbci.l abi_saved1, PS_UM_BIT, 4f 557 544 #endif 558 545 559 546 5: 560 547 #ifdef CONFIG_HAVE_HW_BREAKPOINT 561 548 _bbci.l a4, TIF_DB_DISABLED, 7f 562 - call4 restore_dbreak 549 + abi_call restore_dbreak 563 550 7: 564 551 #endif 565 552 #ifdef CONFIG_DEBUG_TLB_SANITY 566 553 l32i a4, a1, PT_DEPC 567 554 bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f 568 - call4 check_tlb_sanity 555 + abi_call check_tlb_sanity 569 556 #endif 570 557 6: 571 558 4: 572 559 #ifdef CONFIG_TRACE_IRQFLAGS 573 - extui a4, a3, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH 560 + extui a4, abi_saved1, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH 574 561 bgei a4, LOCKLEVEL, 1f 575 - call4 trace_hardirqs_on 562 + abi_call trace_hardirqs_on 576 563 1: 577 564 #endif 578 565 /* Restore optional registers. */ ··· 585 572 l32i a2, a1, PT_SCOMPARE1 586 573 wsr a2, scompare1 587 574 #endif 588 - wsr a3, ps /* disable interrupts */ 575 + wsr abi_saved1, ps /* disable interrupts */ 589 576 590 - _bbci.l a3, PS_UM_BIT, kernel_exception_exit 577 + _bbci.l abi_saved1, PS_UM_BIT, kernel_exception_exit 591 578 592 579 user_exception_exit: 593 580 594 581 /* Restore the state of the task and return from the exception. */ 595 582 583 + #if defined(USER_SUPPORT_WINDOWED) 596 584 /* Switch to the user thread WINDOWBASE. Save SP temporarily in DEPC */ 597 585 598 586 l32i a2, a1, PT_WINDOWBASE ··· 648 634 * frame where we had loaded a2), or at least the lower 4 bits 649 635 * (if we have restored WSBITS-1 frames). 650 636 */ 651 - 652 637 2: 638 + #else 639 + movi a2, 1 640 + #endif 653 641 #if XCHAL_HAVE_THREADPTR 654 642 l32i a3, a1, PT_THREADPTR 655 643 wur a3, threadptr ··· 666 650 667 651 kernel_exception_exit: 668 652 653 + #if defined(__XTENSA_WINDOWED_ABI__) 669 654 /* Check if we have to do a movsp. 670 655 * 671 656 * We only have to do a movsp if the previous window-frame has ··· 719 702 * 720 703 * Note: We expect a2 to hold PT_WMASK 721 704 */ 705 + #else 706 + movi a2, 1 707 + #endif 722 708 723 709 common_exception_exit: 724 710 ··· 940 920 941 921 ENTRY(unrecoverable_exception) 942 922 923 + #if XCHAL_HAVE_WINDOWED 943 924 movi a0, 1 944 925 movi a1, 0 945 926 946 927 wsr a0, windowstart 947 928 wsr a1, windowbase 948 929 rsync 930 + #endif 949 931 950 - movi a1, PS_WOE_MASK | LOCKLEVEL 932 + movi a1, KERNEL_PS_WOE_MASK | LOCKLEVEL 951 933 wsr a1, ps 952 934 rsync 953 935 ··· 957 935 movi a0, 0 958 936 addi a1, a1, PT_REGS_OFFSET 959 937 960 - movi a6, unrecoverable_text 961 - call4 panic 938 + movi abi_arg0, unrecoverable_text 939 + abi_call panic 962 940 963 941 1: j 1b 964 942 ··· 969 947 __XTENSA_HANDLER 970 948 .literal_position 971 949 950 + #ifdef SUPPORT_WINDOWED 972 951 /* 973 952 * Fast-handler for alloca exceptions 974 953 * ··· 1033 1010 8: j _WindowUnderflow8 1034 1011 4: j _WindowUnderflow4 1035 1012 ENDPROC(fast_alloca) 1013 + #endif 1036 1014 1037 1015 #ifdef CONFIG_USER_ABI_CALL0_PROBE 1038 1016 /* ··· 1230 1206 * Note: We assume the stack pointer is EXC_TABLE_KSTK in the fixup handler. 1231 1207 */ 1232 1208 1233 - #ifdef CONFIG_FAST_SYSCALL_SPILL_REGISTERS 1209 + #if defined(CONFIG_FAST_SYSCALL_SPILL_REGISTERS) && \ 1210 + defined(USER_SUPPORT_WINDOWED) 1234 1211 1235 1212 ENTRY(fast_syscall_spill_registers) 1236 1213 ··· 1428 1403 rsr a3, excsave1 1429 1404 l32i a1, a3, EXC_TABLE_KSTK 1430 1405 1431 - movi a4, PS_WOE_MASK | LOCKLEVEL 1406 + movi a4, KERNEL_PS_WOE_MASK | LOCKLEVEL 1432 1407 wsr a4, ps 1433 1408 rsync 1434 1409 1435 - movi a6, SIGSEGV 1436 - call4 do_exit 1410 + movi abi_arg0, SIGSEGV 1411 + abi_call do_exit 1437 1412 1438 1413 /* shouldn't return, so panic */ 1439 1414 ··· 1912 1887 1913 1888 ENTRY(system_call) 1914 1889 1890 + #if defined(__XTENSA_WINDOWED_ABI__) 1915 1891 abi_entry_default 1892 + #elif defined(__XTENSA_CALL0_ABI__) 1893 + abi_entry(12) 1894 + 1895 + s32i a0, sp, 0 1896 + s32i abi_saved0, sp, 4 1897 + s32i abi_saved1, sp, 8 1898 + mov abi_saved0, a2 1899 + #else 1900 + #error Unsupported Xtensa ABI 1901 + #endif 1916 1902 1917 1903 /* regs->syscall = regs->areg[2] */ 1918 1904 1919 - l32i a7, a2, PT_AREG2 1920 - s32i a7, a2, PT_SYSCALL 1905 + l32i a7, abi_saved0, PT_AREG2 1906 + s32i a7, abi_saved0, PT_SYSCALL 1921 1907 1922 1908 GET_THREAD_INFO(a4, a1) 1923 - l32i a3, a4, TI_FLAGS 1909 + l32i abi_saved1, a4, TI_FLAGS 1924 1910 movi a4, _TIF_WORK_MASK 1925 - and a3, a3, a4 1926 - beqz a3, 1f 1911 + and abi_saved1, abi_saved1, a4 1912 + beqz abi_saved1, 1f 1927 1913 1928 - mov a6, a2 1929 - call4 do_syscall_trace_enter 1930 - beqz a6, .Lsyscall_exit 1931 - l32i a7, a2, PT_SYSCALL 1914 + mov abi_arg0, abi_saved0 1915 + abi_call do_syscall_trace_enter 1916 + beqz abi_rv, .Lsyscall_exit 1917 + l32i a7, abi_saved0, PT_SYSCALL 1932 1918 1933 1919 1: 1934 1920 /* syscall = sys_call_table[syscall_nr] */ 1935 1921 1936 1922 movi a4, sys_call_table 1937 1923 movi a5, __NR_syscalls 1938 - movi a6, -ENOSYS 1924 + movi abi_rv, -ENOSYS 1939 1925 bgeu a7, a5, 1f 1940 1926 1941 1927 addx4 a4, a7, a4 1942 - l32i a4, a4, 0 1928 + l32i abi_tmp0, a4, 0 1943 1929 1944 1930 /* Load args: arg0 - arg5 are passed via regs. */ 1945 1931 1946 - l32i a6, a2, PT_AREG6 1947 - l32i a7, a2, PT_AREG3 1948 - l32i a8, a2, PT_AREG4 1949 - l32i a9, a2, PT_AREG5 1950 - l32i a10, a2, PT_AREG8 1951 - l32i a11, a2, PT_AREG9 1932 + l32i abi_arg0, abi_saved0, PT_AREG6 1933 + l32i abi_arg1, abi_saved0, PT_AREG3 1934 + l32i abi_arg2, abi_saved0, PT_AREG4 1935 + l32i abi_arg3, abi_saved0, PT_AREG5 1936 + l32i abi_arg4, abi_saved0, PT_AREG8 1937 + l32i abi_arg5, abi_saved0, PT_AREG9 1952 1938 1953 - callx4 a4 1939 + abi_callx abi_tmp0 1954 1940 1955 1941 1: /* regs->areg[2] = return_value */ 1956 1942 1957 - s32i a6, a2, PT_AREG2 1958 - bnez a3, 1f 1943 + s32i abi_rv, abi_saved0, PT_AREG2 1944 + bnez abi_saved1, 1f 1959 1945 .Lsyscall_exit: 1946 + #if defined(__XTENSA_WINDOWED_ABI__) 1960 1947 abi_ret_default 1948 + #elif defined(__XTENSA_CALL0_ABI__) 1949 + l32i a0, sp, 0 1950 + l32i abi_saved0, sp, 4 1951 + l32i abi_saved1, sp, 8 1952 + abi_ret(12) 1953 + #else 1954 + #error Unsupported Xtensa ABI 1955 + #endif 1961 1956 1962 1957 1: 1963 - mov a6, a2 1964 - call4 do_syscall_trace_leave 1965 - abi_ret_default 1958 + mov abi_arg0, abi_saved0 1959 + abi_call do_syscall_trace_leave 1960 + j .Lsyscall_exit 1966 1961 1967 1962 ENDPROC(system_call) 1968 1963 ··· 2033 1988 2034 1989 ENTRY(_switch_to) 2035 1990 1991 + #if defined(__XTENSA_WINDOWED_ABI__) 2036 1992 abi_entry(XTENSA_SPILL_STACK_RESERVE) 1993 + #elif defined(__XTENSA_CALL0_ABI__) 1994 + abi_entry(16) 2037 1995 1996 + s32i a12, sp, 0 1997 + s32i a13, sp, 4 1998 + s32i a14, sp, 8 1999 + s32i a15, sp, 12 2000 + #else 2001 + #error Unsupported Xtensa ABI 2002 + #endif 2038 2003 mov a11, a3 # and 'next' (a3) 2039 2004 2040 2005 l32i a4, a2, TASK_THREAD_INFO ··· 2088 2033 2089 2034 /* Flush register file. */ 2090 2035 2036 + #if defined(__XTENSA_WINDOWED_ABI__) 2091 2037 spill_registers_kernel 2038 + #endif 2092 2039 2093 2040 /* Set kernel stack (and leave critical section) 2094 2041 * Note: It's save to set it here. The stack will not be overwritten ··· 2112 2055 wsr a14, ps 2113 2056 rsync 2114 2057 2058 + #if defined(__XTENSA_WINDOWED_ABI__) 2115 2059 abi_ret(XTENSA_SPILL_STACK_RESERVE) 2060 + #elif defined(__XTENSA_CALL0_ABI__) 2061 + l32i a12, sp, 0 2062 + l32i a13, sp, 4 2063 + l32i a14, sp, 8 2064 + l32i a15, sp, 12 2065 + abi_ret(16) 2066 + #else 2067 + #error Unsupported Xtensa ABI 2068 + #endif 2116 2069 2117 2070 ENDPROC(_switch_to) 2118 2071 2119 2072 ENTRY(ret_from_fork) 2120 2073 2121 2074 /* void schedule_tail (struct task_struct *prev) 2122 - * Note: prev is still in a6 (return value from fake call4 frame) 2075 + * Note: prev is still in abi_arg0 (return value from fake call frame) 2123 2076 */ 2124 - call4 schedule_tail 2077 + abi_call schedule_tail 2125 2078 2126 - mov a6, a1 2127 - call4 do_syscall_trace_leave 2128 - 2129 - j common_exception_return 2079 + mov abi_arg0, a1 2080 + abi_call do_syscall_trace_leave 2081 + j common_exception_return 2130 2082 2131 2083 ENDPROC(ret_from_fork) 2132 2084 2133 2085 /* 2134 2086 * Kernel thread creation helper 2135 - * On entry, set up by copy_thread: a2 = thread_fn, a3 = thread_fn arg 2136 - * left from _switch_to: a6 = prev 2087 + * On entry, set up by copy_thread: abi_saved0 = thread_fn, 2088 + * abi_saved1 = thread_fn arg. Left from _switch_to: abi_arg0 = prev 2137 2089 */ 2138 2090 ENTRY(ret_from_kernel_thread) 2139 2091 2140 - call4 schedule_tail 2141 - mov a6, a3 2142 - callx4 a2 2143 - j common_exception_return 2092 + abi_call schedule_tail 2093 + mov abi_arg0, abi_saved1 2094 + abi_callx abi_saved0 2095 + j common_exception_return 2144 2096 2145 2097 ENDPROC(ret_from_kernel_thread)
+14 -10
arch/xtensa/kernel/head.S
··· 15 15 * Kevin Chea 16 16 */ 17 17 18 + #include <asm/asmmacro.h> 18 19 #include <asm/processor.h> 19 20 #include <asm/page.h> 20 21 #include <asm/cacheasm.h> ··· 67 66 * xt-gdb to single step via DEBUG exceptions received directly 68 67 * by ocd. 69 68 */ 69 + #if XCHAL_HAVE_WINDOWED 70 70 movi a1, 1 71 71 movi a0, 0 72 72 wsr a1, windowstart 73 73 wsr a0, windowbase 74 74 rsync 75 + #endif 75 76 76 77 movi a1, LOCKLEVEL 77 78 wsr a1, ps ··· 196 193 movi a1, start_info 197 194 l32i a1, a1, 0 198 195 199 - movi a2, PS_WOE_MASK | LOCKLEVEL 200 - # WOE=1, INTLEVEL=LOCKLEVEL, UM=0 201 - wsr a2, ps # (enable reg-windows; progmode stack) 196 + /* Disable interrupts. */ 197 + /* Enable window exceptions if kernel is built with windowed ABI. */ 198 + movi a2, KERNEL_PS_WOE_MASK | LOCKLEVEL 199 + wsr a2, ps 202 200 rsync 203 201 204 202 #ifdef CONFIG_SMP ··· 271 267 l32i a1, a1, 0 272 268 #endif 273 269 274 - movi a6, 0 275 - xsr a6, excsave1 270 + movi abi_arg0, 0 271 + xsr abi_arg0, excsave1 276 272 277 273 /* init_arch kick-starts the linux kernel */ 278 274 279 - call4 init_arch 280 - call4 start_kernel 275 + abi_call init_arch 276 + abi_call start_kernel 281 277 282 278 should_never_return: 283 279 j should_never_return ··· 301 297 s32i a3, a2, 0 302 298 memw 303 299 304 - movi a6, 0 305 - wsr a6, excsave1 300 + movi abi_arg0, 0 301 + wsr abi_arg0, excsave1 306 302 307 - call4 secondary_start_kernel 303 + abi_call secondary_start_kernel 308 304 j should_never_return 309 305 310 306 #endif /* CONFIG_SMP */
+36 -2
arch/xtensa/kernel/mcount.S
··· 17 17 /* 18 18 * Entry condition: 19 19 * 20 - * a2: a0 of the caller 20 + * a2: a0 of the caller in windowed ABI 21 + * a10: a0 of the caller in call0 ABI 22 + * 23 + * In call0 ABI the function _mcount is called with the special ABI: 24 + * its argument is in a10 and all the usual argument registers (a2 - a7) 25 + * must be preserved in addition to callee-saved a12 - a15. 21 26 */ 22 27 23 28 ENTRY(_mcount) 24 - 29 + #if defined(__XTENSA_WINDOWED_ABI__) 25 30 abi_entry_default 26 31 27 32 movi a4, ftrace_trace_function ··· 47 42 callx4 a4 48 43 49 44 abi_ret_default 45 + #elif defined(__XTENSA_CALL0_ABI__) 46 + abi_entry_default 50 47 48 + movi a9, ftrace_trace_function 49 + l32i a9, a9, 0 50 + movi a11, ftrace_stub 51 + bne a9, a11, 1f 52 + abi_ret_default 53 + 54 + 1: abi_entry(28) 55 + s32i a0, sp, 0 56 + s32i a2, sp, 4 57 + s32i a3, sp, 8 58 + s32i a4, sp, 12 59 + s32i a5, sp, 16 60 + s32i a6, sp, 20 61 + s32i a7, sp, 24 62 + addi a2, a10, -MCOUNT_INSN_SIZE 63 + callx0 a9 64 + l32i a0, sp, 0 65 + l32i a2, sp, 4 66 + l32i a3, sp, 8 67 + l32i a4, sp, 12 68 + l32i a5, sp, 16 69 + l32i a6, sp, 20 70 + l32i a7, sp, 24 71 + abi_ret(28) 72 + #else 73 + #error Unsupported Xtensa ABI 74 + #endif 51 75 ENDPROC(_mcount) 52 76 53 77 ENTRY(ftrace_stub)
+24 -3
arch/xtensa/kernel/process.c
··· 211 211 struct thread_info *ti; 212 212 #endif 213 213 214 + #if defined(__XTENSA_WINDOWED_ABI__) 214 215 /* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */ 215 216 SPILL_SLOT(childregs, 1) = (unsigned long)childregs; 216 217 SPILL_SLOT(childregs, 0) = 0; 217 218 218 219 p->thread.sp = (unsigned long)childregs; 220 + #elif defined(__XTENSA_CALL0_ABI__) 221 + /* Reserve 16 bytes for the _switch_to stack frame. */ 222 + p->thread.sp = (unsigned long)childregs - 16; 223 + #else 224 + #error Unsupported Xtensa ABI 225 + #endif 219 226 220 227 if (!(p->flags & (PF_KTHREAD | PF_IO_WORKER))) { 221 228 struct pt_regs *regs = current_pt_regs(); ··· 279 272 p->thread.ra = MAKE_RA_FOR_CALL( 280 273 (unsigned long)ret_from_kernel_thread, 1); 281 274 282 - /* pass parameters to ret_from_kernel_thread: 283 - * a2 = thread_fn, a3 = thread_fn arg 275 + /* pass parameters to ret_from_kernel_thread: */ 276 + #if defined(__XTENSA_WINDOWED_ABI__) 277 + /* 278 + * a2 = thread_fn, a3 = thread_fn arg. 279 + * Window underflow will load registers from the 280 + * spill slots on the stack on return from _switch_to. 284 281 */ 285 - SPILL_SLOT(childregs, 3) = thread_fn_arg; 286 282 SPILL_SLOT(childregs, 2) = usp_thread_fn; 283 + SPILL_SLOT(childregs, 3) = thread_fn_arg; 284 + #elif defined(__XTENSA_CALL0_ABI__) 285 + /* 286 + * a12 = thread_fn, a13 = thread_fn arg. 287 + * _switch_to epilogue will load registers from the stack. 288 + */ 289 + ((unsigned long *)p->thread.sp)[0] = usp_thread_fn; 290 + ((unsigned long *)p->thread.sp)[1] = thread_fn_arg; 291 + #else 292 + #error Unsupported Xtensa ABI 293 + #endif 287 294 288 295 /* Childregs are only used when we're going to userspace 289 296 * in which case start_thread will set them up.
+31 -71
arch/xtensa/kernel/setup.c
··· 37 37 #include <asm/bootparam.h> 38 38 #include <asm/kasan.h> 39 39 #include <asm/mmu_context.h> 40 - #include <asm/processor.h> 41 - #include <asm/timex.h> 42 - #include <asm/platform.h> 43 40 #include <asm/page.h> 44 - #include <asm/setup.h> 45 41 #include <asm/param.h> 42 + #include <asm/platform.h> 43 + #include <asm/processor.h> 44 + #include <asm/sections.h> 45 + #include <asm/setup.h> 46 46 #include <asm/smp.h> 47 47 #include <asm/sysmem.h> 48 + #include <asm/timex.h> 48 49 49 50 #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) 50 51 struct screen_info screen_info = { ··· 272 271 * Initialize system. Setup memory and reserve regions. 273 272 */ 274 273 275 - extern char _end[]; 276 - extern char _stext[]; 277 - extern char _WindowVectors_text_start; 278 - extern char _WindowVectors_text_end; 279 - extern char _DebugInterruptVector_text_start; 280 - extern char _DebugInterruptVector_text_end; 281 - extern char _KernelExceptionVector_text_start; 282 - extern char _KernelExceptionVector_text_end; 283 - extern char _UserExceptionVector_text_start; 284 - extern char _UserExceptionVector_text_end; 285 - extern char _DoubleExceptionVector_text_start; 286 - extern char _DoubleExceptionVector_text_end; 287 - extern char _exception_text_start; 288 - extern char _exception_text_end; 289 - #if XCHAL_EXCM_LEVEL >= 2 290 - extern char _Level2InterruptVector_text_start; 291 - extern char _Level2InterruptVector_text_end; 292 - #endif 293 - #if XCHAL_EXCM_LEVEL >= 3 294 - extern char _Level3InterruptVector_text_start; 295 - extern char _Level3InterruptVector_text_end; 296 - #endif 297 - #if XCHAL_EXCM_LEVEL >= 4 298 - extern char _Level4InterruptVector_text_start; 299 - extern char _Level4InterruptVector_text_end; 300 - #endif 301 - #if XCHAL_EXCM_LEVEL >= 5 302 - extern char _Level5InterruptVector_text_start; 303 - extern char _Level5InterruptVector_text_end; 304 - #endif 305 - #if XCHAL_EXCM_LEVEL >= 6 306 - extern char _Level6InterruptVector_text_start; 307 - extern char _Level6InterruptVector_text_end; 308 - #endif 309 - #ifdef CONFIG_SMP 310 - extern char _SecondaryResetVector_text_start; 311 - extern char _SecondaryResetVector_text_end; 312 - #endif 313 - #ifdef CONFIG_XIP_KERNEL 314 - extern char _xip_start[]; 315 - extern char _xip_end[]; 316 - #endif 317 - 318 274 static inline int __init_memblock mem_reserve(unsigned long start, 319 275 unsigned long end) 320 276 { ··· 307 349 #endif 308 350 309 351 #ifdef CONFIG_VECTORS_ADDR 310 - mem_reserve(__pa(&_WindowVectors_text_start), 311 - __pa(&_WindowVectors_text_end)); 352 + #ifdef SUPPORT_WINDOWED 353 + mem_reserve(__pa(_WindowVectors_text_start), 354 + __pa(_WindowVectors_text_end)); 355 + #endif 312 356 313 - mem_reserve(__pa(&_DebugInterruptVector_text_start), 314 - __pa(&_DebugInterruptVector_text_end)); 357 + mem_reserve(__pa(_DebugInterruptVector_text_start), 358 + __pa(_DebugInterruptVector_text_end)); 315 359 316 - mem_reserve(__pa(&_KernelExceptionVector_text_start), 317 - __pa(&_KernelExceptionVector_text_end)); 360 + mem_reserve(__pa(_KernelExceptionVector_text_start), 361 + __pa(_KernelExceptionVector_text_end)); 318 362 319 - mem_reserve(__pa(&_UserExceptionVector_text_start), 320 - __pa(&_UserExceptionVector_text_end)); 363 + mem_reserve(__pa(_UserExceptionVector_text_start), 364 + __pa(_UserExceptionVector_text_end)); 321 365 322 - mem_reserve(__pa(&_DoubleExceptionVector_text_start), 323 - __pa(&_DoubleExceptionVector_text_end)); 366 + mem_reserve(__pa(_DoubleExceptionVector_text_start), 367 + __pa(_DoubleExceptionVector_text_end)); 324 368 325 - mem_reserve(__pa(&_exception_text_start), 326 - __pa(&_exception_text_end)); 369 + mem_reserve(__pa(_exception_text_start), 370 + __pa(_exception_text_end)); 327 371 #if XCHAL_EXCM_LEVEL >= 2 328 - mem_reserve(__pa(&_Level2InterruptVector_text_start), 329 - __pa(&_Level2InterruptVector_text_end)); 372 + mem_reserve(__pa(_Level2InterruptVector_text_start), 373 + __pa(_Level2InterruptVector_text_end)); 330 374 #endif 331 375 #if XCHAL_EXCM_LEVEL >= 3 332 - mem_reserve(__pa(&_Level3InterruptVector_text_start), 333 - __pa(&_Level3InterruptVector_text_end)); 376 + mem_reserve(__pa(_Level3InterruptVector_text_start), 377 + __pa(_Level3InterruptVector_text_end)); 334 378 #endif 335 379 #if XCHAL_EXCM_LEVEL >= 4 336 - mem_reserve(__pa(&_Level4InterruptVector_text_start), 337 - __pa(&_Level4InterruptVector_text_end)); 380 + mem_reserve(__pa(_Level4InterruptVector_text_start), 381 + __pa(_Level4InterruptVector_text_end)); 338 382 #endif 339 383 #if XCHAL_EXCM_LEVEL >= 5 340 - mem_reserve(__pa(&_Level5InterruptVector_text_start), 341 - __pa(&_Level5InterruptVector_text_end)); 384 + mem_reserve(__pa(_Level5InterruptVector_text_start), 385 + __pa(_Level5InterruptVector_text_end)); 342 386 #endif 343 387 #if XCHAL_EXCM_LEVEL >= 6 344 - mem_reserve(__pa(&_Level6InterruptVector_text_start), 345 - __pa(&_Level6InterruptVector_text_end)); 388 + mem_reserve(__pa(_Level6InterruptVector_text_start), 389 + __pa(_Level6InterruptVector_text_end)); 346 390 #endif 347 391 348 392 #endif /* CONFIG_VECTORS_ADDR */ 349 393 350 394 #ifdef CONFIG_SMP 351 - mem_reserve(__pa(&_SecondaryResetVector_text_start), 352 - __pa(&_SecondaryResetVector_text_end)); 395 + mem_reserve(__pa(_SecondaryResetVector_text_start), 396 + __pa(_SecondaryResetVector_text_end)); 353 397 #endif 354 398 parse_early_param(); 355 399 bootmem_init();
+10 -2
arch/xtensa/kernel/signal.c
··· 45 45 unsigned int window[4]; 46 46 }; 47 47 48 - /* 48 + #if defined(USER_SUPPORT_WINDOWED) 49 + /* 49 50 * Flush register windows stored in pt_regs to stack. 50 51 * Returns 1 for errors. 51 52 */ 52 53 53 - int 54 + static int 54 55 flush_window_regs_user(struct pt_regs *regs) 55 56 { 56 57 const unsigned long ws = regs->windowstart; ··· 122 121 errout: 123 122 return err; 124 123 } 124 + #else 125 + static int 126 + flush_window_regs_user(struct pt_regs *regs) 127 + { 128 + return 0; 129 + } 130 + #endif 125 131 126 132 /* 127 133 * Note: We don't copy double exception 'regs', we have to finish double exc.
+3 -3
arch/xtensa/kernel/traps.c
··· 97 97 /* EXCCAUSE_INSTRUCTION_FETCH unhandled */ 98 98 /* EXCCAUSE_LOAD_STORE_ERROR unhandled*/ 99 99 { EXCCAUSE_LEVEL1_INTERRUPT, 0, do_interrupt }, 100 + #ifdef SUPPORT_WINDOWED 100 101 { EXCCAUSE_ALLOCA, USER|KRNL, fast_alloca }, 102 + #endif 101 103 /* EXCCAUSE_INTEGER_DIVIDE_BY_ZERO unhandled */ 102 104 /* EXCCAUSE_PRIVILEGED unhandled */ 103 105 #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION ··· 464 462 465 463 void show_regs(struct pt_regs * regs) 466 464 { 467 - int i, wmask; 465 + int i; 468 466 469 467 show_regs_print_info(KERN_DEFAULT); 470 - 471 - wmask = regs->wmask & ~1; 472 468 473 469 for (i = 0; i < 16; i++) { 474 470 if ((i % 8) == 0)
+34 -21
arch/xtensa/kernel/vectors.S
··· 226 226 227 227 xsr a0, depc # get DEPC, save a0 228 228 229 + #ifdef SUPPORT_WINDOWED 229 230 movi a2, WINDOW_VECTORS_VADDR 230 231 _bltu a0, a2, .Lfixup 231 232 addi a2, a2, WINDOW_VECTORS_SIZE ··· 275 274 xsr a3, excsave1 276 275 l32i a0, a0, EXC_TABLE_FAST_USER 277 276 jx a0 277 + 278 + #else 279 + j .Lfixup 280 + #endif 278 281 279 282 /* 280 283 * We only allow the ITLB miss exception if we are in kernel space. ··· 348 343 l32i a0, a0, EXC_TABLE_FAST_USER 349 344 jx a0 350 345 346 + #ifdef SUPPORT_WINDOWED 351 347 /* 352 348 * Restart window OVERFLOW exception. 353 349 * Currently: ··· 481 475 rsr a0, depc 482 476 rotw -3 483 477 j 1b 478 + #endif 484 479 485 480 ENDPROC(_DoubleExceptionVector) 481 + 482 + #ifdef SUPPORT_WINDOWED 486 483 487 484 /* 488 485 * Fixup handler for TLB miss in double exception handler for window owerflow. ··· 599 590 600 591 ENDPROC(window_overflow_restore_a0_fixup) 601 592 593 + #endif 594 + 602 595 /* 603 596 * Debug interrupt vector 604 597 * ··· 661 650 irq_entry_level 5 662 651 irq_entry_level 6 663 652 653 + #if XCHAL_EXCM_LEVEL >= 2 654 + /* 655 + * Continuation of medium priority interrupt dispatch code. 656 + * On entry here, a0 contains PS, and EPC2 contains saved a0: 657 + */ 658 + __XTENSA_HANDLER 659 + .align 4 660 + _SimulateUserKernelVectorException: 661 + addi a0, a0, (1 << PS_EXCM_BIT) 662 + #if !XTENSA_FAKE_NMI 663 + wsr a0, ps 664 + #endif 665 + bbsi.l a0, PS_UM_BIT, 1f # branch if user mode 666 + xsr a0, excsave2 # restore a0 667 + j _KernelExceptionVector # simulate kernel vector exception 668 + 1: xsr a0, excsave2 # restore a0 669 + j _UserExceptionVector # simulate user vector exception 670 + #endif 671 + 664 672 665 673 /* Window overflow and underflow handlers. 666 674 * The handlers must be 64 bytes apart, first starting with the underflow ··· 698 668 .section .WindowVectors.text, "ax" 699 669 700 670 671 + #ifdef SUPPORT_WINDOWED 672 + 701 673 /* 4-Register Window Overflow Vector (Handler) */ 702 674 703 675 ENTRY_ALIGN64(_WindowOverflow4) ··· 711 679 rfwo 712 680 713 681 ENDPROC(_WindowOverflow4) 714 - 715 - 716 - #if XCHAL_EXCM_LEVEL >= 2 717 - /* Not a window vector - but a convenient location 718 - * (where we know there's space) for continuation of 719 - * medium priority interrupt dispatch code. 720 - * On entry here, a0 contains PS, and EPC2 contains saved a0: 721 - */ 722 - .align 4 723 - _SimulateUserKernelVectorException: 724 - addi a0, a0, (1 << PS_EXCM_BIT) 725 - #if !XTENSA_FAKE_NMI 726 - wsr a0, ps 727 - #endif 728 - bbsi.l a0, PS_UM_BIT, 1f # branch if user mode 729 - xsr a0, excsave2 # restore a0 730 - j _KernelExceptionVector # simulate kernel vector exception 731 - 1: xsr a0, excsave2 # restore a0 732 - j _UserExceptionVector # simulate user vector exception 733 - #endif 734 - 735 682 736 683 /* 4-Register Window Underflow Vector (Handler) */ 737 684 ··· 799 788 rfwu 800 789 801 790 ENDPROC(_WindowUnderflow12) 791 + 792 + #endif 802 793 803 794 .text
+10 -2
arch/xtensa/kernel/vmlinux.lds.S
··· 94 94 . = ALIGN(PAGE_SIZE); 95 95 _vecbase = .; 96 96 97 + #ifdef SUPPORT_WINDOWED 97 98 SECTION_VECTOR2 (.WindowVectors.text, WINDOW_VECTORS_VADDR) 99 + #endif 98 100 #if XCHAL_EXCM_LEVEL >= 2 99 101 SECTION_VECTOR2 (.Level2InterruptVector.text, INTLEVEL2_VECTOR_VADDR) 100 102 #endif ··· 168 166 __boot_reloc_table_start = ABSOLUTE(.); 169 167 170 168 #if !MERGED_VECTORS 169 + #ifdef SUPPORT_WINDOWED 171 170 RELOCATE_ENTRY(_WindowVectors_text, 172 171 .WindowVectors.text); 172 + #endif 173 173 #if XCHAL_EXCM_LEVEL >= 2 174 174 RELOCATE_ENTRY(_Level2InterruptVector_text, 175 175 .Level2InterruptVector.text); ··· 233 229 #if !MERGED_VECTORS 234 230 /* The vectors are relocated to the real position at startup time */ 235 231 232 + #ifdef SUPPORT_WINDOWED 236 233 SECTION_VECTOR4 (_WindowVectors_text, 237 234 .WindowVectors.text, 238 235 WINDOW_VECTORS_VADDR, 239 - .dummy) 236 + LAST) 237 + #undef LAST 238 + #define LAST .WindowVectors.text 239 + #endif 240 240 SECTION_VECTOR4 (_DebugInterruptVector_text, 241 241 .DebugInterruptVector.text, 242 242 DEBUG_VECTOR_VADDR, 243 - .WindowVectors.text) 243 + LAST) 244 244 #undef LAST 245 245 #define LAST .DebugInterruptVector.text 246 246 #if XCHAL_EXCM_LEVEL >= 2
+8 -9
arch/xtensa/lib/strncpy_user.S
··· 45 45 # a9/ tmp 46 46 # a10/ tmp 47 47 # a11/ dst 48 - # a12/ tmp 49 48 50 49 .text 51 50 ENTRY(__strncpy_user) ··· 60 61 bbsi.l a3, 0, .Lsrc1mod2 # if only 8-bit aligned 61 62 bbsi.l a3, 1, .Lsrc2mod4 # if only 16-bit aligned 62 63 .Lsrcaligned: # return here when src is word-aligned 63 - srli a12, a4, 2 # number of loop iterations with 4B per loop 64 + srli a10, a4, 2 # number of loop iterations with 4B per loop 64 65 movi a9, 3 65 66 bnone a11, a9, .Laligned 66 67 j .Ldstunaligned ··· 101 102 .byte 0 # (0 mod 4 alignment for LBEG) 102 103 .Laligned: 103 104 #if XCHAL_HAVE_LOOPS 104 - loopnez a12, .Loop1done 105 + loopnez a10, .Loop1done 105 106 #else 106 - beqz a12, .Loop1done 107 - slli a12, a12, 2 108 - add a12, a12, a11 # a12 = end of last 4B chunck 107 + beqz a10, .Loop1done 108 + slli a10, a10, 2 109 + add a10, a10, a11 # a10 = end of last 4B chunck 109 110 #endif 110 111 .Loop1: 111 112 EX(11f) l32i a9, a3, 0 # get word from src ··· 117 118 bnone a9, a8, .Lz3 # if byte 3 is zero 118 119 addi a11, a11, 4 # advance dst pointer 119 120 #if !XCHAL_HAVE_LOOPS 120 - blt a11, a12, .Loop1 121 + blt a11, a10, .Loop1 121 122 #endif 122 123 123 124 .Loop1done: ··· 184 185 loopnez a4, .Lunalignedend 185 186 #else 186 187 beqz a4, .Lunalignedend 187 - add a12, a11, a4 # a12 = ending address 188 + add a10, a11, a4 # a10 = ending address 188 189 #endif /* XCHAL_HAVE_LOOPS */ 189 190 .Lnextbyte: 190 191 EX(11f) l8ui a9, a3, 0 ··· 193 194 beqz a9, .Lunalignedend 194 195 addi a11, a11, 1 195 196 #if !XCHAL_HAVE_LOOPS 196 - blt a11, a12, .Lnextbyte 197 + blt a11, a10, .Lnextbyte 197 198 #endif 198 199 199 200 .Lunalignedend:
+22 -6
arch/xtensa/lib/usercopy.S
··· 60 60 .text 61 61 ENTRY(__xtensa_copy_user) 62 62 63 - abi_entry_default 63 + #if !XCHAL_HAVE_LOOPS && defined(__XTENSA_CALL0_ABI__) 64 + #define STACK_SIZE 4 65 + #else 66 + #define STACK_SIZE 0 67 + #endif 68 + abi_entry(STACK_SIZE) 64 69 # a2/ dst, a3/ src, a4/ len 65 70 mov a5, a2 # copy dst so that a2 is return value 66 71 mov a11, a4 # preserve original len for error case ··· 80 75 __ssa8 a3 # set shift amount from byte offset 81 76 bnez a4, .Lsrcunaligned 82 77 movi a2, 0 # return success for len==0 83 - abi_ret_default 78 + abi_ret(STACK_SIZE) 84 79 85 80 /* 86 81 * Destination is unaligned ··· 132 127 #endif /* !XCHAL_HAVE_LOOPS */ 133 128 .Lbytecopydone: 134 129 movi a2, 0 # return success for len bytes copied 135 - abi_ret_default 130 + abi_ret(STACK_SIZE) 136 131 137 132 /* 138 133 * Destination and source are word-aligned. ··· 192 187 EX(10f) s8i a6, a5, 0 193 188 .L5: 194 189 movi a2, 0 # return success for len bytes copied 195 - abi_ret_default 190 + abi_ret(STACK_SIZE) 196 191 197 192 /* 198 193 * Destination is aligned, Source is unaligned ··· 210 205 loopnez a7, .Loop2done 211 206 #else /* !XCHAL_HAVE_LOOPS */ 212 207 beqz a7, .Loop2done 208 + #if defined(__XTENSA_CALL0_ABI__) 209 + s32i a10, a1, 0 210 + slli a10, a7, 4 211 + add a10, a10, a3 # a10 = end of last 16B source chunk 212 + #else 213 213 slli a12, a7, 4 214 214 add a12, a12, a3 # a12 = end of last 16B source chunk 215 + #endif 215 216 #endif /* !XCHAL_HAVE_LOOPS */ 216 217 .Loop2: 217 218 EX(10f) l32i a7, a3, 4 ··· 235 224 EX(10f) s32i a9, a5, 12 236 225 addi a5, a5, 16 237 226 #if !XCHAL_HAVE_LOOPS 227 + #if defined(__XTENSA_CALL0_ABI__) 228 + blt a3, a10, .Loop2 229 + l32i a10, a1, 0 230 + #else 238 231 blt a3, a12, .Loop2 232 + #endif 239 233 #endif /* !XCHAL_HAVE_LOOPS */ 240 234 .Loop2done: 241 235 bbci.l a4, 3, .L12 ··· 280 264 EX(10f) s8i a6, a5, 0 281 265 .L15: 282 266 movi a2, 0 # return success for len bytes copied 283 - abi_ret_default 267 + abi_ret(STACK_SIZE) 284 268 285 269 ENDPROC(__xtensa_copy_user) 286 270 ··· 297 281 10: 298 282 sub a2, a5, a2 /* a2 <-- bytes copied */ 299 283 sub a2, a11, a2 /* a2 <-- bytes not copied */ 300 - abi_ret_default 284 + abi_ret(STACK_SIZE)