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