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