[WATCHDOG] Merge code clean-up's from Alan Cox.
[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 - 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 <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_notify_resume, r6
991         ptabs   r6, tr0
992         or      SP, ZERO, r2
993         or      r7, ZERO, r3
994         blink   tr0, LINK           /* Call do_notify_resume(regs, current_thread_info->flags), 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_WORK_SYSCALL_MASK, 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    do_syscall_trace_enter, r4
1309         or      SP, ZERO, r2
1310         ptabs   r4, tr0
1311         blink   tr0, LINK
1312
1313         /* Save the retval */
1314         st.q    SP, FRAME_R(2), r2
1315
1316         /* Reload syscall number as r5 is trashed by do_syscall_trace_enter */
1317         ld.q    SP, FRAME_S(FSYSCALL_ID), r5
1318         andi    r5, 0x1ff, r5
1319
1320         pta     syscall_ret_trace, tr0
1321         gettr   tr0, LINK
1322
1323 syscall_notrace:
1324         /* Now point to the appropriate 4th level syscall handler */
1325         movi    sys_call_table, r4
1326         shlli   r5, 2, r5
1327         ldx.l   r4, r5, r5
1328         ptabs   r5, tr0
1329
1330         /* Prepare original args */
1331         ld.q    SP, FRAME_R(2), r2
1332         ld.q    SP, FRAME_R(3), r3
1333         ld.q    SP, FRAME_R(4), r4
1334         ld.q    SP, FRAME_R(5), r5
1335         ld.q    SP, FRAME_R(6), r6
1336         ld.q    SP, FRAME_R(7), r7
1337
1338         /* And now the trick for those syscalls requiring regs * ! */
1339         or      SP, ZERO, r8
1340
1341         /* Call it */
1342         blink   tr0, ZERO       /* LINK is already properly set */
1343
1344 syscall_ret_trace:
1345         /* We get back here only if under trace */
1346         st.q    SP, FRAME_R(9), r2      /* Save return value */
1347
1348         movi    do_syscall_trace_leave, LINK
1349         or      SP, ZERO, r2
1350         ptabs   LINK, tr0
1351         blink   tr0, LINK
1352
1353         /* This needs to be done after any syscall tracing */
1354         ld.q    SP, FRAME_S(FSPC), r2
1355         addi    r2, 4, r2       /* Move PC, being pre-execution event */
1356         st.q    SP, FRAME_S(FSPC), r2
1357
1358         pta     ret_from_syscall, tr0
1359         blink   tr0, ZERO               /* Resume normal return sequence */
1360
1361 /*
1362  * --- Switch to running under a particular ASID and return the previous ASID value
1363  * --- The caller is assumed to have done a cli before calling this.
1364  *
1365  * Input r2 : new ASID
1366  * Output r2 : old ASID
1367  */
1368
1369         .global switch_and_save_asid
1370 switch_and_save_asid:
1371         getcon  sr, r0
1372         movi    255, r4
1373         shlli   r4, 16, r4      /* r4 = mask to select ASID */
1374         and     r0, r4, r3      /* r3 = shifted old ASID */
1375         andi    r2, 255, r2     /* mask down new ASID */
1376         shlli   r2, 16, r2      /* align new ASID against SR.ASID */
1377         andc    r0, r4, r0      /* efface old ASID from SR */
1378         or      r0, r2, r0      /* insert the new ASID */
1379         putcon  r0, ssr
1380         movi    1f, r0
1381         putcon  r0, spc
1382         rte
1383         nop
1384 1:
1385         ptabs   LINK, tr0
1386         shlri   r3, 16, r2      /* r2 = old ASID */
1387         blink tr0, r63
1388
1389         .global route_to_panic_handler
1390 route_to_panic_handler:
1391         /* Switch to real mode, goto panic_handler, don't return.  Useful for
1392            last-chance debugging, e.g. if no output wants to go to the console.
1393            */
1394
1395         movi    panic_handler - CONFIG_PAGE_OFFSET, r1
1396         ptabs   r1, tr0
1397         pta     1f, tr1
1398         gettr   tr1, r0
1399         putcon  r0, spc
1400         getcon  sr, r0
1401         movi    1, r1
1402         shlli   r1, 31, r1
1403         andc    r0, r1, r0
1404         putcon  r0, ssr
1405         rte
1406         nop
1407 1:      /* Now in real mode */
1408         blink tr0, r63
1409         nop
1410
1411         .global peek_real_address_q
1412 peek_real_address_q:
1413         /* Two args:
1414            r2 : real mode address to peek
1415            r2(out) : result quadword
1416
1417            This is provided as a cheapskate way of manipulating device
1418            registers for debugging (to avoid the need to onchip_remap the debug
1419            module, and to avoid the need to onchip_remap the watchpoint
1420            controller in a way that identity maps sufficient bits to avoid the
1421            SH5-101 cut2 silicon defect).
1422
1423            This code is not performance critical
1424         */
1425
1426         add.l   r2, r63, r2     /* sign extend address */
1427         getcon  sr, r0          /* r0 = saved original SR */
1428         movi    1, r1
1429         shlli   r1, 28, r1
1430         or      r0, r1, r1      /* r0 with block bit set */
1431         putcon  r1, sr          /* now in critical section */
1432         movi    1, r36
1433         shlli   r36, 31, r36
1434         andc    r1, r36, r1     /* turn sr.mmu off in real mode section */
1435
1436         putcon  r1, ssr
1437         movi    .peek0 - CONFIG_PAGE_OFFSET, r36 /* real mode target address */
1438         movi    1f, r37         /* virtual mode return addr */
1439         putcon  r36, spc
1440
1441         synco
1442         rte
1443         nop
1444
1445 .peek0: /* come here in real mode, don't touch caches!!
1446            still in critical section (sr.bl==1) */
1447         putcon  r0, ssr
1448         putcon  r37, spc
1449         /* Here's the actual peek.  If the address is bad, all bets are now off
1450          * what will happen (handlers invoked in real-mode = bad news) */
1451         ld.q    r2, 0, r2
1452         synco
1453         rte     /* Back to virtual mode */
1454         nop
1455
1456 1:
1457         ptabs   LINK, tr0
1458         blink   tr0, r63
1459
1460         .global poke_real_address_q
1461 poke_real_address_q:
1462         /* Two args:
1463            r2 : real mode address to poke
1464            r3 : quadword value to write.
1465
1466            This is provided as a cheapskate way of manipulating device
1467            registers for debugging (to avoid the need to onchip_remap the debug
1468            module, and to avoid the need to onchip_remap the watchpoint
1469            controller in a way that identity maps sufficient bits to avoid the
1470            SH5-101 cut2 silicon defect).
1471
1472            This code is not performance critical
1473         */
1474
1475         add.l   r2, r63, r2     /* sign extend address */
1476         getcon  sr, r0          /* r0 = saved original SR */
1477         movi    1, r1
1478         shlli   r1, 28, r1
1479         or      r0, r1, r1      /* r0 with block bit set */
1480         putcon  r1, sr          /* now in critical section */
1481         movi    1, r36
1482         shlli   r36, 31, r36
1483         andc    r1, r36, r1     /* turn sr.mmu off in real mode section */
1484
1485         putcon  r1, ssr
1486         movi    .poke0-CONFIG_PAGE_OFFSET, r36 /* real mode target address */
1487         movi    1f, r37         /* virtual mode return addr */
1488         putcon  r36, spc
1489
1490         synco
1491         rte
1492         nop
1493
1494 .poke0: /* come here in real mode, don't touch caches!!
1495            still in critical section (sr.bl==1) */
1496         putcon  r0, ssr
1497         putcon  r37, spc
1498         /* Here's the actual poke.  If the address is bad, all bets are now off
1499          * what will happen (handlers invoked in real-mode = bad news) */
1500         st.q    r2, 0, r3
1501         synco
1502         rte     /* Back to virtual mode */
1503         nop
1504
1505 1:
1506         ptabs   LINK, tr0
1507         blink   tr0, r63
1508
1509 #ifdef CONFIG_MMU
1510 /*
1511  * --- User Access Handling Section
1512  */
1513
1514 /*
1515  * User Access support. It all moved to non inlined Assembler
1516  * functions in here.
1517  *
1518  * __kernel_size_t __copy_user(void *__to, const void *__from,
1519  *                             __kernel_size_t __n)
1520  *
1521  * Inputs:
1522  * (r2)  target address
1523  * (r3)  source address
1524  * (r4)  size in bytes
1525  *
1526  * Ouputs:
1527  * (*r2) target data
1528  * (r2)  non-copied bytes
1529  *
1530  * If a fault occurs on the user pointer, bail out early and return the
1531  * number of bytes not copied in r2.
1532  * Strategy : for large blocks, call a real memcpy function which can
1533  * move >1 byte at a time using unaligned ld/st instructions, and can
1534  * manipulate the cache using prefetch + alloco to improve the speed
1535  * further.  If a fault occurs in that function, just revert to the
1536  * byte-by-byte approach used for small blocks; this is rare so the
1537  * performance hit for that case does not matter.
1538  *
1539  * For small blocks it's not worth the overhead of setting up and calling
1540  * the memcpy routine; do the copy a byte at a time.
1541  *
1542  */
1543         .global __copy_user
1544 __copy_user:
1545         pta     __copy_user_byte_by_byte, tr1
1546         movi    16, r0 ! this value is a best guess, should tune it by benchmarking
1547         bge/u   r0, r4, tr1
1548         pta copy_user_memcpy, tr0
1549         addi    SP, -32, SP
1550         /* Save arguments in case we have to fix-up unhandled page fault */
1551         st.q    SP, 0, r2
1552         st.q    SP, 8, r3
1553         st.q    SP, 16, r4
1554         st.q    SP, 24, r35 ! r35 is callee-save
1555         /* Save LINK in a register to reduce RTS time later (otherwise
1556            ld SP,*,LINK;ptabs LINK;trn;blink trn,r63 becomes a critical path) */
1557         ori     LINK, 0, r35
1558         blink   tr0, LINK
1559
1560         /* Copy completed normally if we get back here */
1561         ptabs   r35, tr0
1562         ld.q    SP, 24, r35
1563         /* don't restore r2-r4, pointless */
1564         /* set result=r2 to zero as the copy must have succeeded. */
1565         or      r63, r63, r2
1566         addi    SP, 32, SP
1567         blink   tr0, r63 ! RTS
1568
1569         .global __copy_user_fixup
1570 __copy_user_fixup:
1571         /* Restore stack frame */
1572         ori     r35, 0, LINK
1573         ld.q    SP, 24, r35
1574         ld.q    SP, 16, r4
1575         ld.q    SP,  8, r3
1576         ld.q    SP,  0, r2
1577         addi    SP, 32, SP
1578         /* Fall through to original code, in the 'same' state we entered with */
1579
1580 /* The slow byte-by-byte method is used if the fast copy traps due to a bad
1581    user address.  In that rare case, the speed drop can be tolerated. */
1582 __copy_user_byte_by_byte:
1583         pta     ___copy_user_exit, tr1
1584         pta     ___copy_user1, tr0
1585         beq/u   r4, r63, tr1    /* early exit for zero length copy */
1586         sub     r2, r3, r0
1587         addi    r0, -1, r0
1588
1589 ___copy_user1:
1590         ld.b    r3, 0, r5               /* Fault address 1 */
1591
1592         /* Could rewrite this to use just 1 add, but the second comes 'free'
1593            due to load latency */
1594         addi    r3, 1, r3
1595         addi    r4, -1, r4              /* No real fixup required */
1596 ___copy_user2:
1597         stx.b   r3, r0, r5              /* Fault address 2 */
1598         bne     r4, ZERO, tr0
1599
1600 ___copy_user_exit:
1601         or      r4, ZERO, r2
1602         ptabs   LINK, tr0
1603         blink   tr0, ZERO
1604
1605 /*
1606  * __kernel_size_t __clear_user(void *addr, __kernel_size_t size)
1607  *
1608  * Inputs:
1609  * (r2)  target address
1610  * (r3)  size in bytes
1611  *
1612  * Ouputs:
1613  * (*r2) zero-ed target data
1614  * (r2)  non-zero-ed bytes
1615  */
1616         .global __clear_user
1617 __clear_user:
1618         pta     ___clear_user_exit, tr1
1619         pta     ___clear_user1, tr0
1620         beq/u   r3, r63, tr1
1621
1622 ___clear_user1:
1623         st.b    r2, 0, ZERO             /* Fault address */
1624         addi    r2, 1, r2
1625         addi    r3, -1, r3              /* No real fixup required */
1626         bne     r3, ZERO, tr0
1627
1628 ___clear_user_exit:
1629         or      r3, ZERO, r2
1630         ptabs   LINK, tr0
1631         blink   tr0, ZERO
1632
1633 #endif /* CONFIG_MMU */
1634
1635 /*
1636  * int __strncpy_from_user(unsigned long __dest, unsigned long __src,
1637  *                         int __count)
1638  *
1639  * Inputs:
1640  * (r2)  target address
1641  * (r3)  source address
1642  * (r4)  maximum size in bytes
1643  *
1644  * Ouputs:
1645  * (*r2) copied data
1646  * (r2)  -EFAULT (in case of faulting)
1647  *       copied data (otherwise)
1648  */
1649         .global __strncpy_from_user
1650 __strncpy_from_user:
1651         pta     ___strncpy_from_user1, tr0
1652         pta     ___strncpy_from_user_done, tr1
1653         or      r4, ZERO, r5            /* r5 = original count */
1654         beq/u   r4, r63, tr1            /* early exit if r4==0 */
1655         movi    -(EFAULT), r6           /* r6 = reply, no real fixup */
1656         or      ZERO, ZERO, r7          /* r7 = data, clear top byte of data */
1657
1658 ___strncpy_from_user1:
1659         ld.b    r3, 0, r7               /* Fault address: only in reading */
1660         st.b    r2, 0, r7
1661         addi    r2, 1, r2
1662         addi    r3, 1, r3
1663         beq/u   ZERO, r7, tr1
1664         addi    r4, -1, r4              /* return real number of copied bytes */
1665         bne/l   ZERO, r4, tr0
1666
1667 ___strncpy_from_user_done:
1668         sub     r5, r4, r6              /* If done, return copied */
1669
1670 ___strncpy_from_user_exit:
1671         or      r6, ZERO, r2
1672         ptabs   LINK, tr0
1673         blink   tr0, ZERO
1674
1675 /*
1676  * extern long __strnlen_user(const char *__s, long __n)
1677  *
1678  * Inputs:
1679  * (r2)  source address
1680  * (r3)  source size in bytes
1681  *
1682  * Ouputs:
1683  * (r2)  -EFAULT (in case of faulting)
1684  *       string length (otherwise)
1685  */
1686         .global __strnlen_user
1687 __strnlen_user:
1688         pta     ___strnlen_user_set_reply, tr0
1689         pta     ___strnlen_user1, tr1
1690         or      ZERO, ZERO, r5          /* r5 = counter */
1691         movi    -(EFAULT), r6           /* r6 = reply, no real fixup */
1692         or      ZERO, ZERO, r7          /* r7 = data, clear top byte of data */
1693         beq     r3, ZERO, tr0
1694
1695 ___strnlen_user1:
1696         ldx.b   r2, r5, r7              /* Fault address: only in reading */
1697         addi    r3, -1, r3              /* No real fixup */
1698         addi    r5, 1, r5
1699         beq     r3, ZERO, tr0
1700         bne     r7, ZERO, tr1
1701 ! The line below used to be active.  This meant led to a junk byte lying between each pair
1702 ! of entries in the argv & envp structures in memory.  Whilst the program saw the right data
1703 ! via the argv and envp arguments to main, it meant the 'flat' representation visible through
1704 ! /proc/$pid/cmdline was corrupt, causing trouble with ps, for example.
1705 !       addi    r5, 1, r5               /* Include '\0' */
1706
1707 ___strnlen_user_set_reply:
1708         or      r5, ZERO, r6            /* If done, return counter */
1709
1710 ___strnlen_user_exit:
1711         or      r6, ZERO, r2
1712         ptabs   LINK, tr0
1713         blink   tr0, ZERO
1714
1715 /*
1716  * extern long __get_user_asm_?(void *val, long addr)
1717  *
1718  * Inputs:
1719  * (r2)  dest address
1720  * (r3)  source address (in User Space)
1721  *
1722  * Ouputs:
1723  * (r2)  -EFAULT (faulting)
1724  *       0       (not faulting)
1725  */
1726         .global __get_user_asm_b
1727 __get_user_asm_b:
1728         or      r2, ZERO, r4
1729         movi    -(EFAULT), r2           /* r2 = reply, no real fixup */
1730
1731 ___get_user_asm_b1:
1732         ld.b    r3, 0, r5               /* r5 = data */
1733         st.b    r4, 0, r5
1734         or      ZERO, ZERO, r2
1735
1736 ___get_user_asm_b_exit:
1737         ptabs   LINK, tr0
1738         blink   tr0, ZERO
1739
1740
1741         .global __get_user_asm_w
1742 __get_user_asm_w:
1743         or      r2, ZERO, r4
1744         movi    -(EFAULT), r2           /* r2 = reply, no real fixup */
1745
1746 ___get_user_asm_w1:
1747         ld.w    r3, 0, r5               /* r5 = data */
1748         st.w    r4, 0, r5
1749         or      ZERO, ZERO, r2
1750
1751 ___get_user_asm_w_exit:
1752         ptabs   LINK, tr0
1753         blink   tr0, ZERO
1754
1755
1756         .global __get_user_asm_l
1757 __get_user_asm_l:
1758         or      r2, ZERO, r4
1759         movi    -(EFAULT), r2           /* r2 = reply, no real fixup */
1760
1761 ___get_user_asm_l1:
1762         ld.l    r3, 0, r5               /* r5 = data */
1763         st.l    r4, 0, r5
1764         or      ZERO, ZERO, r2
1765
1766 ___get_user_asm_l_exit:
1767         ptabs   LINK, tr0
1768         blink   tr0, ZERO
1769
1770
1771         .global __get_user_asm_q
1772 __get_user_asm_q:
1773         or      r2, ZERO, r4
1774         movi    -(EFAULT), r2           /* r2 = reply, no real fixup */
1775
1776 ___get_user_asm_q1:
1777         ld.q    r3, 0, r5               /* r5 = data */
1778         st.q    r4, 0, r5
1779         or      ZERO, ZERO, r2
1780
1781 ___get_user_asm_q_exit:
1782         ptabs   LINK, tr0
1783         blink   tr0, ZERO
1784
1785 /*
1786  * extern long __put_user_asm_?(void *pval, long addr)
1787  *
1788  * Inputs:
1789  * (r2)  kernel pointer to value
1790  * (r3)  dest address (in User Space)
1791  *
1792  * Ouputs:
1793  * (r2)  -EFAULT (faulting)
1794  *       0       (not faulting)
1795  */
1796         .global __put_user_asm_b
1797 __put_user_asm_b:
1798         ld.b    r2, 0, r4               /* r4 = data */
1799         movi    -(EFAULT), r2           /* r2 = reply, no real fixup */
1800
1801 ___put_user_asm_b1:
1802         st.b    r3, 0, r4
1803         or      ZERO, ZERO, r2
1804
1805 ___put_user_asm_b_exit:
1806         ptabs   LINK, tr0
1807         blink   tr0, ZERO
1808
1809
1810         .global __put_user_asm_w
1811 __put_user_asm_w:
1812         ld.w    r2, 0, r4               /* r4 = data */
1813         movi    -(EFAULT), r2           /* r2 = reply, no real fixup */
1814
1815 ___put_user_asm_w1:
1816         st.w    r3, 0, r4
1817         or      ZERO, ZERO, r2
1818
1819 ___put_user_asm_w_exit:
1820         ptabs   LINK, tr0
1821         blink   tr0, ZERO
1822
1823
1824         .global __put_user_asm_l
1825 __put_user_asm_l:
1826         ld.l    r2, 0, r4               /* r4 = data */
1827         movi    -(EFAULT), r2           /* r2 = reply, no real fixup */
1828
1829 ___put_user_asm_l1:
1830         st.l    r3, 0, r4
1831         or      ZERO, ZERO, r2
1832
1833 ___put_user_asm_l_exit:
1834         ptabs   LINK, tr0
1835         blink   tr0, ZERO
1836
1837
1838         .global __put_user_asm_q
1839 __put_user_asm_q:
1840         ld.q    r2, 0, r4               /* r4 = data */
1841         movi    -(EFAULT), r2           /* r2 = reply, no real fixup */
1842
1843 ___put_user_asm_q1:
1844         st.q    r3, 0, r4
1845         or      ZERO, ZERO, r2
1846
1847 ___put_user_asm_q_exit:
1848         ptabs   LINK, tr0
1849         blink   tr0, ZERO
1850
1851 panic_stash_regs:
1852         /* The idea is : when we get an unhandled panic, we dump the registers
1853            to a known memory location, the just sit in a tight loop.
1854            This allows the human to look at the memory region through the GDB
1855            session (assuming the debug module's SHwy initiator isn't locked up
1856            or anything), to hopefully analyze the cause of the panic. */
1857
1858         /* On entry, former r15 (SP) is in DCR
1859            former r0  is at resvec_saved_area + 0
1860            former r1  is at resvec_saved_area + 8
1861            former tr0 is at resvec_saved_area + 32
1862            DCR is the only register whose value is lost altogether.
1863         */
1864
1865         movi    0xffffffff80000000, r0 ! phy of dump area
1866         ld.q    SP, 0x000, r1   ! former r0
1867         st.q    r0,  0x000, r1
1868         ld.q    SP, 0x008, r1   ! former r1
1869         st.q    r0,  0x008, r1
1870         st.q    r0,  0x010, r2
1871         st.q    r0,  0x018, r3
1872         st.q    r0,  0x020, r4
1873         st.q    r0,  0x028, r5
1874         st.q    r0,  0x030, r6
1875         st.q    r0,  0x038, r7
1876         st.q    r0,  0x040, r8
1877         st.q    r0,  0x048, r9
1878         st.q    r0,  0x050, r10
1879         st.q    r0,  0x058, r11
1880         st.q    r0,  0x060, r12
1881         st.q    r0,  0x068, r13
1882         st.q    r0,  0x070, r14
1883         getcon  dcr, r14
1884         st.q    r0,  0x078, r14
1885         st.q    r0,  0x080, r16
1886         st.q    r0,  0x088, r17
1887         st.q    r0,  0x090, r18
1888         st.q    r0,  0x098, r19
1889         st.q    r0,  0x0a0, r20
1890         st.q    r0,  0x0a8, r21
1891         st.q    r0,  0x0b0, r22
1892         st.q    r0,  0x0b8, r23
1893         st.q    r0,  0x0c0, r24
1894         st.q    r0,  0x0c8, r25
1895         st.q    r0,  0x0d0, r26
1896         st.q    r0,  0x0d8, r27
1897         st.q    r0,  0x0e0, r28
1898         st.q    r0,  0x0e8, r29
1899         st.q    r0,  0x0f0, r30
1900         st.q    r0,  0x0f8, r31
1901         st.q    r0,  0x100, r32
1902         st.q    r0,  0x108, r33
1903         st.q    r0,  0x110, r34
1904         st.q    r0,  0x118, r35
1905         st.q    r0,  0x120, r36
1906         st.q    r0,  0x128, r37
1907         st.q    r0,  0x130, r38
1908         st.q    r0,  0x138, r39
1909         st.q    r0,  0x140, r40
1910         st.q    r0,  0x148, r41
1911         st.q    r0,  0x150, r42
1912         st.q    r0,  0x158, r43
1913         st.q    r0,  0x160, r44
1914         st.q    r0,  0x168, r45
1915         st.q    r0,  0x170, r46
1916         st.q    r0,  0x178, r47
1917         st.q    r0,  0x180, r48
1918         st.q    r0,  0x188, r49
1919         st.q    r0,  0x190, r50
1920         st.q    r0,  0x198, r51
1921         st.q    r0,  0x1a0, r52
1922         st.q    r0,  0x1a8, r53
1923         st.q    r0,  0x1b0, r54
1924         st.q    r0,  0x1b8, r55
1925         st.q    r0,  0x1c0, r56
1926         st.q    r0,  0x1c8, r57
1927         st.q    r0,  0x1d0, r58
1928         st.q    r0,  0x1d8, r59
1929         st.q    r0,  0x1e0, r60
1930         st.q    r0,  0x1e8, r61
1931         st.q    r0,  0x1f0, r62
1932         st.q    r0,  0x1f8, r63 ! bogus, but for consistency's sake...
1933
1934         ld.q    SP, 0x020, r1  ! former tr0
1935         st.q    r0,  0x200, r1
1936         gettr   tr1, r1
1937         st.q    r0,  0x208, r1
1938         gettr   tr2, r1
1939         st.q    r0,  0x210, r1
1940         gettr   tr3, r1
1941         st.q    r0,  0x218, r1
1942         gettr   tr4, r1
1943         st.q    r0,  0x220, r1
1944         gettr   tr5, r1
1945         st.q    r0,  0x228, r1
1946         gettr   tr6, r1
1947         st.q    r0,  0x230, r1
1948         gettr   tr7, r1
1949         st.q    r0,  0x238, r1
1950
1951         getcon  sr,  r1
1952         getcon  ssr,  r2
1953         getcon  pssr,  r3
1954         getcon  spc,  r4
1955         getcon  pspc,  r5
1956         getcon  intevt,  r6
1957         getcon  expevt,  r7
1958         getcon  pexpevt,  r8
1959         getcon  tra,  r9
1960         getcon  tea,  r10
1961         getcon  kcr0, r11
1962         getcon  kcr1, r12
1963         getcon  vbr,  r13
1964         getcon  resvec,  r14
1965
1966         st.q    r0,  0x240, r1
1967         st.q    r0,  0x248, r2
1968         st.q    r0,  0x250, r3
1969         st.q    r0,  0x258, r4
1970         st.q    r0,  0x260, r5
1971         st.q    r0,  0x268, r6
1972         st.q    r0,  0x270, r7
1973         st.q    r0,  0x278, r8
1974         st.q    r0,  0x280, r9
1975         st.q    r0,  0x288, r10
1976         st.q    r0,  0x290, r11
1977         st.q    r0,  0x298, r12
1978         st.q    r0,  0x2a0, r13
1979         st.q    r0,  0x2a8, r14
1980
1981         getcon  SPC,r2
1982         getcon  SSR,r3
1983         getcon  EXPEVT,r4
1984         /* Prepare to jump to C - physical address */
1985         movi    panic_handler-CONFIG_PAGE_OFFSET, r1
1986         ori     r1, 1, r1
1987         ptabs   r1, tr0
1988         getcon  DCR, SP
1989         blink   tr0, ZERO
1990         nop
1991         nop
1992         nop
1993         nop
1994
1995
1996
1997
1998 /*
1999  * --- Signal Handling Section
2000  */
2001
2002 /*
2003  * extern long long _sa_default_rt_restorer
2004  * extern long long _sa_default_restorer
2005  *
2006  *               or, better,
2007  *
2008  * extern void _sa_default_rt_restorer(void)
2009  * extern void _sa_default_restorer(void)
2010  *
2011  * Code prototypes to do a sys_rt_sigreturn() or sys_sysreturn()
2012  * from user space. Copied into user space by signal management.
2013  * Both must be quad aligned and 2 quad long (4 instructions).
2014  *
2015  */
2016         .balign 8
2017         .global sa_default_rt_restorer
2018 sa_default_rt_restorer:
2019         movi    0x10, r9
2020         shori   __NR_rt_sigreturn, r9
2021         trapa   r9
2022         nop
2023
2024         .balign 8
2025         .global sa_default_restorer
2026 sa_default_restorer:
2027         movi    0x10, r9
2028         shori   __NR_sigreturn, r9
2029         trapa   r9
2030         nop
2031
2032 /*
2033  * --- __ex_table Section
2034  */
2035
2036 /*
2037  * User Access Exception Table.
2038  */
2039         .section        __ex_table,  "a"
2040
2041         .global asm_uaccess_start       /* Just a marker */
2042 asm_uaccess_start:
2043
2044 #ifdef CONFIG_MMU
2045         .long   ___copy_user1, ___copy_user_exit
2046         .long   ___copy_user2, ___copy_user_exit
2047         .long   ___clear_user1, ___clear_user_exit
2048 #endif
2049         .long   ___strncpy_from_user1, ___strncpy_from_user_exit
2050         .long   ___strnlen_user1, ___strnlen_user_exit
2051         .long   ___get_user_asm_b1, ___get_user_asm_b_exit
2052         .long   ___get_user_asm_w1, ___get_user_asm_w_exit
2053         .long   ___get_user_asm_l1, ___get_user_asm_l_exit
2054         .long   ___get_user_asm_q1, ___get_user_asm_q_exit
2055         .long   ___put_user_asm_b1, ___put_user_asm_b_exit
2056         .long   ___put_user_asm_w1, ___put_user_asm_w_exit
2057         .long   ___put_user_asm_l1, ___put_user_asm_l_exit
2058         .long   ___put_user_asm_q1, ___put_user_asm_q_exit
2059
2060         .global asm_uaccess_end         /* Just a marker */
2061 asm_uaccess_end:
2062
2063
2064
2065
2066 /*
2067  * --- .text.init Section
2068  */
2069
2070         .section        .text.init, "ax"
2071
2072 /*
2073  * void trap_init (void)
2074  *
2075  */
2076         .global trap_init
2077 trap_init:
2078         addi    SP, -24, SP                     /* Room to save r28/r29/r30 */
2079         st.q    SP, 0, r28
2080         st.q    SP, 8, r29
2081         st.q    SP, 16, r30
2082
2083         /* Set VBR and RESVEC */
2084         movi    LVBR_block, r19
2085         andi    r19, -4, r19                    /* reset MMUOFF + reserved */
2086         /* For RESVEC exceptions we force the MMU off, which means we need the
2087            physical address. */
2088         movi    LRESVEC_block-CONFIG_PAGE_OFFSET, r20
2089         andi    r20, -4, r20                    /* reset reserved */
2090         ori     r20, 1, r20                     /* set MMUOFF */
2091         putcon  r19, VBR
2092         putcon  r20, RESVEC
2093
2094         /* Sanity check */
2095         movi    LVBR_block_end, r21
2096         andi    r21, -4, r21
2097         movi    BLOCK_SIZE, r29                 /* r29 = expected size */
2098         or      r19, ZERO, r30
2099         add     r19, r29, r19
2100
2101         /*
2102          * Ugly, but better loop forever now than crash afterwards.
2103          * We should print a message, but if we touch LVBR or
2104          * LRESVEC blocks we should not be surprised if we get stuck
2105          * in trap_init().
2106          */
2107         pta     trap_init_loop, tr1
2108         gettr   tr1, r28                        /* r28 = trap_init_loop */
2109         sub     r21, r30, r30                   /* r30 = actual size */
2110
2111         /*
2112          * VBR/RESVEC handlers overlap by being bigger than
2113          * allowed. Very bad. Just loop forever.
2114          * (r28) panic/loop address
2115          * (r29) expected size
2116          * (r30) actual size
2117          */
2118 trap_init_loop:
2119         bne     r19, r21, tr1
2120
2121         /* Now that exception vectors are set up reset SR.BL */
2122         getcon  SR, r22
2123         movi    SR_UNBLOCK_EXC, r23
2124         and     r22, r23, r22
2125         putcon  r22, SR
2126
2127         addi    SP, 24, SP
2128         ptabs   LINK, tr0
2129         blink   tr0, ZERO
2130