[PARISC] remove remnants of parisc-specific softirq code
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / arch / parisc / kernel / entry.S
blob98ae563a0905d2aae724d99811c3c7bffe97935d
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 #define CMPIB           cmpib,*
44 #define CMPB            cmpb,*
45 #define COND(x)         *x
47         .level 2.0w
48 #else
49 #define CMPIB           cmpib,
50 #define CMPB            cmpb,
51 #define COND(x)         x
53         .level 2.0
54 #endif
56         .import         pa_dbit_lock,data
58         /* space_to_prot macro creates a prot id from a space id */
60 #if (SPACEID_SHIFT) == 0
61         .macro  space_to_prot spc prot
62         depd,z  \spc,62,31,\prot
63         .endm
64 #else
65         .macro  space_to_prot spc prot
66         extrd,u \spc,(64 - (SPACEID_SHIFT)),32,\prot
67         .endm
68 #endif
70         /* Switch to virtual mapping, trashing only %r1 */
71         .macro  virt_map
72         /* pcxt_ssm_bug */
73         rsm     PSW_SM_I, %r0   /* barrier for "Relied upon Translation */
74         mtsp    %r0, %sr4
75         mtsp    %r0, %sr5
76         mfsp    %sr7, %r1
77         or,=    %r0,%r1,%r0     /* Only save sr7 in sr3 if sr7 != 0 */
78         mtsp    %r1, %sr3
79         tovirt_r1 %r29
80         load32  KERNEL_PSW, %r1
82         rsm     PSW_SM_QUIET,%r0        /* second "heavy weight" ctl op */
83         mtsp    %r0, %sr6
84         mtsp    %r0, %sr7
85         mtctl   %r0, %cr17      /* Clear IIASQ tail */
86         mtctl   %r0, %cr17      /* Clear IIASQ head */
87         mtctl   %r1, %ipsw
88         load32  4f, %r1
89         mtctl   %r1, %cr18      /* Set IIAOQ tail */
90         ldo     4(%r1), %r1
91         mtctl   %r1, %cr18      /* Set IIAOQ head */
92         rfir
93         nop
95         .endm
97         /*
98          * The "get_stack" macros are responsible for determining the
99          * kernel stack value.
100          *
101          * For Faults:
102          *      If sr7 == 0
103          *          Already using a kernel stack, so call the
104          *          get_stack_use_r30 macro to push a pt_regs structure
105          *          on the stack, and store registers there.
106          *      else
107          *          Need to set up a kernel stack, so call the
108          *          get_stack_use_cr30 macro to set up a pointer
109          *          to the pt_regs structure contained within the
110          *          task pointer pointed to by cr30. Set the stack
111          *          pointer to point to the end of the task structure.
112          *
113          * For Interrupts:
114          *      If sr7 == 0
115          *          Already using a kernel stack, check to see if r30
116          *          is already pointing to the per processor interrupt
117          *          stack. If it is, call the get_stack_use_r30 macro
118          *          to push a pt_regs structure on the stack, and store
119          *          registers there. Otherwise, call get_stack_use_cr31
120          *          to get a pointer to the base of the interrupt stack
121          *          and push a pt_regs structure on that stack.
122          *      else
123          *          Need to set up a kernel stack, so call the
124          *          get_stack_use_cr30 macro to set up a pointer
125          *          to the pt_regs structure contained within the
126          *          task pointer pointed to by cr30. Set the stack
127          *          pointer to point to the end of the task structure.
128          *          N.B: We don't use the interrupt stack for the
129          *          first interrupt from userland, because signals/
130          *          resched's are processed when returning to userland,
131          *          and we can sleep in those cases.
132          *
133          * Note that we use shadowed registers for temps until
134          * we can save %r26 and %r29. %r26 is used to preserve
135          * %r8 (a shadowed register) which temporarily contained
136          * either the fault type ("code") or the eirr. We need
137          * to use a non-shadowed register to carry the value over
138          * the rfir in virt_map. We use %r26 since this value winds
139          * up being passed as the argument to either do_cpu_irq_mask
140          * or handle_interruption. %r29 is used to hold a pointer
141          * the register save area, and once again, it needs to
142          * be a non-shadowed register so that it survives the rfir.
143          *
144          * N.B. TASK_SZ_ALGN and PT_SZ_ALGN include space for a stack frame.
145          */
147         .macro  get_stack_use_cr30
149         /* we save the registers in the task struct */
151         mfctl   %cr30, %r1
152         tophys  %r1,%r9
153         LDREG   TI_TASK(%r9), %r1       /* thread_info -> task_struct */
154         tophys  %r1,%r9
155         ldo     TASK_REGS(%r9),%r9
156         STREG   %r30, PT_GR30(%r9)
157         STREG   %r29,PT_GR29(%r9)
158         STREG   %r26,PT_GR26(%r9)
159         copy    %r9,%r29
160         mfctl   %cr30, %r1
161         ldo     THREAD_SZ_ALGN(%r1), %r30
162         .endm
164         .macro  get_stack_use_r30
166         /* we put a struct pt_regs on the stack and save the registers there */
168         tophys  %r30,%r9
169         STREG   %r30,PT_GR30(%r9)
170         ldo     PT_SZ_ALGN(%r30),%r30
171         STREG   %r29,PT_GR29(%r9)
172         STREG   %r26,PT_GR26(%r9)
173         copy    %r9,%r29
174         .endm
176         .macro  rest_stack
177         LDREG   PT_GR1(%r29), %r1
178         LDREG   PT_GR30(%r29),%r30
179         LDREG   PT_GR29(%r29),%r29
180         .endm
182         /* default interruption handler
183          * (calls traps.c:handle_interruption) */
184         .macro  def code
185         b       intr_save
186         ldi     \code, %r8
187         .align  32
188         .endm
190         /* Interrupt interruption handler
191          * (calls irq.c:do_cpu_irq_mask) */
192         .macro  extint code
193         b       intr_extint
194         mfsp    %sr7,%r16
195         .align  32
196         .endm   
198         .import os_hpmc, code
200         /* HPMC handler */
201         .macro  hpmc code
202         nop                     /* must be a NOP, will be patched later */
203         load32  PA(os_hpmc), %r3
204         bv,n    0(%r3)
205         nop
206         .word   0               /* checksum (will be patched) */
207         .word   PA(os_hpmc)     /* address of handler */
208         .word   0               /* length of handler */
209         .endm
211         /*
212          * Performance Note: Instructions will be moved up into
213          * this part of the code later on, once we are sure
214          * that the tlb miss handlers are close to final form.
215          */
217         /* Register definitions for tlb miss handler macros */
219         va  = r8        /* virtual address for which the trap occured */
220         spc = r24       /* space for which the trap occured */
222 #ifndef CONFIG_64BIT
224         /*
225          * itlb miss interruption handler (parisc 1.1 - 32 bit)
226          */
228         .macro  itlb_11 code
230         mfctl   %pcsq, spc
231         b       itlb_miss_11
232         mfctl   %pcoq, va
234         .align          32
235         .endm
236 #endif
237         
238         /*
239          * itlb miss interruption handler (parisc 2.0)
240          */
242         .macro  itlb_20 code
243         mfctl   %pcsq, spc
244 #ifdef CONFIG_64BIT
245         b       itlb_miss_20w
246 #else
247         b       itlb_miss_20
248 #endif
249         mfctl   %pcoq, va
251         .align          32
252         .endm
253         
254 #ifndef CONFIG_64BIT
255         /*
256          * naitlb miss interruption handler (parisc 1.1 - 32 bit)
257          *
258          * Note: naitlb misses will be treated
259          * as an ordinary itlb miss for now.
260          * However, note that naitlb misses
261          * have the faulting address in the
262          * IOR/ISR.
263          */
265         .macro  naitlb_11 code
267         mfctl   %isr,spc
268         b       itlb_miss_11
269         mfctl   %ior,va
270         /* FIXME: If user causes a naitlb miss, the priv level may not be in
271          * lower bits of va, where the itlb miss handler is expecting them
272          */
274         .align          32
275         .endm
276 #endif
277         
278         /*
279          * naitlb miss interruption handler (parisc 2.0)
280          *
281          * Note: naitlb misses will be treated
282          * as an ordinary itlb miss for now.
283          * However, note that naitlb misses
284          * have the faulting address in the
285          * IOR/ISR.
286          */
288         .macro  naitlb_20 code
290         mfctl   %isr,spc
291 #ifdef CONFIG_64BIT
292         b       itlb_miss_20w
293 #else
294         b       itlb_miss_20
295 #endif
296         mfctl   %ior,va
297         /* FIXME: If user causes a naitlb miss, the priv level may not be in
298          * lower bits of va, where the itlb miss handler is expecting them
299          */
301         .align          32
302         .endm
303         
304 #ifndef CONFIG_64BIT
305         /*
306          * dtlb miss interruption handler (parisc 1.1 - 32 bit)
307          */
309         .macro  dtlb_11 code
311         mfctl   %isr, spc
312         b       dtlb_miss_11
313         mfctl   %ior, va
315         .align          32
316         .endm
317 #endif
319         /*
320          * dtlb miss interruption handler (parisc 2.0)
321          */
323         .macro  dtlb_20 code
325         mfctl   %isr, spc
326 #ifdef CONFIG_64BIT
327         b       dtlb_miss_20w
328 #else
329         b       dtlb_miss_20
330 #endif
331         mfctl   %ior, va
333         .align          32
334         .endm
335         
336 #ifndef CONFIG_64BIT
337         /* nadtlb miss interruption handler (parisc 1.1 - 32 bit) */
339         .macro  nadtlb_11 code
341         mfctl   %isr,spc
342         b       nadtlb_miss_11
343         mfctl   %ior,va
345         .align          32
346         .endm
347 #endif
348         
349         /* nadtlb miss interruption handler (parisc 2.0) */
351         .macro  nadtlb_20 code
353         mfctl   %isr,spc
354 #ifdef CONFIG_64BIT
355         b       nadtlb_miss_20w
356 #else
357         b       nadtlb_miss_20
358 #endif
359         mfctl   %ior,va
361         .align          32
362         .endm
363         
364 #ifndef CONFIG_64BIT
365         /*
366          * dirty bit trap interruption handler (parisc 1.1 - 32 bit)
367          */
369         .macro  dbit_11 code
371         mfctl   %isr,spc
372         b       dbit_trap_11
373         mfctl   %ior,va
375         .align          32
376         .endm
377 #endif
379         /*
380          * dirty bit trap interruption handler (parisc 2.0)
381          */
383         .macro  dbit_20 code
385         mfctl   %isr,spc
386 #ifdef CONFIG_64BIT
387         b       dbit_trap_20w
388 #else
389         b       dbit_trap_20
390 #endif
391         mfctl   %ior,va
393         .align          32
394         .endm
396         /* The following are simple 32 vs 64 bit instruction
397          * abstractions for the macros */
398         .macro          EXTR    reg1,start,length,reg2
399 #ifdef CONFIG_64BIT
400         extrd,u         \reg1,32+\start,\length,\reg2
401 #else
402         extrw,u         \reg1,\start,\length,\reg2
403 #endif
404         .endm
406         .macro          DEP     reg1,start,length,reg2
407 #ifdef CONFIG_64BIT
408         depd            \reg1,32+\start,\length,\reg2
409 #else
410         depw            \reg1,\start,\length,\reg2
411 #endif
412         .endm
414         .macro          DEPI    val,start,length,reg
415 #ifdef CONFIG_64BIT
416         depdi           \val,32+\start,\length,\reg
417 #else
418         depwi           \val,\start,\length,\reg
419 #endif
420         .endm
422         /* In LP64, the space contains part of the upper 32 bits of the
423          * fault.  We have to extract this and place it in the va,
424          * zeroing the corresponding bits in the space register */
425         .macro          space_adjust    spc,va,tmp
426 #ifdef CONFIG_64BIT
427         extrd,u         \spc,63,SPACEID_SHIFT,\tmp
428         depd            %r0,63,SPACEID_SHIFT,\spc
429         depd            \tmp,31,SPACEID_SHIFT,\va
430 #endif
431         .endm
433         .import         swapper_pg_dir,code
435         /* Get the pgd.  For faults on space zero (kernel space), this
436          * is simply swapper_pg_dir.  For user space faults, the
437          * pgd is stored in %cr25 */
438         .macro          get_pgd         spc,reg
439         ldil            L%PA(swapper_pg_dir),\reg
440         ldo             R%PA(swapper_pg_dir)(\reg),\reg
441         or,COND(=)      %r0,\spc,%r0
442         mfctl           %cr25,\reg
443         .endm
445         /* 
446                 space_check(spc,tmp,fault)
448                 spc - The space we saw the fault with.
449                 tmp - The place to store the current space.
450                 fault - Function to call on failure.
452                 Only allow faults on different spaces from the
453                 currently active one if we're the kernel 
455         */
456         .macro          space_check     spc,tmp,fault
457         mfsp            %sr7,\tmp
458         or,COND(<>)     %r0,\spc,%r0    /* user may execute gateway page
459                                          * as kernel, so defeat the space
460                                          * check if it is */
461         copy            \spc,\tmp
462         or,COND(=)      %r0,\tmp,%r0    /* nullify if executing as kernel */
463         cmpb,COND(<>),n \tmp,\spc,\fault
464         .endm
466         /* Look up a PTE in a 2-Level scheme (faulting at each
467          * level if the entry isn't present 
468          *
469          * NOTE: we use ldw even for LP64, since the short pointers
470          * can address up to 1TB
471          */
472         .macro          L2_ptep pmd,pte,index,va,fault
473 #if PT_NLEVELS == 3
474         EXTR            \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index
475 #else
476         EXTR            \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
477 #endif
478         DEP             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
479         copy            %r0,\pte
480         ldw,s           \index(\pmd),\pmd
481         bb,>=,n         \pmd,_PxD_PRESENT_BIT,\fault
482         DEP             %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
483         copy            \pmd,%r9
484         SHLREG          %r9,PxD_VALUE_SHIFT,\pmd
485         EXTR            \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
486         DEP             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
487         shladd          \index,BITS_PER_PTE_ENTRY,\pmd,\pmd
488         LDREG           %r0(\pmd),\pte          /* pmd is now pte */
489         bb,>=,n         \pte,_PAGE_PRESENT_BIT,\fault
490         .endm
492         /* Look up PTE in a 3-Level scheme.
493          *
494          * Here we implement a Hybrid L2/L3 scheme: we allocate the
495          * first pmd adjacent to the pgd.  This means that we can
496          * subtract a constant offset to get to it.  The pmd and pgd
497          * sizes are arranged so that a single pmd covers 4GB (giving
498          * a full LP64 process access to 8TB) so our lookups are
499          * effectively L2 for the first 4GB of the kernel (i.e. for
500          * all ILP32 processes and all the kernel for machines with
501          * under 4GB of memory) */
502         .macro          L3_ptep pgd,pte,index,va,fault
503 #if PT_NLEVELS == 3 /* we might have a 2-Level scheme, e.g. with 16kb page size */
504         extrd,u         \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
505         copy            %r0,\pte
506         extrd,u,*=      \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
507         ldw,s           \index(\pgd),\pgd
508         extrd,u,*=      \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
509         bb,>=,n         \pgd,_PxD_PRESENT_BIT,\fault
510         extrd,u,*=      \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
511         shld            \pgd,PxD_VALUE_SHIFT,\index
512         extrd,u,*=      \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
513         copy            \index,\pgd
514         extrd,u,*<>     \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
515         ldo             ASM_PGD_PMD_OFFSET(\pgd),\pgd
516 #endif
517         L2_ptep         \pgd,\pte,\index,\va,\fault
518         .endm
520         /* Set the _PAGE_ACCESSED bit of the PTE.  Be clever and
521          * don't needlessly dirty the cache line if it was already set */
522         .macro          update_ptep     ptep,pte,tmp,tmp1
523         ldi             _PAGE_ACCESSED,\tmp1
524         or              \tmp1,\pte,\tmp
525         and,COND(<>)    \tmp1,\pte,%r0
526         STREG           \tmp,0(\ptep)
527         .endm
529         /* Set the dirty bit (and accessed bit).  No need to be
530          * clever, this is only used from the dirty fault */
531         .macro          update_dirty    ptep,pte,tmp
532         ldi             _PAGE_ACCESSED|_PAGE_DIRTY,\tmp
533         or              \tmp,\pte,\pte
534         STREG           \pte,0(\ptep)
535         .endm
537         /* Convert the pte and prot to tlb insertion values.  How
538          * this happens is quite subtle, read below */
539         .macro          make_insert_tlb spc,pte,prot
540         space_to_prot   \spc \prot        /* create prot id from space */
541         /* The following is the real subtlety.  This is depositing
542          * T <-> _PAGE_REFTRAP
543          * D <-> _PAGE_DIRTY
544          * B <-> _PAGE_DMB (memory break)
545          *
546          * Then incredible subtlety: The access rights are
547          * _PAGE_GATEWAY _PAGE_EXEC _PAGE_READ
548          * See 3-14 of the parisc 2.0 manual
549          *
550          * Finally, _PAGE_READ goes in the top bit of PL1 (so we
551          * trigger an access rights trap in user space if the user
552          * tries to read an unreadable page */
553         depd            \pte,8,7,\prot
555         /* PAGE_USER indicates the page can be read with user privileges,
556          * so deposit X1|11 to PL1|PL2 (remember the upper bit of PL1
557          * contains _PAGE_READ */
558         extrd,u,*=      \pte,_PAGE_USER_BIT+32,1,%r0
559         depdi           7,11,3,\prot
560         /* If we're a gateway page, drop PL2 back to zero for promotion
561          * to kernel privilege (so we can execute the page as kernel).
562          * Any privilege promotion page always denys read and write */
563         extrd,u,*=      \pte,_PAGE_GATEWAY_BIT+32,1,%r0
564         depd            %r0,11,2,\prot  /* If Gateway, Set PL2 to 0 */
566         /* Enforce uncacheable pages.
567          * This should ONLY be use for MMIO on PA 2.0 machines.
568          * Memory/DMA is cache coherent on all PA2.0 machines we support
569          * (that means T-class is NOT supported) and the memory controllers
570          * on most of those machines only handles cache transactions.
571          */
572         extrd,u,*=      \pte,_PAGE_NO_CACHE_BIT+32,1,%r0
573         depi            1,12,1,\prot
575         /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
576         extrd,u         \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58),64-PAGE_SHIFT,\pte
577         depdi           _PAGE_SIZE_ENCODING_DEFAULT,63,63-58,\pte
578         .endm
580         /* Identical macro to make_insert_tlb above, except it
581          * makes the tlb entry for the differently formatted pa11
582          * insertion instructions */
583         .macro          make_insert_tlb_11      spc,pte,prot
584         zdep            \spc,30,15,\prot
585         dep             \pte,8,7,\prot
586         extru,=         \pte,_PAGE_NO_CACHE_BIT,1,%r0
587         depi            1,12,1,\prot
588         extru,=         \pte,_PAGE_USER_BIT,1,%r0
589         depi            7,11,3,\prot   /* Set for user space (1 rsvd for read) */
590         extru,=         \pte,_PAGE_GATEWAY_BIT,1,%r0
591         depi            0,11,2,\prot    /* If Gateway, Set PL2 to 0 */
593         /* Get rid of prot bits and convert to page addr for iitlba */
595         depi            _PAGE_SIZE_ENCODING_DEFAULT,31,ASM_PFN_PTE_SHIFT,\pte
596         extru           \pte,24,25,\pte
597         .endm
599         /* This is for ILP32 PA2.0 only.  The TLB insertion needs
600          * to extend into I/O space if the address is 0xfXXXXXXX
601          * so we extend the f's into the top word of the pte in
602          * this case */
603         .macro          f_extend        pte,tmp
604         extrd,s         \pte,42,4,\tmp
605         addi,<>         1,\tmp,%r0
606         extrd,s         \pte,63,25,\pte
607         .endm
609         /* The alias region is an 8MB aligned 16MB to do clear and
610          * copy user pages at addresses congruent with the user
611          * virtual address.
612          *
613          * To use the alias page, you set %r26 up with the to TLB
614          * entry (identifying the physical page) and %r23 up with
615          * the from tlb entry (or nothing if only a to entry---for
616          * clear_user_page_asm) */
617         .macro          do_alias        spc,tmp,tmp1,va,pte,prot,fault
618         cmpib,COND(<>),n 0,\spc,\fault
619         ldil            L%(TMPALIAS_MAP_START),\tmp
620 #if defined(CONFIG_64BIT) && (TMPALIAS_MAP_START >= 0x80000000)
621         /* on LP64, ldi will sign extend into the upper 32 bits,
622          * which is behaviour we don't want */
623         depdi           0,31,32,\tmp
624 #endif
625         copy            \va,\tmp1
626         DEPI            0,31,23,\tmp1
627         cmpb,COND(<>),n \tmp,\tmp1,\fault
628         ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),\prot
629         depd,z          \prot,8,7,\prot
630         /*
631          * OK, it is in the temp alias region, check whether "from" or "to".
632          * Check "subtle" note in pacache.S re: r23/r26.
633          */
634 #ifdef CONFIG_64BIT
635         extrd,u,*=      \va,41,1,%r0
636 #else
637         extrw,u,=       \va,9,1,%r0
638 #endif
639         or,COND(tr)     %r23,%r0,\pte
640         or              %r26,%r0,\pte
641         .endm 
644         /*
645          * Align fault_vector_20 on 4K boundary so that both
646          * fault_vector_11 and fault_vector_20 are on the
647          * same page. This is only necessary as long as we
648          * write protect the kernel text, which we may stop
649          * doing once we use large page translations to cover
650          * the static part of the kernel address space.
651          */
653         .text
655         .align 4096
657 ENTRY(fault_vector_20)
658         /* First vector is invalid (0) */
659         .ascii  "cows can fly"
660         .byte 0
661         .align 32
663         hpmc             1
664         def              2
665         def              3
666         extint           4
667         def              5
668         itlb_20          6
669         def              7
670         def              8
671         def              9
672         def             10
673         def             11
674         def             12
675         def             13
676         def             14
677         dtlb_20         15
678 #if 0
679         naitlb_20       16
680 #else
681         def             16
682 #endif
683         nadtlb_20       17
684         def             18
685         def             19
686         dbit_20         20
687         def             21
688         def             22
689         def             23
690         def             24
691         def             25
692         def             26
693         def             27
694         def             28
695         def             29
696         def             30
697         def             31
698 END(fault_vector_20)
700 #ifndef CONFIG_64BIT
702         .align 2048
704 ENTRY(fault_vector_11)
705         /* First vector is invalid (0) */
706         .ascii  "cows can fly"
707         .byte 0
708         .align 32
710         hpmc             1
711         def              2
712         def              3
713         extint           4
714         def              5
715         itlb_11          6
716         def              7
717         def              8
718         def              9
719         def             10
720         def             11
721         def             12
722         def             13
723         def             14
724         dtlb_11         15
725 #if 0
726         naitlb_11       16
727 #else
728         def             16
729 #endif
730         nadtlb_11       17
731         def             18
732         def             19
733         dbit_11         20
734         def             21
735         def             22
736         def             23
737         def             24
738         def             25
739         def             26
740         def             27
741         def             28
742         def             29
743         def             30
744         def             31
745 END(fault_vector_11)
747 #endif
749         .import         handle_interruption,code
750         .import         do_cpu_irq_mask,code
752         /*
753          * r26 = function to be called
754          * r25 = argument to pass in
755          * r24 = flags for do_fork()
756          *
757          * Kernel threads don't ever return, so they don't need
758          * a true register context. We just save away the arguments
759          * for copy_thread/ret_ to properly set up the child.
760          */
762 #define CLONE_VM 0x100  /* Must agree with <linux/sched.h> */
763 #define CLONE_UNTRACED 0x00800000
765         .import do_fork
766 ENTRY(__kernel_thread)
767         STREG   %r2, -RP_OFFSET(%r30)
769         copy    %r30, %r1
770         ldo     PT_SZ_ALGN(%r30),%r30
771 #ifdef CONFIG_64BIT
772         /* Yo, function pointers in wide mode are little structs... -PB */
773         ldd     24(%r26), %r2
774         STREG   %r2, PT_GR27(%r1)       /* Store childs %dp */
775         ldd     16(%r26), %r26
777         STREG   %r22, PT_GR22(%r1)      /* save r22 (arg5) */
778         copy    %r0, %r22               /* user_tid */
779 #endif
780         STREG   %r26, PT_GR26(%r1)  /* Store function & argument for child */
781         STREG   %r25, PT_GR25(%r1)
782         ldil    L%CLONE_UNTRACED, %r26
783         ldo     CLONE_VM(%r26), %r26   /* Force CLONE_VM since only init_mm */
784         or      %r26, %r24, %r26      /* will have kernel mappings.      */
785         ldi     1, %r25                 /* stack_start, signals kernel thread */
786         stw     %r0, -52(%r30)          /* user_tid */
787 #ifdef CONFIG_64BIT
788         ldo     -16(%r30),%r29          /* Reference param save area */
789 #endif
790         BL      do_fork, %r2
791         copy    %r1, %r24               /* pt_regs */
793         /* Parent Returns here */
795         LDREG   -PT_SZ_ALGN-RP_OFFSET(%r30), %r2
796         ldo     -PT_SZ_ALGN(%r30), %r30
797         bv      %r0(%r2)
798         nop
799 ENDPROC(__kernel_thread)
801         /*
802          * Child Returns here
803          *
804          * copy_thread moved args from temp save area set up above
805          * into task save area.
806          */
808 ENTRY(ret_from_kernel_thread)
810         /* Call schedule_tail first though */
811         BL      schedule_tail, %r2
812         nop
814         LDREG   TI_TASK-THREAD_SZ_ALGN(%r30), %r1
815         LDREG   TASK_PT_GR25(%r1), %r26
816 #ifdef CONFIG_64BIT
817         LDREG   TASK_PT_GR27(%r1), %r27
818         LDREG   TASK_PT_GR22(%r1), %r22
819 #endif
820         LDREG   TASK_PT_GR26(%r1), %r1
821         ble     0(%sr7, %r1)
822         copy    %r31, %r2
824 #ifdef CONFIG_64BIT
825         ldo     -16(%r30),%r29          /* Reference param save area */
826         loadgp                          /* Thread could have been in a module */
827 #endif
828 #ifndef CONFIG_64BIT
829         b       sys_exit
830 #else
831         load32  sys_exit, %r1
832         bv      %r0(%r1)
833 #endif
834         ldi     0, %r26
835 ENDPROC(ret_from_kernel_thread)
837         .import sys_execve, code
838 ENTRY(__execve)
839         copy    %r2, %r15
840         copy    %r30, %r16
841         ldo     PT_SZ_ALGN(%r30), %r30
842         STREG   %r26, PT_GR26(%r16)
843         STREG   %r25, PT_GR25(%r16)
844         STREG   %r24, PT_GR24(%r16)
845 #ifdef CONFIG_64BIT
846         ldo     -16(%r30),%r29          /* Reference param save area */
847 #endif
848         BL      sys_execve, %r2
849         copy    %r16, %r26
851         cmpib,=,n 0,%r28,intr_return    /* forward */
853         /* yes, this will trap and die. */
854         copy    %r15, %r2
855         copy    %r16, %r30
856         bv      %r0(%r2)
857         nop
858 ENDPROC(__execve)
861         /*
862          * struct task_struct *_switch_to(struct task_struct *prev,
863          *      struct task_struct *next)
864          *
865          * switch kernel stacks and return prev */
866 ENTRY(_switch_to)
867         STREG    %r2, -RP_OFFSET(%r30)
869         callee_save_float
870         callee_save
872         load32  _switch_to_ret, %r2
874         STREG   %r2, TASK_PT_KPC(%r26)
875         LDREG   TASK_PT_KPC(%r25), %r2
877         STREG   %r30, TASK_PT_KSP(%r26)
878         LDREG   TASK_PT_KSP(%r25), %r30
879         LDREG   TASK_THREAD_INFO(%r25), %r25
880         bv      %r0(%r2)
881         mtctl   %r25,%cr30
883 _switch_to_ret:
884         mtctl   %r0, %cr0               /* Needed for single stepping */
885         callee_rest
886         callee_rest_float
888         LDREG   -RP_OFFSET(%r30), %r2
889         bv      %r0(%r2)
890         copy    %r26, %r28
891 ENDPROC(_switch_to)
893         /*
894          * Common rfi return path for interruptions, kernel execve, and
895          * sys_rt_sigreturn (sometimes).  The sys_rt_sigreturn syscall will
896          * return via this path if the signal was received when the process
897          * was running; if the process was blocked on a syscall then the
898          * normal syscall_exit path is used.  All syscalls for traced
899          * proceses exit via intr_restore.
900          *
901          * XXX If any syscalls that change a processes space id ever exit
902          * this way, then we will need to copy %sr3 in to PT_SR[3..7], and
903          * adjust IASQ[0..1].
904          *
905          */
907         .align 4096
909 ENTRY(syscall_exit_rfi)
910         mfctl   %cr30,%r16
911         LDREG   TI_TASK(%r16), %r16     /* thread_info -> task_struct */
912         ldo     TASK_REGS(%r16),%r16
913         /* Force iaoq to userspace, as the user has had access to our current
914          * context via sigcontext. Also Filter the PSW for the same reason.
915          */
916         LDREG   PT_IAOQ0(%r16),%r19
917         depi    3,31,2,%r19
918         STREG   %r19,PT_IAOQ0(%r16)
919         LDREG   PT_IAOQ1(%r16),%r19
920         depi    3,31,2,%r19
921         STREG   %r19,PT_IAOQ1(%r16)
922         LDREG   PT_PSW(%r16),%r19
923         load32  USER_PSW_MASK,%r1
924 #ifdef CONFIG_64BIT
925         load32  USER_PSW_HI_MASK,%r20
926         depd    %r20,31,32,%r1
927 #endif
928         and     %r19,%r1,%r19 /* Mask out bits that user shouldn't play with */
929         load32  USER_PSW,%r1
930         or      %r19,%r1,%r19 /* Make sure default USER_PSW bits are set */
931         STREG   %r19,PT_PSW(%r16)
933         /*
934          * If we aren't being traced, we never saved space registers
935          * (we don't store them in the sigcontext), so set them
936          * to "proper" values now (otherwise we'll wind up restoring
937          * whatever was last stored in the task structure, which might
938          * be inconsistent if an interrupt occured while on the gateway
939          * page). Note that we may be "trashing" values the user put in
940          * them, but we don't support the user changing them.
941          */
943         STREG   %r0,PT_SR2(%r16)
944         mfsp    %sr3,%r19
945         STREG   %r19,PT_SR0(%r16)
946         STREG   %r19,PT_SR1(%r16)
947         STREG   %r19,PT_SR3(%r16)
948         STREG   %r19,PT_SR4(%r16)
949         STREG   %r19,PT_SR5(%r16)
950         STREG   %r19,PT_SR6(%r16)
951         STREG   %r19,PT_SR7(%r16)
953 intr_return:
954         /* NOTE: Need to enable interrupts incase we schedule. */
955         ssm     PSW_SM_I, %r0
957 intr_check_resched:
959         /* check for reschedule */
960         mfctl   %cr30,%r1
961         LDREG   TI_FLAGS(%r1),%r19      /* sched.h: TIF_NEED_RESCHED */
962         bb,<,n  %r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */
964         .import do_notify_resume,code
965 intr_check_sig:
966         /* As above */
967         mfctl   %cr30,%r1
968         LDREG   TI_FLAGS(%r1),%r19
969         ldi     (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %r20
970         and,COND(<>)    %r19, %r20, %r0
971         b,n     intr_restore    /* skip past if we've nothing to do */
973         /* This check is critical to having LWS
974          * working. The IASQ is zero on the gateway
975          * page and we cannot deliver any signals until
976          * we get off the gateway page.
977          *
978          * Only do signals if we are returning to user space
979          */
980         LDREG   PT_IASQ0(%r16), %r20
981         CMPIB=,n 0,%r20,intr_restore /* backward */
982         LDREG   PT_IASQ1(%r16), %r20
983         CMPIB=,n 0,%r20,intr_restore /* backward */
985         copy    %r0, %r25                       /* long in_syscall = 0 */
986 #ifdef CONFIG_64BIT
987         ldo     -16(%r30),%r29                  /* Reference param save area */
988 #endif
990         BL      do_notify_resume,%r2
991         copy    %r16, %r26                      /* struct pt_regs *regs */
993         b,n     intr_check_sig
995 intr_restore:
996         copy            %r16,%r29
997         ldo             PT_FR31(%r29),%r1
998         rest_fp         %r1
999         rest_general    %r29
1001         /* inverse of virt_map */
1002         pcxt_ssm_bug
1003         rsm             PSW_SM_QUIET,%r0        /* prepare for rfi */
1004         tophys_r1       %r29
1006         /* Restore space id's and special cr's from PT_REGS
1007          * structure pointed to by r29
1008          */
1009         rest_specials   %r29
1011         /* IMPORTANT: rest_stack restores r29 last (we are using it)!
1012          * It also restores r1 and r30.
1013          */
1014         rest_stack
1016         rfi
1017         nop
1018         nop
1019         nop
1020         nop
1021         nop
1022         nop
1023         nop
1024         nop
1026 #ifndef CONFIG_PREEMPT
1027 # define intr_do_preempt        intr_restore
1028 #endif /* !CONFIG_PREEMPT */
1030         .import schedule,code
1031 intr_do_resched:
1032         /* Only call schedule on return to userspace. If we're returning
1033          * to kernel space, we may schedule if CONFIG_PREEMPT, otherwise
1034          * we jump back to intr_restore.
1035          */
1036         LDREG   PT_IASQ0(%r16), %r20
1037         CMPIB=  0, %r20, intr_do_preempt
1038         nop
1039         LDREG   PT_IASQ1(%r16), %r20
1040         CMPIB=  0, %r20, intr_do_preempt
1041         nop
1043 #ifdef CONFIG_64BIT
1044         ldo     -16(%r30),%r29          /* Reference param save area */
1045 #endif
1047         ldil    L%intr_check_sig, %r2
1048 #ifndef CONFIG_64BIT
1049         b       schedule
1050 #else
1051         load32  schedule, %r20
1052         bv      %r0(%r20)
1053 #endif
1054         ldo     R%intr_check_sig(%r2), %r2
1056         /* preempt the current task on returning to kernel
1057          * mode from an interrupt, iff need_resched is set,
1058          * and preempt_count is 0. otherwise, we continue on
1059          * our merry way back to the current running task.
1060          */
1061 #ifdef CONFIG_PREEMPT
1062         .import preempt_schedule_irq,code
1063 intr_do_preempt:
1064         rsm     PSW_SM_I, %r0           /* disable interrupts */
1066         /* current_thread_info()->preempt_count */
1067         mfctl   %cr30, %r1
1068         LDREG   TI_PRE_COUNT(%r1), %r19
1069         CMPIB<> 0, %r19, intr_restore   /* if preempt_count > 0 */
1070         nop                             /* prev insn branched backwards */
1072         /* check if we interrupted a critical path */
1073         LDREG   PT_PSW(%r16), %r20
1074         bb,<,n  %r20, 31 - PSW_SM_I, intr_restore
1075         nop
1077         BL      preempt_schedule_irq, %r2
1078         nop
1080         b,n     intr_restore            /* ssm PSW_SM_I done by intr_restore */
1081 #endif /* CONFIG_PREEMPT */
1083         /*
1084          * External interrupts.
1085          */
1087 intr_extint:
1088         CMPIB=,n 0,%r16,1f
1089         get_stack_use_cr30
1090         b,n 3f
1093 #if 0  /* Interrupt Stack support not working yet! */
1094         mfctl   %cr31,%r1
1095         copy    %r30,%r17
1096         /* FIXME! depi below has hardcoded idea of interrupt stack size (32k)*/
1097         DEPI    0,31,15,%r17
1098         CMPB=,n %r1,%r17,2f
1099         get_stack_use_cr31
1100         b,n 3f
1101 #endif
1103         get_stack_use_r30
1106         save_specials   %r29
1107         virt_map
1108         save_general    %r29
1110         ldo     PT_FR0(%r29), %r24
1111         save_fp %r24
1112         
1113         loadgp
1115         copy    %r29, %r26      /* arg0 is pt_regs */
1116         copy    %r29, %r16      /* save pt_regs */
1118         ldil    L%intr_return, %r2
1120 #ifdef CONFIG_64BIT
1121         ldo     -16(%r30),%r29  /* Reference param save area */
1122 #endif
1124         b       do_cpu_irq_mask
1125         ldo     R%intr_return(%r2), %r2 /* return to intr_return, not here */
1126 ENDPROC(syscall_exit_rfi)
1129         /* Generic interruptions (illegal insn, unaligned, page fault, etc) */
1131 ENTRY(intr_save)                /* for os_hpmc */
1132         mfsp    %sr7,%r16
1133         CMPIB=,n 0,%r16,1f
1134         get_stack_use_cr30
1135         b       2f
1136         copy    %r8,%r26
1139         get_stack_use_r30
1140         copy    %r8,%r26
1143         save_specials   %r29
1145         /* If this trap is a itlb miss, skip saving/adjusting isr/ior */
1147         /*
1148          * FIXME: 1) Use a #define for the hardwired "6" below (and in
1149          *           traps.c.
1150          *        2) Once we start executing code above 4 Gb, we need
1151          *           to adjust iasq/iaoq here in the same way we
1152          *           adjust isr/ior below.
1153          */
1155         CMPIB=,n        6,%r26,skip_save_ior
1158         mfctl           %cr20, %r16 /* isr */
1159         nop             /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */
1160         mfctl           %cr21, %r17 /* ior */
1163 #ifdef CONFIG_64BIT
1164         /*
1165          * If the interrupted code was running with W bit off (32 bit),
1166          * clear the b bits (bits 0 & 1) in the ior.
1167          * save_specials left ipsw value in r8 for us to test.
1168          */
1169         extrd,u,*<>     %r8,PSW_W_BIT,1,%r0
1170         depdi           0,1,2,%r17
1172         /*
1173          * FIXME: This code has hardwired assumptions about the split
1174          *        between space bits and offset bits. This will change
1175          *        when we allow alternate page sizes.
1176          */
1178         /* adjust isr/ior. */
1179         extrd,u         %r16,63,SPACEID_SHIFT,%r1       /* get high bits from isr for ior */
1180         depd            %r1,31,SPACEID_SHIFT,%r17       /* deposit them into ior */
1181         depdi           0,63,SPACEID_SHIFT,%r16         /* clear them from isr */
1182 #endif
1183         STREG           %r16, PT_ISR(%r29)
1184         STREG           %r17, PT_IOR(%r29)
1187 skip_save_ior:
1188         virt_map
1189         save_general    %r29
1191         ldo             PT_FR0(%r29), %r25
1192         save_fp         %r25
1193         
1194         loadgp
1196         copy            %r29, %r25      /* arg1 is pt_regs */
1197 #ifdef CONFIG_64BIT
1198         ldo             -16(%r30),%r29  /* Reference param save area */
1199 #endif
1201         ldil            L%intr_check_sig, %r2
1202         copy            %r25, %r16      /* save pt_regs */
1204         b               handle_interruption
1205         ldo             R%intr_check_sig(%r2), %r2
1206 ENDPROC(intr_save)
1209         /*
1210          * Note for all tlb miss handlers:
1211          *
1212          * cr24 contains a pointer to the kernel address space
1213          * page directory.
1214          *
1215          * cr25 contains a pointer to the current user address
1216          * space page directory.
1217          *
1218          * sr3 will contain the space id of the user address space
1219          * of the current running thread while that thread is
1220          * running in the kernel.
1221          */
1223         /*
1224          * register number allocations.  Note that these are all
1225          * in the shadowed registers
1226          */
1228         t0 = r1         /* temporary register 0 */
1229         va = r8         /* virtual address for which the trap occured */
1230         t1 = r9         /* temporary register 1 */
1231         pte  = r16      /* pte/phys page # */
1232         prot = r17      /* prot bits */
1233         spc  = r24      /* space for which the trap occured */
1234         ptp = r25       /* page directory/page table pointer */
1236 #ifdef CONFIG_64BIT
1238 dtlb_miss_20w:
1239         space_adjust    spc,va,t0
1240         get_pgd         spc,ptp
1241         space_check     spc,t0,dtlb_fault
1243         L3_ptep         ptp,pte,t0,va,dtlb_check_alias_20w
1245         update_ptep     ptp,pte,t0,t1
1247         make_insert_tlb spc,pte,prot
1248         
1249         idtlbt          pte,prot
1251         rfir
1252         nop
1254 dtlb_check_alias_20w:
1255         do_alias        spc,t0,t1,va,pte,prot,dtlb_fault
1257         idtlbt          pte,prot
1259         rfir
1260         nop
1262 nadtlb_miss_20w:
1263         space_adjust    spc,va,t0
1264         get_pgd         spc,ptp
1265         space_check     spc,t0,nadtlb_fault
1267         L3_ptep         ptp,pte,t0,va,nadtlb_check_flush_20w
1269         update_ptep     ptp,pte,t0,t1
1271         make_insert_tlb spc,pte,prot
1273         idtlbt          pte,prot
1275         rfir
1276         nop
1278 nadtlb_check_flush_20w:
1279         bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
1281         /* Insert a "flush only" translation */
1283         depdi,z         7,7,3,prot
1284         depdi           1,10,1,prot
1286         /* Get rid of prot bits and convert to page addr for idtlbt */
1288         depdi           0,63,12,pte
1289         extrd,u         pte,56,52,pte
1290         idtlbt          pte,prot
1292         rfir
1293         nop
1295 #else
1297 dtlb_miss_11:
1298         get_pgd         spc,ptp
1300         space_check     spc,t0,dtlb_fault
1302         L2_ptep         ptp,pte,t0,va,dtlb_check_alias_11
1304         update_ptep     ptp,pte,t0,t1
1306         make_insert_tlb_11      spc,pte,prot
1308         mfsp            %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
1309         mtsp            spc,%sr1
1311         idtlba          pte,(%sr1,va)
1312         idtlbp          prot,(%sr1,va)
1314         mtsp            t0, %sr1        /* Restore sr1 */
1316         rfir
1317         nop
1319 dtlb_check_alias_11:
1321         /* Check to see if fault is in the temporary alias region */
1323         cmpib,<>,n      0,spc,dtlb_fault /* forward */
1324         ldil            L%(TMPALIAS_MAP_START),t0
1325         copy            va,t1
1326         depwi           0,31,23,t1
1327         cmpb,<>,n       t0,t1,dtlb_fault /* forward */
1328         ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot
1329         depw,z          prot,8,7,prot
1331         /*
1332          * OK, it is in the temp alias region, check whether "from" or "to".
1333          * Check "subtle" note in pacache.S re: r23/r26.
1334          */
1336         extrw,u,=       va,9,1,r0
1337         or,tr           %r23,%r0,pte    /* If "from" use "from" page */
1338         or              %r26,%r0,pte    /* else "to", use "to" page  */
1340         idtlba          pte,(va)
1341         idtlbp          prot,(va)
1343         rfir
1344         nop
1346 nadtlb_miss_11:
1347         get_pgd         spc,ptp
1349         space_check     spc,t0,nadtlb_fault
1351         L2_ptep         ptp,pte,t0,va,nadtlb_check_flush_11
1353         update_ptep     ptp,pte,t0,t1
1355         make_insert_tlb_11      spc,pte,prot
1358         mfsp            %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
1359         mtsp            spc,%sr1
1361         idtlba          pte,(%sr1,va)
1362         idtlbp          prot,(%sr1,va)
1364         mtsp            t0, %sr1        /* Restore sr1 */
1366         rfir
1367         nop
1369 nadtlb_check_flush_11:
1370         bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
1372         /* Insert a "flush only" translation */
1374         zdepi           7,7,3,prot
1375         depi            1,10,1,prot
1377         /* Get rid of prot bits and convert to page addr for idtlba */
1379         depi            0,31,12,pte
1380         extru           pte,24,25,pte
1382         mfsp            %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
1383         mtsp            spc,%sr1
1385         idtlba          pte,(%sr1,va)
1386         idtlbp          prot,(%sr1,va)
1388         mtsp            t0, %sr1        /* Restore sr1 */
1390         rfir
1391         nop
1393 dtlb_miss_20:
1394         space_adjust    spc,va,t0
1395         get_pgd         spc,ptp
1396         space_check     spc,t0,dtlb_fault
1398         L2_ptep         ptp,pte,t0,va,dtlb_check_alias_20
1400         update_ptep     ptp,pte,t0,t1
1402         make_insert_tlb spc,pte,prot
1404         f_extend        pte,t0
1406         idtlbt          pte,prot
1408         rfir
1409         nop
1411 dtlb_check_alias_20:
1412         do_alias        spc,t0,t1,va,pte,prot,dtlb_fault
1413         
1414         idtlbt          pte,prot
1416         rfir
1417         nop
1419 nadtlb_miss_20:
1420         get_pgd         spc,ptp
1422         space_check     spc,t0,nadtlb_fault
1424         L2_ptep         ptp,pte,t0,va,nadtlb_check_flush_20
1426         update_ptep     ptp,pte,t0,t1
1428         make_insert_tlb spc,pte,prot
1430         f_extend        pte,t0
1431         
1432         idtlbt          pte,prot
1434         rfir
1435         nop
1437 nadtlb_check_flush_20:
1438         bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
1440         /* Insert a "flush only" translation */
1442         depdi,z         7,7,3,prot
1443         depdi           1,10,1,prot
1445         /* Get rid of prot bits and convert to page addr for idtlbt */
1447         depdi           0,63,12,pte
1448         extrd,u         pte,56,32,pte
1449         idtlbt          pte,prot
1451         rfir
1452         nop
1453 #endif
1455 nadtlb_emulate:
1457         /*
1458          * Non access misses can be caused by fdc,fic,pdc,lpa,probe and
1459          * probei instructions. We don't want to fault for these
1460          * instructions (not only does it not make sense, it can cause
1461          * deadlocks, since some flushes are done with the mmap
1462          * semaphore held). If the translation doesn't exist, we can't
1463          * insert a translation, so have to emulate the side effects
1464          * of the instruction. Since we don't insert a translation
1465          * we can get a lot of faults during a flush loop, so it makes
1466          * sense to try to do it here with minimum overhead. We only
1467          * emulate fdc,fic,pdc,probew,prober instructions whose base 
1468          * and index registers are not shadowed. We defer everything 
1469          * else to the "slow" path.
1470          */
1472         mfctl           %cr19,%r9 /* Get iir */
1474         /* PA 2.0 Arch Ref. Book pg 382 has a good description of the insn bits.
1475            Checks for fdc,fdce,pdc,"fic,4f",prober,probeir,probew, probeiw */
1477         /* Checks for fdc,fdce,pdc,"fic,4f" only */
1478         ldi             0x280,%r16
1479         and             %r9,%r16,%r17
1480         cmpb,<>,n       %r16,%r17,nadtlb_probe_check
1481         bb,>=,n         %r9,26,nadtlb_nullify  /* m bit not set, just nullify */
1482         BL              get_register,%r25
1483         extrw,u         %r9,15,5,%r8           /* Get index register # */
1484         CMPIB=,n        -1,%r1,nadtlb_fault    /* have to use slow path */
1485         copy            %r1,%r24
1486         BL              get_register,%r25
1487         extrw,u         %r9,10,5,%r8           /* Get base register # */
1488         CMPIB=,n        -1,%r1,nadtlb_fault    /* have to use slow path */
1489         BL              set_register,%r25
1490         add,l           %r1,%r24,%r1           /* doesn't affect c/b bits */
1492 nadtlb_nullify:
1493         mfctl           %ipsw,%r8
1494         ldil            L%PSW_N,%r9
1495         or              %r8,%r9,%r8            /* Set PSW_N */
1496         mtctl           %r8,%ipsw
1498         rfir
1499         nop
1501         /* 
1502                 When there is no translation for the probe address then we
1503                 must nullify the insn and return zero in the target regsiter.
1504                 This will indicate to the calling code that it does not have 
1505                 write/read privileges to this address.
1507                 This should technically work for prober and probew in PA 1.1,
1508                 and also probe,r and probe,w in PA 2.0
1510                 WARNING: USE ONLY NON-SHADOW REGISTERS WITH PROBE INSN!
1511                 THE SLOW-PATH EMULATION HAS NOT BEEN WRITTEN YET.
1513         */
1514 nadtlb_probe_check:
1515         ldi             0x80,%r16
1516         and             %r9,%r16,%r17
1517         cmpb,<>,n       %r16,%r17,nadtlb_fault /* Must be probe,[rw]*/
1518         BL              get_register,%r25      /* Find the target register */
1519         extrw,u         %r9,31,5,%r8           /* Get target register */
1520         CMPIB=,n        -1,%r1,nadtlb_fault    /* have to use slow path */
1521         BL              set_register,%r25
1522         copy            %r0,%r1                /* Write zero to target register */
1523         b nadtlb_nullify                       /* Nullify return insn */
1524         nop
1527 #ifdef CONFIG_64BIT
1528 itlb_miss_20w:
1530         /*
1531          * I miss is a little different, since we allow users to fault
1532          * on the gateway page which is in the kernel address space.
1533          */
1535         space_adjust    spc,va,t0
1536         get_pgd         spc,ptp
1537         space_check     spc,t0,itlb_fault
1539         L3_ptep         ptp,pte,t0,va,itlb_fault
1541         update_ptep     ptp,pte,t0,t1
1543         make_insert_tlb spc,pte,prot
1544         
1545         iitlbt          pte,prot
1547         rfir
1548         nop
1550 #else
1552 itlb_miss_11:
1553         get_pgd         spc,ptp
1555         space_check     spc,t0,itlb_fault
1557         L2_ptep         ptp,pte,t0,va,itlb_fault
1559         update_ptep     ptp,pte,t0,t1
1561         make_insert_tlb_11      spc,pte,prot
1563         mfsp            %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
1564         mtsp            spc,%sr1
1566         iitlba          pte,(%sr1,va)
1567         iitlbp          prot,(%sr1,va)
1569         mtsp            t0, %sr1        /* Restore sr1 */
1571         rfir
1572         nop
1574 itlb_miss_20:
1575         get_pgd         spc,ptp
1577         space_check     spc,t0,itlb_fault
1579         L2_ptep         ptp,pte,t0,va,itlb_fault
1581         update_ptep     ptp,pte,t0,t1
1583         make_insert_tlb spc,pte,prot
1585         f_extend        pte,t0  
1587         iitlbt          pte,prot
1589         rfir
1590         nop
1592 #endif
1594 #ifdef CONFIG_64BIT
1596 dbit_trap_20w:
1597         space_adjust    spc,va,t0
1598         get_pgd         spc,ptp
1599         space_check     spc,t0,dbit_fault
1601         L3_ptep         ptp,pte,t0,va,dbit_fault
1603 #ifdef CONFIG_SMP
1604         CMPIB=,n        0,spc,dbit_nolock_20w
1605         load32          PA(pa_dbit_lock),t0
1607 dbit_spin_20w:
1608         LDCW            0(t0),t1
1609         cmpib,=         0,t1,dbit_spin_20w
1610         nop
1612 dbit_nolock_20w:
1613 #endif
1614         update_dirty    ptp,pte,t1
1616         make_insert_tlb spc,pte,prot
1617                 
1618         idtlbt          pte,prot
1619 #ifdef CONFIG_SMP
1620         CMPIB=,n        0,spc,dbit_nounlock_20w
1621         ldi             1,t1
1622         stw             t1,0(t0)
1624 dbit_nounlock_20w:
1625 #endif
1627         rfir
1628         nop
1629 #else
1631 dbit_trap_11:
1633         get_pgd         spc,ptp
1635         space_check     spc,t0,dbit_fault
1637         L2_ptep         ptp,pte,t0,va,dbit_fault
1639 #ifdef CONFIG_SMP
1640         CMPIB=,n        0,spc,dbit_nolock_11
1641         load32          PA(pa_dbit_lock),t0
1643 dbit_spin_11:
1644         LDCW            0(t0),t1
1645         cmpib,=         0,t1,dbit_spin_11
1646         nop
1648 dbit_nolock_11:
1649 #endif
1650         update_dirty    ptp,pte,t1
1652         make_insert_tlb_11      spc,pte,prot
1654         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1655         mtsp            spc,%sr1
1657         idtlba          pte,(%sr1,va)
1658         idtlbp          prot,(%sr1,va)
1660         mtsp            t1, %sr1     /* Restore sr1 */
1661 #ifdef CONFIG_SMP
1662         CMPIB=,n        0,spc,dbit_nounlock_11
1663         ldi             1,t1
1664         stw             t1,0(t0)
1666 dbit_nounlock_11:
1667 #endif
1669         rfir
1670         nop
1672 dbit_trap_20:
1673         get_pgd         spc,ptp
1675         space_check     spc,t0,dbit_fault
1677         L2_ptep         ptp,pte,t0,va,dbit_fault
1679 #ifdef CONFIG_SMP
1680         CMPIB=,n        0,spc,dbit_nolock_20
1681         load32          PA(pa_dbit_lock),t0
1683 dbit_spin_20:
1684         LDCW            0(t0),t1
1685         cmpib,=         0,t1,dbit_spin_20
1686         nop
1688 dbit_nolock_20:
1689 #endif
1690         update_dirty    ptp,pte,t1
1692         make_insert_tlb spc,pte,prot
1694         f_extend        pte,t1
1695         
1696         idtlbt          pte,prot
1698 #ifdef CONFIG_SMP
1699         CMPIB=,n        0,spc,dbit_nounlock_20
1700         ldi             1,t1
1701         stw             t1,0(t0)
1703 dbit_nounlock_20:
1704 #endif
1706         rfir
1707         nop
1708 #endif
1710         .import handle_interruption,code
1712 kernel_bad_space:
1713         b               intr_save
1714         ldi             31,%r8  /* Use an unused code */
1716 dbit_fault:
1717         b               intr_save
1718         ldi             20,%r8
1720 itlb_fault:
1721         b               intr_save
1722         ldi             6,%r8
1724 nadtlb_fault:
1725         b               intr_save
1726         ldi             17,%r8
1728 dtlb_fault:
1729         b               intr_save
1730         ldi             15,%r8
1732         /* Register saving semantics for system calls:
1734            %r1             clobbered by system call macro in userspace
1735            %r2             saved in PT_REGS by gateway page
1736            %r3  - %r18     preserved by C code (saved by signal code)
1737            %r19 - %r20     saved in PT_REGS by gateway page
1738            %r21 - %r22     non-standard syscall args
1739                            stored in kernel stack by gateway page
1740            %r23 - %r26     arg3-arg0, saved in PT_REGS by gateway page
1741            %r27 - %r30     saved in PT_REGS by gateway page
1742            %r31            syscall return pointer
1743          */
1745         /* Floating point registers (FIXME: what do we do with these?)
1747            %fr0  - %fr3    status/exception, not preserved
1748            %fr4  - %fr7    arguments
1749            %fr8  - %fr11   not preserved by C code
1750            %fr12 - %fr21   preserved by C code
1751            %fr22 - %fr31   not preserved by C code
1752          */
1754         .macro  reg_save regs
1755         STREG   %r3, PT_GR3(\regs)
1756         STREG   %r4, PT_GR4(\regs)
1757         STREG   %r5, PT_GR5(\regs)
1758         STREG   %r6, PT_GR6(\regs)
1759         STREG   %r7, PT_GR7(\regs)
1760         STREG   %r8, PT_GR8(\regs)
1761         STREG   %r9, PT_GR9(\regs)
1762         STREG   %r10,PT_GR10(\regs)
1763         STREG   %r11,PT_GR11(\regs)
1764         STREG   %r12,PT_GR12(\regs)
1765         STREG   %r13,PT_GR13(\regs)
1766         STREG   %r14,PT_GR14(\regs)
1767         STREG   %r15,PT_GR15(\regs)
1768         STREG   %r16,PT_GR16(\regs)
1769         STREG   %r17,PT_GR17(\regs)
1770         STREG   %r18,PT_GR18(\regs)
1771         .endm
1773         .macro  reg_restore regs
1774         LDREG   PT_GR3(\regs), %r3
1775         LDREG   PT_GR4(\regs), %r4
1776         LDREG   PT_GR5(\regs), %r5
1777         LDREG   PT_GR6(\regs), %r6
1778         LDREG   PT_GR7(\regs), %r7
1779         LDREG   PT_GR8(\regs), %r8
1780         LDREG   PT_GR9(\regs), %r9
1781         LDREG   PT_GR10(\regs),%r10
1782         LDREG   PT_GR11(\regs),%r11
1783         LDREG   PT_GR12(\regs),%r12
1784         LDREG   PT_GR13(\regs),%r13
1785         LDREG   PT_GR14(\regs),%r14
1786         LDREG   PT_GR15(\regs),%r15
1787         LDREG   PT_GR16(\regs),%r16
1788         LDREG   PT_GR17(\regs),%r17
1789         LDREG   PT_GR18(\regs),%r18
1790         .endm
1792 ENTRY(sys_fork_wrapper)
1793         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
1794         ldo     TASK_REGS(%r1),%r1
1795         reg_save %r1
1796         mfctl   %cr27, %r3
1797         STREG   %r3, PT_CR27(%r1)
1799         STREG   %r2,-RP_OFFSET(%r30)
1800         ldo     FRAME_SIZE(%r30),%r30
1801 #ifdef CONFIG_64BIT
1802         ldo     -16(%r30),%r29          /* Reference param save area */
1803 #endif
1805         /* These are call-clobbered registers and therefore
1806            also syscall-clobbered (we hope). */
1807         STREG   %r2,PT_GR19(%r1)        /* save for child */
1808         STREG   %r30,PT_GR21(%r1)
1810         LDREG   PT_GR30(%r1),%r25
1811         copy    %r1,%r24
1812         BL      sys_clone,%r2
1813         ldi     SIGCHLD,%r26
1815         LDREG   -RP_OFFSET-FRAME_SIZE(%r30),%r2
1816 wrapper_exit:
1817         ldo     -FRAME_SIZE(%r30),%r30          /* get the stackframe */
1818         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1819         ldo     TASK_REGS(%r1),%r1       /* get pt regs */
1821         LDREG   PT_CR27(%r1), %r3
1822         mtctl   %r3, %cr27
1823         reg_restore %r1
1825         /* strace expects syscall # to be preserved in r20 */
1826         ldi     __NR_fork,%r20
1827         bv %r0(%r2)
1828         STREG   %r20,PT_GR20(%r1)
1829 ENDPROC(sys_fork_wrapper)
1831         /* Set the return value for the child */
1832 ENTRY(child_return)
1833         BL      schedule_tail, %r2
1834         nop
1836         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%r30), %r1
1837         LDREG   TASK_PT_GR19(%r1),%r2
1838         b       wrapper_exit
1839         copy    %r0,%r28
1840 ENDPROC(child_return)
1843 ENTRY(sys_clone_wrapper)
1844         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1845         ldo     TASK_REGS(%r1),%r1      /* get pt regs */
1846         reg_save %r1
1847         mfctl   %cr27, %r3
1848         STREG   %r3, PT_CR27(%r1)
1850         STREG   %r2,-RP_OFFSET(%r30)
1851         ldo     FRAME_SIZE(%r30),%r30
1852 #ifdef CONFIG_64BIT
1853         ldo     -16(%r30),%r29          /* Reference param save area */
1854 #endif
1856         /* WARNING - Clobbers r19 and r21, userspace must save these! */
1857         STREG   %r2,PT_GR19(%r1)        /* save for child */
1858         STREG   %r30,PT_GR21(%r1)
1859         BL      sys_clone,%r2
1860         copy    %r1,%r24
1862         b       wrapper_exit
1863         LDREG   -RP_OFFSET-FRAME_SIZE(%r30),%r2
1864 ENDPROC(sys_clone_wrapper)
1867 ENTRY(sys_vfork_wrapper)
1868         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1869         ldo     TASK_REGS(%r1),%r1      /* get pt regs */
1870         reg_save %r1
1871         mfctl   %cr27, %r3
1872         STREG   %r3, PT_CR27(%r1)
1874         STREG   %r2,-RP_OFFSET(%r30)
1875         ldo     FRAME_SIZE(%r30),%r30
1876 #ifdef CONFIG_64BIT
1877         ldo     -16(%r30),%r29          /* Reference param save area */
1878 #endif
1880         STREG   %r2,PT_GR19(%r1)        /* save for child */
1881         STREG   %r30,PT_GR21(%r1)
1883         BL      sys_vfork,%r2
1884         copy    %r1,%r26
1886         b       wrapper_exit
1887         LDREG   -RP_OFFSET-FRAME_SIZE(%r30),%r2
1888 ENDPROC(sys_vfork_wrapper)
1890         
1891         .macro  execve_wrapper execve
1892         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1893         ldo     TASK_REGS(%r1),%r1      /* get pt regs */
1895         /*
1896          * Do we need to save/restore r3-r18 here?
1897          * I don't think so. why would new thread need old
1898          * threads registers?
1899          */
1901         /* %arg0 - %arg3 are already saved for us. */
1903         STREG %r2,-RP_OFFSET(%r30)
1904         ldo FRAME_SIZE(%r30),%r30
1905 #ifdef CONFIG_64BIT
1906         ldo     -16(%r30),%r29          /* Reference param save area */
1907 #endif
1908         BL \execve,%r2
1909         copy %r1,%arg0
1911         ldo -FRAME_SIZE(%r30),%r30
1912         LDREG -RP_OFFSET(%r30),%r2
1914         /* If exec succeeded we need to load the args */
1916         ldo -1024(%r0),%r1
1917         cmpb,>>= %r28,%r1,error_\execve
1918         copy %r2,%r19
1920 error_\execve:
1921         bv %r0(%r19)
1922         nop
1923         .endm
1925         .import sys_execve
1926 ENTRY(sys_execve_wrapper)
1927         execve_wrapper sys_execve
1928 ENDPROC(sys_execve_wrapper)
1930 #ifdef CONFIG_64BIT
1931         .import sys32_execve
1932 ENTRY(sys32_execve_wrapper)
1933         execve_wrapper sys32_execve
1934 ENDPROC(sys32_execve_wrapper)
1935 #endif
1937 ENTRY(sys_rt_sigreturn_wrapper)
1938         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
1939         ldo     TASK_REGS(%r26),%r26    /* get pt regs */
1940         /* Don't save regs, we are going to restore them from sigcontext. */
1941         STREG   %r2, -RP_OFFSET(%r30)
1942 #ifdef CONFIG_64BIT
1943         ldo     FRAME_SIZE(%r30), %r30
1944         BL      sys_rt_sigreturn,%r2
1945         ldo     -16(%r30),%r29          /* Reference param save area */
1946 #else
1947         BL      sys_rt_sigreturn,%r2
1948         ldo     FRAME_SIZE(%r30), %r30
1949 #endif
1951         ldo     -FRAME_SIZE(%r30), %r30
1952         LDREG   -RP_OFFSET(%r30), %r2
1954         /* FIXME: I think we need to restore a few more things here. */
1955         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1956         ldo     TASK_REGS(%r1),%r1      /* get pt regs */
1957         reg_restore %r1
1959         /* If the signal was received while the process was blocked on a
1960          * syscall, then r2 will take us to syscall_exit; otherwise r2 will
1961          * take us to syscall_exit_rfi and on to intr_return.
1962          */
1963         bv      %r0(%r2)
1964         LDREG   PT_GR28(%r1),%r28  /* reload original r28 for syscall_exit */
1965 ENDPROC(sys_rt_sigreturn_wrapper)
1967 ENTRY(sys_sigaltstack_wrapper)
1968         /* Get the user stack pointer */
1969         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1970         ldo     TASK_REGS(%r1),%r24     /* get pt regs */
1971         LDREG   TASK_PT_GR30(%r24),%r24
1972         STREG   %r2, -RP_OFFSET(%r30)
1973 #ifdef CONFIG_64BIT
1974         ldo     FRAME_SIZE(%r30), %r30
1975         BL      do_sigaltstack,%r2
1976         ldo     -16(%r30),%r29          /* Reference param save area */
1977 #else
1978         BL      do_sigaltstack,%r2
1979         ldo     FRAME_SIZE(%r30), %r30
1980 #endif
1982         ldo     -FRAME_SIZE(%r30), %r30
1983         LDREG   -RP_OFFSET(%r30), %r2
1984         bv      %r0(%r2)
1985         nop
1986 ENDPROC(sys_sigaltstack_wrapper)
1988 #ifdef CONFIG_64BIT
1989 ENTRY(sys32_sigaltstack_wrapper)
1990         /* Get the user stack pointer */
1991         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r24
1992         LDREG   TASK_PT_GR30(%r24),%r24
1993         STREG   %r2, -RP_OFFSET(%r30)
1994         ldo     FRAME_SIZE(%r30), %r30
1995         BL      do_sigaltstack32,%r2
1996         ldo     -16(%r30),%r29          /* Reference param save area */
1998         ldo     -FRAME_SIZE(%r30), %r30
1999         LDREG   -RP_OFFSET(%r30), %r2
2000         bv      %r0(%r2)
2001         nop
2002 ENDPROC(sys32_sigaltstack_wrapper)
2003 #endif
2005 ENTRY(syscall_exit)
2006         /* NOTE: HP-UX syscalls also come through here
2007          * after hpux_syscall_exit fixes up return
2008          * values. */
2010         /* NOTE: Not all syscalls exit this way.  rt_sigreturn will exit
2011          * via syscall_exit_rfi if the signal was received while the process
2012          * was running.
2013          */
2015         /* save return value now */
2017         mfctl     %cr30, %r1
2018         LDREG     TI_TASK(%r1),%r1
2019         STREG     %r28,TASK_PT_GR28(%r1)
2021 #ifdef CONFIG_HPUX
2023 /* <linux/personality.h> cannot be easily included */
2024 #define PER_HPUX 0x10
2025         LDREG     TASK_PERSONALITY(%r1),%r19
2027         /* We can't use "CMPIB<> PER_HPUX" since "im5" field is sign extended */
2028         ldo       -PER_HPUX(%r19), %r19
2029         CMPIB<>,n 0,%r19,1f
2031         /* Save other hpux returns if personality is PER_HPUX */
2032         STREG     %r22,TASK_PT_GR22(%r1)
2033         STREG     %r29,TASK_PT_GR29(%r1)
2036 #endif /* CONFIG_HPUX */
2038         /* Seems to me that dp could be wrong here, if the syscall involved
2039          * calling a module, and nothing got round to restoring dp on return.
2040          */
2041         loadgp
2043 syscall_check_resched:
2045         /* check for reschedule */
2047         LDREG   TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19   /* long */
2048         bb,<,n  %r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */
2050         .import do_signal,code
2051 syscall_check_sig:
2052         LDREG   TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19
2053         ldi     (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %r26
2054         and,COND(<>)    %r19, %r26, %r0
2055         b,n     syscall_restore /* skip past if we've nothing to do */
2057 syscall_do_signal:
2058         /* Save callee-save registers (for sigcontext).
2059          * FIXME: After this point the process structure should be
2060          * consistent with all the relevant state of the process
2061          * before the syscall.  We need to verify this.
2062          */
2063         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
2064         ldo     TASK_REGS(%r1), %r26            /* struct pt_regs *regs */
2065         reg_save %r26
2067 #ifdef CONFIG_64BIT
2068         ldo     -16(%r30),%r29                  /* Reference param save area */
2069 #endif
2071         BL      do_notify_resume,%r2
2072         ldi     1, %r25                         /* long in_syscall = 1 */
2074         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
2075         ldo     TASK_REGS(%r1), %r20            /* reload pt_regs */
2076         reg_restore %r20
2078         b,n     syscall_check_sig
2080 syscall_restore:
2081         /* Are we being ptraced? */
2082         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
2084         LDREG   TASK_PTRACE(%r1), %r19
2085         bb,<    %r19,31,syscall_restore_rfi
2086         nop
2088         ldo     TASK_PT_FR31(%r1),%r19             /* reload fpregs */
2089         rest_fp %r19
2091         LDREG   TASK_PT_SAR(%r1),%r19              /* restore SAR */
2092         mtsar   %r19
2094         LDREG   TASK_PT_GR2(%r1),%r2               /* restore user rp */
2095         LDREG   TASK_PT_GR19(%r1),%r19
2096         LDREG   TASK_PT_GR20(%r1),%r20
2097         LDREG   TASK_PT_GR21(%r1),%r21
2098         LDREG   TASK_PT_GR22(%r1),%r22
2099         LDREG   TASK_PT_GR23(%r1),%r23
2100         LDREG   TASK_PT_GR24(%r1),%r24
2101         LDREG   TASK_PT_GR25(%r1),%r25
2102         LDREG   TASK_PT_GR26(%r1),%r26
2103         LDREG   TASK_PT_GR27(%r1),%r27     /* restore user dp */
2104         LDREG   TASK_PT_GR28(%r1),%r28     /* syscall return value */
2105         LDREG   TASK_PT_GR29(%r1),%r29
2106         LDREG   TASK_PT_GR31(%r1),%r31     /* restore syscall rp */
2108         /* NOTE: We use rsm/ssm pair to make this operation atomic */
2109         rsm     PSW_SM_I, %r0
2110         LDREG   TASK_PT_GR30(%r1),%r30             /* restore user sp */
2111         mfsp    %sr3,%r1                           /* Get users space id */
2112         mtsp    %r1,%sr7                           /* Restore sr7 */
2113         ssm     PSW_SM_I, %r0
2115         /* Set sr2 to zero for userspace syscalls to work. */
2116         mtsp    %r0,%sr2 
2117         mtsp    %r1,%sr4                           /* Restore sr4 */
2118         mtsp    %r1,%sr5                           /* Restore sr5 */
2119         mtsp    %r1,%sr6                           /* Restore sr6 */
2121         depi    3,31,2,%r31                        /* ensure return to user mode. */
2123 #ifdef CONFIG_64BIT
2124         /* decide whether to reset the wide mode bit
2125          *
2126          * For a syscall, the W bit is stored in the lowest bit
2127          * of sp.  Extract it and reset W if it is zero */
2128         extrd,u,*<>     %r30,63,1,%r1
2129         rsm     PSW_SM_W, %r0
2130         /* now reset the lowest bit of sp if it was set */
2131         xor     %r30,%r1,%r30
2132 #endif
2133         be,n    0(%sr3,%r31)                       /* return to user space */
2135         /* We have to return via an RFI, so that PSW T and R bits can be set
2136          * appropriately.
2137          * This sets up pt_regs so we can return via intr_restore, which is not
2138          * the most efficient way of doing things, but it works.
2139          */
2140 syscall_restore_rfi:
2141         ldo     -1(%r0),%r2                        /* Set recovery cntr to -1 */
2142         mtctl   %r2,%cr0                           /*   for immediate trap */
2143         LDREG   TASK_PT_PSW(%r1),%r2               /* Get old PSW */
2144         ldi     0x0b,%r20                          /* Create new PSW */
2145         depi    -1,13,1,%r20                       /* C, Q, D, and I bits */
2147         /* The values of PA_SINGLESTEP_BIT and PA_BLOCKSTEP_BIT are
2148          * set in include/linux/ptrace.h and converted to PA bitmap
2149          * numbers in asm-offsets.c */
2151         /* if ((%r19.PA_SINGLESTEP_BIT)) { %r20.27=1} */
2152         extru,= %r19,PA_SINGLESTEP_BIT,1,%r0
2153         depi    -1,27,1,%r20                       /* R bit */
2155         /* if ((%r19.PA_BLOCKSTEP_BIT)) { %r20.7=1} */
2156         extru,= %r19,PA_BLOCKSTEP_BIT,1,%r0
2157         depi    -1,7,1,%r20                        /* T bit */
2159         STREG   %r20,TASK_PT_PSW(%r1)
2161         /* Always store space registers, since sr3 can be changed (e.g. fork) */
2163         mfsp    %sr3,%r25
2164         STREG   %r25,TASK_PT_SR3(%r1)
2165         STREG   %r25,TASK_PT_SR4(%r1)
2166         STREG   %r25,TASK_PT_SR5(%r1)
2167         STREG   %r25,TASK_PT_SR6(%r1)
2168         STREG   %r25,TASK_PT_SR7(%r1)
2169         STREG   %r25,TASK_PT_IASQ0(%r1)
2170         STREG   %r25,TASK_PT_IASQ1(%r1)
2172         /* XXX W bit??? */
2173         /* Now if old D bit is clear, it means we didn't save all registers
2174          * on syscall entry, so do that now.  This only happens on TRACEME
2175          * calls, or if someone attached to us while we were on a syscall.
2176          * We could make this more efficient by not saving r3-r18, but
2177          * then we wouldn't be able to use the common intr_restore path.
2178          * It is only for traced processes anyway, so performance is not
2179          * an issue.
2180          */
2181         bb,<    %r2,30,pt_regs_ok                  /* Branch if D set */
2182         ldo     TASK_REGS(%r1),%r25
2183         reg_save %r25                              /* Save r3 to r18 */
2185         /* Save the current sr */
2186         mfsp    %sr0,%r2
2187         STREG   %r2,TASK_PT_SR0(%r1)
2189         /* Save the scratch sr */
2190         mfsp    %sr1,%r2
2191         STREG   %r2,TASK_PT_SR1(%r1)
2193         /* sr2 should be set to zero for userspace syscalls */
2194         STREG   %r0,TASK_PT_SR2(%r1)
2196 pt_regs_ok:
2197         LDREG   TASK_PT_GR31(%r1),%r2
2198         depi    3,31,2,%r2                         /* ensure return to user mode. */
2199         STREG   %r2,TASK_PT_IAOQ0(%r1)
2200         ldo     4(%r2),%r2
2201         STREG   %r2,TASK_PT_IAOQ1(%r1)
2202         copy    %r25,%r16
2203         b       intr_restore
2204         nop
2206         .import schedule,code
2207 syscall_do_resched:
2208         BL      schedule,%r2
2209 #ifdef CONFIG_64BIT
2210         ldo     -16(%r30),%r29          /* Reference param save area */
2211 #else
2212         nop
2213 #endif
2214         b       syscall_check_resched   /* if resched, we start over again */
2215         nop
2216 ENDPROC(syscall_exit)
2219 get_register:
2220         /*
2221          * get_register is used by the non access tlb miss handlers to
2222          * copy the value of the general register specified in r8 into
2223          * r1. This routine can't be used for shadowed registers, since
2224          * the rfir will restore the original value. So, for the shadowed
2225          * registers we put a -1 into r1 to indicate that the register
2226          * should not be used (the register being copied could also have
2227          * a -1 in it, but that is OK, it just means that we will have
2228          * to use the slow path instead).
2229          */
2230         blr     %r8,%r0
2231         nop
2232         bv      %r0(%r25)    /* r0 */
2233         copy    %r0,%r1
2234         bv      %r0(%r25)    /* r1 - shadowed */
2235         ldi     -1,%r1
2236         bv      %r0(%r25)    /* r2 */
2237         copy    %r2,%r1
2238         bv      %r0(%r25)    /* r3 */
2239         copy    %r3,%r1
2240         bv      %r0(%r25)    /* r4 */
2241         copy    %r4,%r1
2242         bv      %r0(%r25)    /* r5 */
2243         copy    %r5,%r1
2244         bv      %r0(%r25)    /* r6 */
2245         copy    %r6,%r1
2246         bv      %r0(%r25)    /* r7 */
2247         copy    %r7,%r1
2248         bv      %r0(%r25)    /* r8 - shadowed */
2249         ldi     -1,%r1
2250         bv      %r0(%r25)    /* r9 - shadowed */
2251         ldi     -1,%r1
2252         bv      %r0(%r25)    /* r10 */
2253         copy    %r10,%r1
2254         bv      %r0(%r25)    /* r11 */
2255         copy    %r11,%r1
2256         bv      %r0(%r25)    /* r12 */
2257         copy    %r12,%r1
2258         bv      %r0(%r25)    /* r13 */
2259         copy    %r13,%r1
2260         bv      %r0(%r25)    /* r14 */
2261         copy    %r14,%r1
2262         bv      %r0(%r25)    /* r15 */
2263         copy    %r15,%r1
2264         bv      %r0(%r25)    /* r16 - shadowed */
2265         ldi     -1,%r1
2266         bv      %r0(%r25)    /* r17 - shadowed */
2267         ldi     -1,%r1
2268         bv      %r0(%r25)    /* r18 */
2269         copy    %r18,%r1
2270         bv      %r0(%r25)    /* r19 */
2271         copy    %r19,%r1
2272         bv      %r0(%r25)    /* r20 */
2273         copy    %r20,%r1
2274         bv      %r0(%r25)    /* r21 */
2275         copy    %r21,%r1
2276         bv      %r0(%r25)    /* r22 */
2277         copy    %r22,%r1
2278         bv      %r0(%r25)    /* r23 */
2279         copy    %r23,%r1
2280         bv      %r0(%r25)    /* r24 - shadowed */
2281         ldi     -1,%r1
2282         bv      %r0(%r25)    /* r25 - shadowed */
2283         ldi     -1,%r1
2284         bv      %r0(%r25)    /* r26 */
2285         copy    %r26,%r1
2286         bv      %r0(%r25)    /* r27 */
2287         copy    %r27,%r1
2288         bv      %r0(%r25)    /* r28 */
2289         copy    %r28,%r1
2290         bv      %r0(%r25)    /* r29 */
2291         copy    %r29,%r1
2292         bv      %r0(%r25)    /* r30 */
2293         copy    %r30,%r1
2294         bv      %r0(%r25)    /* r31 */
2295         copy    %r31,%r1
2298 set_register:
2299         /*
2300          * set_register is used by the non access tlb miss handlers to
2301          * copy the value of r1 into the general register specified in
2302          * r8.
2303          */
2304         blr     %r8,%r0
2305         nop
2306         bv      %r0(%r25)    /* r0 (silly, but it is a place holder) */
2307         copy    %r1,%r0
2308         bv      %r0(%r25)    /* r1 */
2309         copy    %r1,%r1
2310         bv      %r0(%r25)    /* r2 */
2311         copy    %r1,%r2
2312         bv      %r0(%r25)    /* r3 */
2313         copy    %r1,%r3
2314         bv      %r0(%r25)    /* r4 */
2315         copy    %r1,%r4
2316         bv      %r0(%r25)    /* r5 */
2317         copy    %r1,%r5
2318         bv      %r0(%r25)    /* r6 */
2319         copy    %r1,%r6
2320         bv      %r0(%r25)    /* r7 */
2321         copy    %r1,%r7
2322         bv      %r0(%r25)    /* r8 */
2323         copy    %r1,%r8
2324         bv      %r0(%r25)    /* r9 */
2325         copy    %r1,%r9
2326         bv      %r0(%r25)    /* r10 */
2327         copy    %r1,%r10
2328         bv      %r0(%r25)    /* r11 */
2329         copy    %r1,%r11
2330         bv      %r0(%r25)    /* r12 */
2331         copy    %r1,%r12
2332         bv      %r0(%r25)    /* r13 */
2333         copy    %r1,%r13
2334         bv      %r0(%r25)    /* r14 */
2335         copy    %r1,%r14
2336         bv      %r0(%r25)    /* r15 */
2337         copy    %r1,%r15
2338         bv      %r0(%r25)    /* r16 */
2339         copy    %r1,%r16
2340         bv      %r0(%r25)    /* r17 */
2341         copy    %r1,%r17
2342         bv      %r0(%r25)    /* r18 */
2343         copy    %r1,%r18
2344         bv      %r0(%r25)    /* r19 */
2345         copy    %r1,%r19
2346         bv      %r0(%r25)    /* r20 */
2347         copy    %r1,%r20
2348         bv      %r0(%r25)    /* r21 */
2349         copy    %r1,%r21
2350         bv      %r0(%r25)    /* r22 */
2351         copy    %r1,%r22
2352         bv      %r0(%r25)    /* r23 */
2353         copy    %r1,%r23
2354         bv      %r0(%r25)    /* r24 */
2355         copy    %r1,%r24
2356         bv      %r0(%r25)    /* r25 */
2357         copy    %r1,%r25
2358         bv      %r0(%r25)    /* r26 */
2359         copy    %r1,%r26
2360         bv      %r0(%r25)    /* r27 */
2361         copy    %r1,%r27
2362         bv      %r0(%r25)    /* r28 */
2363         copy    %r1,%r28
2364         bv      %r0(%r25)    /* r29 */
2365         copy    %r1,%r29
2366         bv      %r0(%r25)    /* r30 */
2367         copy    %r1,%r30
2368         bv      %r0(%r25)    /* r31 */
2369         copy    %r1,%r31