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