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