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