ab025c1f6e23639f82ca016ad33f46da150e8b26
[cascardo/linux.git] / arch / xtensa / kernel / entry.S
1 /*
2  * arch/xtensa/kernel/entry.S
3  *
4  * Low-level exception handling
5  *
6  * This file is subject to the terms and conditions of the GNU General Public
7  * License.  See the file "COPYING" in the main directory of this archive
8  * for more details.
9  *
10  * Copyright (C) 2004 - 2008 by Tensilica Inc.
11  *
12  * Chris Zankel <chris@zankel.net>
13  *
14  */
15
16 #include <linux/linkage.h>
17 #include <asm/asm-offsets.h>
18 #include <asm/processor.h>
19 #include <asm/coprocessor.h>
20 #include <asm/thread_info.h>
21 #include <asm/uaccess.h>
22 #include <asm/unistd.h>
23 #include <asm/ptrace.h>
24 #include <asm/current.h>
25 #include <asm/pgtable.h>
26 #include <asm/page.h>
27 #include <asm/signal.h>
28 #include <asm/tlbflush.h>
29 #include <variant/tie-asm.h>
30
31 /* Unimplemented features. */
32
33 #undef KERNEL_STACK_OVERFLOW_CHECK
34 #undef ALLOCA_EXCEPTION_IN_IRAM
35
36 /* Not well tested.
37  *
38  * - fast_coprocessor
39  */
40
41 /*
42  * Macro to find first bit set in WINDOWBASE from the left + 1
43  *
44  * 100....0 -> 1
45  * 010....0 -> 2
46  * 000....1 -> WSBITS
47  */
48
49         .macro ffs_ws bit mask
50
51 #if XCHAL_HAVE_NSA
52         nsau    \bit, \mask                     # 32-WSBITS ... 31 (32 iff 0)
53         addi    \bit, \bit, WSBITS - 32 + 1     # uppest bit set -> return 1
54 #else
55         movi    \bit, WSBITS
56 #if WSBITS > 16
57         _bltui  \mask, 0x10000, 99f
58         addi    \bit, \bit, -16
59         extui   \mask, \mask, 16, 16
60 #endif
61 #if WSBITS > 8
62 99:     _bltui  \mask, 0x100, 99f
63         addi    \bit, \bit, -8
64         srli    \mask, \mask, 8
65 #endif
66 99:     _bltui  \mask, 0x10, 99f
67         addi    \bit, \bit, -4
68         srli    \mask, \mask, 4
69 99:     _bltui  \mask, 0x4, 99f
70         addi    \bit, \bit, -2
71         srli    \mask, \mask, 2
72 99:     _bltui  \mask, 0x2, 99f
73         addi    \bit, \bit, -1
74 99:
75
76 #endif
77         .endm
78
79 /* ----------------- DEFAULT FIRST LEVEL EXCEPTION HANDLERS ----------------- */
80
81 /*
82  * First-level exception handler for user exceptions.
83  * Save some special registers, extra states and all registers in the AR
84  * register file that were in use in the user task, and jump to the common
85  * exception code.
86  * We save SAR (used to calculate WMASK), and WB and WS (we don't have to
87  * save them for kernel exceptions).
88  *
89  * Entry condition for user_exception:
90  *
91  *   a0:        trashed, original value saved on stack (PT_AREG0)
92  *   a1:        a1
93  *   a2:        new stack pointer, original value in depc
94  *   a3:        a3
95  *   depc:      a2, original value saved on stack (PT_DEPC)
96  *   excsave1:  dispatch table
97  *
98  *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
99  *           <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
100  *
101  * Entry condition for _user_exception:
102  *
103  *   a0-a3 and depc have been saved to PT_AREG0...PT_AREG3 and PT_DEPC
104  *   excsave has been restored, and
105  *   stack pointer (a1) has been set.
106  *
107  * Note: _user_exception might be at an odd address. Don't use call0..call12
108  */
109
110 ENTRY(user_exception)
111
112         /* Save a1, a2, a3, and set SP. */
113
114         rsr     a0, depc
115         s32i    a1, a2, PT_AREG1
116         s32i    a0, a2, PT_AREG2
117         s32i    a3, a2, PT_AREG3
118         mov     a1, a2
119
120         .globl _user_exception
121 _user_exception:
122
123         /* Save SAR and turn off single stepping */
124
125         movi    a2, 0
126         rsr     a3, sar
127         xsr     a2, icountlevel
128         s32i    a3, a1, PT_SAR
129         s32i    a2, a1, PT_ICOUNTLEVEL
130
131 #if XCHAL_HAVE_THREADPTR
132         rur     a2, threadptr
133         s32i    a2, a1, PT_THREADPTR
134 #endif
135
136         /* Rotate ws so that the current windowbase is at bit0. */
137         /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */
138
139         rsr     a2, windowbase
140         rsr     a3, windowstart
141         ssr     a2
142         s32i    a2, a1, PT_WINDOWBASE
143         s32i    a3, a1, PT_WINDOWSTART
144         slli    a2, a3, 32-WSBITS
145         src     a2, a3, a2
146         srli    a2, a2, 32-WSBITS
147         s32i    a2, a1, PT_WMASK        # needed for restoring registers
148
149         /* Save only live registers. */
150
151         _bbsi.l a2, 1, 1f
152         s32i    a4, a1, PT_AREG4
153         s32i    a5, a1, PT_AREG5
154         s32i    a6, a1, PT_AREG6
155         s32i    a7, a1, PT_AREG7
156         _bbsi.l a2, 2, 1f
157         s32i    a8, a1, PT_AREG8
158         s32i    a9, a1, PT_AREG9
159         s32i    a10, a1, PT_AREG10
160         s32i    a11, a1, PT_AREG11
161         _bbsi.l a2, 3, 1f
162         s32i    a12, a1, PT_AREG12
163         s32i    a13, a1, PT_AREG13
164         s32i    a14, a1, PT_AREG14
165         s32i    a15, a1, PT_AREG15
166         _bnei   a2, 1, 1f               # only one valid frame?
167
168         /* Only one valid frame, skip saving regs. */
169
170         j       2f
171
172         /* Save the remaining registers.
173          * We have to save all registers up to the first '1' from
174          * the right, except the current frame (bit 0).
175          * Assume a2 is:  001001000110001
176          * All register frames starting from the top field to the marked '1'
177          * must be saved.
178          */
179
180 1:      addi    a3, a2, -1              # eliminate '1' in bit 0: yyyyxxww0
181         neg     a3, a3                  # yyyyxxww0 -> YYYYXXWW1+1
182         and     a3, a3, a2              # max. only one bit is set
183
184         /* Find number of frames to save */
185
186         ffs_ws  a0, a3                  # number of frames to the '1' from left
187
188         /* Store information into WMASK:
189          * bits 0..3: xxx1 masked lower 4 bits of the rotated windowstart,
190          * bits 4...: number of valid 4-register frames
191          */
192
193         slli    a3, a0, 4               # number of frames to save in bits 8..4
194         extui   a2, a2, 0, 4            # mask for the first 16 registers
195         or      a2, a3, a2
196         s32i    a2, a1, PT_WMASK        # needed when we restore the reg-file
197
198         /* Save 4 registers at a time */
199
200 1:      rotw    -1
201         s32i    a0, a5, PT_AREG_END - 16
202         s32i    a1, a5, PT_AREG_END - 12
203         s32i    a2, a5, PT_AREG_END - 8
204         s32i    a3, a5, PT_AREG_END - 4
205         addi    a0, a4, -1
206         addi    a1, a5, -16
207         _bnez   a0, 1b
208
209         /* WINDOWBASE still in SAR! */
210
211         rsr     a2, sar                 # original WINDOWBASE
212         movi    a3, 1
213         ssl     a2
214         sll     a3, a3
215         wsr     a3, windowstart         # set corresponding WINDOWSTART bit
216         wsr     a2, windowbase          # and WINDOWSTART
217         rsync
218
219         /* We are back to the original stack pointer (a1) */
220
221 2:      /* Now, jump to the common exception handler. */
222
223         j       common_exception
224
225 ENDPROC(user_exception)
226
227 /*
228  * First-level exit handler for kernel exceptions
229  * Save special registers and the live window frame.
230  * Note: Even though we changes the stack pointer, we don't have to do a
231  *       MOVSP here, as we do that when we return from the exception.
232  *       (See comment in the kernel exception exit code)
233  *
234  * Entry condition for kernel_exception:
235  *
236  *   a0:        trashed, original value saved on stack (PT_AREG0)
237  *   a1:        a1
238  *   a2:        new stack pointer, original in DEPC
239  *   a3:        a3
240  *   depc:      a2, original value saved on stack (PT_DEPC)
241  *   excsave_1: dispatch table
242  *
243  *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
244  *           <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
245  *
246  * Entry condition for _kernel_exception:
247  *
248  *   a0-a3 and depc have been saved to PT_AREG0...PT_AREG3 and PT_DEPC
249  *   excsave has been restored, and
250  *   stack pointer (a1) has been set.
251  *
252  * Note: _kernel_exception might be at an odd address. Don't use call0..call12
253  */
254
255 ENTRY(kernel_exception)
256
257         /* Save a1, a2, a3, and set SP. */
258
259         rsr     a0, depc                # get a2
260         s32i    a1, a2, PT_AREG1
261         s32i    a0, a2, PT_AREG2
262         s32i    a3, a2, PT_AREG3
263         mov     a1, a2
264
265         .globl _kernel_exception
266 _kernel_exception:
267
268         /* Save SAR and turn off single stepping */
269
270         movi    a2, 0
271         rsr     a3, sar
272         xsr     a2, icountlevel
273         s32i    a3, a1, PT_SAR
274         s32i    a2, a1, PT_ICOUNTLEVEL
275
276         /* Rotate ws so that the current windowbase is at bit0. */
277         /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */
278
279         rsr     a2, windowbase          # don't need to save these, we only
280         rsr     a3, windowstart         # need shifted windowstart: windowmask
281         ssr     a2
282         slli    a2, a3, 32-WSBITS
283         src     a2, a3, a2
284         srli    a2, a2, 32-WSBITS
285         s32i    a2, a1, PT_WMASK        # needed for kernel_exception_exit
286
287         /* Save only the live window-frame */
288
289         _bbsi.l a2, 1, 1f
290         s32i    a4, a1, PT_AREG4
291         s32i    a5, a1, PT_AREG5
292         s32i    a6, a1, PT_AREG6
293         s32i    a7, a1, PT_AREG7
294         _bbsi.l a2, 2, 1f
295         s32i    a8, a1, PT_AREG8
296         s32i    a9, a1, PT_AREG9
297         s32i    a10, a1, PT_AREG10
298         s32i    a11, a1, PT_AREG11
299         _bbsi.l a2, 3, 1f
300         s32i    a12, a1, PT_AREG12
301         s32i    a13, a1, PT_AREG13
302         s32i    a14, a1, PT_AREG14
303         s32i    a15, a1, PT_AREG15
304
305 1:
306
307 #ifdef KERNEL_STACK_OVERFLOW_CHECK
308
309         /*  Stack overflow check, for debugging  */
310         extui   a2, a1, TASK_SIZE_BITS,XX
311         movi    a3, SIZE??
312         _bge    a2, a3, out_of_stack_panic
313
314 #endif
315
316 /*
317  * This is the common exception handler.
318  * We get here from the user exception handler or simply by falling through
319  * from the kernel exception handler.
320  * Save the remaining special registers, switch to kernel mode, and jump
321  * to the second-level exception handler.
322  *
323  */
324
325 common_exception:
326
327         /* Save some registers, disable loops and clear the syscall flag. */
328
329         rsr     a2, debugcause
330         rsr     a3, epc1
331         s32i    a2, a1, PT_DEBUGCAUSE
332         s32i    a3, a1, PT_PC
333
334         movi    a2, -1
335         rsr     a3, excvaddr
336         s32i    a2, a1, PT_SYSCALL
337         movi    a2, 0
338         s32i    a3, a1, PT_EXCVADDR
339         xsr     a2, lcount
340         s32i    a2, a1, PT_LCOUNT
341
342         /* It is now save to restore the EXC_TABLE_FIXUP variable. */
343
344         rsr     a0, exccause
345         movi    a3, 0
346         rsr     a2, excsave1
347         s32i    a0, a1, PT_EXCCAUSE
348         s32i    a3, a2, EXC_TABLE_FIXUP
349
350         /* All unrecoverable states are saved on stack, now, and a1 is valid,
351          * so we can allow exceptions and interrupts (*) again.
352          * Set PS(EXCM = 0, UM = 0, RING = 0, OWB = 0, WOE = 1, INTLEVEL = X)
353          *
354          * (*) We only allow interrupts if they were previously enabled and
355          *     we're not handling an IRQ
356          */
357
358         rsr     a3, ps
359         addi    a0, a0, -EXCCAUSE_LEVEL1_INTERRUPT
360         movi    a2, LOCKLEVEL
361         extui   a3, a3, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH
362                                         # a3 = PS.INTLEVEL
363         moveqz  a3, a2, a0              # a3 = LOCKLEVEL iff interrupt
364         movi    a2, 1 << PS_WOE_BIT
365         or      a3, a3, a2
366         rsr     a0, exccause
367         xsr     a3, ps
368
369         s32i    a3, a1, PT_PS           # save ps
370
371         /* Save lbeg, lend */
372
373         rsr     a2, lbeg
374         rsr     a3, lend
375         s32i    a2, a1, PT_LBEG
376         s32i    a3, a1, PT_LEND
377
378         /* Save SCOMPARE1 */
379
380 #if XCHAL_HAVE_S32C1I
381         rsr     a2, scompare1
382         s32i    a2, a1, PT_SCOMPARE1
383 #endif
384
385         /* Save optional registers. */
386
387         save_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
388         
389 #ifdef CONFIG_TRACE_IRQFLAGS
390         l32i    a4, a1, PT_DEPC
391         /* Double exception means we came here with an exception
392          * while PS.EXCM was set, i.e. interrupts disabled.
393          */
394         bgeui   a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
395         l32i    a4, a1, PT_EXCCAUSE
396         bnei    a4, EXCCAUSE_LEVEL1_INTERRUPT, 1f
397         /* We came here with an interrupt means interrupts were enabled
398          * and we've just disabled them.
399          */
400         movi    a4, trace_hardirqs_off
401         callx4  a4
402 1:
403 #endif
404
405         /* Go to second-level dispatcher. Set up parameters to pass to the
406          * exception handler and call the exception handler.
407          */
408
409         rsr     a4, excsave1
410         mov     a6, a1                  # pass stack frame
411         mov     a7, a0                  # pass EXCCAUSE
412         addx4   a4, a0, a4
413         l32i    a4, a4, EXC_TABLE_DEFAULT               # load handler
414
415         /* Call the second-level handler */
416
417         callx4  a4
418
419         /* Jump here for exception exit */
420         .global common_exception_return
421 common_exception_return:
422
423 1:
424         rsil    a2, LOCKLEVEL
425
426         /* Jump if we are returning from kernel exceptions. */
427
428         l32i    a3, a1, PT_PS
429         GET_THREAD_INFO(a2, a1)
430         l32i    a4, a2, TI_FLAGS
431         _bbci.l a3, PS_UM_BIT, 6f
432
433         /* Specific to a user exception exit:
434          * We need to check some flags for signal handling and rescheduling,
435          * and have to restore WB and WS, extra states, and all registers
436          * in the register file that were in use in the user task.
437          * Note that we don't disable interrupts here. 
438          */
439
440         _bbsi.l a4, TIF_NEED_RESCHED, 3f
441         _bbsi.l a4, TIF_NOTIFY_RESUME, 2f
442         _bbci.l a4, TIF_SIGPENDING, 5f
443
444 2:      l32i    a4, a1, PT_DEPC
445         bgeui   a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f
446
447         /* Call do_signal() */
448
449         rsil    a2, 0
450         movi    a4, do_notify_resume    # int do_notify_resume(struct pt_regs*)
451         mov     a6, a1
452         callx4  a4
453         j       1b
454
455 3:      /* Reschedule */
456
457         rsil    a2, 0
458         movi    a4, schedule    # void schedule (void)
459         callx4  a4
460         j       1b
461
462 #ifdef CONFIG_PREEMPT
463 6:
464         _bbci.l a4, TIF_NEED_RESCHED, 4f
465
466         /* Check current_thread_info->preempt_count */
467
468         l32i    a4, a2, TI_PRE_COUNT
469         bnez    a4, 4f
470         movi    a4, preempt_schedule_irq
471         callx4  a4
472         j       1b
473 #endif
474
475 5:
476 #ifdef CONFIG_DEBUG_TLB_SANITY
477         l32i    a4, a1, PT_DEPC
478         bgeui   a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f
479         movi    a4, check_tlb_sanity
480         callx4  a4
481 #endif
482 6:
483 4:
484 #ifdef CONFIG_TRACE_IRQFLAGS
485         l32i    a4, a1, PT_DEPC
486         /* Double exception means we came here with an exception
487          * while PS.EXCM was set, i.e. interrupts disabled.
488          */
489         bgeui   a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
490         l32i    a4, a1, PT_EXCCAUSE
491         bnei    a4, EXCCAUSE_LEVEL1_INTERRUPT, 1f
492         /* We came here with an interrupt means interrupts were enabled
493          * and we'll reenable them on return.
494          */
495         movi    a4, trace_hardirqs_on
496         callx4  a4
497 1:
498 #endif
499         /* Restore optional registers. */
500
501         load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
502
503         /* Restore SCOMPARE1 */
504
505 #if XCHAL_HAVE_S32C1I
506         l32i    a2, a1, PT_SCOMPARE1
507         wsr     a2, scompare1
508 #endif
509         wsr     a3, ps          /* disable interrupts */
510
511         _bbci.l a3, PS_UM_BIT, kernel_exception_exit
512
513 user_exception_exit:
514
515         /* Restore the state of the task and return from the exception. */
516
517         /* Switch to the user thread WINDOWBASE. Save SP temporarily in DEPC */
518
519         l32i    a2, a1, PT_WINDOWBASE
520         l32i    a3, a1, PT_WINDOWSTART
521         wsr     a1, depc                # use DEPC as temp storage
522         wsr     a3, windowstart         # restore WINDOWSTART
523         ssr     a2                      # preserve user's WB in the SAR
524         wsr     a2, windowbase          # switch to user's saved WB
525         rsync
526         rsr     a1, depc                # restore stack pointer
527         l32i    a2, a1, PT_WMASK        # register frames saved (in bits 4...9)
528         rotw    -1                      # we restore a4..a7
529         _bltui  a6, 16, 1f              # only have to restore current window?
530
531         /* The working registers are a0 and a3.  We are restoring to
532          * a4..a7.  Be careful not to destroy what we have just restored.
533          * Note: wmask has the format YYYYM:
534          *       Y: number of registers saved in groups of 4
535          *       M: 4 bit mask of first 16 registers
536          */
537
538         mov     a2, a6
539         mov     a3, a5
540
541 2:      rotw    -1                      # a0..a3 become a4..a7
542         addi    a3, a7, -4*4            # next iteration
543         addi    a2, a6, -16             # decrementing Y in WMASK
544         l32i    a4, a3, PT_AREG_END + 0
545         l32i    a5, a3, PT_AREG_END + 4
546         l32i    a6, a3, PT_AREG_END + 8
547         l32i    a7, a3, PT_AREG_END + 12
548         _bgeui  a2, 16, 2b
549
550         /* Clear unrestored registers (don't leak anything to user-land */
551
552 1:      rsr     a0, windowbase
553         rsr     a3, sar
554         sub     a3, a0, a3
555         beqz    a3, 2f
556         extui   a3, a3, 0, WBBITS
557
558 1:      rotw    -1
559         addi    a3, a7, -1
560         movi    a4, 0
561         movi    a5, 0
562         movi    a6, 0
563         movi    a7, 0
564         bgei    a3, 1, 1b
565
566         /* We are back were we were when we started.
567          * Note: a2 still contains WMASK (if we've returned to the original
568          *       frame where we had loaded a2), or at least the lower 4 bits
569          *       (if we have restored WSBITS-1 frames).
570          */
571
572 #if XCHAL_HAVE_THREADPTR
573         l32i    a3, a1, PT_THREADPTR
574         wur     a3, threadptr
575 #endif
576
577 2:      j       common_exception_exit
578
579         /* This is the kernel exception exit.
580          * We avoided to do a MOVSP when we entered the exception, but we
581          * have to do it here.
582          */
583
584 kernel_exception_exit:
585
586         /* Check if we have to do a movsp.
587          *
588          * We only have to do a movsp if the previous window-frame has
589          * been spilled to the *temporary* exception stack instead of the
590          * task's stack. This is the case if the corresponding bit in
591          * WINDOWSTART for the previous window-frame was set before
592          * (not spilled) but is zero now (spilled).
593          * If this bit is zero, all other bits except the one for the
594          * current window frame are also zero. So, we can use a simple test:
595          * 'and' WINDOWSTART and WINDOWSTART-1:
596          *
597          *  (XXXXXX1[0]* - 1) AND XXXXXX1[0]* = XXXXXX0[0]*
598          *
599          * The result is zero only if one bit was set.
600          *
601          * (Note: We might have gone through several task switches before
602          *        we come back to the current task, so WINDOWBASE might be
603          *        different from the time the exception occurred.)
604          */
605
606         /* Test WINDOWSTART before and after the exception.
607          * We actually have WMASK, so we only have to test if it is 1 or not.
608          */
609
610         l32i    a2, a1, PT_WMASK
611         _beqi   a2, 1, common_exception_exit    # Spilled before exception,jump
612
613         /* Test WINDOWSTART now. If spilled, do the movsp */
614
615         rsr     a3, windowstart
616         addi    a0, a3, -1
617         and     a3, a3, a0
618         _bnez   a3, common_exception_exit
619
620         /* Do a movsp (we returned from a call4, so we have at least a0..a7) */
621
622         addi    a0, a1, -16
623         l32i    a3, a0, 0
624         l32i    a4, a0, 4
625         s32i    a3, a1, PT_SIZE+0
626         s32i    a4, a1, PT_SIZE+4
627         l32i    a3, a0, 8
628         l32i    a4, a0, 12
629         s32i    a3, a1, PT_SIZE+8
630         s32i    a4, a1, PT_SIZE+12
631
632         /* Common exception exit.
633          * We restore the special register and the current window frame, and
634          * return from the exception.
635          *
636          * Note: We expect a2 to hold PT_WMASK
637          */
638
639 common_exception_exit:
640
641         /* Restore address registers. */
642
643         _bbsi.l a2, 1, 1f
644         l32i    a4,  a1, PT_AREG4
645         l32i    a5,  a1, PT_AREG5
646         l32i    a6,  a1, PT_AREG6
647         l32i    a7,  a1, PT_AREG7
648         _bbsi.l a2, 2, 1f
649         l32i    a8,  a1, PT_AREG8
650         l32i    a9,  a1, PT_AREG9
651         l32i    a10, a1, PT_AREG10
652         l32i    a11, a1, PT_AREG11
653         _bbsi.l a2, 3, 1f
654         l32i    a12, a1, PT_AREG12
655         l32i    a13, a1, PT_AREG13
656         l32i    a14, a1, PT_AREG14
657         l32i    a15, a1, PT_AREG15
658
659         /* Restore PC, SAR */
660
661 1:      l32i    a2, a1, PT_PC
662         l32i    a3, a1, PT_SAR
663         wsr     a2, epc1
664         wsr     a3, sar
665
666         /* Restore LBEG, LEND, LCOUNT */
667
668         l32i    a2, a1, PT_LBEG
669         l32i    a3, a1, PT_LEND
670         wsr     a2, lbeg
671         l32i    a2, a1, PT_LCOUNT
672         wsr     a3, lend
673         wsr     a2, lcount
674
675         /* We control single stepping through the ICOUNTLEVEL register. */
676
677         l32i    a2, a1, PT_ICOUNTLEVEL
678         movi    a3, -2
679         wsr     a2, icountlevel
680         wsr     a3, icount
681
682         /* Check if it was double exception. */
683
684         l32i    a0, a1, PT_DEPC
685         l32i    a3, a1, PT_AREG3
686         l32i    a2, a1, PT_AREG2
687         _bgeui  a0, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
688
689         /* Restore a0...a3 and return */
690
691         l32i    a0, a1, PT_AREG0
692         l32i    a1, a1, PT_AREG1
693         rfe
694
695 1:      wsr     a0, depc
696         l32i    a0, a1, PT_AREG0
697         l32i    a1, a1, PT_AREG1
698         rfde
699
700 ENDPROC(kernel_exception)
701
702 /*
703  * Debug exception handler.
704  *
705  * Currently, we don't support KGDB, so only user application can be debugged.
706  *
707  * When we get here,  a0 is trashed and saved to excsave[debuglevel]
708  */
709
710 ENTRY(debug_exception)
711
712         rsr     a0, SREG_EPS + XCHAL_DEBUGLEVEL
713         bbsi.l  a0, PS_EXCM_BIT, 1f     # exception mode
714
715         /* Set EPC1 and EXCCAUSE */
716
717         wsr     a2, depc                # save a2 temporarily
718         rsr     a2, SREG_EPC + XCHAL_DEBUGLEVEL
719         wsr     a2, epc1
720
721         movi    a2, EXCCAUSE_MAPPED_DEBUG
722         wsr     a2, exccause
723
724         /* Restore PS to the value before the debug exc but with PS.EXCM set.*/
725
726         movi    a2, 1 << PS_EXCM_BIT
727         or      a2, a0, a2
728         movi    a0, debug_exception     # restore a3, debug jump vector
729         wsr     a2, ps
730         xsr     a0, SREG_EXCSAVE + XCHAL_DEBUGLEVEL
731
732         /* Switch to kernel/user stack, restore jump vector, and save a0 */
733
734         bbsi.l  a2, PS_UM_BIT, 2f       # jump if user mode
735
736         addi    a2, a1, -16-PT_SIZE     # assume kernel stack
737         s32i    a0, a2, PT_AREG0
738         movi    a0, 0
739         s32i    a1, a2, PT_AREG1
740         s32i    a0, a2, PT_DEPC         # mark it as a regular exception
741         xsr     a0, depc
742         s32i    a3, a2, PT_AREG3
743         s32i    a0, a2, PT_AREG2
744         mov     a1, a2
745         j       _kernel_exception
746
747 2:      rsr     a2, excsave1
748         l32i    a2, a2, EXC_TABLE_KSTK  # load kernel stack pointer
749         s32i    a0, a2, PT_AREG0
750         movi    a0, 0
751         s32i    a1, a2, PT_AREG1
752         s32i    a0, a2, PT_DEPC
753         xsr     a0, depc
754         s32i    a3, a2, PT_AREG3
755         s32i    a0, a2, PT_AREG2
756         mov     a1, a2
757         j       _user_exception
758
759         /* Debug exception while in exception mode. */
760 1:      j       1b      // FIXME!!
761
762 ENDPROC(debug_exception)
763
764 /*
765  * We get here in case of an unrecoverable exception.
766  * The only thing we can do is to be nice and print a panic message.
767  * We only produce a single stack frame for panic, so ???
768  *
769  *
770  * Entry conditions:
771  *
772  *   - a0 contains the caller address; original value saved in excsave1.
773  *   - the original a0 contains a valid return address (backtrace) or 0.
774  *   - a2 contains a valid stackpointer
775  *
776  * Notes:
777  *
778  *   - If the stack pointer could be invalid, the caller has to setup a
779  *     dummy stack pointer (e.g. the stack of the init_task)
780  *
781  *   - If the return address could be invalid, the caller has to set it
782  *     to 0, so the backtrace would stop.
783  *
784  */
785         .align 4
786 unrecoverable_text:
787         .ascii "Unrecoverable error in exception handler\0"
788
789 ENTRY(unrecoverable_exception)
790
791         movi    a0, 1
792         movi    a1, 0
793
794         wsr     a0, windowstart
795         wsr     a1, windowbase
796         rsync
797
798         movi    a1, (1 << PS_WOE_BIT) | LOCKLEVEL
799         wsr     a1, ps
800         rsync
801
802         movi    a1, init_task
803         movi    a0, 0
804         addi    a1, a1, PT_REGS_OFFSET
805
806         movi    a4, panic
807         movi    a6, unrecoverable_text
808
809         callx4  a4
810
811 1:      j       1b
812
813 ENDPROC(unrecoverable_exception)
814
815 /* -------------------------- FAST EXCEPTION HANDLERS ----------------------- */
816
817 /*
818  * Fast-handler for alloca exceptions
819  *
820  *  The ALLOCA handler is entered when user code executes the MOVSP
821  *  instruction and the caller's frame is not in the register file.
822  *  In this case, the caller frame's a0..a3 are on the stack just
823  *  below sp (a1), and this handler moves them.
824  *
825  *  For "MOVSP <ar>,<as>" without destination register a1, this routine
826  *  simply moves the value from <as> to <ar> without moving the save area.
827  *
828  * Entry condition:
829  *
830  *   a0:        trashed, original value saved on stack (PT_AREG0)
831  *   a1:        a1
832  *   a2:        new stack pointer, original in DEPC
833  *   a3:        a3
834  *   depc:      a2, original value saved on stack (PT_DEPC)
835  *   excsave_1: dispatch table
836  *
837  *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
838  *           <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
839  */
840
841 #if XCHAL_HAVE_BE
842 #define _EXTUI_MOVSP_SRC(ar)    extui ar, ar, 4, 4
843 #define _EXTUI_MOVSP_DST(ar)    extui ar, ar, 0, 4
844 #else
845 #define _EXTUI_MOVSP_SRC(ar)    extui ar, ar, 0, 4
846 #define _EXTUI_MOVSP_DST(ar)    extui ar, ar, 4, 4
847 #endif
848
849 ENTRY(fast_alloca)
850
851         /* We shouldn't be in a double exception. */
852
853         l32i    a0, a2, PT_DEPC
854         _bgeui  a0, VALID_DOUBLE_EXCEPTION_ADDRESS, .Lunhandled_double
855
856         rsr     a0, depc                # get a2
857         s32i    a4, a2, PT_AREG4        # save a4 and
858         s32i    a3, a2, PT_AREG3
859         s32i    a0, a2, PT_AREG2        # a2 to stack
860
861         /* Exit critical section. */
862
863         movi    a0, 0
864         rsr     a3, excsave1
865         s32i    a0, a3, EXC_TABLE_FIXUP
866
867         rsr     a4, epc1                # get exception address
868
869 #ifdef ALLOCA_EXCEPTION_IN_IRAM
870 #error  iram not supported
871 #else
872         /* Note: l8ui not allowed in IRAM/IROM!! */
873         l8ui    a0, a4, 1               # read as(src) from MOVSP instruction
874 #endif
875         movi    a3, .Lmovsp_src
876         _EXTUI_MOVSP_SRC(a0)            # extract source register number
877         addx8   a3, a0, a3
878         jx      a3
879
880 .Lunhandled_double:
881         wsr     a0, excsave1
882         movi    a0, unrecoverable_exception
883         callx0  a0
884
885         .align 8
886 .Lmovsp_src:
887         l32i    a3, a2, PT_AREG0;       _j 1f;  .align 8
888         mov     a3, a1;                 _j 1f;  .align 8
889         l32i    a3, a2, PT_AREG2;       _j 1f;  .align 8
890         l32i    a3, a2, PT_AREG3;       _j 1f;  .align 8
891         l32i    a3, a2, PT_AREG4;       _j 1f;  .align 8
892         mov     a3, a5;                 _j 1f;  .align 8
893         mov     a3, a6;                 _j 1f;  .align 8
894         mov     a3, a7;                 _j 1f;  .align 8
895         mov     a3, a8;                 _j 1f;  .align 8
896         mov     a3, a9;                 _j 1f;  .align 8
897         mov     a3, a10;                _j 1f;  .align 8
898         mov     a3, a11;                _j 1f;  .align 8
899         mov     a3, a12;                _j 1f;  .align 8
900         mov     a3, a13;                _j 1f;  .align 8
901         mov     a3, a14;                _j 1f;  .align 8
902         mov     a3, a15;                _j 1f;  .align 8
903
904 1:
905
906 #ifdef ALLOCA_EXCEPTION_IN_IRAM
907 #error  iram not supported
908 #else
909         l8ui    a0, a4, 0               # read ar(dst) from MOVSP instruction
910 #endif
911         addi    a4, a4, 3               # step over movsp
912         _EXTUI_MOVSP_DST(a0)            # extract destination register
913         wsr     a4, epc1                # save new epc_1
914
915         _bnei   a0, 1, 1f               # no 'movsp a1, ax': jump
916
917         /* Move the save area. This implies the use of the L32E
918          * and S32E instructions, because this move must be done with
919          * the user's PS.RING privilege levels, not with ring 0
920          * (kernel's) privileges currently active with PS.EXCM
921          * set. Note that we have stil registered a fixup routine with the
922          * double exception vector in case a double exception occurs.
923          */
924
925         /* a0,a4:avail a1:old user stack a2:exc. stack a3:new user stack. */
926
927         l32e    a0, a1, -16
928         l32e    a4, a1, -12
929         s32e    a0, a3, -16
930         s32e    a4, a3, -12
931         l32e    a0, a1, -8
932         l32e    a4, a1, -4
933         s32e    a0, a3, -8
934         s32e    a4, a3, -4
935
936         /* Restore stack-pointer and all the other saved registers. */
937
938         mov     a1, a3
939
940         l32i    a4, a2, PT_AREG4
941         l32i    a3, a2, PT_AREG3
942         l32i    a0, a2, PT_AREG0
943         l32i    a2, a2, PT_AREG2
944         rfe
945
946         /*  MOVSP <at>,<as>  was invoked with <at> != a1.
947          *  Because the stack pointer is not being modified,
948          *  we should be able to just modify the pointer
949          *  without moving any save area.
950          *  The processor only traps these occurrences if the
951          *  caller window isn't live, so unfortunately we can't
952          *  use this as an alternate trap mechanism.
953          *  So we just do the move.  This requires that we
954          *  resolve the destination register, not just the source,
955          *  so there's some extra work.
956          *  (PERHAPS NOT REALLY NEEDED, BUT CLEANER...)
957          */
958
959         /* a0 dst-reg, a1 user-stack, a2 stack, a3 value of src reg. */
960
961 1:      movi    a4, .Lmovsp_dst
962         addx8   a4, a0, a4
963         jx      a4
964
965         .align 8
966 .Lmovsp_dst:
967         s32i    a3, a2, PT_AREG0;       _j 1f;  .align 8
968         mov     a1, a3;                 _j 1f;  .align 8
969         s32i    a3, a2, PT_AREG2;       _j 1f;  .align 8
970         s32i    a3, a2, PT_AREG3;       _j 1f;  .align 8
971         s32i    a3, a2, PT_AREG4;       _j 1f;  .align 8
972         mov     a5, a3;                 _j 1f;  .align 8
973         mov     a6, a3;                 _j 1f;  .align 8
974         mov     a7, a3;                 _j 1f;  .align 8
975         mov     a8, a3;                 _j 1f;  .align 8
976         mov     a9, a3;                 _j 1f;  .align 8
977         mov     a10, a3;                _j 1f;  .align 8
978         mov     a11, a3;                _j 1f;  .align 8
979         mov     a12, a3;                _j 1f;  .align 8
980         mov     a13, a3;                _j 1f;  .align 8
981         mov     a14, a3;                _j 1f;  .align 8
982         mov     a15, a3;                _j 1f;  .align 8
983
984 1:      l32i    a4, a2, PT_AREG4
985         l32i    a3, a2, PT_AREG3
986         l32i    a0, a2, PT_AREG0
987         l32i    a2, a2, PT_AREG2
988         rfe
989
990 ENDPROC(fast_alloca)
991
992 /*
993  * fast system calls.
994  *
995  * WARNING:  The kernel doesn't save the entire user context before
996  * handling a fast system call.  These functions are small and short,
997  * usually offering some functionality not available to user tasks.
998  *
999  * BE CAREFUL TO PRESERVE THE USER'S CONTEXT.
1000  *
1001  * Entry condition:
1002  *
1003  *   a0:        trashed, original value saved on stack (PT_AREG0)
1004  *   a1:        a1
1005  *   a2:        new stack pointer, original in DEPC
1006  *   a3:        a3
1007  *   depc:      a2, original value saved on stack (PT_DEPC)
1008  *   excsave_1: dispatch table
1009  */
1010
1011 ENTRY(fast_syscall_kernel)
1012
1013         /* Skip syscall. */
1014
1015         rsr     a0, epc1
1016         addi    a0, a0, 3
1017         wsr     a0, epc1
1018
1019         l32i    a0, a2, PT_DEPC
1020         bgeui   a0, VALID_DOUBLE_EXCEPTION_ADDRESS, fast_syscall_unrecoverable
1021
1022         rsr     a0, depc                        # get syscall-nr
1023         _beqz   a0, fast_syscall_spill_registers
1024         _beqi   a0, __NR_xtensa, fast_syscall_xtensa
1025
1026         j       kernel_exception
1027
1028 ENDPROC(fast_syscall_kernel)
1029
1030 ENTRY(fast_syscall_user)
1031
1032         /* Skip syscall. */
1033
1034         rsr     a0, epc1
1035         addi    a0, a0, 3
1036         wsr     a0, epc1
1037
1038         l32i    a0, a2, PT_DEPC
1039         bgeui   a0, VALID_DOUBLE_EXCEPTION_ADDRESS, fast_syscall_unrecoverable
1040
1041         rsr     a0, depc                        # get syscall-nr
1042         _beqz   a0, fast_syscall_spill_registers
1043         _beqi   a0, __NR_xtensa, fast_syscall_xtensa
1044
1045         j       user_exception
1046
1047 ENDPROC(fast_syscall_user)
1048
1049 ENTRY(fast_syscall_unrecoverable)
1050
1051         /* Restore all states. */
1052
1053         l32i    a0, a2, PT_AREG0        # restore a0
1054         xsr     a2, depc                # restore a2, depc
1055
1056         wsr     a0, excsave1
1057         movi    a0, unrecoverable_exception
1058         callx0  a0
1059
1060 ENDPROC(fast_syscall_unrecoverable)
1061
1062 /*
1063  * sysxtensa syscall handler
1064  *
1065  * int sysxtensa (SYS_XTENSA_ATOMIC_SET,     ptr, val,    unused);
1066  * int sysxtensa (SYS_XTENSA_ATOMIC_ADD,     ptr, val,    unused);
1067  * int sysxtensa (SYS_XTENSA_ATOMIC_EXG_ADD, ptr, val,    unused);
1068  * int sysxtensa (SYS_XTENSA_ATOMIC_CMP_SWP, ptr, oldval, newval);
1069  *        a2            a6                   a3    a4      a5
1070  *
1071  * Entry condition:
1072  *
1073  *   a0:        a2 (syscall-nr), original value saved on stack (PT_AREG0)
1074  *   a1:        a1
1075  *   a2:        new stack pointer, original in a0 and DEPC
1076  *   a3:        a3
1077  *   a4..a15:   unchanged
1078  *   depc:      a2, original value saved on stack (PT_DEPC)
1079  *   excsave_1: dispatch table
1080  *
1081  *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
1082  *           <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
1083  *
1084  * Note: we don't have to save a2; a2 holds the return value
1085  *
1086  * We use the two macros TRY and CATCH:
1087  *
1088  * TRY   adds an entry to the __ex_table fixup table for the immediately
1089  *       following instruction.
1090  *
1091  * CATCH catches any exception that occurred at one of the preceding TRY
1092  *       statements and continues from there
1093  *
1094  * Usage TRY    l32i    a0, a1, 0
1095  *              <other code>
1096  *       done:  rfe
1097  *       CATCH  <set return code>
1098  *              j done
1099  */
1100
1101 #define TRY                                                             \
1102         .section __ex_table, "a";                                       \
1103         .word   66f, 67f;                                               \
1104         .text;                                                          \
1105 66:
1106
1107 #define CATCH                                                           \
1108 67:
1109
1110 ENTRY(fast_syscall_xtensa)
1111
1112         s32i    a7, a2, PT_AREG7        # we need an additional register
1113         movi    a7, 4                   # sizeof(unsigned int)
1114         access_ok a3, a7, a0, a2, .Leac # a0: scratch reg, a2: sp
1115
1116         addi    a6, a6, -1              # assuming SYS_XTENSA_ATOMIC_SET = 1
1117         _bgeui  a6, SYS_XTENSA_COUNT - 1, .Lill
1118         _bnei   a6, SYS_XTENSA_ATOMIC_CMP_SWP - 1, .Lnswp
1119
1120         /* Fall through for ATOMIC_CMP_SWP. */
1121
1122 .Lswp:  /* Atomic compare and swap */
1123
1124 TRY     l32i    a0, a3, 0               # read old value
1125         bne     a0, a4, 1f              # same as old value? jump
1126 TRY     s32i    a5, a3, 0               # different, modify value
1127         l32i    a7, a2, PT_AREG7        # restore a7
1128         l32i    a0, a2, PT_AREG0        # restore a0
1129         movi    a2, 1                   # and return 1
1130         addi    a6, a6, 1               # restore a6 (really necessary?)
1131         rfe
1132
1133 1:      l32i    a7, a2, PT_AREG7        # restore a7
1134         l32i    a0, a2, PT_AREG0        # restore a0
1135         movi    a2, 0                   # return 0 (note that we cannot set
1136         addi    a6, a6, 1               # restore a6 (really necessary?)
1137         rfe
1138
1139 .Lnswp: /* Atomic set, add, and exg_add. */
1140
1141 TRY     l32i    a7, a3, 0               # orig
1142         add     a0, a4, a7              # + arg
1143         moveqz  a0, a4, a6              # set
1144 TRY     s32i    a0, a3, 0               # write new value
1145
1146         mov     a0, a2
1147         mov     a2, a7
1148         l32i    a7, a0, PT_AREG7        # restore a7
1149         l32i    a0, a0, PT_AREG0        # restore a0
1150         addi    a6, a6, 1               # restore a6 (really necessary?)
1151         rfe
1152
1153 CATCH
1154 .Leac:  l32i    a7, a2, PT_AREG7        # restore a7
1155         l32i    a0, a2, PT_AREG0        # restore a0
1156         movi    a2, -EFAULT
1157         rfe
1158
1159 .Lill:  l32i    a7, a2, PT_AREG0        # restore a7
1160         l32i    a0, a2, PT_AREG0        # restore a0
1161         movi    a2, -EINVAL
1162         rfe
1163
1164 ENDPROC(fast_syscall_xtensa)
1165
1166
1167 /* fast_syscall_spill_registers.
1168  *
1169  * Entry condition:
1170  *
1171  *   a0:        trashed, original value saved on stack (PT_AREG0)
1172  *   a1:        a1
1173  *   a2:        new stack pointer, original in DEPC
1174  *   a3:        a3
1175  *   depc:      a2, original value saved on stack (PT_DEPC)
1176  *   excsave_1: dispatch table
1177  *
1178  * Note: We assume the stack pointer is EXC_TABLE_KSTK in the fixup handler.
1179  */
1180
1181 ENTRY(fast_syscall_spill_registers)
1182
1183         /* Register a FIXUP handler (pass current wb as a parameter) */
1184
1185         xsr     a3, excsave1
1186         movi    a0, fast_syscall_spill_registers_fixup
1187         s32i    a0, a3, EXC_TABLE_FIXUP
1188         rsr     a0, windowbase
1189         s32i    a0, a3, EXC_TABLE_PARAM
1190         xsr     a3, excsave1            # restore a3 and excsave_1
1191
1192         /* Save a3, a4 and SAR on stack. */
1193
1194         rsr     a0, sar
1195         s32i    a3, a2, PT_AREG3
1196         s32i    a4, a2, PT_AREG4
1197         s32i    a0, a2, PT_AREG5        # store SAR to PT_AREG5
1198
1199         /* The spill routine might clobber a7, a11, and a15. */
1200
1201         s32i    a7, a2, PT_AREG7
1202         s32i    a11, a2, PT_AREG11
1203         s32i    a15, a2, PT_AREG15
1204
1205         call0   _spill_registers        # destroys a3, a4, and SAR
1206
1207         /* Advance PC, restore registers and SAR, and return from exception. */
1208
1209         l32i    a3, a2, PT_AREG5
1210         l32i    a4, a2, PT_AREG4
1211         l32i    a0, a2, PT_AREG0
1212         wsr     a3, sar
1213         l32i    a3, a2, PT_AREG3
1214
1215         /* Restore clobbered registers. */
1216
1217         l32i    a7, a2, PT_AREG7
1218         l32i    a11, a2, PT_AREG11
1219         l32i    a15, a2, PT_AREG15
1220
1221         movi    a2, 0
1222         rfe
1223
1224 ENDPROC(fast_syscall_spill_registers)
1225
1226 /* Fixup handler.
1227  *
1228  * We get here if the spill routine causes an exception, e.g. tlb miss.
1229  * We basically restore WINDOWBASE and WINDOWSTART to the condition when
1230  * we entered the spill routine and jump to the user exception handler.
1231  *
1232  * a0: value of depc, original value in depc
1233  * a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE
1234  * a3: exctable, original value in excsave1
1235  */
1236
1237 fast_syscall_spill_registers_fixup:
1238
1239         rsr     a2, windowbase  # get current windowbase (a2 is saved)
1240         xsr     a0, depc        # restore depc and a0
1241         ssl     a2              # set shift (32 - WB)
1242
1243         /* We need to make sure the current registers (a0-a3) are preserved.
1244          * To do this, we simply set the bit for the current window frame
1245          * in WS, so that the exception handlers save them to the task stack.
1246          */
1247
1248         xsr     a3, excsave1    # get spill-mask
1249         slli    a2, a3, 1       # shift left by one
1250
1251         slli    a3, a2, 32-WSBITS
1252         src     a2, a2, a3      # a1 = xxwww1yyxxxwww1yy......
1253         wsr     a2, windowstart # set corrected windowstart
1254
1255         rsr     a3, excsave1
1256         l32i    a2, a3, EXC_TABLE_DOUBLE_SAVE   # restore a2
1257         l32i    a3, a3, EXC_TABLE_PARAM # original WB (in user task)
1258
1259         /* Return to the original (user task) WINDOWBASE.
1260          * We leave the following frame behind:
1261          * a0, a1, a2   same
1262          * a3:          trashed (saved in excsave_1)
1263          * depc:        depc (we have to return to that address)
1264          * excsave_1:   a3
1265          */
1266
1267         wsr     a3, windowbase
1268         rsync
1269
1270         /* We are now in the original frame when we entered _spill_registers:
1271          *  a0: return address
1272          *  a1: used, stack pointer
1273          *  a2: kernel stack pointer
1274          *  a3: available, saved in EXCSAVE_1
1275          *  depc: exception address
1276          *  excsave: a3
1277          * Note: This frame might be the same as above.
1278          */
1279
1280         /* Setup stack pointer. */
1281
1282         addi    a2, a2, -PT_USER_SIZE
1283         s32i    a0, a2, PT_AREG0
1284
1285         /* Make sure we return to this fixup handler. */
1286
1287         movi    a3, fast_syscall_spill_registers_fixup_return
1288         s32i    a3, a2, PT_DEPC         # setup depc
1289
1290         /* Jump to the exception handler. */
1291
1292         rsr     a3, excsave1
1293         rsr     a0, exccause
1294         addx4   a0, a0, a3                      # find entry in table
1295         l32i    a0, a0, EXC_TABLE_FAST_USER     # load handler
1296         jx      a0
1297
1298 fast_syscall_spill_registers_fixup_return:
1299
1300         /* When we return here, all registers have been restored (a2: DEPC) */
1301
1302         wsr     a2, depc                # exception address
1303
1304         /* Restore fixup handler. */
1305
1306         xsr     a3, excsave1
1307         movi    a2, fast_syscall_spill_registers_fixup
1308         s32i    a2, a3, EXC_TABLE_FIXUP
1309         s32i    a0, a3, EXC_TABLE_DOUBLE_SAVE
1310         rsr     a2, windowbase
1311         s32i    a2, a3, EXC_TABLE_PARAM
1312         l32i    a2, a3, EXC_TABLE_KSTK
1313
1314         /* Load WB at the time the exception occurred. */
1315
1316         rsr     a3, sar                 # WB is still in SAR
1317         neg     a3, a3
1318         wsr     a3, windowbase
1319         rsync
1320
1321         rfde
1322
1323
1324 /*
1325  * spill all registers.
1326  *
1327  * This is not a real function. The following conditions must be met:
1328  *
1329  *  - must be called with call0.
1330  *  - uses a3, a4 and SAR.
1331  *  - the last 'valid' register of each frame are clobbered.
1332  *  - the caller must have registered a fixup handler
1333  *    (or be inside a critical section)
1334  *  - PS_EXCM must be set (PS_WOE cleared?)
1335  */
1336
1337 ENTRY(_spill_registers)
1338
1339         /*
1340          * Rotate ws so that the current windowbase is at bit 0.
1341          * Assume ws = xxxwww1yy (www1 current window frame).
1342          * Rotate ws right so that a4 = yyxxxwww1.
1343          */
1344
1345         rsr     a4, windowbase
1346         rsr     a3, windowstart         # a3 = xxxwww1yy
1347         ssr     a4                      # holds WB
1348         slli    a4, a3, WSBITS
1349         or      a3, a3, a4              # a3 = xxxwww1yyxxxwww1yy
1350         srl     a3, a3                  # a3 = 00xxxwww1yyxxxwww1
1351
1352         /* We are done if there are no more than the current register frame. */
1353
1354         extui   a3, a3, 1, WSBITS-1     # a3 = 0yyxxxwww
1355         movi    a4, (1 << (WSBITS-1))
1356         _beqz   a3, .Lnospill           # only one active frame? jump
1357
1358         /* We want 1 at the top, so that we return to the current windowbase */
1359
1360         or      a3, a3, a4              # 1yyxxxwww
1361
1362         /* Skip empty frames - get 'oldest' WINDOWSTART-bit. */
1363
1364         wsr     a3, windowstart         # save shifted windowstart
1365         neg     a4, a3
1366         and     a3, a4, a3              # first bit set from right: 000010000
1367
1368         ffs_ws  a4, a3                  # a4: shifts to skip empty frames
1369         movi    a3, WSBITS
1370         sub     a4, a3, a4              # WSBITS-a4:number of 0-bits from right
1371         ssr     a4                      # save in SAR for later.
1372
1373         rsr     a3, windowbase
1374         add     a3, a3, a4
1375         wsr     a3, windowbase
1376         rsync
1377
1378         rsr     a3, windowstart
1379         srl     a3, a3                  # shift windowstart
1380
1381         /* WB is now just one frame below the oldest frame in the register
1382            window. WS is shifted so the oldest frame is in bit 0, thus, WB
1383            and WS differ by one 4-register frame. */
1384
1385         /* Save frames. Depending what call was used (call4, call8, call12),
1386          * we have to save 4,8. or 12 registers.
1387          */
1388
1389         _bbsi.l a3, 1, .Lc4
1390         _bbsi.l a3, 2, .Lc8
1391
1392         /* Special case: we have a call12-frame starting at a4. */
1393
1394         _bbci.l a3, 3, .Lc12    # bit 3 shouldn't be zero! (Jump to Lc12 first)
1395
1396         s32e    a4, a1, -16     # a1 is valid with an empty spill area
1397         l32e    a4, a5, -12
1398         s32e    a8, a4, -48
1399         mov     a8, a4
1400         l32e    a4, a1, -16
1401         j       .Lc12c
1402
1403 .Lnospill:
1404         ret
1405
1406 .Lloop: _bbsi.l a3, 1, .Lc4
1407         _bbci.l a3, 2, .Lc12
1408
1409 .Lc8:   s32e    a4, a13, -16
1410         l32e    a4, a5, -12
1411         s32e    a8, a4, -32
1412         s32e    a5, a13, -12
1413         s32e    a6, a13, -8
1414         s32e    a7, a13, -4
1415         s32e    a9, a4, -28
1416         s32e    a10, a4, -24
1417         s32e    a11, a4, -20
1418
1419         srli    a11, a3, 2              # shift windowbase by 2
1420         rotw    2
1421         _bnei   a3, 1, .Lloop
1422
1423 .Lexit: /* Done. Do the final rotation, set WS, and return. */
1424
1425         rotw    1
1426         rsr     a3, windowbase
1427         ssl     a3
1428         movi    a3, 1
1429         sll     a3, a3
1430         wsr     a3, windowstart
1431         ret
1432
1433 .Lc4:   s32e    a4, a9, -16
1434         s32e    a5, a9, -12
1435         s32e    a6, a9, -8
1436         s32e    a7, a9, -4
1437
1438         srli    a7, a3, 1
1439         rotw    1
1440         _bnei   a3, 1, .Lloop
1441         j       .Lexit
1442
1443 .Lc12:  _bbci.l a3, 3, .Linvalid_mask   # bit 2 shouldn't be zero!
1444
1445         /* 12-register frame (call12) */
1446
1447         l32e    a2, a5, -12
1448         s32e    a8, a2, -48
1449         mov     a8, a2
1450
1451 .Lc12c: s32e    a9, a8, -44
1452         s32e    a10, a8, -40
1453         s32e    a11, a8, -36
1454         s32e    a12, a8, -32
1455         s32e    a13, a8, -28
1456         s32e    a14, a8, -24
1457         s32e    a15, a8, -20
1458         srli    a15, a3, 3
1459
1460         /* The stack pointer for a4..a7 is out of reach, so we rotate the
1461          * window, grab the stackpointer, and rotate back.
1462          * Alternatively, we could also use the following approach, but that
1463          * makes the fixup routine much more complicated:
1464          * rotw 1
1465          * s32e a0, a13, -16
1466          * ...
1467          * rotw 2
1468          */
1469
1470         rotw    1
1471         mov     a5, a13
1472         rotw    -1
1473
1474         s32e    a4, a9, -16
1475         s32e    a5, a9, -12
1476         s32e    a6, a9, -8
1477         s32e    a7, a9, -4
1478
1479         rotw    3
1480
1481         _beqi   a3, 1, .Lexit
1482         j       .Lloop
1483
1484 .Linvalid_mask:
1485
1486         /* We get here because of an unrecoverable error in the window
1487          * registers. If we are in user space, we kill the application,
1488          * however, this condition is unrecoverable in kernel space.
1489          */
1490
1491         rsr     a0, ps
1492         _bbci.l a0, PS_UM_BIT, 1f
1493
1494         /* User space: Setup a dummy frame and kill application.
1495          * Note: We assume EXC_TABLE_KSTK contains a valid stack pointer.
1496          */
1497
1498         movi    a0, 1
1499         movi    a1, 0
1500
1501         wsr     a0, windowstart
1502         wsr     a1, windowbase
1503         rsync
1504
1505         movi    a0, 0
1506
1507         rsr     a3, excsave1
1508         l32i    a1, a3, EXC_TABLE_KSTK
1509
1510         movi    a4, (1 << PS_WOE_BIT) | LOCKLEVEL
1511         wsr     a4, ps
1512         rsync
1513
1514         movi    a6, SIGSEGV
1515         movi    a4, do_exit
1516         callx4  a4
1517
1518 1:      /* Kernel space: PANIC! */
1519
1520         wsr     a0, excsave1
1521         movi    a0, unrecoverable_exception
1522         callx0  a0              # should not return
1523 1:      j       1b
1524
1525 ENDPROC(_spill_registers)
1526
1527 #ifdef CONFIG_MMU
1528 /*
1529  * We should never get here. Bail out!
1530  */
1531
1532 ENTRY(fast_second_level_miss_double_kernel)
1533
1534 1:      movi    a0, unrecoverable_exception
1535         callx0  a0              # should not return
1536 1:      j       1b
1537
1538 ENDPROC(fast_second_level_miss_double_kernel)
1539
1540 /* First-level entry handler for user, kernel, and double 2nd-level
1541  * TLB miss exceptions.  Note that for now, user and kernel miss
1542  * exceptions share the same entry point and are handled identically.
1543  *
1544  * An old, less-efficient C version of this function used to exist.
1545  * We include it below, interleaved as comments, for reference.
1546  *
1547  * Entry condition:
1548  *
1549  *   a0:        trashed, original value saved on stack (PT_AREG0)
1550  *   a1:        a1
1551  *   a2:        new stack pointer, original in DEPC
1552  *   a3:        a3
1553  *   depc:      a2, original value saved on stack (PT_DEPC)
1554  *   excsave_1: dispatch table
1555  *
1556  *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
1557  *           <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
1558  */
1559
1560 ENTRY(fast_second_level_miss)
1561
1562         /* Save a1 and a3. Note: we don't expect a double exception. */
1563
1564         s32i    a1, a2, PT_AREG1
1565         s32i    a3, a2, PT_AREG3
1566
1567         /* We need to map the page of PTEs for the user task.  Find
1568          * the pointer to that page.  Also, it's possible for tsk->mm
1569          * to be NULL while tsk->active_mm is nonzero if we faulted on
1570          * a vmalloc address.  In that rare case, we must use
1571          * active_mm instead to avoid a fault in this handler.  See
1572          *
1573          * http://mail.nl.linux.org/linux-mm/2002-08/msg00258.html
1574          *   (or search Internet on "mm vs. active_mm")
1575          *
1576          *      if (!mm)
1577          *              mm = tsk->active_mm;
1578          *      pgd = pgd_offset (mm, regs->excvaddr);
1579          *      pmd = pmd_offset (pgd, regs->excvaddr);
1580          *      pmdval = *pmd;
1581          */
1582
1583         GET_CURRENT(a1,a2)
1584         l32i    a0, a1, TASK_MM         # tsk->mm
1585         beqz    a0, 9f
1586
1587 8:      rsr     a3, excvaddr            # fault address
1588         _PGD_OFFSET(a0, a3, a1)
1589         l32i    a0, a0, 0               # read pmdval
1590         beqz    a0, 2f
1591
1592         /* Read ptevaddr and convert to top of page-table page.
1593          *
1594          *      vpnval = read_ptevaddr_register() & PAGE_MASK;
1595          *      vpnval += DTLB_WAY_PGTABLE;
1596          *      pteval = mk_pte (virt_to_page(pmd_val(pmdval)), PAGE_KERNEL);
1597          *      write_dtlb_entry (pteval, vpnval);
1598          *
1599          * The messy computation for 'pteval' above really simplifies
1600          * into the following:
1601          *
1602          * pteval = ((pmdval - PAGE_OFFSET) & PAGE_MASK) | PAGE_DIRECTORY
1603          */
1604
1605         movi    a1, (-PAGE_OFFSET) & 0xffffffff
1606         add     a0, a0, a1              # pmdval - PAGE_OFFSET
1607         extui   a1, a0, 0, PAGE_SHIFT   # ... & PAGE_MASK
1608         xor     a0, a0, a1
1609
1610         movi    a1, _PAGE_DIRECTORY
1611         or      a0, a0, a1              # ... | PAGE_DIRECTORY
1612
1613         /*
1614          * We utilize all three wired-ways (7-9) to hold pmd translations.
1615          * Memory regions are mapped to the DTLBs according to bits 28 and 29.
1616          * This allows to map the three most common regions to three different
1617          * DTLBs:
1618          *  0,1 -> way 7        program (0040.0000) and virtual (c000.0000)
1619          *  2   -> way 8        shared libaries (2000.0000)
1620          *  3   -> way 0        stack (3000.0000)
1621          */
1622
1623         extui   a3, a3, 28, 2           # addr. bit 28 and 29   0,1,2,3
1624         rsr     a1, ptevaddr
1625         addx2   a3, a3, a3              # ->                    0,3,6,9
1626         srli    a1, a1, PAGE_SHIFT
1627         extui   a3, a3, 2, 2            # ->                    0,0,1,2
1628         slli    a1, a1, PAGE_SHIFT      # ptevaddr & PAGE_MASK
1629         addi    a3, a3, DTLB_WAY_PGD
1630         add     a1, a1, a3              # ... + way_number
1631
1632 3:      wdtlb   a0, a1
1633         dsync
1634
1635         /* Exit critical section. */
1636
1637 4:      rsr     a3, excsave1
1638         movi    a0, 0
1639         s32i    a0, a3, EXC_TABLE_FIXUP
1640
1641         /* Restore the working registers, and return. */
1642
1643         l32i    a0, a2, PT_AREG0
1644         l32i    a1, a2, PT_AREG1
1645         l32i    a3, a2, PT_AREG3
1646         l32i    a2, a2, PT_DEPC
1647
1648         bgeui   a2, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
1649
1650         /* Restore excsave1 and return. */
1651
1652         rsr     a2, depc
1653         rfe
1654
1655         /* Return from double exception. */
1656
1657 1:      xsr     a2, depc
1658         esync
1659         rfde
1660
1661 9:      l32i    a0, a1, TASK_ACTIVE_MM  # unlikely case mm == 0
1662         j       8b
1663
1664 #if (DCACHE_WAY_SIZE > PAGE_SIZE)
1665
1666 2:      /* Special case for cache aliasing.
1667          * We (should) only get here if a clear_user_page, copy_user_page
1668          * or the aliased cache flush functions got preemptively interrupted 
1669          * by another task. Re-establish temporary mapping to the 
1670          * TLBTEMP_BASE areas.
1671          */
1672
1673         /* We shouldn't be in a double exception */
1674
1675         l32i    a0, a2, PT_DEPC
1676         bgeui   a0, VALID_DOUBLE_EXCEPTION_ADDRESS, 2f
1677
1678         /* Make sure the exception originated in the special functions */
1679
1680         movi    a0, __tlbtemp_mapping_start
1681         rsr     a3, epc1
1682         bltu    a3, a0, 2f
1683         movi    a0, __tlbtemp_mapping_end
1684         bgeu    a3, a0, 2f
1685
1686         /* Check if excvaddr was in one of the TLBTEMP_BASE areas. */
1687
1688         movi    a3, TLBTEMP_BASE_1
1689         rsr     a0, excvaddr
1690         bltu    a0, a3, 2f
1691
1692         addi    a1, a0, -(2 << (DCACHE_ALIAS_ORDER + PAGE_SHIFT))
1693         bgeu    a1, a3, 2f
1694
1695         /* Check if we have to restore an ITLB mapping. */
1696
1697         movi    a1, __tlbtemp_mapping_itlb
1698         rsr     a3, epc1
1699         sub     a3, a3, a1
1700
1701         /* Calculate VPN */
1702
1703         movi    a1, PAGE_MASK
1704         and     a1, a1, a0
1705
1706         /* Jump for ITLB entry */
1707
1708         bgez    a3, 1f
1709
1710         /* We can use up to two TLBTEMP areas, one for src and one for dst. */
1711
1712         extui   a3, a0, PAGE_SHIFT + DCACHE_ALIAS_ORDER, 1
1713         add     a1, a3, a1
1714
1715         /* PPN is in a6 for the first TLBTEMP area and in a7 for the second. */
1716
1717         mov     a0, a6
1718         movnez  a0, a7, a3
1719         j       3b
1720
1721         /* ITLB entry. We only use dst in a6. */
1722
1723 1:      witlb   a6, a1
1724         isync
1725         j       4b
1726
1727
1728 #endif  // DCACHE_WAY_SIZE > PAGE_SIZE
1729
1730
1731 2:      /* Invalid PGD, default exception handling */
1732
1733         rsr     a1, depc
1734         s32i    a1, a2, PT_AREG2
1735         mov     a1, a2
1736
1737         rsr     a2, ps
1738         bbsi.l  a2, PS_UM_BIT, 1f
1739         j       _kernel_exception
1740 1:      j       _user_exception
1741
1742 ENDPROC(fast_second_level_miss)
1743
1744 /*
1745  * StoreProhibitedException
1746  *
1747  * Update the pte and invalidate the itlb mapping for this pte.
1748  *
1749  * Entry condition:
1750  *
1751  *   a0:        trashed, original value saved on stack (PT_AREG0)
1752  *   a1:        a1
1753  *   a2:        new stack pointer, original in DEPC
1754  *   a3:        a3
1755  *   depc:      a2, original value saved on stack (PT_DEPC)
1756  *   excsave_1: dispatch table
1757  *
1758  *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
1759  *           <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
1760  */
1761
1762 ENTRY(fast_store_prohibited)
1763
1764         /* Save a1 and a3. */
1765
1766         s32i    a1, a2, PT_AREG1
1767         s32i    a3, a2, PT_AREG3
1768
1769         GET_CURRENT(a1,a2)
1770         l32i    a0, a1, TASK_MM         # tsk->mm
1771         beqz    a0, 9f
1772
1773 8:      rsr     a1, excvaddr            # fault address
1774         _PGD_OFFSET(a0, a1, a3)
1775         l32i    a0, a0, 0
1776         beqz    a0, 2f
1777
1778         /*
1779          * Note that we test _PAGE_WRITABLE_BIT only if PTE is present
1780          * and is not PAGE_NONE. See pgtable.h for possible PTE layouts.
1781          */
1782
1783         _PTE_OFFSET(a0, a1, a3)
1784         l32i    a3, a0, 0               # read pteval
1785         movi    a1, _PAGE_CA_INVALID
1786         ball    a3, a1, 2f
1787         bbci.l  a3, _PAGE_WRITABLE_BIT, 2f
1788
1789         movi    a1, _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_HW_WRITE
1790         or      a3, a3, a1
1791         rsr     a1, excvaddr
1792         s32i    a3, a0, 0
1793
1794         /* We need to flush the cache if we have page coloring. */
1795 #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
1796         dhwb    a0, 0
1797 #endif
1798         pdtlb   a0, a1
1799         wdtlb   a3, a0
1800
1801         /* Exit critical section. */
1802
1803         movi    a0, 0
1804         rsr     a3, excsave1
1805         s32i    a0, a3, EXC_TABLE_FIXUP
1806
1807         /* Restore the working registers, and return. */
1808
1809         l32i    a3, a2, PT_AREG3
1810         l32i    a1, a2, PT_AREG1
1811         l32i    a0, a2, PT_AREG0
1812         l32i    a2, a2, PT_DEPC
1813
1814         bgeui   a2, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
1815
1816         rsr     a2, depc
1817         rfe
1818
1819         /* Double exception. Restore FIXUP handler and return. */
1820
1821 1:      xsr     a2, depc
1822         esync
1823         rfde
1824
1825 9:      l32i    a0, a1, TASK_ACTIVE_MM  # unlikely case mm == 0
1826         j       8b
1827
1828 2:      /* If there was a problem, handle fault in C */
1829
1830         rsr     a3, depc        # still holds a2
1831         s32i    a3, a2, PT_AREG2
1832         mov     a1, a2
1833
1834         rsr     a2, ps
1835         bbsi.l  a2, PS_UM_BIT, 1f
1836         j       _kernel_exception
1837 1:      j       _user_exception
1838
1839 ENDPROC(fast_store_prohibited)
1840
1841 #endif /* CONFIG_MMU */
1842
1843 /*
1844  * System Calls.
1845  *
1846  * void system_call (struct pt_regs* regs, int exccause)
1847  *                            a2                 a3
1848  */
1849
1850 ENTRY(system_call)
1851
1852         entry   a1, 32
1853
1854         /* regs->syscall = regs->areg[2] */
1855
1856         l32i    a3, a2, PT_AREG2
1857         mov     a6, a2
1858         movi    a4, do_syscall_trace_enter
1859         s32i    a3, a2, PT_SYSCALL
1860         callx4  a4
1861
1862         /* syscall = sys_call_table[syscall_nr] */
1863
1864         movi    a4, sys_call_table;
1865         movi    a5, __NR_syscall_count
1866         movi    a6, -ENOSYS
1867         bgeu    a3, a5, 1f
1868
1869         addx4   a4, a3, a4
1870         l32i    a4, a4, 0
1871         movi    a5, sys_ni_syscall;
1872         beq     a4, a5, 1f
1873
1874         /* Load args: arg0 - arg5 are passed via regs. */
1875
1876         l32i    a6, a2, PT_AREG6
1877         l32i    a7, a2, PT_AREG3
1878         l32i    a8, a2, PT_AREG4
1879         l32i    a9, a2, PT_AREG5
1880         l32i    a10, a2, PT_AREG8
1881         l32i    a11, a2, PT_AREG9
1882
1883         /* Pass one additional argument to the syscall: pt_regs (on stack) */
1884         s32i    a2, a1, 0
1885
1886         callx4  a4
1887
1888 1:      /* regs->areg[2] = return_value */
1889
1890         s32i    a6, a2, PT_AREG2
1891         movi    a4, do_syscall_trace_leave
1892         mov     a6, a2
1893         callx4  a4
1894         retw
1895
1896 ENDPROC(system_call)
1897
1898
1899 /*
1900  * Task switch.
1901  *
1902  * struct task*  _switch_to (struct task* prev, struct task* next)
1903  *         a2                              a2                 a3
1904  */
1905
1906 ENTRY(_switch_to)
1907
1908         entry   a1, 16
1909
1910         mov     a12, a2                 # preserve 'prev' (a2)
1911         mov     a13, a3                 # and 'next' (a3)
1912
1913         l32i    a4, a2, TASK_THREAD_INFO
1914         l32i    a5, a3, TASK_THREAD_INFO
1915
1916         save_xtregs_user a4 a6 a8 a9 a10 a11 THREAD_XTREGS_USER
1917
1918         s32i    a0, a12, THREAD_RA      # save return address
1919         s32i    a1, a12, THREAD_SP      # save stack pointer
1920
1921         /* Disable ints while we manipulate the stack pointer. */
1922
1923         movi    a14, (1 << PS_EXCM_BIT) | LOCKLEVEL
1924         xsr     a14, ps
1925         rsr     a3, excsave1
1926         rsync
1927         s32i    a3, a3, EXC_TABLE_FIXUP /* enter critical section */
1928
1929         /* Switch CPENABLE */
1930
1931 #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS)
1932         l32i    a3, a5, THREAD_CPENABLE
1933         xsr     a3, cpenable
1934         s32i    a3, a4, THREAD_CPENABLE
1935 #endif
1936
1937         /* Flush register file. */
1938
1939         call0   _spill_registers        # destroys a3, a4, and SAR
1940
1941         /* Set kernel stack (and leave critical section)
1942          * Note: It's save to set it here. The stack will not be overwritten
1943          *       because the kernel stack will only be loaded again after
1944          *       we return from kernel space.
1945          */
1946
1947         rsr     a3, excsave1            # exc_table
1948         movi    a6, 0
1949         addi    a7, a5, PT_REGS_OFFSET
1950         s32i    a6, a3, EXC_TABLE_FIXUP
1951         s32i    a7, a3, EXC_TABLE_KSTK
1952
1953         /* restore context of the task 'next' */
1954
1955         l32i    a0, a13, THREAD_RA      # restore return address
1956         l32i    a1, a13, THREAD_SP      # restore stack pointer
1957
1958         load_xtregs_user a5 a6 a8 a9 a10 a11 THREAD_XTREGS_USER
1959
1960         wsr     a14, ps
1961         mov     a2, a12                 # return 'prev'
1962         rsync
1963
1964         retw
1965
1966 ENDPROC(_switch_to)
1967
1968 ENTRY(ret_from_fork)
1969
1970         /* void schedule_tail (struct task_struct *prev)
1971          * Note: prev is still in a6 (return value from fake call4 frame)
1972          */
1973         movi    a4, schedule_tail
1974         callx4  a4
1975
1976         movi    a4, do_syscall_trace_leave
1977         mov     a6, a1
1978         callx4  a4
1979
1980         j       common_exception_return
1981
1982 ENDPROC(ret_from_fork)
1983
1984 /*
1985  * Kernel thread creation helper
1986  * On entry, set up by copy_thread: a2 = thread_fn, a3 = thread_fn arg
1987  *           left from _switch_to: a6 = prev
1988  */
1989 ENTRY(ret_from_kernel_thread)
1990
1991         call4   schedule_tail
1992         mov     a6, a3
1993         callx4  a2
1994         j       common_exception_return
1995
1996 ENDPROC(ret_from_kernel_thread)