Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / arch / sh / kernel / cpu / sh5 / entry.S
1 /*
2  * arch/sh/kernel/cpu/sh5/entry.S
3  *
4  * Copyright (C) 2000, 2001  Paolo Alberelli
5  * Copyright (C) 2004 - 2008  Paul Mundt
6  * Copyright (C) 2003, 2004  Richard Curnow
7  *
8  * This file is subject to the terms and conditions of the GNU General Public
9  * License.  See the file "COPYING" in the main directory of this archive
10  * for more details.
11  */
12 #include <linux/errno.h>
13 #include <linux/init.h>
14 #include <linux/sys.h>
15 #include <cpu/registers.h>
16 #include <asm/processor.h>
17 #include <asm/unistd.h>
18 #include <asm/thread_info.h>
19 #include <asm/asm-offsets.h>
20
21 /*
22  * SR fields.
23  */
24 #define SR_ASID_MASK    0x00ff0000
25 #define SR_FD_MASK      0x00008000
26 #define SR_SS           0x08000000
27 #define SR_BL           0x10000000
28 #define SR_MD           0x40000000
29
30 /*
31  * Event code.
32  */
33 #define EVENT_INTERRUPT         0
34 #define EVENT_FAULT_TLB         1
35 #define EVENT_FAULT_NOT_TLB     2
36 #define EVENT_DEBUG             3
37
38 /* EXPEVT values */
39 #define RESET_CAUSE             0x20
40 #define DEBUGSS_CAUSE           0x980
41
42 /*
43  * Frame layout. Quad index.
44  */
45 #define FRAME_T(x)      FRAME_TBASE+(x*8)
46 #define FRAME_R(x)      FRAME_RBASE+(x*8)
47 #define FRAME_S(x)      FRAME_SBASE+(x*8)
48 #define FSPC            0
49 #define FSSR            1
50 #define FSYSCALL_ID     2
51
52 /* Arrange the save frame to be a multiple of 32 bytes long */
53 #define FRAME_SBASE     0
54 #define FRAME_RBASE     (FRAME_SBASE+(3*8))     /* SYSCALL_ID - SSR - SPC */
55 #define FRAME_TBASE     (FRAME_RBASE+(63*8))    /* r0 - r62 */
56 #define FRAME_PBASE     (FRAME_TBASE+(8*8))     /* tr0 -tr7 */
57 #define FRAME_SIZE      (FRAME_PBASE+(2*8))     /* pad0-pad1 */
58
59 #define FP_FRAME_SIZE   FP_FRAME_BASE+(33*8)    /* dr0 - dr31 + fpscr */
60 #define FP_FRAME_BASE   0
61
62 #define SAVED_R2        0*8
63 #define SAVED_R3        1*8
64 #define SAVED_R4        2*8
65 #define SAVED_R5        3*8
66 #define SAVED_R18       4*8
67 #define SAVED_R6        5*8
68 #define SAVED_TR0       6*8
69
70 /* These are the registers saved in the TLB path that aren't saved in the first
71    level of the normal one. */
72 #define TLB_SAVED_R25   7*8
73 #define TLB_SAVED_TR1   8*8
74 #define TLB_SAVED_TR2   9*8
75 #define TLB_SAVED_TR3   10*8
76 #define TLB_SAVED_TR4   11*8
77 /* Save R0/R1 : PT-migrating compiler currently dishounours -ffixed-r0 and -ffixed-r1 causing
78    breakage otherwise. */
79 #define TLB_SAVED_R0    12*8
80 #define TLB_SAVED_R1    13*8
81
82 #define CLI()                           \
83         getcon  SR, r6;                 \
84         ori     r6, 0xf0, r6;           \
85         putcon  r6, SR;
86
87 #define STI()                           \
88         getcon  SR, r6;                 \
89         andi    r6, ~0xf0, r6;          \
90         putcon  r6, SR;
91
92 #ifdef CONFIG_PREEMPT
93 #  define preempt_stop()        CLI()
94 #else
95 #  define preempt_stop()
96 #  define resume_kernel         restore_all
97 #endif
98
99         .section        .data, "aw"
100
101 #define FAST_TLBMISS_STACK_CACHELINES 4
102 #define FAST_TLBMISS_STACK_QUADWORDS (4*FAST_TLBMISS_STACK_CACHELINES)
103
104 /* Register back-up area for all exceptions */
105         .balign 32
106         /* Allow for 16 quadwords to be pushed by fast tlbmiss handling
107          * register saves etc. */
108         .fill FAST_TLBMISS_STACK_QUADWORDS, 8, 0x0
109 /* This is 32 byte aligned by construction */
110 /* Register back-up area for all exceptions */
111 reg_save_area:
112         .quad   0
113         .quad   0
114         .quad   0
115         .quad   0
116
117         .quad   0
118         .quad   0
119         .quad   0
120         .quad   0
121
122         .quad   0
123         .quad   0
124         .quad   0
125         .quad   0
126
127         .quad   0
128         .quad   0
129
130 /* Save area for RESVEC exceptions. We cannot use reg_save_area because of
131  * reentrancy. Note this area may be accessed via physical address.
132  * Align so this fits a whole single cache line, for ease of purging.
133  */
134         .balign 32,0,32
135 resvec_save_area:
136         .quad   0
137         .quad   0
138         .quad   0
139         .quad   0
140         .quad   0
141         .balign 32,0,32
142
143 /* Jump table of 3rd level handlers  */
144 trap_jtable:
145         .long   do_exception_error              /* 0x000 */
146         .long   do_exception_error              /* 0x020 */
147 #ifdef CONFIG_MMU
148         .long   tlb_miss_load                           /* 0x040 */
149         .long   tlb_miss_store                          /* 0x060 */
150 #else
151         .long   do_exception_error
152         .long   do_exception_error
153 #endif
154         ! ARTIFICIAL pseudo-EXPEVT setting
155         .long   do_debug_interrupt              /* 0x080 */
156 #ifdef CONFIG_MMU
157         .long   tlb_miss_load                           /* 0x0A0 */
158         .long   tlb_miss_store                          /* 0x0C0 */
159 #else
160         .long   do_exception_error
161         .long   do_exception_error
162 #endif
163         .long   do_address_error_load   /* 0x0E0 */
164         .long   do_address_error_store  /* 0x100 */
165 #ifdef CONFIG_SH_FPU
166         .long   do_fpu_error            /* 0x120 */
167 #else
168         .long   do_exception_error              /* 0x120 */
169 #endif
170         .long   do_exception_error              /* 0x140 */
171         .long   system_call                             /* 0x160 */
172         .long   do_reserved_inst                /* 0x180 */
173         .long   do_illegal_slot_inst    /* 0x1A0 */
174         .long   do_exception_error              /* 0x1C0 - NMI */
175         .long   do_exception_error              /* 0x1E0 */
176         .rept 15
177                 .long do_IRQ            /* 0x200 - 0x3C0 */
178         .endr
179         .long   do_exception_error              /* 0x3E0 */
180         .rept 32
181                 .long do_IRQ            /* 0x400 - 0x7E0 */
182         .endr
183         .long   fpu_error_or_IRQA                       /* 0x800 */
184         .long   fpu_error_or_IRQB                       /* 0x820 */
185         .long   do_IRQ                  /* 0x840 */
186         .long   do_IRQ                  /* 0x860 */
187         .rept 6
188                 .long do_exception_error        /* 0x880 - 0x920 */
189         .endr
190         .long   do_software_break_point /* 0x940 */
191         .long   do_exception_error              /* 0x960 */
192         .long   do_single_step          /* 0x980 */
193
194         .rept 3
195                 .long do_exception_error        /* 0x9A0 - 0x9E0 */
196         .endr
197         .long   do_IRQ                  /* 0xA00 */
198         .long   do_IRQ                  /* 0xA20 */
199 #ifdef CONFIG_MMU
200         .long   itlb_miss_or_IRQ                        /* 0xA40 */
201 #else
202         .long   do_IRQ
203 #endif
204         .long   do_IRQ                  /* 0xA60 */
205         .long   do_IRQ                  /* 0xA80 */
206 #ifdef CONFIG_MMU
207         .long   itlb_miss_or_IRQ                        /* 0xAA0 */
208 #else
209         .long   do_IRQ
210 #endif
211         .long   do_exception_error              /* 0xAC0 */
212         .long   do_address_error_exec   /* 0xAE0 */
213         .rept 8
214                 .long do_exception_error        /* 0xB00 - 0xBE0 */
215         .endr
216         .rept 18
217                 .long do_IRQ            /* 0xC00 - 0xE20 */
218         .endr
219
220         .section        .text64, "ax"
221
222 /*
223  * --- Exception/Interrupt/Event Handling Section
224  */
225
226 /*
227  * VBR and RESVEC blocks.
228  *
229  * First level handler for VBR-based exceptions.
230  *
231  * To avoid waste of space, align to the maximum text block size.
232  * This is assumed to be at most 128 bytes or 32 instructions.
233  * DO NOT EXCEED 32 instructions on the first level handlers !
234  *
235  * Also note that RESVEC is contained within the VBR block
236  * where the room left (1KB - TEXT_SIZE) allows placing
237  * the RESVEC block (at most 512B + TEXT_SIZE).
238  *
239  * So first (and only) level handler for RESVEC-based exceptions.
240  *
241  * Where the fault/interrupt is handled (not_a_tlb_miss, tlb_miss
242  * and interrupt) we are a lot tight with register space until
243  * saving onto the stack frame, which is done in handle_exception().
244  *
245  */
246
247 #define TEXT_SIZE       128
248 #define BLOCK_SIZE      1664            /* Dynamic check, 13*128 */
249
250         .balign TEXT_SIZE
251 LVBR_block:
252         .space  256, 0                  /* Power-on class handler, */
253                                         /* not required here       */
254 not_a_tlb_miss:
255         synco   /* TAKum03020 (but probably a good idea anyway.) */
256         /* Save original stack pointer into KCR1 */
257         putcon  SP, KCR1
258
259         /* Save other original registers into reg_save_area */
260         movi  reg_save_area, SP
261         st.q    SP, SAVED_R2, r2
262         st.q    SP, SAVED_R3, r3
263         st.q    SP, SAVED_R4, r4
264         st.q    SP, SAVED_R5, r5
265         st.q    SP, SAVED_R6, r6
266         st.q    SP, SAVED_R18, r18
267         gettr   tr0, r3
268         st.q    SP, SAVED_TR0, r3
269
270         /* Set args for Non-debug, Not a TLB miss class handler */
271         getcon  EXPEVT, r2
272         movi    ret_from_exception, r3
273         ori     r3, 1, r3
274         movi    EVENT_FAULT_NOT_TLB, r4
275         or      SP, ZERO, r5
276         getcon  KCR1, SP
277         pta     handle_exception, tr0
278         blink   tr0, ZERO
279
280         .balign 256
281         ! VBR+0x200
282         nop
283         .balign 256
284         ! VBR+0x300
285         nop
286         .balign 256
287         /*
288          * Instead of the natural .balign 1024 place RESVEC here
289          * respecting the final 1KB alignment.
290          */
291         .balign TEXT_SIZE
292         /*
293          * Instead of '.space 1024-TEXT_SIZE' place the RESVEC
294          * block making sure the final alignment is correct.
295          */
296 #ifdef CONFIG_MMU
297 tlb_miss:
298         synco   /* TAKum03020 (but probably a good idea anyway.) */
299         putcon  SP, KCR1
300         movi    reg_save_area, SP
301         /* SP is guaranteed 32-byte aligned. */
302         st.q    SP, TLB_SAVED_R0 , r0
303         st.q    SP, TLB_SAVED_R1 , r1
304         st.q    SP, SAVED_R2 , r2
305         st.q    SP, SAVED_R3 , r3
306         st.q    SP, SAVED_R4 , r4
307         st.q    SP, SAVED_R5 , r5
308         st.q    SP, SAVED_R6 , r6
309         st.q    SP, SAVED_R18, r18
310
311         /* Save R25 for safety; as/ld may want to use it to achieve the call to
312          * the code in mm/tlbmiss.c */
313         st.q    SP, TLB_SAVED_R25, r25
314         gettr   tr0, r2
315         gettr   tr1, r3
316         gettr   tr2, r4
317         gettr   tr3, r5
318         gettr   tr4, r18
319         st.q    SP, SAVED_TR0 , r2
320         st.q    SP, TLB_SAVED_TR1 , r3
321         st.q    SP, TLB_SAVED_TR2 , r4
322         st.q    SP, TLB_SAVED_TR3 , r5
323         st.q    SP, TLB_SAVED_TR4 , r18
324
325         pt      do_fast_page_fault, tr0
326         getcon  SSR, r2
327         getcon  EXPEVT, r3
328         getcon  TEA, r4
329         shlri   r2, 30, r2
330         andi    r2, 1, r2       /* r2 = SSR.MD */
331         blink   tr0, LINK
332
333         pt      fixup_to_invoke_general_handler, tr1
334
335         /* If the fast path handler fixed the fault, just drop through quickly
336            to the restore code right away to return to the excepting context.
337            */
338         beqi/u  r2, 0, tr1
339
340 fast_tlb_miss_restore:
341         ld.q    SP, SAVED_TR0, r2
342         ld.q    SP, TLB_SAVED_TR1, r3
343         ld.q    SP, TLB_SAVED_TR2, r4
344
345         ld.q    SP, TLB_SAVED_TR3, r5
346         ld.q    SP, TLB_SAVED_TR4, r18
347
348         ptabs   r2, tr0
349         ptabs   r3, tr1
350         ptabs   r4, tr2
351         ptabs   r5, tr3
352         ptabs   r18, tr4
353
354         ld.q    SP, TLB_SAVED_R0, r0
355         ld.q    SP, TLB_SAVED_R1, r1
356         ld.q    SP, SAVED_R2, r2
357         ld.q    SP, SAVED_R3, r3
358         ld.q    SP, SAVED_R4, r4
359         ld.q    SP, SAVED_R5, r5
360         ld.q    SP, SAVED_R6, r6
361         ld.q    SP, SAVED_R18, r18
362         ld.q    SP, TLB_SAVED_R25, r25
363
364         getcon  KCR1, SP
365         rte
366         nop /* for safety, in case the code is run on sh5-101 cut1.x */
367
368 fixup_to_invoke_general_handler:
369
370         /* OK, new method.  Restore stuff that's not expected to get saved into
371            the 'first-level' reg save area, then just fall through to setting
372            up the registers and calling the second-level handler. */
373
374         /* 2nd level expects r2,3,4,5,6,18,tr0 to be saved.  So we must restore
375            r25,tr1-4 and save r6 to get into the right state.  */
376
377         ld.q    SP, TLB_SAVED_TR1, r3
378         ld.q    SP, TLB_SAVED_TR2, r4
379         ld.q    SP, TLB_SAVED_TR3, r5
380         ld.q    SP, TLB_SAVED_TR4, r18
381         ld.q    SP, TLB_SAVED_R25, r25
382
383         ld.q    SP, TLB_SAVED_R0, r0
384         ld.q    SP, TLB_SAVED_R1, r1
385
386         ptabs/u r3, tr1
387         ptabs/u r4, tr2
388         ptabs/u r5, tr3
389         ptabs/u r18, tr4
390
391         /* Set args for Non-debug, TLB miss class handler */
392         getcon  EXPEVT, r2
393         movi    ret_from_exception, r3
394         ori     r3, 1, r3
395         movi    EVENT_FAULT_TLB, r4
396         or      SP, ZERO, r5
397         getcon  KCR1, SP
398         pta     handle_exception, tr0
399         blink   tr0, ZERO
400 #else /* CONFIG_MMU */
401         .balign 256
402 #endif
403
404 /* NB TAKE GREAT CARE HERE TO ENSURE THAT THE INTERRUPT CODE
405    DOES END UP AT VBR+0x600 */
406         nop
407         nop
408         nop
409         nop
410         nop
411         nop
412
413         .balign 256
414         /* VBR + 0x600 */
415
416 interrupt:
417         synco   /* TAKum03020 (but probably a good idea anyway.) */
418         /* Save original stack pointer into KCR1 */
419         putcon  SP, KCR1
420
421         /* Save other original registers into reg_save_area */
422         movi  reg_save_area, SP
423         st.q    SP, SAVED_R2, r2
424         st.q    SP, SAVED_R3, r3
425         st.q    SP, SAVED_R4, r4
426         st.q    SP, SAVED_R5, r5
427         st.q    SP, SAVED_R6, r6
428         st.q    SP, SAVED_R18, r18
429         gettr   tr0, r3
430         st.q    SP, SAVED_TR0, r3
431
432         /* Set args for interrupt class handler */
433         getcon  INTEVT, r2
434         movi    ret_from_irq, r3
435         ori     r3, 1, r3
436         movi    EVENT_INTERRUPT, r4
437         or      SP, ZERO, r5
438         getcon  KCR1, SP
439         pta     handle_exception, tr0
440         blink   tr0, ZERO
441         .balign TEXT_SIZE               /* let's waste the bare minimum */
442
443 LVBR_block_end:                         /* Marker. Used for total checking */
444
445         .balign 256
446 LRESVEC_block:
447         /* Panic handler. Called with MMU off. Possible causes/actions:
448          * - Reset:             Jump to program start.
449          * - Single Step:       Turn off Single Step & return.
450          * - Others:            Call panic handler, passing PC as arg.
451          *                      (this may need to be extended...)
452          */
453 reset_or_panic:
454         synco   /* TAKum03020 (but probably a good idea anyway.) */
455         putcon  SP, DCR
456         /* First save r0-1 and tr0, as we need to use these */
457         movi    resvec_save_area-CONFIG_PAGE_OFFSET, SP
458         st.q    SP, 0, r0
459         st.q    SP, 8, r1
460         gettr   tr0, r0
461         st.q    SP, 32, r0
462
463         /* Check cause */
464         getcon  EXPEVT, r0
465         movi    RESET_CAUSE, r1
466         sub     r1, r0, r1              /* r1=0 if reset */
467         movi    _stext-CONFIG_PAGE_OFFSET, r0
468         ori     r0, 1, r0
469         ptabs   r0, tr0
470         beqi    r1, 0, tr0              /* Jump to start address if reset */
471
472         getcon  EXPEVT, r0
473         movi    DEBUGSS_CAUSE, r1
474         sub     r1, r0, r1              /* r1=0 if single step */
475         pta     single_step_panic, tr0
476         beqi    r1, 0, tr0              /* jump if single step */
477
478         /* Now jump to where we save the registers. */
479         movi    panic_stash_regs-CONFIG_PAGE_OFFSET, r1
480         ptabs   r1, tr0
481         blink   tr0, r63
482
483 single_step_panic:
484         /* We are in a handler with Single Step set. We need to resume the
485          * handler, by turning on MMU & turning off Single Step. */
486         getcon  SSR, r0
487         movi    SR_MMU, r1
488         or      r0, r1, r0
489         movi    ~SR_SS, r1
490         and     r0, r1, r0
491         putcon  r0, SSR
492         /* Restore EXPEVT, as the rte won't do this */
493         getcon  PEXPEVT, r0
494         putcon  r0, EXPEVT
495         /* Restore regs */
496         ld.q    SP, 32, r0
497         ptabs   r0, tr0
498         ld.q    SP, 0, r0
499         ld.q    SP, 8, r1
500         getcon  DCR, SP
501         synco
502         rte
503
504
505         .balign 256
506 debug_exception:
507         synco   /* TAKum03020 (but probably a good idea anyway.) */
508         /*
509          * Single step/software_break_point first level handler.
510          * Called with MMU off, so the first thing we do is enable it
511          * by doing an rte with appropriate SSR.
512          */
513         putcon  SP, DCR
514         /* Save SSR & SPC, together with R0 & R1, as we need to use 2 regs. */
515         movi    resvec_save_area-CONFIG_PAGE_OFFSET, SP
516
517         /* With the MMU off, we are bypassing the cache, so purge any
518          * data that will be made stale by the following stores.
519          */
520         ocbp    SP, 0
521         synco
522
523         st.q    SP, 0, r0
524         st.q    SP, 8, r1
525         getcon  SPC, r0
526         st.q    SP, 16, r0
527         getcon  SSR, r0
528         st.q    SP, 24, r0
529
530         /* Enable MMU, block exceptions, set priv mode, disable single step */
531         movi    SR_MMU | SR_BL | SR_MD, r1
532         or      r0, r1, r0
533         movi    ~SR_SS, r1
534         and     r0, r1, r0
535         putcon  r0, SSR
536         /* Force control to debug_exception_2 when rte is executed */
537         movi    debug_exeception_2, r0
538         ori     r0, 1, r0      /* force SHmedia, just in case */
539         putcon  r0, SPC
540         getcon  DCR, SP
541         synco
542         rte
543 debug_exeception_2:
544         /* Restore saved regs */
545         putcon  SP, KCR1
546         movi    resvec_save_area, SP
547         ld.q    SP, 24, r0
548         putcon  r0, SSR
549         ld.q    SP, 16, r0
550         putcon  r0, SPC
551         ld.q    SP, 0, r0
552         ld.q    SP, 8, r1
553
554         /* Save other original registers into reg_save_area */
555         movi  reg_save_area, SP
556         st.q    SP, SAVED_R2, r2
557         st.q    SP, SAVED_R3, r3
558         st.q    SP, SAVED_R4, r4
559         st.q    SP, SAVED_R5, r5
560         st.q    SP, SAVED_R6, r6
561         st.q    SP, SAVED_R18, r18
562         gettr   tr0, r3
563         st.q    SP, SAVED_TR0, r3
564
565         /* Set args for debug class handler */
566         getcon  EXPEVT, r2
567         movi    ret_from_exception, r3
568         ori     r3, 1, r3
569         movi    EVENT_DEBUG, r4
570         or      SP, ZERO, r5
571         getcon  KCR1, SP
572         pta     handle_exception, tr0
573         blink   tr0, ZERO
574
575         .balign 256
576 debug_interrupt:
577         /* !!! WE COME HERE IN REAL MODE !!! */
578         /* Hook-up debug interrupt to allow various debugging options to be
579          * hooked into its handler. */
580         /* Save original stack pointer into KCR1 */
581         synco
582         putcon  SP, KCR1
583         movi    resvec_save_area-CONFIG_PAGE_OFFSET, SP
584         ocbp    SP, 0
585         ocbp    SP, 32
586         synco
587
588         /* Save other original registers into reg_save_area thru real addresses */
589         st.q    SP, SAVED_R2, r2
590         st.q    SP, SAVED_R3, r3
591         st.q    SP, SAVED_R4, r4
592         st.q    SP, SAVED_R5, r5
593         st.q    SP, SAVED_R6, r6
594         st.q    SP, SAVED_R18, r18
595         gettr   tr0, r3
596         st.q    SP, SAVED_TR0, r3
597
598         /* move (spc,ssr)->(pspc,pssr).  The rte will shift
599            them back again, so that they look like the originals
600            as far as the real handler code is concerned. */
601         getcon  spc, r6
602         putcon  r6, pspc
603         getcon  ssr, r6
604         putcon  r6, pssr
605
606         ! construct useful SR for handle_exception
607         movi    3, r6
608         shlli   r6, 30, r6
609         getcon  sr, r18
610         or      r18, r6, r6
611         putcon  r6, ssr
612
613         ! SSR is now the current SR with the MD and MMU bits set
614         ! i.e. the rte will switch back to priv mode and put
615         ! the mmu back on
616
617         ! construct spc
618         movi    handle_exception, r18
619         ori     r18, 1, r18             ! for safety (do we need this?)
620         putcon  r18, spc
621
622         /* Set args for Non-debug, Not a TLB miss class handler */
623
624         ! EXPEVT==0x80 is unused, so 'steal' this value to put the
625         ! debug interrupt handler in the vectoring table
626         movi    0x80, r2
627         movi    ret_from_exception, r3
628         ori     r3, 1, r3
629         movi    EVENT_FAULT_NOT_TLB, r4
630
631         or      SP, ZERO, r5
632         movi    CONFIG_PAGE_OFFSET, r6
633         add     r6, r5, r5
634         getcon  KCR1, SP
635
636         synco   ! for safety
637         rte     ! -> handle_exception, switch back to priv mode again
638
639 LRESVEC_block_end:                      /* Marker. Unused. */
640
641         .balign TEXT_SIZE
642
643 /*
644  * Second level handler for VBR-based exceptions. Pre-handler.
645  * In common to all stack-frame sensitive handlers.
646  *
647  * Inputs:
648  * (KCR0) Current [current task union]
649  * (KCR1) Original SP
650  * (r2)   INTEVT/EXPEVT
651  * (r3)   appropriate return address
652  * (r4)   Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault, 3=debug)
653  * (r5)   Pointer to reg_save_area
654  * (SP)   Original SP
655  *
656  * Available registers:
657  * (r6)
658  * (r18)
659  * (tr0)
660  *
661  */
662 handle_exception:
663         /* Common 2nd level handler. */
664
665         /* First thing we need an appropriate stack pointer */
666         getcon  SSR, r6
667         shlri   r6, 30, r6
668         andi    r6, 1, r6
669         pta     stack_ok, tr0
670         bne     r6, ZERO, tr0           /* Original stack pointer is fine */
671
672         /* Set stack pointer for user fault */
673         getcon  KCR0, SP
674         movi    THREAD_SIZE, r6         /* Point to the end */
675         add     SP, r6, SP
676
677 stack_ok:
678
679 /* DEBUG : check for underflow/overflow of the kernel stack */
680         pta     no_underflow, tr0
681         getcon  KCR0, r6
682         movi    1024, r18
683         add     r6, r18, r6
684         bge     SP, r6, tr0     ! ? below 1k from bottom of stack : danger zone
685
686 /* Just panic to cause a crash. */
687 bad_sp:
688         ld.b    r63, 0, r6
689         nop
690
691 no_underflow:
692         pta     bad_sp, tr0
693         getcon  kcr0, r6
694         movi    THREAD_SIZE, r18
695         add     r18, r6, r6
696         bgt     SP, r6, tr0     ! sp above the stack
697
698         /* Make some room for the BASIC frame. */
699         movi    -(FRAME_SIZE), r6
700         add     SP, r6, SP
701
702 /* Could do this with no stalling if we had another spare register, but the
703    code below will be OK. */
704         ld.q    r5, SAVED_R2, r6
705         ld.q    r5, SAVED_R3, r18
706         st.q    SP, FRAME_R(2), r6
707         ld.q    r5, SAVED_R4, r6
708         st.q    SP, FRAME_R(3), r18
709         ld.q    r5, SAVED_R5, r18
710         st.q    SP, FRAME_R(4), r6
711         ld.q    r5, SAVED_R6, r6
712         st.q    SP, FRAME_R(5), r18
713         ld.q    r5, SAVED_R18, r18
714         st.q    SP, FRAME_R(6), r6
715         ld.q    r5, SAVED_TR0, r6
716         st.q    SP, FRAME_R(18), r18
717         st.q    SP, FRAME_T(0), r6
718
719         /* Keep old SP around */
720         getcon  KCR1, r6
721
722         /* Save the rest of the general purpose registers */
723         st.q    SP, FRAME_R(0), r0
724         st.q    SP, FRAME_R(1), r1
725         st.q    SP, FRAME_R(7), r7
726         st.q    SP, FRAME_R(8), r8
727         st.q    SP, FRAME_R(9), r9
728         st.q    SP, FRAME_R(10), r10
729         st.q    SP, FRAME_R(11), r11
730         st.q    SP, FRAME_R(12), r12
731         st.q    SP, FRAME_R(13), r13
732         st.q    SP, FRAME_R(14), r14
733
734         /* SP is somewhere else */
735         st.q    SP, FRAME_R(15), r6
736
737         st.q    SP, FRAME_R(16), r16
738         st.q    SP, FRAME_R(17), r17
739         /* r18 is saved earlier. */
740         st.q    SP, FRAME_R(19), r19
741         st.q    SP, FRAME_R(20), r20
742         st.q    SP, FRAME_R(21), r21
743         st.q    SP, FRAME_R(22), r22
744         st.q    SP, FRAME_R(23), r23
745         st.q    SP, FRAME_R(24), r24
746         st.q    SP, FRAME_R(25), r25
747         st.q    SP, FRAME_R(26), r26
748         st.q    SP, FRAME_R(27), r27
749         st.q    SP, FRAME_R(28), r28
750         st.q    SP, FRAME_R(29), r29
751         st.q    SP, FRAME_R(30), r30
752         st.q    SP, FRAME_R(31), r31
753         st.q    SP, FRAME_R(32), r32
754         st.q    SP, FRAME_R(33), r33
755         st.q    SP, FRAME_R(34), r34
756         st.q    SP, FRAME_R(35), r35
757         st.q    SP, FRAME_R(36), r36
758         st.q    SP, FRAME_R(37), r37
759         st.q    SP, FRAME_R(38), r38
760         st.q    SP, FRAME_R(39), r39
761         st.q    SP, FRAME_R(40), r40
762         st.q    SP, FRAME_R(41), r41
763         st.q    SP, FRAME_R(42), r42
764         st.q    SP, FRAME_R(43), r43
765         st.q    SP, FRAME_R(44), r44
766         st.q    SP, FRAME_R(45), r45
767         st.q    SP, FRAME_R(46), r46
768         st.q    SP, FRAME_R(47), r47
769         st.q    SP, FRAME_R(48), r48
770         st.q    SP, FRAME_R(49), r49
771         st.q    SP, FRAME_R(50), r50
772         st.q    SP, FRAME_R(51), r51
773         st.q    SP, FRAME_R(52), r52
774         st.q    SP, FRAME_R(53), r53
775         st.q    SP, FRAME_R(54), r54
776         st.q    SP, FRAME_R(55), r55
777         st.q    SP, FRAME_R(56), r56
778         st.q    SP, FRAME_R(57), r57
779         st.q    SP, FRAME_R(58), r58
780         st.q    SP, FRAME_R(59), r59
781         st.q    SP, FRAME_R(60), r60
782         st.q    SP, FRAME_R(61), r61
783         st.q    SP, FRAME_R(62), r62
784
785         /*
786          * Save the S* registers.
787          */
788         getcon  SSR, r61
789         st.q    SP, FRAME_S(FSSR), r61
790         getcon  SPC, r62
791         st.q    SP, FRAME_S(FSPC), r62
792         movi    -1, r62                 /* Reset syscall_nr */
793         st.q    SP, FRAME_S(FSYSCALL_ID), r62
794
795         /* Save the rest of the target registers */
796         gettr   tr1, r6
797         st.q    SP, FRAME_T(1), r6
798         gettr   tr2, r6
799         st.q    SP, FRAME_T(2), r6
800         gettr   tr3, r6
801         st.q    SP, FRAME_T(3), r6
802         gettr   tr4, r6
803         st.q    SP, FRAME_T(4), r6
804         gettr   tr5, r6
805         st.q    SP, FRAME_T(5), r6
806         gettr   tr6, r6
807         st.q    SP, FRAME_T(6), r6
808         gettr   tr7, r6
809         st.q    SP, FRAME_T(7), r6
810
811         ! setup FP so that unwinder can wind back through nested kernel mode
812         ! exceptions
813         add     SP, ZERO, r14
814
815 #ifdef CONFIG_POOR_MANS_STRACE
816         /* We've pushed all the registers now, so only r2-r4 hold anything
817          * useful. Move them into callee save registers */
818         or      r2, ZERO, r28
819         or      r3, ZERO, r29
820         or      r4, ZERO, r30
821
822         /* Preserve r2 as the event code */
823         movi    evt_debug, r3
824         ori     r3, 1, r3
825         ptabs   r3, tr0
826
827         or      SP, ZERO, r6
828         getcon  TRA, r5
829         blink   tr0, LINK
830
831         or      r28, ZERO, r2
832         or      r29, ZERO, r3
833         or      r30, ZERO, r4
834 #endif
835
836         /* For syscall and debug race condition, get TRA now */
837         getcon  TRA, r5
838
839         /* We are in a safe position to turn SR.BL off, but set IMASK=0xf
840          * Also set FD, to catch FPU usage in the kernel.
841          *
842          * benedict.gaster@superh.com 29/07/2002
843          *
844          * On all SH5-101 revisions it is unsafe to raise the IMASK and at the
845          * same time change BL from 1->0, as any pending interrupt of a level
846          * higher than he previous value of IMASK will leak through and be
847          * taken unexpectedly.
848          *
849          * To avoid this we raise the IMASK and then issue another PUTCON to
850          * enable interrupts.
851          */
852         getcon  SR, r6
853         movi    SR_IMASK | SR_FD, r7
854         or      r6, r7, r6
855         putcon  r6, SR
856         movi    SR_UNBLOCK_EXC, r7
857         and     r6, r7, r6
858         putcon  r6, SR
859
860
861         /* Now call the appropriate 3rd level handler */
862         or      r3, ZERO, LINK
863         movi    trap_jtable, r3
864         shlri   r2, 3, r2
865         ldx.l   r2, r3, r3
866         shlri   r2, 2, r2
867         ptabs   r3, tr0
868         or      SP, ZERO, r3
869         blink   tr0, ZERO
870
871 /*
872  * Second level handler for VBR-based exceptions. Post-handlers.
873  *
874  * Post-handlers for interrupts (ret_from_irq), exceptions
875  * (ret_from_exception) and common reentrance doors (restore_all
876  * to get back to the original context, ret_from_syscall loop to
877  * check kernel exiting).
878  *
879  * ret_with_reschedule and work_notifysig are an inner lables of
880  * the ret_from_syscall loop.
881  *
882  * In common to all stack-frame sensitive handlers.
883  *
884  * Inputs:
885  * (SP)   struct pt_regs *, original register's frame pointer (basic)
886  *
887  */
888         .global ret_from_irq
889 ret_from_irq:
890 #ifdef CONFIG_POOR_MANS_STRACE
891         pta     evt_debug_ret_from_irq, tr0
892         ori     SP, 0, r2
893         blink   tr0, LINK
894 #endif
895         ld.q    SP, FRAME_S(FSSR), r6
896         shlri   r6, 30, r6
897         andi    r6, 1, r6
898         pta     resume_kernel, tr0
899         bne     r6, ZERO, tr0           /* no further checks */
900         STI()
901         pta     ret_with_reschedule, tr0
902         blink   tr0, ZERO               /* Do not check softirqs */
903
904         .global ret_from_exception
905 ret_from_exception:
906         preempt_stop()
907
908 #ifdef CONFIG_POOR_MANS_STRACE
909         pta     evt_debug_ret_from_exc, tr0
910         ori     SP, 0, r2
911         blink   tr0, LINK
912 #endif
913
914         ld.q    SP, FRAME_S(FSSR), r6
915         shlri   r6, 30, r6
916         andi    r6, 1, r6
917         pta     resume_kernel, tr0
918         bne     r6, ZERO, tr0           /* no further checks */
919
920         /* Check softirqs */
921
922 #ifdef CONFIG_PREEMPT
923         pta   ret_from_syscall, tr0
924         blink   tr0, ZERO
925
926 resume_kernel:
927         CLI()
928
929         pta     restore_all, tr0
930
931         getcon  KCR0, r6
932         ld.l    r6, TI_PRE_COUNT, r7
933         beq/u   r7, ZERO, tr0
934
935 need_resched:
936         ld.l    r6, TI_FLAGS, r7
937         movi    (1 << TIF_NEED_RESCHED), r8
938         and     r8, r7, r8
939         bne     r8, ZERO, tr0
940
941         getcon  SR, r7
942         andi    r7, 0xf0, r7
943         bne     r7, ZERO, tr0
944
945         movi    preempt_schedule_irq, r7
946         ori     r7, 1, r7
947         ptabs   r7, tr1
948         blink   tr1, LINK
949
950         pta     need_resched, tr1
951         blink   tr1, ZERO
952 #endif
953
954         .global ret_from_syscall
955 ret_from_syscall:
956
957 ret_with_reschedule:
958         getcon  KCR0, r6                ! r6 contains current_thread_info
959         ld.l    r6, TI_FLAGS, r7        ! r7 contains current_thread_info->flags
960
961         movi    _TIF_NEED_RESCHED, r8
962         and     r8, r7, r8
963         pta     work_resched, tr0
964         bne     r8, ZERO, tr0
965
966         pta     restore_all, tr1
967
968         movi    (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r8
969         and     r8, r7, r8
970         pta     work_notifysig, tr0
971         bne     r8, ZERO, tr0
972
973         blink   tr1, ZERO
974
975 work_resched:
976         pta     ret_from_syscall, tr0
977         gettr   tr0, LINK
978         movi    schedule, r6
979         ptabs   r6, tr0
980         blink   tr0, ZERO               /* Call schedule(), return on top */
981
982 work_notifysig:
983         gettr   tr1, LINK
984
985         movi    do_notify_resume, r6
986         ptabs   r6, tr0
987         or      SP, ZERO, r2
988         or      r7, ZERO, r3
989         blink   tr0, LINK           /* Call do_notify_resume(regs, current_thread_info->flags), return here */
990
991 restore_all:
992         /* Do prefetches */
993
994         ld.q    SP, FRAME_T(0), r6
995         ld.q    SP, FRAME_T(1), r7
996         ld.q    SP, FRAME_T(2), r8
997         ld.q    SP, FRAME_T(3), r9
998         ptabs   r6, tr0
999         ptabs   r7, tr1
1000         ptabs   r8, tr2
1001         ptabs   r9, tr3
1002         ld.q    SP, FRAME_T(4), r6
1003         ld.q    SP, FRAME_T(5), r7
1004         ld.q    SP, FRAME_T(6), r8
1005         ld.q    SP, FRAME_T(7), r9
1006         ptabs   r6, tr4
1007         ptabs   r7, tr5
1008         ptabs   r8, tr6
1009         ptabs   r9, tr7
1010
1011         ld.q    SP, FRAME_R(0), r0
1012         ld.q    SP, FRAME_R(1), r1
1013         ld.q    SP, FRAME_R(2), r2
1014         ld.q    SP, FRAME_R(3), r3
1015         ld.q    SP, FRAME_R(4), r4
1016         ld.q    SP, FRAME_R(5), r5
1017         ld.q    SP, FRAME_R(6), r6
1018         ld.q    SP, FRAME_R(7), r7
1019         ld.q    SP, FRAME_R(8), r8
1020         ld.q    SP, FRAME_R(9), r9
1021         ld.q    SP, FRAME_R(10), r10
1022         ld.q    SP, FRAME_R(11), r11
1023         ld.q    SP, FRAME_R(12), r12
1024         ld.q    SP, FRAME_R(13), r13
1025         ld.q    SP, FRAME_R(14), r14
1026
1027         ld.q    SP, FRAME_R(16), r16
1028         ld.q    SP, FRAME_R(17), r17
1029         ld.q    SP, FRAME_R(18), r18
1030         ld.q    SP, FRAME_R(19), r19
1031         ld.q    SP, FRAME_R(20), r20
1032         ld.q    SP, FRAME_R(21), r21
1033         ld.q    SP, FRAME_R(22), r22
1034         ld.q    SP, FRAME_R(23), r23
1035         ld.q    SP, FRAME_R(24), r24
1036         ld.q    SP, FRAME_R(25), r25
1037         ld.q    SP, FRAME_R(26), r26
1038         ld.q    SP, FRAME_R(27), r27
1039         ld.q    SP, FRAME_R(28), r28
1040         ld.q    SP, FRAME_R(29), r29
1041         ld.q    SP, FRAME_R(30), r30
1042         ld.q    SP, FRAME_R(31), r31
1043         ld.q    SP, FRAME_R(32), r32
1044         ld.q    SP, FRAME_R(33), r33
1045         ld.q    SP, FRAME_R(34), r34
1046         ld.q    SP, FRAME_R(35), r35
1047         ld.q    SP, FRAME_R(36), r36
1048         ld.q    SP, FRAME_R(37), r37
1049         ld.q    SP, FRAME_R(38), r38
1050         ld.q    SP, FRAME_R(39), r39
1051         ld.q    SP, FRAME_R(40), r40
1052         ld.q    SP, FRAME_R(41), r41
1053         ld.q    SP, FRAME_R(42), r42
1054         ld.q    SP, FRAME_R(43), r43
1055         ld.q    SP, FRAME_R(44), r44
1056         ld.q    SP, FRAME_R(45), r45
1057         ld.q    SP, FRAME_R(46), r46
1058         ld.q    SP, FRAME_R(47), r47
1059         ld.q    SP, FRAME_R(48), r48
1060         ld.q    SP, FRAME_R(49), r49
1061         ld.q    SP, FRAME_R(50), r50
1062         ld.q    SP, FRAME_R(51), r51
1063         ld.q    SP, FRAME_R(52), r52
1064         ld.q    SP, FRAME_R(53), r53
1065         ld.q    SP, FRAME_R(54), r54
1066         ld.q    SP, FRAME_R(55), r55
1067         ld.q    SP, FRAME_R(56), r56
1068         ld.q    SP, FRAME_R(57), r57
1069         ld.q    SP, FRAME_R(58), r58
1070
1071         getcon  SR, r59
1072         movi    SR_BLOCK_EXC, r60
1073         or      r59, r60, r59
1074         putcon  r59, SR                 /* SR.BL = 1, keep nesting out */
1075         ld.q    SP, FRAME_S(FSSR), r61
1076         ld.q    SP, FRAME_S(FSPC), r62
1077         movi    SR_ASID_MASK, r60
1078         and     r59, r60, r59
1079         andc    r61, r60, r61           /* Clear out older ASID */
1080         or      r59, r61, r61           /* Retain current ASID */
1081         putcon  r61, SSR
1082         putcon  r62, SPC
1083
1084         /* Ignore FSYSCALL_ID */
1085
1086         ld.q    SP, FRAME_R(59), r59
1087         ld.q    SP, FRAME_R(60), r60
1088         ld.q    SP, FRAME_R(61), r61
1089         ld.q    SP, FRAME_R(62), r62
1090
1091         /* Last touch */
1092         ld.q    SP, FRAME_R(15), SP
1093         rte
1094         nop
1095
1096 /*
1097  * Third level handlers for VBR-based exceptions. Adapting args to
1098  * and/or deflecting to fourth level handlers.
1099  *
1100  * Fourth level handlers interface.
1101  * Most are C-coded handlers directly pointed by the trap_jtable.
1102  * (Third = Fourth level)
1103  * Inputs:
1104  * (r2)   fault/interrupt code, entry number (e.g. NMI = 14,
1105  *        IRL0-3 (0000) = 16, RTLBMISS = 2, SYSCALL = 11, etc ...)
1106  * (r3)   struct pt_regs *, original register's frame pointer
1107  * (r4)   Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault)
1108  * (r5)   TRA control register (for syscall/debug benefit only)
1109  * (LINK) return address
1110  * (SP)   = r3
1111  *
1112  * Kernel TLB fault handlers will get a slightly different interface.
1113  * (r2)   struct pt_regs *, original register's frame pointer
1114  * (r3)   writeaccess, whether it's a store fault as opposed to load fault
1115  * (r4)   execaccess, whether it's a ITLB fault as opposed to DTLB fault
1116  * (r5)   Effective Address of fault
1117  * (LINK) return address
1118  * (SP)   = r2
1119  *
1120  * fpu_error_or_IRQ? is a helper to deflect to the right cause.
1121  *
1122  */
1123 #ifdef CONFIG_MMU
1124 tlb_miss_load:
1125         or      SP, ZERO, r2
1126         or      ZERO, ZERO, r3          /* Read */
1127         or      ZERO, ZERO, r4          /* Data */
1128         getcon  TEA, r5
1129         pta     call_do_page_fault, tr0
1130         beq     ZERO, ZERO, tr0
1131
1132 tlb_miss_store:
1133         or      SP, ZERO, r2
1134         movi    1, r3                   /* Write */
1135         or      ZERO, ZERO, r4          /* Data */
1136         getcon  TEA, r5
1137         pta     call_do_page_fault, tr0
1138         beq     ZERO, ZERO, tr0
1139
1140 itlb_miss_or_IRQ:
1141         pta     its_IRQ, tr0
1142         beqi/u  r4, EVENT_INTERRUPT, tr0
1143         or      SP, ZERO, r2
1144         or      ZERO, ZERO, r3          /* Read */
1145         movi    1, r4                   /* Text */
1146         getcon  TEA, r5
1147         /* Fall through */
1148
1149 call_do_page_fault:
1150         movi    do_page_fault, r6
1151         ptabs   r6, tr0
1152         blink   tr0, ZERO
1153 #endif /* CONFIG_MMU */
1154
1155 fpu_error_or_IRQA:
1156         pta     its_IRQ, tr0
1157         beqi/l  r4, EVENT_INTERRUPT, tr0
1158 #ifdef CONFIG_SH_FPU
1159         movi    do_fpu_state_restore, r6
1160 #else
1161         movi    do_exception_error, r6
1162 #endif
1163         ptabs   r6, tr0
1164         blink   tr0, ZERO
1165
1166 fpu_error_or_IRQB:
1167         pta     its_IRQ, tr0
1168         beqi/l  r4, EVENT_INTERRUPT, tr0
1169 #ifdef CONFIG_SH_FPU
1170         movi    do_fpu_state_restore, r6
1171 #else
1172         movi    do_exception_error, r6
1173 #endif
1174         ptabs   r6, tr0
1175         blink   tr0, ZERO
1176
1177 its_IRQ:
1178         movi    do_IRQ, r6
1179         ptabs   r6, tr0
1180         blink   tr0, ZERO
1181
1182 /*
1183  * system_call/unknown_trap third level handler:
1184  *
1185  * Inputs:
1186  * (r2)   fault/interrupt code, entry number (TRAP = 11)
1187  * (r3)   struct pt_regs *, original register's frame pointer
1188  * (r4)   Not used. Event (0=interrupt, 1=TLB miss fault, 2=Not TLB miss fault)
1189  * (r5)   TRA Control Reg (0x00xyzzzz: x=1 SYSCALL, y = #args, z=nr)
1190  * (SP)   = r3
1191  * (LINK) return address: ret_from_exception
1192  * (*r3)  Syscall parms: SC#, arg0, arg1, ..., arg5 in order (Saved r2/r7)
1193  *
1194  * Outputs:
1195  * (*r3)  Syscall reply (Saved r2)
1196  * (LINK) In case of syscall only it can be scrapped.
1197  *        Common second level post handler will be ret_from_syscall.
1198  *        Common (non-trace) exit point to that is syscall_ret (saving
1199  *        result to r2). Common bad exit point is syscall_bad (returning
1200  *        ENOSYS then saved to r2).
1201  *
1202  */
1203
1204 unknown_trap:
1205         /* Unknown Trap or User Trace */
1206         movi    do_unknown_trapa, r6
1207         ptabs   r6, tr0
1208         ld.q    r3, FRAME_R(9), r2      /* r2 = #arg << 16 | syscall # */
1209         andi    r2, 0x1ff, r2           /* r2 = syscall # */
1210         blink   tr0, LINK
1211
1212         pta     syscall_ret, tr0
1213         blink   tr0, ZERO
1214
1215         /* New syscall implementation*/
1216 system_call:
1217         pta     unknown_trap, tr0
1218         or      r5, ZERO, r4            /* TRA (=r5) -> r4 */
1219         shlri   r4, 20, r4
1220         bnei    r4, 1, tr0              /* unknown_trap if not 0x1yzzzz */
1221
1222         /* It's a system call */
1223         st.q    r3, FRAME_S(FSYSCALL_ID), r5    /* ID (0x1yzzzz) -> stack */
1224         andi    r5, 0x1ff, r5                   /* syscall # -> r5        */
1225
1226         STI()
1227
1228         pta     syscall_allowed, tr0
1229         movi    NR_syscalls - 1, r4     /* Last valid */
1230         bgeu/l  r4, r5, tr0
1231
1232 syscall_bad:
1233         /* Return ENOSYS ! */
1234         movi    -(ENOSYS), r2           /* Fall-through */
1235
1236         .global syscall_ret
1237 syscall_ret:
1238         st.q    SP, FRAME_R(9), r2      /* Expecting SP back to BASIC frame */
1239
1240 #ifdef CONFIG_POOR_MANS_STRACE
1241         /* nothing useful in registers at this point */
1242
1243         movi    evt_debug2, r5
1244         ori     r5, 1, r5
1245         ptabs   r5, tr0
1246         ld.q    SP, FRAME_R(9), r2
1247         or      SP, ZERO, r3
1248         blink   tr0, LINK
1249 #endif
1250
1251         ld.q    SP, FRAME_S(FSPC), r2
1252         addi    r2, 4, r2               /* Move PC, being pre-execution event */
1253         st.q    SP, FRAME_S(FSPC), r2
1254         pta     ret_from_syscall, tr0
1255         blink   tr0, ZERO
1256
1257
1258 /*  A different return path for ret_from_fork, because we now need
1259  *  to call schedule_tail with the later kernels. Because prev is
1260  *  loaded into r2 by switch_to() means we can just call it straight  away
1261  */
1262
1263 .global ret_from_fork
1264 ret_from_fork:
1265
1266         movi    schedule_tail,r5
1267         ori     r5, 1, r5
1268         ptabs   r5, tr0
1269         blink   tr0, LINK
1270
1271 #ifdef CONFIG_POOR_MANS_STRACE
1272         /* nothing useful in registers at this point */
1273
1274         movi    evt_debug2, r5
1275         ori     r5, 1, r5
1276         ptabs   r5, tr0
1277         ld.q    SP, FRAME_R(9), r2
1278         or      SP, ZERO, r3
1279         blink   tr0, LINK
1280 #endif
1281
1282         ld.q    SP, FRAME_S(FSPC), r2
1283         addi    r2, 4, r2               /* Move PC, being pre-execution event */
1284         st.q    SP, FRAME_S(FSPC), r2
1285         pta     ret_from_syscall, tr0
1286         blink   tr0, ZERO
1287
1288
1289
1290 syscall_allowed:
1291         /* Use LINK to deflect the exit point, default is syscall_ret */
1292         pta     syscall_ret, tr0
1293         gettr   tr0, LINK
1294         pta     syscall_notrace, tr0
1295
1296         getcon  KCR0, r2
1297         ld.l    r2, TI_FLAGS, r4
1298         movi    _TIF_WORK_SYSCALL_MASK, r6
1299         and     r6, r4, r6
1300         beq/l   r6, ZERO, tr0
1301
1302         /* Trace it by calling syscall_trace before and after */
1303         movi    do_syscall_trace_enter, r4
1304         or      SP, ZERO, r2
1305         ptabs   r4, tr0
1306         blink   tr0, LINK
1307
1308         /* Save the retval */
1309         st.q    SP, FRAME_R(2), r2
1310
1311         /* Reload syscall number as r5 is trashed by do_syscall_trace_enter */
1312         ld.q    SP, FRAME_S(FSYSCALL_ID), r5
1313         andi    r5, 0x1ff, r5
1314
1315         pta     syscall_ret_trace, tr0
1316         gettr   tr0, LINK
1317
1318 syscall_notrace:
1319         /* Now point to the appropriate 4th level syscall handler */
1320         movi    sys_call_table, r4
1321         shlli   r5, 2, r5
1322         ldx.l   r4, r5, r5
1323         ptabs   r5, tr0
1324
1325         /* Prepare original args */
1326         ld.q    SP, FRAME_R(2), r2
1327         ld.q    SP, FRAME_R(3), r3
1328         ld.q    SP, FRAME_R(4), r4
1329         ld.q    SP, FRAME_R(5), r5
1330         ld.q    SP, FRAME_R(6), r6
1331         ld.q    SP, FRAME_R(7), r7
1332
1333         /* And now the trick for those syscalls requiring regs * ! */
1334         or      SP, ZERO, r8
1335
1336         /* Call it */
1337         blink   tr0, ZERO       /* LINK is already properly set */
1338
1339 syscall_ret_trace:
1340         /* We get back here only if under trace */
1341         st.q    SP, FRAME_R(9), r2      /* Save return value */
1342
1343         movi    do_syscall_trace_leave, LINK
1344         or      SP, ZERO, r2
1345         ptabs   LINK, tr0
1346         blink   tr0, LINK
1347
1348         /* This needs to be done after any syscall tracing */
1349         ld.q    SP, FRAME_S(FSPC), r2
1350         addi    r2, 4, r2       /* Move PC, being pre-execution event */
1351         st.q    SP, FRAME_S(FSPC), r2
1352
1353         pta     ret_from_syscall, tr0
1354         blink   tr0, ZERO               /* Resume normal return sequence */
1355
1356 /*
1357  * --- Switch to running under a particular ASID and return the previous ASID value
1358  * --- The caller is assumed to have done a cli before calling this.
1359  *
1360  * Input r2 : new ASID
1361  * Output r2 : old ASID
1362  */
1363
1364         .global switch_and_save_asid
1365 switch_and_save_asid:
1366         getcon  sr, r0
1367         movi    255, r4
1368         shlli   r4, 16, r4      /* r4 = mask to select ASID */
1369         and     r0, r4, r3      /* r3 = shifted old ASID */
1370         andi    r2, 255, r2     /* mask down new ASID */
1371         shlli   r2, 16, r2      /* align new ASID against SR.ASID */
1372         andc    r0, r4, r0      /* efface old ASID from SR */
1373         or      r0, r2, r0      /* insert the new ASID */
1374         putcon  r0, ssr
1375         movi    1f, r0
1376         putcon  r0, spc
1377         rte
1378         nop
1379 1:
1380         ptabs   LINK, tr0
1381         shlri   r3, 16, r2      /* r2 = old ASID */
1382         blink tr0, r63
1383
1384         .global route_to_panic_handler
1385 route_to_panic_handler:
1386         /* Switch to real mode, goto panic_handler, don't return.  Useful for
1387            last-chance debugging, e.g. if no output wants to go to the console.
1388            */
1389
1390         movi    panic_handler - CONFIG_PAGE_OFFSET, r1
1391         ptabs   r1, tr0
1392         pta     1f, tr1
1393         gettr   tr1, r0
1394         putcon  r0, spc
1395         getcon  sr, r0
1396         movi    1, r1
1397         shlli   r1, 31, r1
1398         andc    r0, r1, r0
1399         putcon  r0, ssr
1400         rte
1401         nop
1402 1:      /* Now in real mode */
1403         blink tr0, r63
1404         nop
1405
1406         .global peek_real_address_q
1407 peek_real_address_q:
1408         /* Two args:
1409            r2 : real mode address to peek
1410            r2(out) : result quadword
1411
1412            This is provided as a cheapskate way of manipulating device
1413            registers for debugging (to avoid the need to onchip_remap the debug
1414            module, and to avoid the need to onchip_remap the watchpoint
1415            controller in a way that identity maps sufficient bits to avoid the
1416            SH5-101 cut2 silicon defect).
1417
1418            This code is not performance critical
1419         */
1420
1421         add.l   r2, r63, r2     /* sign extend address */
1422         getcon  sr, r0          /* r0 = saved original SR */
1423         movi    1, r1
1424         shlli   r1, 28, r1
1425         or      r0, r1, r1      /* r0 with block bit set */
1426         putcon  r1, sr          /* now in critical section */
1427         movi    1, r36
1428         shlli   r36, 31, r36
1429         andc    r1, r36, r1     /* turn sr.mmu off in real mode section */
1430
1431         putcon  r1, ssr
1432         movi    .peek0 - CONFIG_PAGE_OFFSET, r36 /* real mode target address */
1433         movi    1f, r37         /* virtual mode return addr */
1434         putcon  r36, spc
1435
1436         synco
1437         rte
1438         nop
1439
1440 .peek0: /* come here in real mode, don't touch caches!!
1441            still in critical section (sr.bl==1) */
1442         putcon  r0, ssr
1443         putcon  r37, spc
1444         /* Here's the actual peek.  If the address is bad, all bets are now off
1445          * what will happen (handlers invoked in real-mode = bad news) */
1446         ld.q    r2, 0, r2
1447         synco
1448         rte     /* Back to virtual mode */
1449         nop
1450
1451 1:
1452         ptabs   LINK, tr0
1453         blink   tr0, r63
1454
1455         .global poke_real_address_q
1456 poke_real_address_q:
1457         /* Two args:
1458            r2 : real mode address to poke
1459            r3 : quadword value to write.
1460
1461            This is provided as a cheapskate way of manipulating device
1462            registers for debugging (to avoid the need to onchip_remap the debug
1463            module, and to avoid the need to onchip_remap the watchpoint
1464            controller in a way that identity maps sufficient bits to avoid the
1465            SH5-101 cut2 silicon defect).
1466
1467            This code is not performance critical
1468         */
1469
1470         add.l   r2, r63, r2     /* sign extend address */
1471         getcon  sr, r0          /* r0 = saved original SR */
1472         movi    1, r1
1473         shlli   r1, 28, r1
1474         or      r0, r1, r1      /* r0 with block bit set */
1475         putcon  r1, sr          /* now in critical section */
1476         movi    1, r36
1477         shlli   r36, 31, r36
1478         andc    r1, r36, r1     /* turn sr.mmu off in real mode section */
1479
1480         putcon  r1, ssr
1481         movi    .poke0-CONFIG_PAGE_OFFSET, r36 /* real mode target address */
1482         movi    1f, r37         /* virtual mode return addr */
1483         putcon  r36, spc
1484
1485         synco
1486         rte
1487         nop
1488
1489 .poke0: /* come here in real mode, don't touch caches!!
1490            still in critical section (sr.bl==1) */
1491         putcon  r0, ssr
1492         putcon  r37, spc
1493         /* Here's the actual poke.  If the address is bad, all bets are now off
1494          * what will happen (handlers invoked in real-mode = bad news) */
1495         st.q    r2, 0, r3
1496         synco
1497         rte     /* Back to virtual mode */
1498         nop
1499
1500 1:
1501         ptabs   LINK, tr0
1502         blink   tr0, r63
1503
1504 #ifdef CONFIG_MMU
1505 /*
1506  * --- User Access Handling Section
1507  */
1508
1509 /*
1510  * User Access support. It all moved to non inlined Assembler
1511  * functions in here.
1512  *
1513  * __kernel_size_t __copy_user(void *__to, const void *__from,
1514  *                             __kernel_size_t __n)
1515  *
1516  * Inputs:
1517  * (r2)  target address
1518  * (r3)  source address
1519  * (r4)  size in bytes
1520  *
1521  * Ouputs:
1522  * (*r2) target data
1523  * (r2)  non-copied bytes
1524  *
1525  * If a fault occurs on the user pointer, bail out early and return the
1526  * number of bytes not copied in r2.
1527  * Strategy : for large blocks, call a real memcpy function which can
1528  * move >1 byte at a time using unaligned ld/st instructions, and can
1529  * manipulate the cache using prefetch + alloco to improve the speed
1530  * further.  If a fault occurs in that function, just revert to the
1531  * byte-by-byte approach used for small blocks; this is rare so the
1532  * performance hit for that case does not matter.
1533  *
1534  * For small blocks it's not worth the overhead of setting up and calling
1535  * the memcpy routine; do the copy a byte at a time.
1536  *
1537  */
1538         .global __copy_user
1539 __copy_user:
1540         pta     __copy_user_byte_by_byte, tr1
1541         movi    16, r0 ! this value is a best guess, should tune it by benchmarking
1542         bge/u   r0, r4, tr1
1543         pta copy_user_memcpy, tr0
1544         addi    SP, -32, SP
1545         /* Save arguments in case we have to fix-up unhandled page fault */
1546         st.q    SP, 0, r2
1547         st.q    SP, 8, r3
1548         st.q    SP, 16, r4
1549         st.q    SP, 24, r35 ! r35 is callee-save
1550         /* Save LINK in a register to reduce RTS time later (otherwise
1551            ld SP,*,LINK;ptabs LINK;trn;blink trn,r63 becomes a critical path) */
1552         ori     LINK, 0, r35
1553         blink   tr0, LINK
1554
1555         /* Copy completed normally if we get back here */
1556         ptabs   r35, tr0
1557         ld.q    SP, 24, r35
1558         /* don't restore r2-r4, pointless */
1559         /* set result=r2 to zero as the copy must have succeeded. */
1560         or      r63, r63, r2
1561         addi    SP, 32, SP
1562         blink   tr0, r63 ! RTS
1563
1564         .global __copy_user_fixup
1565 __copy_user_fixup:
1566         /* Restore stack frame */
1567         ori     r35, 0, LINK
1568         ld.q    SP, 24, r35
1569         ld.q    SP, 16, r4
1570         ld.q    SP,  8, r3
1571         ld.q    SP,  0, r2
1572         addi    SP, 32, SP
1573         /* Fall through to original code, in the 'same' state we entered with */
1574
1575 /* The slow byte-by-byte method is used if the fast copy traps due to a bad
1576    user address.  In that rare case, the speed drop can be tolerated. */
1577 __copy_user_byte_by_byte:
1578         pta     ___copy_user_exit, tr1
1579         pta     ___copy_user1, tr0
1580         beq/u   r4, r63, tr1    /* early exit for zero length copy */
1581         sub     r2, r3, r0
1582         addi    r0, -1, r0
1583
1584 ___copy_user1:
1585         ld.b    r3, 0, r5               /* Fault address 1 */
1586
1587         /* Could rewrite this to use just 1 add, but the second comes 'free'
1588            due to load latency */
1589         addi    r3, 1, r3
1590         addi    r4, -1, r4              /* No real fixup required */
1591 ___copy_user2:
1592         stx.b   r3, r0, r5              /* Fault address 2 */
1593         bne     r4, ZERO, tr0
1594
1595 ___copy_user_exit:
1596         or      r4, ZERO, r2
1597         ptabs   LINK, tr0
1598         blink   tr0, ZERO
1599
1600 /*
1601  * __kernel_size_t __clear_user(void *addr, __kernel_size_t size)
1602  *
1603  * Inputs:
1604  * (r2)  target address
1605  * (r3)  size in bytes
1606  *
1607  * Ouputs:
1608  * (*r2) zero-ed target data
1609  * (r2)  non-zero-ed bytes
1610  */
1611         .global __clear_user
1612 __clear_user:
1613         pta     ___clear_user_exit, tr1
1614         pta     ___clear_user1, tr0
1615         beq/u   r3, r63, tr1
1616
1617 ___clear_user1:
1618         st.b    r2, 0, ZERO             /* Fault address */
1619         addi    r2, 1, r2
1620         addi    r3, -1, r3              /* No real fixup required */
1621         bne     r3, ZERO, tr0
1622
1623 ___clear_user_exit:
1624         or      r3, ZERO, r2
1625         ptabs   LINK, tr0
1626         blink   tr0, ZERO
1627
1628 #endif /* CONFIG_MMU */
1629
1630 /*
1631  * int __strncpy_from_user(unsigned long __dest, unsigned long __src,
1632  *                         int __count)
1633  *
1634  * Inputs:
1635  * (r2)  target address
1636  * (r3)  source address
1637  * (r4)  maximum size in bytes
1638  *
1639  * Ouputs:
1640  * (*r2) copied data
1641  * (r2)  -EFAULT (in case of faulting)
1642  *       copied data (otherwise)
1643  */
1644         .global __strncpy_from_user
1645 __strncpy_from_user:
1646         pta     ___strncpy_from_user1, tr0
1647         pta     ___strncpy_from_user_done, tr1
1648         or      r4, ZERO, r5            /* r5 = original count */
1649         beq/u   r4, r63, tr1            /* early exit if r4==0 */
1650         movi    -(EFAULT), r6           /* r6 = reply, no real fixup */
1651         or      ZERO, ZERO, r7          /* r7 = data, clear top byte of data */
1652
1653 ___strncpy_from_user1:
1654         ld.b    r3, 0, r7               /* Fault address: only in reading */
1655         st.b    r2, 0, r7
1656         addi    r2, 1, r2
1657         addi    r3, 1, r3
1658         beq/u   ZERO, r7, tr1
1659         addi    r4, -1, r4              /* return real number of copied bytes */
1660         bne/l   ZERO, r4, tr0
1661
1662 ___strncpy_from_user_done:
1663         sub     r5, r4, r6              /* If done, return copied */
1664
1665 ___strncpy_from_user_exit:
1666         or      r6, ZERO, r2
1667         ptabs   LINK, tr0
1668         blink   tr0, ZERO
1669
1670 /*
1671  * extern long __strnlen_user(const char *__s, long __n)
1672  *
1673  * Inputs:
1674  * (r2)  source address
1675  * (r3)  source size in bytes
1676  *
1677  * Ouputs:
1678  * (r2)  -EFAULT (in case of faulting)
1679  *       string length (otherwise)
1680  */
1681         .global __strnlen_user
1682 __strnlen_user:
1683         pta     ___strnlen_user_set_reply, tr0
1684         pta     ___strnlen_user1, tr1
1685         or      ZERO, ZERO, r5          /* r5 = counter */
1686         movi    -(EFAULT), r6           /* r6 = reply, no real fixup */
1687         or      ZERO, ZERO, r7          /* r7 = data, clear top byte of data */
1688         beq     r3, ZERO, tr0
1689
1690 ___strnlen_user1:
1691         ldx.b   r2, r5, r7              /* Fault address: only in reading */
1692         addi    r3, -1, r3              /* No real fixup */
1693         addi    r5, 1, r5
1694         beq     r3, ZERO, tr0
1695         bne     r7, ZERO, tr1
1696 ! The line below used to be active.  This meant led to a junk byte lying between each pair
1697 ! of entries in the argv & envp structures in memory.  Whilst the program saw the right data
1698 ! via the argv and envp arguments to main, it meant the 'flat' representation visible through
1699 ! /proc/$pid/cmdline was corrupt, causing trouble with ps, for example.
1700 !       addi    r5, 1, r5               /* Include '\0' */
1701
1702 ___strnlen_user_set_reply:
1703         or      r5, ZERO, r6            /* If done, return counter */
1704
1705 ___strnlen_user_exit:
1706         or      r6, ZERO, r2
1707         ptabs   LINK, tr0
1708         blink   tr0, ZERO
1709
1710 /*
1711  * extern long __get_user_asm_?(void *val, long addr)
1712  *
1713  * Inputs:
1714  * (r2)  dest address
1715  * (r3)  source address (in User Space)
1716  *
1717  * Ouputs:
1718  * (r2)  -EFAULT (faulting)
1719  *       0       (not faulting)
1720  */
1721         .global __get_user_asm_b
1722 __get_user_asm_b:
1723         or      r2, ZERO, r4
1724         movi    -(EFAULT), r2           /* r2 = reply, no real fixup */
1725
1726 ___get_user_asm_b1:
1727         ld.b    r3, 0, r5               /* r5 = data */
1728         st.b    r4, 0, r5
1729         or      ZERO, ZERO, r2
1730
1731 ___get_user_asm_b_exit:
1732         ptabs   LINK, tr0
1733         blink   tr0, ZERO
1734
1735
1736         .global __get_user_asm_w
1737 __get_user_asm_w:
1738         or      r2, ZERO, r4
1739         movi    -(EFAULT), r2           /* r2 = reply, no real fixup */
1740
1741 ___get_user_asm_w1:
1742         ld.w    r3, 0, r5               /* r5 = data */
1743         st.w    r4, 0, r5
1744         or      ZERO, ZERO, r2
1745
1746 ___get_user_asm_w_exit:
1747         ptabs   LINK, tr0
1748         blink   tr0, ZERO
1749
1750
1751         .global __get_user_asm_l
1752 __get_user_asm_l:
1753         or      r2, ZERO, r4
1754         movi    -(EFAULT), r2           /* r2 = reply, no real fixup */
1755
1756 ___get_user_asm_l1:
1757         ld.l    r3, 0, r5               /* r5 = data */
1758         st.l    r4, 0, r5
1759         or      ZERO, ZERO, r2
1760
1761 ___get_user_asm_l_exit:
1762         ptabs   LINK, tr0
1763         blink   tr0, ZERO
1764
1765
1766         .global __get_user_asm_q
1767 __get_user_asm_q:
1768         or      r2, ZERO, r4
1769         movi    -(EFAULT), r2           /* r2 = reply, no real fixup */
1770
1771 ___get_user_asm_q1:
1772         ld.q    r3, 0, r5               /* r5 = data */
1773         st.q    r4, 0, r5
1774         or      ZERO, ZERO, r2
1775
1776 ___get_user_asm_q_exit:
1777         ptabs   LINK, tr0
1778         blink   tr0, ZERO
1779
1780 /*
1781  * extern long __put_user_asm_?(void *pval, long addr)
1782  *
1783  * Inputs:
1784  * (r2)  kernel pointer to value
1785  * (r3)  dest address (in User Space)
1786  *
1787  * Ouputs:
1788  * (r2)  -EFAULT (faulting)
1789  *       0       (not faulting)
1790  */
1791         .global __put_user_asm_b
1792 __put_user_asm_b:
1793         ld.b    r2, 0, r4               /* r4 = data */
1794         movi    -(EFAULT), r2           /* r2 = reply, no real fixup */
1795
1796 ___put_user_asm_b1:
1797         st.b    r3, 0, r4
1798         or      ZERO, ZERO, r2
1799
1800 ___put_user_asm_b_exit:
1801         ptabs   LINK, tr0
1802         blink   tr0, ZERO
1803
1804
1805         .global __put_user_asm_w
1806 __put_user_asm_w:
1807         ld.w    r2, 0, r4               /* r4 = data */
1808         movi    -(EFAULT), r2           /* r2 = reply, no real fixup */
1809
1810 ___put_user_asm_w1:
1811         st.w    r3, 0, r4
1812         or      ZERO, ZERO, r2
1813
1814 ___put_user_asm_w_exit:
1815         ptabs   LINK, tr0
1816         blink   tr0, ZERO
1817
1818
1819         .global __put_user_asm_l
1820 __put_user_asm_l:
1821         ld.l    r2, 0, r4               /* r4 = data */
1822         movi    -(EFAULT), r2           /* r2 = reply, no real fixup */
1823
1824 ___put_user_asm_l1:
1825         st.l    r3, 0, r4
1826         or      ZERO, ZERO, r2
1827
1828 ___put_user_asm_l_exit:
1829         ptabs   LINK, tr0
1830         blink   tr0, ZERO
1831
1832
1833         .global __put_user_asm_q
1834 __put_user_asm_q:
1835         ld.q    r2, 0, r4               /* r4 = data */
1836         movi    -(EFAULT), r2           /* r2 = reply, no real fixup */
1837
1838 ___put_user_asm_q1:
1839         st.q    r3, 0, r4
1840         or      ZERO, ZERO, r2
1841
1842 ___put_user_asm_q_exit:
1843         ptabs   LINK, tr0
1844         blink   tr0, ZERO
1845
1846 panic_stash_regs:
1847         /* The idea is : when we get an unhandled panic, we dump the registers
1848            to a known memory location, the just sit in a tight loop.
1849            This allows the human to look at the memory region through the GDB
1850            session (assuming the debug module's SHwy initiator isn't locked up
1851            or anything), to hopefully analyze the cause of the panic. */
1852
1853         /* On entry, former r15 (SP) is in DCR
1854            former r0  is at resvec_saved_area + 0
1855            former r1  is at resvec_saved_area + 8
1856            former tr0 is at resvec_saved_area + 32
1857            DCR is the only register whose value is lost altogether.
1858         */
1859
1860         movi    0xffffffff80000000, r0 ! phy of dump area
1861         ld.q    SP, 0x000, r1   ! former r0
1862         st.q    r0,  0x000, r1
1863         ld.q    SP, 0x008, r1   ! former r1
1864         st.q    r0,  0x008, r1
1865         st.q    r0,  0x010, r2
1866         st.q    r0,  0x018, r3
1867         st.q    r0,  0x020, r4
1868         st.q    r0,  0x028, r5
1869         st.q    r0,  0x030, r6
1870         st.q    r0,  0x038, r7
1871         st.q    r0,  0x040, r8
1872         st.q    r0,  0x048, r9
1873         st.q    r0,  0x050, r10
1874         st.q    r0,  0x058, r11
1875         st.q    r0,  0x060, r12
1876         st.q    r0,  0x068, r13
1877         st.q    r0,  0x070, r14
1878         getcon  dcr, r14
1879         st.q    r0,  0x078, r14
1880         st.q    r0,  0x080, r16
1881         st.q    r0,  0x088, r17
1882         st.q    r0,  0x090, r18
1883         st.q    r0,  0x098, r19
1884         st.q    r0,  0x0a0, r20
1885         st.q    r0,  0x0a8, r21
1886         st.q    r0,  0x0b0, r22
1887         st.q    r0,  0x0b8, r23
1888         st.q    r0,  0x0c0, r24
1889         st.q    r0,  0x0c8, r25
1890         st.q    r0,  0x0d0, r26
1891         st.q    r0,  0x0d8, r27
1892         st.q    r0,  0x0e0, r28
1893         st.q    r0,  0x0e8, r29
1894         st.q    r0,  0x0f0, r30
1895         st.q    r0,  0x0f8, r31
1896         st.q    r0,  0x100, r32
1897         st.q    r0,  0x108, r33
1898         st.q    r0,  0x110, r34
1899         st.q    r0,  0x118, r35
1900         st.q    r0,  0x120, r36
1901         st.q    r0,  0x128, r37
1902         st.q    r0,  0x130, r38
1903         st.q    r0,  0x138, r39
1904         st.q    r0,  0x140, r40
1905         st.q    r0,  0x148, r41
1906         st.q    r0,  0x150, r42
1907         st.q    r0,  0x158, r43
1908         st.q    r0,  0x160, r44
1909         st.q    r0,  0x168, r45
1910         st.q    r0,  0x170, r46
1911         st.q    r0,  0x178, r47
1912         st.q    r0,  0x180, r48
1913         st.q    r0,  0x188, r49
1914         st.q    r0,  0x190, r50
1915         st.q    r0,  0x198, r51
1916         st.q    r0,  0x1a0, r52
1917         st.q    r0,  0x1a8, r53
1918         st.q    r0,  0x1b0, r54
1919         st.q    r0,  0x1b8, r55
1920         st.q    r0,  0x1c0, r56
1921         st.q    r0,  0x1c8, r57
1922         st.q    r0,  0x1d0, r58
1923         st.q    r0,  0x1d8, r59
1924         st.q    r0,  0x1e0, r60
1925         st.q    r0,  0x1e8, r61
1926         st.q    r0,  0x1f0, r62
1927         st.q    r0,  0x1f8, r63 ! bogus, but for consistency's sake...
1928
1929         ld.q    SP, 0x020, r1  ! former tr0
1930         st.q    r0,  0x200, r1
1931         gettr   tr1, r1
1932         st.q    r0,  0x208, r1
1933         gettr   tr2, r1
1934         st.q    r0,  0x210, r1
1935         gettr   tr3, r1
1936         st.q    r0,  0x218, r1
1937         gettr   tr4, r1
1938         st.q    r0,  0x220, r1
1939         gettr   tr5, r1
1940         st.q    r0,  0x228, r1
1941         gettr   tr6, r1
1942         st.q    r0,  0x230, r1
1943         gettr   tr7, r1
1944         st.q    r0,  0x238, r1
1945
1946         getcon  sr,  r1
1947         getcon  ssr,  r2
1948         getcon  pssr,  r3
1949         getcon  spc,  r4
1950         getcon  pspc,  r5
1951         getcon  intevt,  r6
1952         getcon  expevt,  r7
1953         getcon  pexpevt,  r8
1954         getcon  tra,  r9
1955         getcon  tea,  r10
1956         getcon  kcr0, r11
1957         getcon  kcr1, r12
1958         getcon  vbr,  r13
1959         getcon  resvec,  r14
1960
1961         st.q    r0,  0x240, r1
1962         st.q    r0,  0x248, r2
1963         st.q    r0,  0x250, r3
1964         st.q    r0,  0x258, r4
1965         st.q    r0,  0x260, r5
1966         st.q    r0,  0x268, r6
1967         st.q    r0,  0x270, r7
1968         st.q    r0,  0x278, r8
1969         st.q    r0,  0x280, r9
1970         st.q    r0,  0x288, r10
1971         st.q    r0,  0x290, r11
1972         st.q    r0,  0x298, r12
1973         st.q    r0,  0x2a0, r13
1974         st.q    r0,  0x2a8, r14
1975
1976         getcon  SPC,r2
1977         getcon  SSR,r3
1978         getcon  EXPEVT,r4
1979         /* Prepare to jump to C - physical address */
1980         movi    panic_handler-CONFIG_PAGE_OFFSET, r1
1981         ori     r1, 1, r1
1982         ptabs   r1, tr0
1983         getcon  DCR, SP
1984         blink   tr0, ZERO
1985         nop
1986         nop
1987         nop
1988         nop
1989
1990
1991
1992
1993 /*
1994  * --- Signal Handling Section
1995  */
1996
1997 /*
1998  * extern long long _sa_default_rt_restorer
1999  * extern long long _sa_default_restorer
2000  *
2001  *               or, better,
2002  *
2003  * extern void _sa_default_rt_restorer(void)
2004  * extern void _sa_default_restorer(void)
2005  *
2006  * Code prototypes to do a sys_rt_sigreturn() or sys_sysreturn()
2007  * from user space. Copied into user space by signal management.
2008  * Both must be quad aligned and 2 quad long (4 instructions).
2009  *
2010  */
2011         .balign 8
2012         .global sa_default_rt_restorer
2013 sa_default_rt_restorer:
2014         movi    0x10, r9
2015         shori   __NR_rt_sigreturn, r9
2016         trapa   r9
2017         nop
2018
2019         .balign 8
2020         .global sa_default_restorer
2021 sa_default_restorer:
2022         movi    0x10, r9
2023         shori   __NR_sigreturn, r9
2024         trapa   r9
2025         nop
2026
2027 /*
2028  * --- __ex_table Section
2029  */
2030
2031 /*
2032  * User Access Exception Table.
2033  */
2034         .section        __ex_table,  "a"
2035
2036         .global asm_uaccess_start       /* Just a marker */
2037 asm_uaccess_start:
2038
2039 #ifdef CONFIG_MMU
2040         .long   ___copy_user1, ___copy_user_exit
2041         .long   ___copy_user2, ___copy_user_exit
2042         .long   ___clear_user1, ___clear_user_exit
2043 #endif
2044         .long   ___strncpy_from_user1, ___strncpy_from_user_exit
2045         .long   ___strnlen_user1, ___strnlen_user_exit
2046         .long   ___get_user_asm_b1, ___get_user_asm_b_exit
2047         .long   ___get_user_asm_w1, ___get_user_asm_w_exit
2048         .long   ___get_user_asm_l1, ___get_user_asm_l_exit
2049         .long   ___get_user_asm_q1, ___get_user_asm_q_exit
2050         .long   ___put_user_asm_b1, ___put_user_asm_b_exit
2051         .long   ___put_user_asm_w1, ___put_user_asm_w_exit
2052         .long   ___put_user_asm_l1, ___put_user_asm_l_exit
2053         .long   ___put_user_asm_q1, ___put_user_asm_q_exit
2054
2055         .global asm_uaccess_end         /* Just a marker */
2056 asm_uaccess_end:
2057
2058
2059
2060
2061 /*
2062  * --- .init.text Section
2063  */
2064
2065         __INIT
2066
2067 /*
2068  * void trap_init (void)
2069  *
2070  */
2071         .global trap_init
2072 trap_init:
2073         addi    SP, -24, SP                     /* Room to save r28/r29/r30 */
2074         st.q    SP, 0, r28
2075         st.q    SP, 8, r29
2076         st.q    SP, 16, r30
2077
2078         /* Set VBR and RESVEC */
2079         movi    LVBR_block, r19
2080         andi    r19, -4, r19                    /* reset MMUOFF + reserved */
2081         /* For RESVEC exceptions we force the MMU off, which means we need the
2082            physical address. */
2083         movi    LRESVEC_block-CONFIG_PAGE_OFFSET, r20
2084         andi    r20, -4, r20                    /* reset reserved */
2085         ori     r20, 1, r20                     /* set MMUOFF */
2086         putcon  r19, VBR
2087         putcon  r20, RESVEC
2088
2089         /* Sanity check */
2090         movi    LVBR_block_end, r21
2091         andi    r21, -4, r21
2092         movi    BLOCK_SIZE, r29                 /* r29 = expected size */
2093         or      r19, ZERO, r30
2094         add     r19, r29, r19
2095
2096         /*
2097          * Ugly, but better loop forever now than crash afterwards.
2098          * We should print a message, but if we touch LVBR or
2099          * LRESVEC blocks we should not be surprised if we get stuck
2100          * in trap_init().
2101          */
2102         pta     trap_init_loop, tr1
2103         gettr   tr1, r28                        /* r28 = trap_init_loop */
2104         sub     r21, r30, r30                   /* r30 = actual size */
2105
2106         /*
2107          * VBR/RESVEC handlers overlap by being bigger than
2108          * allowed. Very bad. Just loop forever.
2109          * (r28) panic/loop address
2110          * (r29) expected size
2111          * (r30) actual size
2112          */
2113 trap_init_loop:
2114         bne     r19, r21, tr1
2115
2116         /* Now that exception vectors are set up reset SR.BL */
2117         getcon  SR, r22
2118         movi    SR_UNBLOCK_EXC, r23
2119         and     r22, r23, r22
2120         putcon  r22, SR
2121
2122         addi    SP, 24, SP
2123         ptabs   LINK, tr0
2124         blink   tr0, ZERO
2125