GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / arch / parisc / kernel / entry.S
blobfbd0341e7d70c411395cbf4220f4ff0f0144215c
1 /*
2  * Linux/PA-RISC Project (http://www.parisc-linux.org/)
3  *
4  * kernel entry points (interruptions, system call wrappers)
5  *  Copyright (C) 1999,2000 Philipp Rumpf 
6  *  Copyright (C) 1999 SuSE GmbH Nuernberg 
7  *  Copyright (C) 2000 Hewlett-Packard (John Marvin)
8  *  Copyright (C) 1999 Hewlett-Packard (Frank Rowand)
9  *
10  *    This program is free software; you can redistribute it and/or modify
11  *    it under the terms of the GNU General Public License as published by
12  *    the Free Software Foundation; either version 2, or (at your option)
13  *    any later version.
14  *
15  *    This program is distributed in the hope that it will be useful,
16  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *    GNU General Public License for more details.
19  *
20  *    You should have received a copy of the GNU General Public License
21  *    along with this program; if not, write to the Free Software
22  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
25 #include <asm/asm-offsets.h>
27 /* we have the following possibilities to act on an interruption:
28  *  - handle in assembly and use shadowed registers only
29  *  - save registers to kernel stack and handle in assembly or C */
32 #include <asm/psw.h>
33 #include <asm/cache.h>          /* for L1_CACHE_SHIFT */
34 #include <asm/assembly.h>       /* for LDREG/STREG defines */
35 #include <asm/pgtable.h>
36 #include <asm/signal.h>
37 #include <asm/unistd.h>
38 #include <asm/thread_info.h>
40 #include <linux/linkage.h>
42 #ifdef CONFIG_64BIT
43         .level 2.0w
44 #else
45         .level 2.0
46 #endif
48         .import         pa_dbit_lock,data
50         /* space_to_prot macro creates a prot id from a space id */
52 #if SPACEID_SHIFT == 0
53         .macro  space_to_prot spc prot
54         depd,z  \spc,62,31,\prot
55         .endm
56 #else
57         .macro  space_to_prot spc prot
58         extrd,u \spc,(64 - (SPACEID_SHIFT)),32,\prot
59         .endm
60 #endif
62         /* Switch to virtual mapping, trashing only %r1 */
63         .macro  virt_map
64         /* pcxt_ssm_bug */
65         rsm     PSW_SM_I, %r0   /* barrier for "Relied upon Translation */
66         mtsp    %r0, %sr4
67         mtsp    %r0, %sr5
68         mfsp    %sr7, %r1
69         or,=    %r0,%r1,%r0     /* Only save sr7 in sr3 if sr7 != 0 */
70         mtsp    %r1, %sr3
71         tovirt_r1 %r29
72         load32  KERNEL_PSW, %r1
74         rsm     PSW_SM_QUIET,%r0        /* second "heavy weight" ctl op */
75         mtsp    %r0, %sr6
76         mtsp    %r0, %sr7
77         mtctl   %r0, %cr17      /* Clear IIASQ tail */
78         mtctl   %r0, %cr17      /* Clear IIASQ head */
79         mtctl   %r1, %ipsw
80         load32  4f, %r1
81         mtctl   %r1, %cr18      /* Set IIAOQ tail */
82         ldo     4(%r1), %r1
83         mtctl   %r1, %cr18      /* Set IIAOQ head */
84         rfir
85         nop
87         .endm
89         /*
90          * The "get_stack" macros are responsible for determining the
91          * kernel stack value.
92          *
93          *      If sr7 == 0
94          *          Already using a kernel stack, so call the
95          *          get_stack_use_r30 macro to push a pt_regs structure
96          *          on the stack, and store registers there.
97          *      else
98          *          Need to set up a kernel stack, so call the
99          *          get_stack_use_cr30 macro to set up a pointer
100          *          to the pt_regs structure contained within the
101          *          task pointer pointed to by cr30. Set the stack
102          *          pointer to point to the end of the task structure.
103          *
104          * Note that we use shadowed registers for temps until
105          * we can save %r26 and %r29. %r26 is used to preserve
106          * %r8 (a shadowed register) which temporarily contained
107          * either the fault type ("code") or the eirr. We need
108          * to use a non-shadowed register to carry the value over
109          * the rfir in virt_map. We use %r26 since this value winds
110          * up being passed as the argument to either do_cpu_irq_mask
111          * or handle_interruption. %r29 is used to hold a pointer
112          * the register save area, and once again, it needs to
113          * be a non-shadowed register so that it survives the rfir.
114          *
115          * N.B. TASK_SZ_ALGN and PT_SZ_ALGN include space for a stack frame.
116          */
118         .macro  get_stack_use_cr30
120         /* we save the registers in the task struct */
122         mfctl   %cr30, %r1
123         tophys  %r1,%r9
124         LDREG   TI_TASK(%r9), %r1       /* thread_info -> task_struct */
125         tophys  %r1,%r9
126         ldo     TASK_REGS(%r9),%r9
127         STREG   %r30, PT_GR30(%r9)
128         STREG   %r29,PT_GR29(%r9)
129         STREG   %r26,PT_GR26(%r9)
130         copy    %r9,%r29
131         mfctl   %cr30, %r1
132         ldo     THREAD_SZ_ALGN(%r1), %r30
133         .endm
135         .macro  get_stack_use_r30
137         /* we put a struct pt_regs on the stack and save the registers there */
139         tophys  %r30,%r9
140         STREG   %r30,PT_GR30(%r9)
141         ldo     PT_SZ_ALGN(%r30),%r30
142         STREG   %r29,PT_GR29(%r9)
143         STREG   %r26,PT_GR26(%r9)
144         copy    %r9,%r29
145         .endm
147         .macro  rest_stack
148         LDREG   PT_GR1(%r29), %r1
149         LDREG   PT_GR30(%r29),%r30
150         LDREG   PT_GR29(%r29),%r29
151         .endm
153         /* default interruption handler
154          * (calls traps.c:handle_interruption) */
155         .macro  def code
156         b       intr_save
157         ldi     \code, %r8
158         .align  32
159         .endm
161         /* Interrupt interruption handler
162          * (calls irq.c:do_cpu_irq_mask) */
163         .macro  extint code
164         b       intr_extint
165         mfsp    %sr7,%r16
166         .align  32
167         .endm   
169         .import os_hpmc, code
171         /* HPMC handler */
172         .macro  hpmc code
173         nop                     /* must be a NOP, will be patched later */
174         load32  PA(os_hpmc), %r3
175         bv,n    0(%r3)
176         nop
177         .word   0               /* checksum (will be patched) */
178         .word   PA(os_hpmc)     /* address of handler */
179         .word   0               /* length of handler */
180         .endm
182         /*
183          * Performance Note: Instructions will be moved up into
184          * this part of the code later on, once we are sure
185          * that the tlb miss handlers are close to final form.
186          */
188         /* Register definitions for tlb miss handler macros */
190         va  = r8        /* virtual address for which the trap occured */
191         spc = r24       /* space for which the trap occured */
193 #ifndef CONFIG_64BIT
195         /*
196          * itlb miss interruption handler (parisc 1.1 - 32 bit)
197          */
199         .macro  itlb_11 code
201         mfctl   %pcsq, spc
202         b       itlb_miss_11
203         mfctl   %pcoq, va
205         .align          32
206         .endm
207 #endif
208         
209         /*
210          * itlb miss interruption handler (parisc 2.0)
211          */
213         .macro  itlb_20 code
214         mfctl   %pcsq, spc
215 #ifdef CONFIG_64BIT
216         b       itlb_miss_20w
217 #else
218         b       itlb_miss_20
219 #endif
220         mfctl   %pcoq, va
222         .align          32
223         .endm
224         
225 #ifndef CONFIG_64BIT
226         /*
227          * naitlb miss interruption handler (parisc 1.1 - 32 bit)
228          *
229          * Note: naitlb misses will be treated
230          * as an ordinary itlb miss for now.
231          * However, note that naitlb misses
232          * have the faulting address in the
233          * IOR/ISR.
234          */
236         .macro  naitlb_11 code
238         mfctl   %isr,spc
239         b       itlb_miss_11
240         mfctl   %ior,va
242         .align          32
243         .endm
244 #endif
245         
246         /*
247          * naitlb miss interruption handler (parisc 2.0)
248          *
249          * Note: naitlb misses will be treated
250          * as an ordinary itlb miss for now.
251          * However, note that naitlb misses
252          * have the faulting address in the
253          * IOR/ISR.
254          */
256         .macro  naitlb_20 code
258         mfctl   %isr,spc
259 #ifdef CONFIG_64BIT
260         b       itlb_miss_20w
261 #else
262         b       itlb_miss_20
263 #endif
264         mfctl   %ior,va
266         .align          32
267         .endm
268         
269 #ifndef CONFIG_64BIT
270         /*
271          * dtlb miss interruption handler (parisc 1.1 - 32 bit)
272          */
274         .macro  dtlb_11 code
276         mfctl   %isr, spc
277         b       dtlb_miss_11
278         mfctl   %ior, va
280         .align          32
281         .endm
282 #endif
284         /*
285          * dtlb miss interruption handler (parisc 2.0)
286          */
288         .macro  dtlb_20 code
290         mfctl   %isr, spc
291 #ifdef CONFIG_64BIT
292         b       dtlb_miss_20w
293 #else
294         b       dtlb_miss_20
295 #endif
296         mfctl   %ior, va
298         .align          32
299         .endm
300         
301 #ifndef CONFIG_64BIT
302         /* nadtlb miss interruption handler (parisc 1.1 - 32 bit) */
304         .macro  nadtlb_11 code
306         mfctl   %isr,spc
307         b       nadtlb_miss_11
308         mfctl   %ior,va
310         .align          32
311         .endm
312 #endif
313         
314         /* nadtlb miss interruption handler (parisc 2.0) */
316         .macro  nadtlb_20 code
318         mfctl   %isr,spc
319 #ifdef CONFIG_64BIT
320         b       nadtlb_miss_20w
321 #else
322         b       nadtlb_miss_20
323 #endif
324         mfctl   %ior,va
326         .align          32
327         .endm
328         
329 #ifndef CONFIG_64BIT
330         /*
331          * dirty bit trap interruption handler (parisc 1.1 - 32 bit)
332          */
334         .macro  dbit_11 code
336         mfctl   %isr,spc
337         b       dbit_trap_11
338         mfctl   %ior,va
340         .align          32
341         .endm
342 #endif
344         /*
345          * dirty bit trap interruption handler (parisc 2.0)
346          */
348         .macro  dbit_20 code
350         mfctl   %isr,spc
351 #ifdef CONFIG_64BIT
352         b       dbit_trap_20w
353 #else
354         b       dbit_trap_20
355 #endif
356         mfctl   %ior,va
358         .align          32
359         .endm
361         /* In LP64, the space contains part of the upper 32 bits of the
362          * fault.  We have to extract this and place it in the va,
363          * zeroing the corresponding bits in the space register */
364         .macro          space_adjust    spc,va,tmp
365 #ifdef CONFIG_64BIT
366         extrd,u         \spc,63,SPACEID_SHIFT,\tmp
367         depd            %r0,63,SPACEID_SHIFT,\spc
368         depd            \tmp,31,SPACEID_SHIFT,\va
369 #endif
370         .endm
372         .import         swapper_pg_dir,code
374         /* Get the pgd.  For faults on space zero (kernel space), this
375          * is simply swapper_pg_dir.  For user space faults, the
376          * pgd is stored in %cr25 */
377         .macro          get_pgd         spc,reg
378         ldil            L%PA(swapper_pg_dir),\reg
379         ldo             R%PA(swapper_pg_dir)(\reg),\reg
380         or,COND(=)      %r0,\spc,%r0
381         mfctl           %cr25,\reg
382         .endm
384         /* 
385                 space_check(spc,tmp,fault)
387                 spc - The space we saw the fault with.
388                 tmp - The place to store the current space.
389                 fault - Function to call on failure.
391                 Only allow faults on different spaces from the
392                 currently active one if we're the kernel 
394         */
395         .macro          space_check     spc,tmp,fault
396         mfsp            %sr7,\tmp
397         or,COND(<>)     %r0,\spc,%r0    /* user may execute gateway page
398                                          * as kernel, so defeat the space
399                                          * check if it is */
400         copy            \spc,\tmp
401         or,COND(=)      %r0,\tmp,%r0    /* nullify if executing as kernel */
402         cmpb,COND(<>),n \tmp,\spc,\fault
403         .endm
405         /* Look up a PTE in a 2-Level scheme (faulting at each
406          * level if the entry isn't present 
407          *
408          * NOTE: we use ldw even for LP64, since the short pointers
409          * can address up to 1TB
410          */
411         .macro          L2_ptep pmd,pte,index,va,fault
412 #if PT_NLEVELS == 3
413         extru           \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index
414 #else
415         extru           \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
416 #endif
417         dep             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
418         copy            %r0,\pte
419         ldw,s           \index(\pmd),\pmd
420         bb,>=,n         \pmd,_PxD_PRESENT_BIT,\fault
421         dep             %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
422         copy            \pmd,%r9
423         SHLREG          %r9,PxD_VALUE_SHIFT,\pmd
424         extru           \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
425         dep             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
426         shladd          \index,BITS_PER_PTE_ENTRY,\pmd,\pmd
427         LDREG           %r0(\pmd),\pte          /* pmd is now pte */
428         bb,>=,n         \pte,_PAGE_PRESENT_BIT,\fault
429         .endm
431         /* Look up PTE in a 3-Level scheme.
432          *
433          * Here we implement a Hybrid L2/L3 scheme: we allocate the
434          * first pmd adjacent to the pgd.  This means that we can
435          * subtract a constant offset to get to it.  The pmd and pgd
436          * sizes are arranged so that a single pmd covers 4GB (giving
437          * a full LP64 process access to 8TB) so our lookups are
438          * effectively L2 for the first 4GB of the kernel (i.e. for
439          * all ILP32 processes and all the kernel for machines with
440          * under 4GB of memory) */
441         .macro          L3_ptep pgd,pte,index,va,fault
442 #if PT_NLEVELS == 3     /* we might have a 2-Level scheme, e.g. with 16kb page size */
443         extrd,u         \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
444         copy            %r0,\pte
445         extrd,u,*=      \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
446         ldw,s           \index(\pgd),\pgd
447         extrd,u,*=      \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
448         bb,>=,n         \pgd,_PxD_PRESENT_BIT,\fault
449         extrd,u,*=      \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
450         shld            \pgd,PxD_VALUE_SHIFT,\index
451         extrd,u,*=      \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
452         copy            \index,\pgd
453         extrd,u,*<>     \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
454         ldo             ASM_PGD_PMD_OFFSET(\pgd),\pgd
455 #endif
456         L2_ptep         \pgd,\pte,\index,\va,\fault
457         .endm
459         /* Set the _PAGE_ACCESSED bit of the PTE.  Be clever and
460          * don't needlessly dirty the cache line if it was already set */
461         .macro          update_ptep     ptep,pte,tmp,tmp1
462         ldi             _PAGE_ACCESSED,\tmp1
463         or              \tmp1,\pte,\tmp
464         and,COND(<>)    \tmp1,\pte,%r0
465         STREG           \tmp,0(\ptep)
466         .endm
468         /* Set the dirty bit (and accessed bit).  No need to be
469          * clever, this is only used from the dirty fault */
470         .macro          update_dirty    ptep,pte,tmp
471         ldi             _PAGE_ACCESSED|_PAGE_DIRTY,\tmp
472         or              \tmp,\pte,\pte
473         STREG           \pte,0(\ptep)
474         .endm
476         /* bitshift difference between a PFN (based on kernel's PAGE_SIZE)
477          * to a CPU TLB 4k PFN (4k => 12 bits to shift) */
478         #define PAGE_ADD_SHIFT  (PAGE_SHIFT-12)
480         /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
481         .macro          convert_for_tlb_insert20 pte
482         extrd,u         \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
483                                 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
484         depdi           _PAGE_SIZE_ENCODING_DEFAULT,63,\
485                                 (63-58)+PAGE_ADD_SHIFT,\pte
486         .endm
488         /* Convert the pte and prot to tlb insertion values.  How
489          * this happens is quite subtle, read below */
490         .macro          make_insert_tlb spc,pte,prot
491         space_to_prot   \spc \prot        /* create prot id from space */
492         /* The following is the real subtlety.  This is depositing
493          * T <-> _PAGE_REFTRAP
494          * D <-> _PAGE_DIRTY
495          * B <-> _PAGE_DMB (memory break)
496          *
497          * Then incredible subtlety: The access rights are
498          * _PAGE_GATEWAY _PAGE_EXEC _PAGE_READ
499          * See 3-14 of the parisc 2.0 manual
500          *
501          * Finally, _PAGE_READ goes in the top bit of PL1 (so we
502          * trigger an access rights trap in user space if the user
503          * tries to read an unreadable page */
504         depd            \pte,8,7,\prot
506         /* PAGE_USER indicates the page can be read with user privileges,
507          * so deposit X1|11 to PL1|PL2 (remember the upper bit of PL1
508          * contains _PAGE_READ */
509         extrd,u,*=      \pte,_PAGE_USER_BIT+32,1,%r0
510         depdi           7,11,3,\prot
511         /* If we're a gateway page, drop PL2 back to zero for promotion
512          * to kernel privilege (so we can execute the page as kernel).
513          * Any privilege promotion page always denys read and write */
514         extrd,u,*=      \pte,_PAGE_GATEWAY_BIT+32,1,%r0
515         depd            %r0,11,2,\prot  /* If Gateway, Set PL2 to 0 */
517         /* Enforce uncacheable pages.
518          * This should ONLY be use for MMIO on PA 2.0 machines.
519          * Memory/DMA is cache coherent on all PA2.0 machines we support
520          * (that means T-class is NOT supported) and the memory controllers
521          * on most of those machines only handles cache transactions.
522          */
523         extrd,u,*=      \pte,_PAGE_NO_CACHE_BIT+32,1,%r0
524         depdi           1,12,1,\prot
526         /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
527         convert_for_tlb_insert20 \pte
528         .endm
530         /* Identical macro to make_insert_tlb above, except it
531          * makes the tlb entry for the differently formatted pa11
532          * insertion instructions */
533         .macro          make_insert_tlb_11      spc,pte,prot
534         zdep            \spc,30,15,\prot
535         dep             \pte,8,7,\prot
536         extru,=         \pte,_PAGE_NO_CACHE_BIT,1,%r0
537         depi            1,12,1,\prot
538         extru,=         \pte,_PAGE_USER_BIT,1,%r0
539         depi            7,11,3,\prot   /* Set for user space (1 rsvd for read) */
540         extru,=         \pte,_PAGE_GATEWAY_BIT,1,%r0
541         depi            0,11,2,\prot    /* If Gateway, Set PL2 to 0 */
543         /* Get rid of prot bits and convert to page addr for iitlba */
545         depi            0,31,ASM_PFN_PTE_SHIFT,\pte
546         SHRREG          \pte,(ASM_PFN_PTE_SHIFT-(31-26)),\pte
547         .endm
549         /* This is for ILP32 PA2.0 only.  The TLB insertion needs
550          * to extend into I/O space if the address is 0xfXXXXXXX
551          * so we extend the f's into the top word of the pte in
552          * this case */
553         .macro          f_extend        pte,tmp
554         extrd,s         \pte,42,4,\tmp
555         addi,<>         1,\tmp,%r0
556         extrd,s         \pte,63,25,\pte
557         .endm
559         /* The alias region is an 8MB aligned 16MB to do clear and
560          * copy user pages at addresses congruent with the user
561          * virtual address.
562          *
563          * To use the alias page, you set %r26 up with the to TLB
564          * entry (identifying the physical page) and %r23 up with
565          * the from tlb entry (or nothing if only a to entry---for
566          * clear_user_page_asm) */
567         .macro          do_alias        spc,tmp,tmp1,va,pte,prot,fault
568         cmpib,COND(<>),n 0,\spc,\fault
569         ldil            L%(TMPALIAS_MAP_START),\tmp
570 #if defined(CONFIG_64BIT) && (TMPALIAS_MAP_START >= 0x80000000)
571         /* on LP64, ldi will sign extend into the upper 32 bits,
572          * which is behaviour we don't want */
573         depdi           0,31,32,\tmp
574 #endif
575         copy            \va,\tmp1
576         depi            0,31,23,\tmp1
577         cmpb,COND(<>),n \tmp,\tmp1,\fault
578         ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),\prot
579         depd,z          \prot,8,7,\prot
580         /*
581          * OK, it is in the temp alias region, check whether "from" or "to".
582          * Check "subtle" note in pacache.S re: r23/r26.
583          */
584 #ifdef CONFIG_64BIT
585         extrd,u,*=      \va,41,1,%r0
586 #else
587         extrw,u,=       \va,9,1,%r0
588 #endif
589         or,COND(tr)     %r23,%r0,\pte
590         or              %r26,%r0,\pte
591         .endm 
594         /*
595          * Align fault_vector_20 on 4K boundary so that both
596          * fault_vector_11 and fault_vector_20 are on the
597          * same page. This is only necessary as long as we
598          * write protect the kernel text, which we may stop
599          * doing once we use large page translations to cover
600          * the static part of the kernel address space.
601          */
603         .text
605         .align  PAGE_SIZE
607 ENTRY(fault_vector_20)
608         /* First vector is invalid (0) */
609         .ascii  "cows can fly"
610         .byte 0
611         .align 32
613         hpmc             1
614         def              2
615         def              3
616         extint           4
617         def              5
618         itlb_20          6
619         def              7
620         def              8
621         def              9
622         def             10
623         def             11
624         def             12
625         def             13
626         def             14
627         dtlb_20         15
628         def             16
629         nadtlb_20       17
630         def             18
631         def             19
632         dbit_20         20
633         def             21
634         def             22
635         def             23
636         def             24
637         def             25
638         def             26
639         def             27
640         def             28
641         def             29
642         def             30
643         def             31
644 END(fault_vector_20)
646 #ifndef CONFIG_64BIT
648         .align 2048
650 ENTRY(fault_vector_11)
651         /* First vector is invalid (0) */
652         .ascii  "cows can fly"
653         .byte 0
654         .align 32
656         hpmc             1
657         def              2
658         def              3
659         extint           4
660         def              5
661         itlb_11          6
662         def              7
663         def              8
664         def              9
665         def             10
666         def             11
667         def             12
668         def             13
669         def             14
670         dtlb_11         15
671         def             16
672         nadtlb_11       17
673         def             18
674         def             19
675         dbit_11         20
676         def             21
677         def             22
678         def             23
679         def             24
680         def             25
681         def             26
682         def             27
683         def             28
684         def             29
685         def             30
686         def             31
687 END(fault_vector_11)
689 #endif
691         .import         handle_interruption,code
692         .import         do_cpu_irq_mask,code
694         /*
695          * r26 = function to be called
696          * r25 = argument to pass in
697          * r24 = flags for do_fork()
698          *
699          * Kernel threads don't ever return, so they don't need
700          * a true register context. We just save away the arguments
701          * for copy_thread/ret_ to properly set up the child.
702          */
704 #define CLONE_VM 0x100  /* Must agree with <linux/sched.h> */
705 #define CLONE_UNTRACED 0x00800000
707         .import do_fork
708 ENTRY(__kernel_thread)
709         STREG   %r2, -RP_OFFSET(%r30)
711         copy    %r30, %r1
712         ldo     PT_SZ_ALGN(%r30),%r30
713 #ifdef CONFIG_64BIT
714         /* Yo, function pointers in wide mode are little structs... -PB */
715         ldd     24(%r26), %r2
716         STREG   %r2, PT_GR27(%r1)       /* Store childs %dp */
717         ldd     16(%r26), %r26
719         STREG   %r22, PT_GR22(%r1)      /* save r22 (arg5) */
720         copy    %r0, %r22               /* user_tid */
721 #endif
722         STREG   %r26, PT_GR26(%r1)  /* Store function & argument for child */
723         STREG   %r25, PT_GR25(%r1)
724         ldil    L%CLONE_UNTRACED, %r26
725         ldo     CLONE_VM(%r26), %r26   /* Force CLONE_VM since only init_mm */
726         or      %r26, %r24, %r26      /* will have kernel mappings.      */
727         ldi     1, %r25                 /* stack_start, signals kernel thread */
728         stw     %r0, -52(%r30)          /* user_tid */
729 #ifdef CONFIG_64BIT
730         ldo     -16(%r30),%r29          /* Reference param save area */
731 #endif
732         BL      do_fork, %r2
733         copy    %r1, %r24               /* pt_regs */
735         /* Parent Returns here */
737         LDREG   -PT_SZ_ALGN-RP_OFFSET(%r30), %r2
738         ldo     -PT_SZ_ALGN(%r30), %r30
739         bv      %r0(%r2)
740         nop
741 ENDPROC(__kernel_thread)
743         /*
744          * Child Returns here
745          *
746          * copy_thread moved args from temp save area set up above
747          * into task save area.
748          */
750 ENTRY(ret_from_kernel_thread)
752         /* Call schedule_tail first though */
753         BL      schedule_tail, %r2
754         nop
756         LDREG   TI_TASK-THREAD_SZ_ALGN(%r30), %r1
757         LDREG   TASK_PT_GR25(%r1), %r26
758 #ifdef CONFIG_64BIT
759         LDREG   TASK_PT_GR27(%r1), %r27
760         LDREG   TASK_PT_GR22(%r1), %r22
761 #endif
762         LDREG   TASK_PT_GR26(%r1), %r1
763         ble     0(%sr7, %r1)
764         copy    %r31, %r2
766 #ifdef CONFIG_64BIT
767         ldo     -16(%r30),%r29          /* Reference param save area */
768         loadgp                          /* Thread could have been in a module */
769 #endif
770 #ifndef CONFIG_64BIT
771         b       sys_exit
772 #else
773         load32  sys_exit, %r1
774         bv      %r0(%r1)
775 #endif
776         ldi     0, %r26
777 ENDPROC(ret_from_kernel_thread)
779         .import sys_execve, code
780 ENTRY(__execve)
781         copy    %r2, %r15
782         copy    %r30, %r16
783         ldo     PT_SZ_ALGN(%r30), %r30
784         STREG   %r26, PT_GR26(%r16)
785         STREG   %r25, PT_GR25(%r16)
786         STREG   %r24, PT_GR24(%r16)
787 #ifdef CONFIG_64BIT
788         ldo     -16(%r30),%r29          /* Reference param save area */
789 #endif
790         BL      sys_execve, %r2
791         copy    %r16, %r26
793         cmpib,=,n 0,%r28,intr_return    /* forward */
795         /* yes, this will trap and die. */
796         copy    %r15, %r2
797         copy    %r16, %r30
798         bv      %r0(%r2)
799         nop
800 ENDPROC(__execve)
803         /*
804          * struct task_struct *_switch_to(struct task_struct *prev,
805          *      struct task_struct *next)
806          *
807          * switch kernel stacks and return prev */
808 ENTRY(_switch_to)
809         STREG    %r2, -RP_OFFSET(%r30)
811         callee_save_float
812         callee_save
814         load32  _switch_to_ret, %r2
816         STREG   %r2, TASK_PT_KPC(%r26)
817         LDREG   TASK_PT_KPC(%r25), %r2
819         STREG   %r30, TASK_PT_KSP(%r26)
820         LDREG   TASK_PT_KSP(%r25), %r30
821         LDREG   TASK_THREAD_INFO(%r25), %r25
822         bv      %r0(%r2)
823         mtctl   %r25,%cr30
825 _switch_to_ret:
826         mtctl   %r0, %cr0               /* Needed for single stepping */
827         callee_rest
828         callee_rest_float
830         LDREG   -RP_OFFSET(%r30), %r2
831         bv      %r0(%r2)
832         copy    %r26, %r28
833 ENDPROC(_switch_to)
836         .align  PAGE_SIZE
838 ENTRY(syscall_exit_rfi)
839         mfctl   %cr30,%r16
840         LDREG   TI_TASK(%r16), %r16     /* thread_info -> task_struct */
841         ldo     TASK_REGS(%r16),%r16
842         /* Force iaoq to userspace, as the user has had access to our current
843          * context via sigcontext. Also Filter the PSW for the same reason.
844          */
845         LDREG   PT_IAOQ0(%r16),%r19
846         depi    3,31,2,%r19
847         STREG   %r19,PT_IAOQ0(%r16)
848         LDREG   PT_IAOQ1(%r16),%r19
849         depi    3,31,2,%r19
850         STREG   %r19,PT_IAOQ1(%r16)
851         LDREG   PT_PSW(%r16),%r19
852         load32  USER_PSW_MASK,%r1
853 #ifdef CONFIG_64BIT
854         load32  USER_PSW_HI_MASK,%r20
855         depd    %r20,31,32,%r1
856 #endif
857         and     %r19,%r1,%r19 /* Mask out bits that user shouldn't play with */
858         load32  USER_PSW,%r1
859         or      %r19,%r1,%r19 /* Make sure default USER_PSW bits are set */
860         STREG   %r19,PT_PSW(%r16)
862         /*
863          * If we aren't being traced, we never saved space registers
864          * (we don't store them in the sigcontext), so set them
865          * to "proper" values now (otherwise we'll wind up restoring
866          * whatever was last stored in the task structure, which might
867          * be inconsistent if an interrupt occured while on the gateway
868          * page). Note that we may be "trashing" values the user put in
869          * them, but we don't support the user changing them.
870          */
872         STREG   %r0,PT_SR2(%r16)
873         mfsp    %sr3,%r19
874         STREG   %r19,PT_SR0(%r16)
875         STREG   %r19,PT_SR1(%r16)
876         STREG   %r19,PT_SR3(%r16)
877         STREG   %r19,PT_SR4(%r16)
878         STREG   %r19,PT_SR5(%r16)
879         STREG   %r19,PT_SR6(%r16)
880         STREG   %r19,PT_SR7(%r16)
882 intr_return:
883         /* NOTE: Need to enable interrupts incase we schedule. */
884         ssm     PSW_SM_I, %r0
886 intr_check_resched:
888         /* check for reschedule */
889         mfctl   %cr30,%r1
890         LDREG   TI_FLAGS(%r1),%r19      /* sched.h: TIF_NEED_RESCHED */
891         bb,<,n  %r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */
893         .import do_notify_resume,code
894 intr_check_sig:
895         /* As above */
896         mfctl   %cr30,%r1
897         LDREG   TI_FLAGS(%r1),%r19
898         ldi     (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NOTIFY_RESUME), %r20
899         and,COND(<>)    %r19, %r20, %r0
900         b,n     intr_restore    /* skip past if we've nothing to do */
902         /* This check is critical to having LWS
903          * working. The IASQ is zero on the gateway
904          * page and we cannot deliver any signals until
905          * we get off the gateway page.
906          *
907          * Only do signals if we are returning to user space
908          */
909         LDREG   PT_IASQ0(%r16), %r20
910         cmpib,COND(=),n 0,%r20,intr_restore /* backward */
911         LDREG   PT_IASQ1(%r16), %r20
912         cmpib,COND(=),n 0,%r20,intr_restore /* backward */
914         copy    %r0, %r25                       /* long in_syscall = 0 */
915 #ifdef CONFIG_64BIT
916         ldo     -16(%r30),%r29                  /* Reference param save area */
917 #endif
919         BL      do_notify_resume,%r2
920         copy    %r16, %r26                      /* struct pt_regs *regs */
922         b,n     intr_check_sig
924 intr_restore:
925         copy            %r16,%r29
926         ldo             PT_FR31(%r29),%r1
927         rest_fp         %r1
928         rest_general    %r29
930         /* inverse of virt_map */
931         pcxt_ssm_bug
932         rsm             PSW_SM_QUIET,%r0        /* prepare for rfi */
933         tophys_r1       %r29
935         /* Restore space id's and special cr's from PT_REGS
936          * structure pointed to by r29
937          */
938         rest_specials   %r29
940         /* IMPORTANT: rest_stack restores r29 last (we are using it)!
941          * It also restores r1 and r30.
942          */
943         rest_stack
945         rfi
946         nop
948 #ifndef CONFIG_PREEMPT
949 # define intr_do_preempt        intr_restore
950 #endif /* !CONFIG_PREEMPT */
952         .import schedule,code
953 intr_do_resched:
954         /* Only call schedule on return to userspace. If we're returning
955          * to kernel space, we may schedule if CONFIG_PREEMPT, otherwise
956          * we jump back to intr_restore.
957          */
958         LDREG   PT_IASQ0(%r16), %r20
959         cmpib,COND(=)   0, %r20, intr_do_preempt
960         nop
961         LDREG   PT_IASQ1(%r16), %r20
962         cmpib,COND(=)   0, %r20, intr_do_preempt
963         nop
965 #ifdef CONFIG_64BIT
966         ldo     -16(%r30),%r29          /* Reference param save area */
967 #endif
969         ldil    L%intr_check_sig, %r2
970 #ifndef CONFIG_64BIT
971         b       schedule
972 #else
973         load32  schedule, %r20
974         bv      %r0(%r20)
975 #endif
976         ldo     R%intr_check_sig(%r2), %r2
978         /* preempt the current task on returning to kernel
979          * mode from an interrupt, iff need_resched is set,
980          * and preempt_count is 0. otherwise, we continue on
981          * our merry way back to the current running task.
982          */
983 #ifdef CONFIG_PREEMPT
984         .import preempt_schedule_irq,code
985 intr_do_preempt:
986         rsm     PSW_SM_I, %r0           /* disable interrupts */
988         /* current_thread_info()->preempt_count */
989         mfctl   %cr30, %r1
990         LDREG   TI_PRE_COUNT(%r1), %r19
991         cmpib,COND(<>)  0, %r19, intr_restore   /* if preempt_count > 0 */
992         nop                             /* prev insn branched backwards */
994         /* check if we interrupted a critical path */
995         LDREG   PT_PSW(%r16), %r20
996         bb,<,n  %r20, 31 - PSW_SM_I, intr_restore
997         nop
999         BL      preempt_schedule_irq, %r2
1000         nop
1002         b,n     intr_restore            /* ssm PSW_SM_I done by intr_restore */
1003 #endif /* CONFIG_PREEMPT */
1005         /*
1006          * External interrupts.
1007          */
1009 intr_extint:
1010         cmpib,COND(=),n 0,%r16,1f
1012         get_stack_use_cr30
1013         b,n 2f
1016         get_stack_use_r30
1018         save_specials   %r29
1019         virt_map
1020         save_general    %r29
1022         ldo     PT_FR0(%r29), %r24
1023         save_fp %r24
1024         
1025         loadgp
1027         copy    %r29, %r26      /* arg0 is pt_regs */
1028         copy    %r29, %r16      /* save pt_regs */
1030         ldil    L%intr_return, %r2
1032 #ifdef CONFIG_64BIT
1033         ldo     -16(%r30),%r29  /* Reference param save area */
1034 #endif
1036         b       do_cpu_irq_mask
1037         ldo     R%intr_return(%r2), %r2 /* return to intr_return, not here */
1038 ENDPROC(syscall_exit_rfi)
1041         /* Generic interruptions (illegal insn, unaligned, page fault, etc) */
1043 ENTRY(intr_save)                /* for os_hpmc */
1044         mfsp    %sr7,%r16
1045         cmpib,COND(=),n 0,%r16,1f
1046         get_stack_use_cr30
1047         b       2f
1048         copy    %r8,%r26
1051         get_stack_use_r30
1052         copy    %r8,%r26
1055         save_specials   %r29
1057         /* If this trap is a itlb miss, skip saving/adjusting isr/ior */
1060         cmpib,COND(=),n        6,%r26,skip_save_ior
1063         mfctl           %cr20, %r16 /* isr */
1064         nop             /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */
1065         mfctl           %cr21, %r17 /* ior */
1068 #ifdef CONFIG_64BIT
1069         /*
1070          * If the interrupted code was running with W bit off (32 bit),
1071          * clear the b bits (bits 0 & 1) in the ior.
1072          * save_specials left ipsw value in r8 for us to test.
1073          */
1074         extrd,u,*<>     %r8,PSW_W_BIT,1,%r0
1075         depdi           0,1,2,%r17
1078         /* adjust isr/ior. */
1079         extrd,u         %r16,63,SPACEID_SHIFT,%r1       /* get high bits from isr for ior */
1080         depd            %r1,31,SPACEID_SHIFT,%r17       /* deposit them into ior */
1081         depdi           0,63,SPACEID_SHIFT,%r16         /* clear them from isr */
1082 #endif
1083         STREG           %r16, PT_ISR(%r29)
1084         STREG           %r17, PT_IOR(%r29)
1087 skip_save_ior:
1088         virt_map
1089         save_general    %r29
1091         ldo             PT_FR0(%r29), %r25
1092         save_fp         %r25
1093         
1094         loadgp
1096         copy            %r29, %r25      /* arg1 is pt_regs */
1097 #ifdef CONFIG_64BIT
1098         ldo             -16(%r30),%r29  /* Reference param save area */
1099 #endif
1101         ldil            L%intr_check_sig, %r2
1102         copy            %r25, %r16      /* save pt_regs */
1104         b               handle_interruption
1105         ldo             R%intr_check_sig(%r2), %r2
1106 ENDPROC(intr_save)
1109         /*
1110          * Note for all tlb miss handlers:
1111          *
1112          * cr24 contains a pointer to the kernel address space
1113          * page directory.
1114          *
1115          * cr25 contains a pointer to the current user address
1116          * space page directory.
1117          *
1118          * sr3 will contain the space id of the user address space
1119          * of the current running thread while that thread is
1120          * running in the kernel.
1121          */
1123         /*
1124          * register number allocations.  Note that these are all
1125          * in the shadowed registers
1126          */
1128         t0 = r1         /* temporary register 0 */
1129         va = r8         /* virtual address for which the trap occured */
1130         t1 = r9         /* temporary register 1 */
1131         pte  = r16      /* pte/phys page # */
1132         prot = r17      /* prot bits */
1133         spc  = r24      /* space for which the trap occured */
1134         ptp = r25       /* page directory/page table pointer */
1136 #ifdef CONFIG_64BIT
1138 dtlb_miss_20w:
1139         space_adjust    spc,va,t0
1140         get_pgd         spc,ptp
1141         space_check     spc,t0,dtlb_fault
1143         L3_ptep         ptp,pte,t0,va,dtlb_check_alias_20w
1145         update_ptep     ptp,pte,t0,t1
1147         make_insert_tlb spc,pte,prot
1148         
1149         idtlbt          pte,prot
1151         rfir
1152         nop
1154 dtlb_check_alias_20w:
1155         do_alias        spc,t0,t1,va,pte,prot,dtlb_fault
1157         idtlbt          pte,prot
1159         rfir
1160         nop
1162 nadtlb_miss_20w:
1163         space_adjust    spc,va,t0
1164         get_pgd         spc,ptp
1165         space_check     spc,t0,nadtlb_fault
1167         L3_ptep         ptp,pte,t0,va,nadtlb_check_flush_20w
1169         update_ptep     ptp,pte,t0,t1
1171         make_insert_tlb spc,pte,prot
1173         idtlbt          pte,prot
1175         rfir
1176         nop
1178 nadtlb_check_flush_20w:
1179         bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
1181         /* Insert a "flush only" translation */
1183         depdi,z         7,7,3,prot
1184         depdi           1,10,1,prot
1186         /* Drop prot bits from pte and convert to page addr for idtlbt */
1187         convert_for_tlb_insert20 pte
1189         idtlbt          pte,prot
1191         rfir
1192         nop
1194 #else
1196 dtlb_miss_11:
1197         get_pgd         spc,ptp
1199         space_check     spc,t0,dtlb_fault
1201         L2_ptep         ptp,pte,t0,va,dtlb_check_alias_11
1203         update_ptep     ptp,pte,t0,t1
1205         make_insert_tlb_11      spc,pte,prot
1207         mfsp            %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
1208         mtsp            spc,%sr1
1210         idtlba          pte,(%sr1,va)
1211         idtlbp          prot,(%sr1,va)
1213         mtsp            t0, %sr1        /* Restore sr1 */
1215         rfir
1216         nop
1218 dtlb_check_alias_11:
1220         /* Check to see if fault is in the temporary alias region */
1222         cmpib,<>,n      0,spc,dtlb_fault /* forward */
1223         ldil            L%(TMPALIAS_MAP_START),t0
1224         copy            va,t1
1225         depwi           0,31,23,t1
1226         cmpb,<>,n       t0,t1,dtlb_fault /* forward */
1227         ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot
1228         depw,z          prot,8,7,prot
1230         /*
1231          * OK, it is in the temp alias region, check whether "from" or "to".
1232          * Check "subtle" note in pacache.S re: r23/r26.
1233          */
1235         extrw,u,=       va,9,1,r0
1236         or,tr           %r23,%r0,pte    /* If "from" use "from" page */
1237         or              %r26,%r0,pte    /* else "to", use "to" page  */
1239         idtlba          pte,(va)
1240         idtlbp          prot,(va)
1242         rfir
1243         nop
1245 nadtlb_miss_11:
1246         get_pgd         spc,ptp
1248         space_check     spc,t0,nadtlb_fault
1250         L2_ptep         ptp,pte,t0,va,nadtlb_check_flush_11
1252         update_ptep     ptp,pte,t0,t1
1254         make_insert_tlb_11      spc,pte,prot
1257         mfsp            %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
1258         mtsp            spc,%sr1
1260         idtlba          pte,(%sr1,va)
1261         idtlbp          prot,(%sr1,va)
1263         mtsp            t0, %sr1        /* Restore sr1 */
1265         rfir
1266         nop
1268 nadtlb_check_flush_11:
1269         bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
1271         /* Insert a "flush only" translation */
1273         zdepi           7,7,3,prot
1274         depi            1,10,1,prot
1276         /* Get rid of prot bits and convert to page addr for idtlba */
1278         depi            0,31,ASM_PFN_PTE_SHIFT,pte
1279         SHRREG          pte,(ASM_PFN_PTE_SHIFT-(31-26)),pte
1281         mfsp            %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
1282         mtsp            spc,%sr1
1284         idtlba          pte,(%sr1,va)
1285         idtlbp          prot,(%sr1,va)
1287         mtsp            t0, %sr1        /* Restore sr1 */
1289         rfir
1290         nop
1292 dtlb_miss_20:
1293         space_adjust    spc,va,t0
1294         get_pgd         spc,ptp
1295         space_check     spc,t0,dtlb_fault
1297         L2_ptep         ptp,pte,t0,va,dtlb_check_alias_20
1299         update_ptep     ptp,pte,t0,t1
1301         make_insert_tlb spc,pte,prot
1303         f_extend        pte,t0
1305         idtlbt          pte,prot
1307         rfir
1308         nop
1310 dtlb_check_alias_20:
1311         do_alias        spc,t0,t1,va,pte,prot,dtlb_fault
1312         
1313         idtlbt          pte,prot
1315         rfir
1316         nop
1318 nadtlb_miss_20:
1319         get_pgd         spc,ptp
1321         space_check     spc,t0,nadtlb_fault
1323         L2_ptep         ptp,pte,t0,va,nadtlb_check_flush_20
1325         update_ptep     ptp,pte,t0,t1
1327         make_insert_tlb spc,pte,prot
1329         f_extend        pte,t0
1330         
1331         idtlbt          pte,prot
1333         rfir
1334         nop
1336 nadtlb_check_flush_20:
1337         bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
1339         /* Insert a "flush only" translation */
1341         depdi,z         7,7,3,prot
1342         depdi           1,10,1,prot
1344         /* Drop prot bits from pte and convert to page addr for idtlbt */
1345         convert_for_tlb_insert20 pte
1347         idtlbt          pte,prot
1349         rfir
1350         nop
1351 #endif
1353 nadtlb_emulate:
1355         /*
1356          * Non access misses can be caused by fdc,fic,pdc,lpa,probe and
1357          * probei instructions. We don't want to fault for these
1358          * instructions (not only does it not make sense, it can cause
1359          * deadlocks, since some flushes are done with the mmap
1360          * semaphore held). If the translation doesn't exist, we can't
1361          * insert a translation, so have to emulate the side effects
1362          * of the instruction. Since we don't insert a translation
1363          * we can get a lot of faults during a flush loop, so it makes
1364          * sense to try to do it here with minimum overhead. We only
1365          * emulate fdc,fic,pdc,probew,prober instructions whose base 
1366          * and index registers are not shadowed. We defer everything 
1367          * else to the "slow" path.
1368          */
1370         mfctl           %cr19,%r9 /* Get iir */
1372         /* PA 2.0 Arch Ref. Book pg 382 has a good description of the insn bits.
1373            Checks for fdc,fdce,pdc,"fic,4f",prober,probeir,probew, probeiw */
1375         /* Checks for fdc,fdce,pdc,"fic,4f" only */
1376         ldi             0x280,%r16
1377         and             %r9,%r16,%r17
1378         cmpb,<>,n       %r16,%r17,nadtlb_probe_check
1379         bb,>=,n         %r9,26,nadtlb_nullify  /* m bit not set, just nullify */
1380         BL              get_register,%r25
1381         extrw,u         %r9,15,5,%r8           /* Get index register # */
1382         cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
1383         copy            %r1,%r24
1384         BL              get_register,%r25
1385         extrw,u         %r9,10,5,%r8           /* Get base register # */
1386         cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
1387         BL              set_register,%r25
1388         add,l           %r1,%r24,%r1           /* doesn't affect c/b bits */
1390 nadtlb_nullify:
1391         mfctl           %ipsw,%r8
1392         ldil            L%PSW_N,%r9
1393         or              %r8,%r9,%r8            /* Set PSW_N */
1394         mtctl           %r8,%ipsw
1396         rfir
1397         nop
1399         /* 
1400                 When there is no translation for the probe address then we
1401                 must nullify the insn and return zero in the target regsiter.
1402                 This will indicate to the calling code that it does not have 
1403                 write/read privileges to this address.
1405                 This should technically work for prober and probew in PA 1.1,
1406                 and also probe,r and probe,w in PA 2.0
1408                 WARNING: USE ONLY NON-SHADOW REGISTERS WITH PROBE INSN!
1409                 THE SLOW-PATH EMULATION HAS NOT BEEN WRITTEN YET.
1411         */
1412 nadtlb_probe_check:
1413         ldi             0x80,%r16
1414         and             %r9,%r16,%r17
1415         cmpb,<>,n       %r16,%r17,nadtlb_fault /* Must be probe,[rw]*/
1416         BL              get_register,%r25      /* Find the target register */
1417         extrw,u         %r9,31,5,%r8           /* Get target register */
1418         cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
1419         BL              set_register,%r25
1420         copy            %r0,%r1                /* Write zero to target register */
1421         b nadtlb_nullify                       /* Nullify return insn */
1422         nop
1425 #ifdef CONFIG_64BIT
1426 itlb_miss_20w:
1428         /*
1429          * I miss is a little different, since we allow users to fault
1430          * on the gateway page which is in the kernel address space.
1431          */
1433         space_adjust    spc,va,t0
1434         get_pgd         spc,ptp
1435         space_check     spc,t0,itlb_fault
1437         L3_ptep         ptp,pte,t0,va,itlb_fault
1439         update_ptep     ptp,pte,t0,t1
1441         make_insert_tlb spc,pte,prot
1442         
1443         iitlbt          pte,prot
1445         rfir
1446         nop
1448 #else
1450 itlb_miss_11:
1451         get_pgd         spc,ptp
1453         space_check     spc,t0,itlb_fault
1455         L2_ptep         ptp,pte,t0,va,itlb_fault
1457         update_ptep     ptp,pte,t0,t1
1459         make_insert_tlb_11      spc,pte,prot
1461         mfsp            %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
1462         mtsp            spc,%sr1
1464         iitlba          pte,(%sr1,va)
1465         iitlbp          prot,(%sr1,va)
1467         mtsp            t0, %sr1        /* Restore sr1 */
1469         rfir
1470         nop
1472 itlb_miss_20:
1473         get_pgd         spc,ptp
1475         space_check     spc,t0,itlb_fault
1477         L2_ptep         ptp,pte,t0,va,itlb_fault
1479         update_ptep     ptp,pte,t0,t1
1481         make_insert_tlb spc,pte,prot
1483         f_extend        pte,t0  
1485         iitlbt          pte,prot
1487         rfir
1488         nop
1490 #endif
1492 #ifdef CONFIG_64BIT
1494 dbit_trap_20w:
1495         space_adjust    spc,va,t0
1496         get_pgd         spc,ptp
1497         space_check     spc,t0,dbit_fault
1499         L3_ptep         ptp,pte,t0,va,dbit_fault
1501 #ifdef CONFIG_SMP
1502         cmpib,COND(=),n        0,spc,dbit_nolock_20w
1503         load32          PA(pa_dbit_lock),t0
1505 dbit_spin_20w:
1506         LDCW            0(t0),t1
1507         cmpib,COND(=)         0,t1,dbit_spin_20w
1508         nop
1510 dbit_nolock_20w:
1511 #endif
1512         update_dirty    ptp,pte,t1
1514         make_insert_tlb spc,pte,prot
1515                 
1516         idtlbt          pte,prot
1517 #ifdef CONFIG_SMP
1518         cmpib,COND(=),n        0,spc,dbit_nounlock_20w
1519         ldi             1,t1
1520         stw             t1,0(t0)
1522 dbit_nounlock_20w:
1523 #endif
1525         rfir
1526         nop
1527 #else
1529 dbit_trap_11:
1531         get_pgd         spc,ptp
1533         space_check     spc,t0,dbit_fault
1535         L2_ptep         ptp,pte,t0,va,dbit_fault
1537 #ifdef CONFIG_SMP
1538         cmpib,COND(=),n        0,spc,dbit_nolock_11
1539         load32          PA(pa_dbit_lock),t0
1541 dbit_spin_11:
1542         LDCW            0(t0),t1
1543         cmpib,=         0,t1,dbit_spin_11
1544         nop
1546 dbit_nolock_11:
1547 #endif
1548         update_dirty    ptp,pte,t1
1550         make_insert_tlb_11      spc,pte,prot
1552         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1553         mtsp            spc,%sr1
1555         idtlba          pte,(%sr1,va)
1556         idtlbp          prot,(%sr1,va)
1558         mtsp            t1, %sr1     /* Restore sr1 */
1559 #ifdef CONFIG_SMP
1560         cmpib,COND(=),n        0,spc,dbit_nounlock_11
1561         ldi             1,t1
1562         stw             t1,0(t0)
1564 dbit_nounlock_11:
1565 #endif
1567         rfir
1568         nop
1570 dbit_trap_20:
1571         get_pgd         spc,ptp
1573         space_check     spc,t0,dbit_fault
1575         L2_ptep         ptp,pte,t0,va,dbit_fault
1577 #ifdef CONFIG_SMP
1578         cmpib,COND(=),n        0,spc,dbit_nolock_20
1579         load32          PA(pa_dbit_lock),t0
1581 dbit_spin_20:
1582         LDCW            0(t0),t1
1583         cmpib,=         0,t1,dbit_spin_20
1584         nop
1586 dbit_nolock_20:
1587 #endif
1588         update_dirty    ptp,pte,t1
1590         make_insert_tlb spc,pte,prot
1592         f_extend        pte,t1
1593         
1594         idtlbt          pte,prot
1596 #ifdef CONFIG_SMP
1597         cmpib,COND(=),n        0,spc,dbit_nounlock_20
1598         ldi             1,t1
1599         stw             t1,0(t0)
1601 dbit_nounlock_20:
1602 #endif
1604         rfir
1605         nop
1606 #endif
1608         .import handle_interruption,code
1610 kernel_bad_space:
1611         b               intr_save
1612         ldi             31,%r8  /* Use an unused code */
1614 dbit_fault:
1615         b               intr_save
1616         ldi             20,%r8
1618 itlb_fault:
1619         b               intr_save
1620         ldi             6,%r8
1622 nadtlb_fault:
1623         b               intr_save
1624         ldi             17,%r8
1626 dtlb_fault:
1627         b               intr_save
1628         ldi             15,%r8
1630         /* Register saving semantics for system calls:
1632            %r1             clobbered by system call macro in userspace
1633            %r2             saved in PT_REGS by gateway page
1634            %r3  - %r18     preserved by C code (saved by signal code)
1635            %r19 - %r20     saved in PT_REGS by gateway page
1636            %r21 - %r22     non-standard syscall args
1637                            stored in kernel stack by gateway page
1638            %r23 - %r26     arg3-arg0, saved in PT_REGS by gateway page
1639            %r27 - %r30     saved in PT_REGS by gateway page
1640            %r31            syscall return pointer
1641          */
1644         .macro  reg_save regs
1645         STREG   %r3, PT_GR3(\regs)
1646         STREG   %r4, PT_GR4(\regs)
1647         STREG   %r5, PT_GR5(\regs)
1648         STREG   %r6, PT_GR6(\regs)
1649         STREG   %r7, PT_GR7(\regs)
1650         STREG   %r8, PT_GR8(\regs)
1651         STREG   %r9, PT_GR9(\regs)
1652         STREG   %r10,PT_GR10(\regs)
1653         STREG   %r11,PT_GR11(\regs)
1654         STREG   %r12,PT_GR12(\regs)
1655         STREG   %r13,PT_GR13(\regs)
1656         STREG   %r14,PT_GR14(\regs)
1657         STREG   %r15,PT_GR15(\regs)
1658         STREG   %r16,PT_GR16(\regs)
1659         STREG   %r17,PT_GR17(\regs)
1660         STREG   %r18,PT_GR18(\regs)
1661         .endm
1663         .macro  reg_restore regs
1664         LDREG   PT_GR3(\regs), %r3
1665         LDREG   PT_GR4(\regs), %r4
1666         LDREG   PT_GR5(\regs), %r5
1667         LDREG   PT_GR6(\regs), %r6
1668         LDREG   PT_GR7(\regs), %r7
1669         LDREG   PT_GR8(\regs), %r8
1670         LDREG   PT_GR9(\regs), %r9
1671         LDREG   PT_GR10(\regs),%r10
1672         LDREG   PT_GR11(\regs),%r11
1673         LDREG   PT_GR12(\regs),%r12
1674         LDREG   PT_GR13(\regs),%r13
1675         LDREG   PT_GR14(\regs),%r14
1676         LDREG   PT_GR15(\regs),%r15
1677         LDREG   PT_GR16(\regs),%r16
1678         LDREG   PT_GR17(\regs),%r17
1679         LDREG   PT_GR18(\regs),%r18
1680         .endm
1682 ENTRY(sys_fork_wrapper)
1683         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
1684         ldo     TASK_REGS(%r1),%r1
1685         reg_save %r1
1686         mfctl   %cr27, %r3
1687         STREG   %r3, PT_CR27(%r1)
1689         STREG   %r2,-RP_OFFSET(%r30)
1690         ldo     FRAME_SIZE(%r30),%r30
1691 #ifdef CONFIG_64BIT
1692         ldo     -16(%r30),%r29          /* Reference param save area */
1693 #endif
1695         /* These are call-clobbered registers and therefore
1696            also syscall-clobbered (we hope). */
1697         STREG   %r2,PT_GR19(%r1)        /* save for child */
1698         STREG   %r30,PT_GR21(%r1)
1700         LDREG   PT_GR30(%r1),%r25
1701         copy    %r1,%r24
1702         BL      sys_clone,%r2
1703         ldi     SIGCHLD,%r26
1705         LDREG   -RP_OFFSET-FRAME_SIZE(%r30),%r2
1706 wrapper_exit:
1707         ldo     -FRAME_SIZE(%r30),%r30          /* get the stackframe */
1708         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1709         ldo     TASK_REGS(%r1),%r1       /* get pt regs */
1711         LDREG   PT_CR27(%r1), %r3
1712         mtctl   %r3, %cr27
1713         reg_restore %r1
1715         /* strace expects syscall # to be preserved in r20 */
1716         ldi     __NR_fork,%r20
1717         bv %r0(%r2)
1718         STREG   %r20,PT_GR20(%r1)
1719 ENDPROC(sys_fork_wrapper)
1721         /* Set the return value for the child */
1722 ENTRY(child_return)
1723         BL      schedule_tail, %r2
1724         nop
1726         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%r30), %r1
1727         LDREG   TASK_PT_GR19(%r1),%r2
1728         b       wrapper_exit
1729         copy    %r0,%r28
1730 ENDPROC(child_return)
1733 ENTRY(sys_clone_wrapper)
1734         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1735         ldo     TASK_REGS(%r1),%r1      /* get pt regs */
1736         reg_save %r1
1737         mfctl   %cr27, %r3
1738         STREG   %r3, PT_CR27(%r1)
1740         STREG   %r2,-RP_OFFSET(%r30)
1741         ldo     FRAME_SIZE(%r30),%r30
1742 #ifdef CONFIG_64BIT
1743         ldo     -16(%r30),%r29          /* Reference param save area */
1744 #endif
1746         /* WARNING - Clobbers r19 and r21, userspace must save these! */
1747         STREG   %r2,PT_GR19(%r1)        /* save for child */
1748         STREG   %r30,PT_GR21(%r1)
1749         BL      sys_clone,%r2
1750         copy    %r1,%r24
1752         b       wrapper_exit
1753         LDREG   -RP_OFFSET-FRAME_SIZE(%r30),%r2
1754 ENDPROC(sys_clone_wrapper)
1757 ENTRY(sys_vfork_wrapper)
1758         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1759         ldo     TASK_REGS(%r1),%r1      /* get pt regs */
1760         reg_save %r1
1761         mfctl   %cr27, %r3
1762         STREG   %r3, PT_CR27(%r1)
1764         STREG   %r2,-RP_OFFSET(%r30)
1765         ldo     FRAME_SIZE(%r30),%r30
1766 #ifdef CONFIG_64BIT
1767         ldo     -16(%r30),%r29          /* Reference param save area */
1768 #endif
1770         STREG   %r2,PT_GR19(%r1)        /* save for child */
1771         STREG   %r30,PT_GR21(%r1)
1773         BL      sys_vfork,%r2
1774         copy    %r1,%r26
1776         b       wrapper_exit
1777         LDREG   -RP_OFFSET-FRAME_SIZE(%r30),%r2
1778 ENDPROC(sys_vfork_wrapper)
1780         
1781         .macro  execve_wrapper execve
1782         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1783         ldo     TASK_REGS(%r1),%r1      /* get pt regs */
1785         /*
1786          * Do we need to save/restore r3-r18 here?
1787          * I don't think so. why would new thread need old
1788          * threads registers?
1789          */
1791         /* %arg0 - %arg3 are already saved for us. */
1793         STREG %r2,-RP_OFFSET(%r30)
1794         ldo FRAME_SIZE(%r30),%r30
1795 #ifdef CONFIG_64BIT
1796         ldo     -16(%r30),%r29          /* Reference param save area */
1797 #endif
1798         BL \execve,%r2
1799         copy %r1,%arg0
1801         ldo -FRAME_SIZE(%r30),%r30
1802         LDREG -RP_OFFSET(%r30),%r2
1804         /* If exec succeeded we need to load the args */
1806         ldo -1024(%r0),%r1
1807         cmpb,>>= %r28,%r1,error_\execve
1808         copy %r2,%r19
1810 error_\execve:
1811         bv %r0(%r19)
1812         nop
1813         .endm
1815         .import sys_execve
1816 ENTRY(sys_execve_wrapper)
1817         execve_wrapper sys_execve
1818 ENDPROC(sys_execve_wrapper)
1820 #ifdef CONFIG_64BIT
1821         .import sys32_execve
1822 ENTRY(sys32_execve_wrapper)
1823         execve_wrapper sys32_execve
1824 ENDPROC(sys32_execve_wrapper)
1825 #endif
1827 ENTRY(sys_rt_sigreturn_wrapper)
1828         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
1829         ldo     TASK_REGS(%r26),%r26    /* get pt regs */
1830         /* Don't save regs, we are going to restore them from sigcontext. */
1831         STREG   %r2, -RP_OFFSET(%r30)
1832 #ifdef CONFIG_64BIT
1833         ldo     FRAME_SIZE(%r30), %r30
1834         BL      sys_rt_sigreturn,%r2
1835         ldo     -16(%r30),%r29          /* Reference param save area */
1836 #else
1837         BL      sys_rt_sigreturn,%r2
1838         ldo     FRAME_SIZE(%r30), %r30
1839 #endif
1841         ldo     -FRAME_SIZE(%r30), %r30
1842         LDREG   -RP_OFFSET(%r30), %r2
1844         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1845         ldo     TASK_REGS(%r1),%r1      /* get pt regs */
1846         reg_restore %r1
1848         /* If the signal was received while the process was blocked on a
1849          * syscall, then r2 will take us to syscall_exit; otherwise r2 will
1850          * take us to syscall_exit_rfi and on to intr_return.
1851          */
1852         bv      %r0(%r2)
1853         LDREG   PT_GR28(%r1),%r28  /* reload original r28 for syscall_exit */
1854 ENDPROC(sys_rt_sigreturn_wrapper)
1856 ENTRY(sys_sigaltstack_wrapper)
1857         /* Get the user stack pointer */
1858         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1859         ldo     TASK_REGS(%r1),%r24     /* get pt regs */
1860         LDREG   TASK_PT_GR30(%r24),%r24
1861         STREG   %r2, -RP_OFFSET(%r30)
1862 #ifdef CONFIG_64BIT
1863         ldo     FRAME_SIZE(%r30), %r30
1864         BL      do_sigaltstack,%r2
1865         ldo     -16(%r30),%r29          /* Reference param save area */
1866 #else
1867         BL      do_sigaltstack,%r2
1868         ldo     FRAME_SIZE(%r30), %r30
1869 #endif
1871         ldo     -FRAME_SIZE(%r30), %r30
1872         LDREG   -RP_OFFSET(%r30), %r2
1873         bv      %r0(%r2)
1874         nop
1875 ENDPROC(sys_sigaltstack_wrapper)
1877 #ifdef CONFIG_64BIT
1878 ENTRY(sys32_sigaltstack_wrapper)
1879         /* Get the user stack pointer */
1880         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r24
1881         LDREG   TASK_PT_GR30(%r24),%r24
1882         STREG   %r2, -RP_OFFSET(%r30)
1883         ldo     FRAME_SIZE(%r30), %r30
1884         BL      do_sigaltstack32,%r2
1885         ldo     -16(%r30),%r29          /* Reference param save area */
1887         ldo     -FRAME_SIZE(%r30), %r30
1888         LDREG   -RP_OFFSET(%r30), %r2
1889         bv      %r0(%r2)
1890         nop
1891 ENDPROC(sys32_sigaltstack_wrapper)
1892 #endif
1894 ENTRY(syscall_exit)
1895         /* NOTE: HP-UX syscalls also come through here
1896          * after hpux_syscall_exit fixes up return
1897          * values. */
1899         /* NOTE: Not all syscalls exit this way.  rt_sigreturn will exit
1900          * via syscall_exit_rfi if the signal was received while the process
1901          * was running.
1902          */
1904         /* save return value now */
1906         mfctl     %cr30, %r1
1907         LDREG     TI_TASK(%r1),%r1
1908         STREG     %r28,TASK_PT_GR28(%r1)
1910 #ifdef CONFIG_HPUX
1911 /* <linux/personality.h> cannot be easily included */
1912 #define PER_HPUX 0x10
1913         ldw     TASK_PERSONALITY(%r1),%r19
1915         /* We can't use "CMPIB<> PER_HPUX" since "im5" field is sign extended */
1916         ldo       -PER_HPUX(%r19), %r19
1917         cmpib,COND(<>),n 0,%r19,1f
1919         /* Save other hpux returns if personality is PER_HPUX */
1920         STREG     %r22,TASK_PT_GR22(%r1)
1921         STREG     %r29,TASK_PT_GR29(%r1)
1924 #endif /* CONFIG_HPUX */
1926         /* Seems to me that dp could be wrong here, if the syscall involved
1927          * calling a module, and nothing got round to restoring dp on return.
1928          */
1929         loadgp
1931 syscall_check_resched:
1933         /* check for reschedule */
1935         LDREG   TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19   /* long */
1936         bb,<,n  %r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */
1938         .import do_signal,code
1939 syscall_check_sig:
1940         LDREG   TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19
1941         ldi     (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %r26
1942         and,COND(<>)    %r19, %r26, %r0
1943         b,n     syscall_restore /* skip past if we've nothing to do */
1945 syscall_do_signal:
1946         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1947         ldo     TASK_REGS(%r1), %r26            /* struct pt_regs *regs */
1948         reg_save %r26
1950 #ifdef CONFIG_64BIT
1951         ldo     -16(%r30),%r29                  /* Reference param save area */
1952 #endif
1954         BL      do_notify_resume,%r2
1955         ldi     1, %r25                         /* long in_syscall = 1 */
1957         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1958         ldo     TASK_REGS(%r1), %r20            /* reload pt_regs */
1959         reg_restore %r20
1961         b,n     syscall_check_sig
1963 syscall_restore:
1964         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1966         /* Are we being ptraced? */
1967         ldw     TASK_FLAGS(%r1),%r19
1968         ldi     (_TIF_SINGLESTEP|_TIF_BLOCKSTEP),%r2
1969         and,COND(=)     %r19,%r2,%r0
1970         b,n     syscall_restore_rfi
1972         ldo     TASK_PT_FR31(%r1),%r19             /* reload fpregs */
1973         rest_fp %r19
1975         LDREG   TASK_PT_SAR(%r1),%r19              /* restore SAR */
1976         mtsar   %r19
1978         LDREG   TASK_PT_GR2(%r1),%r2               /* restore user rp */
1979         LDREG   TASK_PT_GR19(%r1),%r19
1980         LDREG   TASK_PT_GR20(%r1),%r20
1981         LDREG   TASK_PT_GR21(%r1),%r21
1982         LDREG   TASK_PT_GR22(%r1),%r22
1983         LDREG   TASK_PT_GR23(%r1),%r23
1984         LDREG   TASK_PT_GR24(%r1),%r24
1985         LDREG   TASK_PT_GR25(%r1),%r25
1986         LDREG   TASK_PT_GR26(%r1),%r26
1987         LDREG   TASK_PT_GR27(%r1),%r27     /* restore user dp */
1988         LDREG   TASK_PT_GR28(%r1),%r28     /* syscall return value */
1989         LDREG   TASK_PT_GR29(%r1),%r29
1990         LDREG   TASK_PT_GR31(%r1),%r31     /* restore syscall rp */
1992         /* NOTE: We use rsm/ssm pair to make this operation atomic */
1993         LDREG   TASK_PT_GR30(%r1),%r1              /* Get user sp */
1994         rsm     PSW_SM_I, %r0
1995         copy    %r1,%r30                           /* Restore user sp */
1996         mfsp    %sr3,%r1                           /* Get user space id */
1997         mtsp    %r1,%sr7                           /* Restore sr7 */
1998         ssm     PSW_SM_I, %r0
2000         /* Set sr2 to zero for userspace syscalls to work. */
2001         mtsp    %r0,%sr2 
2002         mtsp    %r1,%sr4                           /* Restore sr4 */
2003         mtsp    %r1,%sr5                           /* Restore sr5 */
2004         mtsp    %r1,%sr6                           /* Restore sr6 */
2006         depi    3,31,2,%r31                        /* ensure return to user mode. */
2008 #ifdef CONFIG_64BIT
2009         /* decide whether to reset the wide mode bit
2010          *
2011          * For a syscall, the W bit is stored in the lowest bit
2012          * of sp.  Extract it and reset W if it is zero */
2013         extrd,u,*<>     %r30,63,1,%r1
2014         rsm     PSW_SM_W, %r0
2015         /* now reset the lowest bit of sp if it was set */
2016         xor     %r30,%r1,%r30
2017 #endif
2018         be,n    0(%sr3,%r31)                       /* return to user space */
2020         /* We have to return via an RFI, so that PSW T and R bits can be set
2021          * appropriately.
2022          * This sets up pt_regs so we can return via intr_restore, which is not
2023          * the most efficient way of doing things, but it works.
2024          */
2025 syscall_restore_rfi:
2026         ldo     -1(%r0),%r2                        /* Set recovery cntr to -1 */
2027         mtctl   %r2,%cr0                           /*   for immediate trap */
2028         LDREG   TASK_PT_PSW(%r1),%r2               /* Get old PSW */
2029         ldi     0x0b,%r20                          /* Create new PSW */
2030         depi    -1,13,1,%r20                       /* C, Q, D, and I bits */
2032         /* The values of SINGLESTEP_BIT and BLOCKSTEP_BIT are
2033          * set in thread_info.h and converted to PA bitmap
2034          * numbers in asm-offsets.c */
2036         /* if ((%r19.SINGLESTEP_BIT)) { %r20.27=1} */
2037         extru,= %r19,TIF_SINGLESTEP_PA_BIT,1,%r0
2038         depi    -1,27,1,%r20                       /* R bit */
2040         /* if ((%r19.BLOCKSTEP_BIT)) { %r20.7=1} */
2041         extru,= %r19,TIF_BLOCKSTEP_PA_BIT,1,%r0
2042         depi    -1,7,1,%r20                        /* T bit */
2044         STREG   %r20,TASK_PT_PSW(%r1)
2046         /* Always store space registers, since sr3 can be changed (e.g. fork) */
2048         mfsp    %sr3,%r25
2049         STREG   %r25,TASK_PT_SR3(%r1)
2050         STREG   %r25,TASK_PT_SR4(%r1)
2051         STREG   %r25,TASK_PT_SR5(%r1)
2052         STREG   %r25,TASK_PT_SR6(%r1)
2053         STREG   %r25,TASK_PT_SR7(%r1)
2054         STREG   %r25,TASK_PT_IASQ0(%r1)
2055         STREG   %r25,TASK_PT_IASQ1(%r1)
2057         /* Now if old D bit is clear, it means we didn't save all registers
2058          * on syscall entry, so do that now.  This only happens on TRACEME
2059          * calls, or if someone attached to us while we were on a syscall.
2060          * We could make this more efficient by not saving r3-r18, but
2061          * then we wouldn't be able to use the common intr_restore path.
2062          * It is only for traced processes anyway, so performance is not
2063          * an issue.
2064          */
2065         bb,<    %r2,30,pt_regs_ok                  /* Branch if D set */
2066         ldo     TASK_REGS(%r1),%r25
2067         reg_save %r25                              /* Save r3 to r18 */
2069         /* Save the current sr */
2070         mfsp    %sr0,%r2
2071         STREG   %r2,TASK_PT_SR0(%r1)
2073         /* Save the scratch sr */
2074         mfsp    %sr1,%r2
2075         STREG   %r2,TASK_PT_SR1(%r1)
2077         /* sr2 should be set to zero for userspace syscalls */
2078         STREG   %r0,TASK_PT_SR2(%r1)
2080 pt_regs_ok:
2081         LDREG   TASK_PT_GR31(%r1),%r2
2082         depi    3,31,2,%r2                         /* ensure return to user mode. */
2083         STREG   %r2,TASK_PT_IAOQ0(%r1)
2084         ldo     4(%r2),%r2
2085         STREG   %r2,TASK_PT_IAOQ1(%r1)
2086         copy    %r25,%r16
2087         b       intr_restore
2088         nop
2090         .import schedule,code
2091 syscall_do_resched:
2092         BL      schedule,%r2
2093 #ifdef CONFIG_64BIT
2094         ldo     -16(%r30),%r29          /* Reference param save area */
2095 #else
2096         nop
2097 #endif
2098         b       syscall_check_resched   /* if resched, we start over again */
2099         nop
2100 ENDPROC(syscall_exit)
2103 #ifdef CONFIG_FUNCTION_TRACER
2104         .import ftrace_function_trampoline,code
2105 ENTRY(_mcount)
2106         copy    %r3, %arg2
2107         b       ftrace_function_trampoline
2108         nop
2109 ENDPROC(_mcount)
2111 ENTRY(return_to_handler)
2112         load32  return_trampoline, %rp
2113         copy    %ret0, %arg0
2114         copy    %ret1, %arg1
2115         b       ftrace_return_to_handler
2116         nop
2117 return_trampoline:
2118         copy    %ret0, %rp
2119         copy    %r23, %ret0
2120         copy    %r24, %ret1
2122 .globl ftrace_stub
2123 ftrace_stub:
2124         bv      %r0(%rp)
2125         nop
2126 ENDPROC(return_to_handler)
2127 #endif  /* CONFIG_FUNCTION_TRACER */
2130 get_register:
2131         /*
2132          * get_register is used by the non access tlb miss handlers to
2133          * copy the value of the general register specified in r8 into
2134          * r1. This routine can't be used for shadowed registers, since
2135          * the rfir will restore the original value. So, for the shadowed
2136          * registers we put a -1 into r1 to indicate that the register
2137          * should not be used (the register being copied could also have
2138          * a -1 in it, but that is OK, it just means that we will have
2139          * to use the slow path instead).
2140          */
2141         blr     %r8,%r0
2142         nop
2143         bv      %r0(%r25)    /* r0 */
2144         copy    %r0,%r1
2145         bv      %r0(%r25)    /* r1 - shadowed */
2146         ldi     -1,%r1
2147         bv      %r0(%r25)    /* r2 */
2148         copy    %r2,%r1
2149         bv      %r0(%r25)    /* r3 */
2150         copy    %r3,%r1
2151         bv      %r0(%r25)    /* r4 */
2152         copy    %r4,%r1
2153         bv      %r0(%r25)    /* r5 */
2154         copy    %r5,%r1
2155         bv      %r0(%r25)    /* r6 */
2156         copy    %r6,%r1
2157         bv      %r0(%r25)    /* r7 */
2158         copy    %r7,%r1
2159         bv      %r0(%r25)    /* r8 - shadowed */
2160         ldi     -1,%r1
2161         bv      %r0(%r25)    /* r9 - shadowed */
2162         ldi     -1,%r1
2163         bv      %r0(%r25)    /* r10 */
2164         copy    %r10,%r1
2165         bv      %r0(%r25)    /* r11 */
2166         copy    %r11,%r1
2167         bv      %r0(%r25)    /* r12 */
2168         copy    %r12,%r1
2169         bv      %r0(%r25)    /* r13 */
2170         copy    %r13,%r1
2171         bv      %r0(%r25)    /* r14 */
2172         copy    %r14,%r1
2173         bv      %r0(%r25)    /* r15 */
2174         copy    %r15,%r1
2175         bv      %r0(%r25)    /* r16 - shadowed */
2176         ldi     -1,%r1
2177         bv      %r0(%r25)    /* r17 - shadowed */
2178         ldi     -1,%r1
2179         bv      %r0(%r25)    /* r18 */
2180         copy    %r18,%r1
2181         bv      %r0(%r25)    /* r19 */
2182         copy    %r19,%r1
2183         bv      %r0(%r25)    /* r20 */
2184         copy    %r20,%r1
2185         bv      %r0(%r25)    /* r21 */
2186         copy    %r21,%r1
2187         bv      %r0(%r25)    /* r22 */
2188         copy    %r22,%r1
2189         bv      %r0(%r25)    /* r23 */
2190         copy    %r23,%r1
2191         bv      %r0(%r25)    /* r24 - shadowed */
2192         ldi     -1,%r1
2193         bv      %r0(%r25)    /* r25 - shadowed */
2194         ldi     -1,%r1
2195         bv      %r0(%r25)    /* r26 */
2196         copy    %r26,%r1
2197         bv      %r0(%r25)    /* r27 */
2198         copy    %r27,%r1
2199         bv      %r0(%r25)    /* r28 */
2200         copy    %r28,%r1
2201         bv      %r0(%r25)    /* r29 */
2202         copy    %r29,%r1
2203         bv      %r0(%r25)    /* r30 */
2204         copy    %r30,%r1
2205         bv      %r0(%r25)    /* r31 */
2206         copy    %r31,%r1
2209 set_register:
2210         /*
2211          * set_register is used by the non access tlb miss handlers to
2212          * copy the value of r1 into the general register specified in
2213          * r8.
2214          */
2215         blr     %r8,%r0
2216         nop
2217         bv      %r0(%r25)    /* r0 (silly, but it is a place holder) */
2218         copy    %r1,%r0
2219         bv      %r0(%r25)    /* r1 */
2220         copy    %r1,%r1
2221         bv      %r0(%r25)    /* r2 */
2222         copy    %r1,%r2
2223         bv      %r0(%r25)    /* r3 */
2224         copy    %r1,%r3
2225         bv      %r0(%r25)    /* r4 */
2226         copy    %r1,%r4
2227         bv      %r0(%r25)    /* r5 */
2228         copy    %r1,%r5
2229         bv      %r0(%r25)    /* r6 */
2230         copy    %r1,%r6
2231         bv      %r0(%r25)    /* r7 */
2232         copy    %r1,%r7
2233         bv      %r0(%r25)    /* r8 */
2234         copy    %r1,%r8
2235         bv      %r0(%r25)    /* r9 */
2236         copy    %r1,%r9
2237         bv      %r0(%r25)    /* r10 */
2238         copy    %r1,%r10
2239         bv      %r0(%r25)    /* r11 */
2240         copy    %r1,%r11
2241         bv      %r0(%r25)    /* r12 */
2242         copy    %r1,%r12
2243         bv      %r0(%r25)    /* r13 */
2244         copy    %r1,%r13
2245         bv      %r0(%r25)    /* r14 */
2246         copy    %r1,%r14
2247         bv      %r0(%r25)    /* r15 */
2248         copy    %r1,%r15
2249         bv      %r0(%r25)    /* r16 */
2250         copy    %r1,%r16
2251         bv      %r0(%r25)    /* r17 */
2252         copy    %r1,%r17
2253         bv      %r0(%r25)    /* r18 */
2254         copy    %r1,%r18
2255         bv      %r0(%r25)    /* r19 */
2256         copy    %r1,%r19
2257         bv      %r0(%r25)    /* r20 */
2258         copy    %r1,%r20
2259         bv      %r0(%r25)    /* r21 */
2260         copy    %r1,%r21
2261         bv      %r0(%r25)    /* r22 */
2262         copy    %r1,%r22
2263         bv      %r0(%r25)    /* r23 */
2264         copy    %r1,%r23
2265         bv      %r0(%r25)    /* r24 */
2266         copy    %r1,%r24
2267         bv      %r0(%r25)    /* r25 */
2268         copy    %r1,%r25
2269         bv      %r0(%r25)    /* r26 */
2270         copy    %r1,%r26
2271         bv      %r0(%r25)    /* r27 */
2272         copy    %r1,%r27
2273         bv      %r0(%r25)    /* r28 */
2274         copy    %r1,%r28
2275         bv      %r0(%r25)    /* r29 */
2276         copy    %r1,%r29
2277         bv      %r0(%r25)    /* r30 */
2278         copy    %r1,%r30
2279         bv      %r0(%r25)    /* r31 */
2280         copy    %r1,%r31