Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/cpufreq
[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 #define CMPIB           cmpib,*
44 #define CMPB            cmpb,*
45 #define COND(x)         *x
46
47         .level 2.0w
48 #else
49 #define CMPIB           cmpib,
50 #define CMPB            cmpb,
51 #define COND(x)         x
52
53         .level 2.0
54 #endif
55
56         .import         pa_dbit_lock,data
57
58         /* space_to_prot macro creates a prot id from a space id */
59
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
69
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
81
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
94 4:
95         .endm
96
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          */
146
147         .macro  get_stack_use_cr30
148
149         /* we save the registers in the task struct */
150
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
163
164         .macro  get_stack_use_r30
165
166         /* we put a struct pt_regs on the stack and save the registers there */
167
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
175
176         .macro  rest_stack
177         LDREG   PT_GR1(%r29), %r1
178         LDREG   PT_GR30(%r29),%r30
179         LDREG   PT_GR29(%r29),%r29
180         .endm
181
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
189
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   
197
198         .import os_hpmc, code
199
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
210
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          */
216
217         /* Register definitions for tlb miss handler macros */
218
219         va  = r8        /* virtual address for which the trap occured */
220         spc = r24       /* space for which the trap occured */
221
222 #ifndef CONFIG_64BIT
223
224         /*
225          * itlb miss interruption handler (parisc 1.1 - 32 bit)
226          */
227
228         .macro  itlb_11 code
229
230         mfctl   %pcsq, spc
231         b       itlb_miss_11
232         mfctl   %pcoq, va
233
234         .align          32
235         .endm
236 #endif
237         
238         /*
239          * itlb miss interruption handler (parisc 2.0)
240          */
241
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
250
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          */
264
265         .macro  naitlb_11 code
266
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          */
273
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          */
287
288         .macro  naitlb_20 code
289
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          */
300
301         .align          32
302         .endm
303         
304 #ifndef CONFIG_64BIT
305         /*
306          * dtlb miss interruption handler (parisc 1.1 - 32 bit)
307          */
308
309         .macro  dtlb_11 code
310
311         mfctl   %isr, spc
312         b       dtlb_miss_11
313         mfctl   %ior, va
314
315         .align          32
316         .endm
317 #endif
318
319         /*
320          * dtlb miss interruption handler (parisc 2.0)
321          */
322
323         .macro  dtlb_20 code
324
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
332
333         .align          32
334         .endm
335         
336 #ifndef CONFIG_64BIT
337         /* nadtlb miss interruption handler (parisc 1.1 - 32 bit) */
338
339         .macro  nadtlb_11 code
340
341         mfctl   %isr,spc
342         b       nadtlb_miss_11
343         mfctl   %ior,va
344
345         .align          32
346         .endm
347 #endif
348         
349         /* nadtlb miss interruption handler (parisc 2.0) */
350
351         .macro  nadtlb_20 code
352
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
360
361         .align          32
362         .endm
363         
364 #ifndef CONFIG_64BIT
365         /*
366          * dirty bit trap interruption handler (parisc 1.1 - 32 bit)
367          */
368
369         .macro  dbit_11 code
370
371         mfctl   %isr,spc
372         b       dbit_trap_11
373         mfctl   %ior,va
374
375         .align          32
376         .endm
377 #endif
378
379         /*
380          * dirty bit trap interruption handler (parisc 2.0)
381          */
382
383         .macro  dbit_20 code
384
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
392
393         .align          32
394         .endm
395
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
405
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
413
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
421
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
432
433         .import         swapper_pg_dir,code
434
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
444
445         /* 
446                 space_check(spc,tmp,fault)
447
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.
451
452                 Only allow faults on different spaces from the
453                 currently active one if we're the kernel 
454
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
465
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
491
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
519
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
528
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
536
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
554
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 */
565
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
574
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
579
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 */
592
593         /* Get rid of prot bits and convert to page addr for iitlba */
594
595         depi            _PAGE_SIZE_ENCODING_DEFAULT,31,ASM_PFN_PTE_SHIFT,\pte
596         extru           \pte,24,25,\pte
597         .endm
598
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
608
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 
642
643
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          */
652
653         .text
654
655         .align 4096
656
657 ENTRY(fault_vector_20)
658         /* First vector is invalid (0) */
659         .ascii  "cows can fly"
660         .byte 0
661         .align 32
662
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)
699
700 #ifndef CONFIG_64BIT
701
702         .align 2048
703
704 ENTRY(fault_vector_11)
705         /* First vector is invalid (0) */
706         .ascii  "cows can fly"
707         .byte 0
708         .align 32
709
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)
746
747 #endif
748
749         .import         handle_interruption,code
750         .import         do_cpu_irq_mask,code
751
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          */
761
762 #define CLONE_VM 0x100  /* Must agree with <linux/sched.h> */
763 #define CLONE_UNTRACED 0x00800000
764
765         .import do_fork
766 ENTRY(__kernel_thread)
767         STREG   %r2, -RP_OFFSET(%r30)
768
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
776
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 */
792
793         /* Parent Returns here */
794
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)
800
801         /*
802          * Child Returns here
803          *
804          * copy_thread moved args from temp save area set up above
805          * into task save area.
806          */
807
808 ENTRY(ret_from_kernel_thread)
809
810         /* Call schedule_tail first though */
811         BL      schedule_tail, %r2
812         nop
813
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
823
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)
836
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
850
851         cmpib,=,n 0,%r28,intr_return    /* forward */
852
853         /* yes, this will trap and die. */
854         copy    %r15, %r2
855         copy    %r16, %r30
856         bv      %r0(%r2)
857         nop
858 ENDPROC(__execve)
859
860
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)
868
869         callee_save_float
870         callee_save
871
872         load32  _switch_to_ret, %r2
873
874         STREG   %r2, TASK_PT_KPC(%r26)
875         LDREG   TASK_PT_KPC(%r25), %r2
876
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
882
883 _switch_to_ret:
884         mtctl   %r0, %cr0               /* Needed for single stepping */
885         callee_rest
886         callee_rest_float
887
888         LDREG   -RP_OFFSET(%r30), %r2
889         bv      %r0(%r2)
890         copy    %r26, %r28
891 ENDPROC(_switch_to)
892
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          */
906
907         .align 4096
908
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)
932
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          */
942
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)
952
953 intr_return:
954         /* NOTE: Need to enable interrupts incase we schedule. */
955         ssm     PSW_SM_I, %r0
956
957         /* Check for software interrupts */
958
959         .import irq_stat,data
960
961         load32  irq_stat,%r19
962 #ifdef CONFIG_SMP
963         mfctl   %cr30,%r1
964         ldw     TI_CPU(%r1),%r1 /* get cpu # - int */
965         /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) amount
966         ** irq_stat[] is defined using ____cacheline_aligned.
967         */
968         SHLREG  %r1,L1_CACHE_SHIFT,%r20
969         add     %r19,%r20,%r19  /* now have &irq_stat[smp_processor_id()] */
970 #endif /* CONFIG_SMP */
971
972 intr_check_resched:
973
974         /* check for reschedule */
975         mfctl   %cr30,%r1
976         LDREG   TI_FLAGS(%r1),%r19      /* sched.h: TIF_NEED_RESCHED */
977         bb,<,n  %r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */
978
979         .import do_notify_resume,code
980 intr_check_sig:
981         /* As above */
982         mfctl   %cr30,%r1
983         LDREG   TI_FLAGS(%r1),%r19
984         ldi     (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %r20
985         and,COND(<>)    %r19, %r20, %r0
986         b,n     intr_restore    /* skip past if we've nothing to do */
987
988         /* This check is critical to having LWS
989          * working. The IASQ is zero on the gateway
990          * page and we cannot deliver any signals until
991          * we get off the gateway page.
992          *
993          * Only do signals if we are returning to user space
994          */
995         LDREG   PT_IASQ0(%r16), %r20
996         CMPIB=,n 0,%r20,intr_restore /* backward */
997         LDREG   PT_IASQ1(%r16), %r20
998         CMPIB=,n 0,%r20,intr_restore /* backward */
999
1000         copy    %r0, %r25                       /* long in_syscall = 0 */
1001 #ifdef CONFIG_64BIT
1002         ldo     -16(%r30),%r29                  /* Reference param save area */
1003 #endif
1004
1005         BL      do_notify_resume,%r2
1006         copy    %r16, %r26                      /* struct pt_regs *regs */
1007
1008         b,n     intr_check_sig
1009
1010 intr_restore:
1011         copy            %r16,%r29
1012         ldo             PT_FR31(%r29),%r1
1013         rest_fp         %r1
1014         rest_general    %r29
1015
1016         /* inverse of virt_map */
1017         pcxt_ssm_bug
1018         rsm             PSW_SM_QUIET,%r0        /* prepare for rfi */
1019         tophys_r1       %r29
1020
1021         /* Restore space id's and special cr's from PT_REGS
1022          * structure pointed to by r29
1023          */
1024         rest_specials   %r29
1025
1026         /* IMPORTANT: rest_stack restores r29 last (we are using it)!
1027          * It also restores r1 and r30.
1028          */
1029         rest_stack
1030
1031         rfi
1032         nop
1033         nop
1034         nop
1035         nop
1036         nop
1037         nop
1038         nop
1039         nop
1040
1041 #ifndef CONFIG_PREEMPT
1042 # define intr_do_preempt        intr_restore
1043 #endif /* !CONFIG_PREEMPT */
1044
1045         .import schedule,code
1046 intr_do_resched:
1047         /* Only call schedule on return to userspace. If we're returning
1048          * to kernel space, we may schedule if CONFIG_PREEMPT, otherwise
1049          * we jump back to intr_restore.
1050          */
1051         LDREG   PT_IASQ0(%r16), %r20
1052         CMPIB=  0, %r20, intr_do_preempt
1053         nop
1054         LDREG   PT_IASQ1(%r16), %r20
1055         CMPIB=  0, %r20, intr_do_preempt
1056         nop
1057
1058 #ifdef CONFIG_64BIT
1059         ldo     -16(%r30),%r29          /* Reference param save area */
1060 #endif
1061
1062         ldil    L%intr_check_sig, %r2
1063 #ifndef CONFIG_64BIT
1064         b       schedule
1065 #else
1066         load32  schedule, %r20
1067         bv      %r0(%r20)
1068 #endif
1069         ldo     R%intr_check_sig(%r2), %r2
1070
1071         /* preempt the current task on returning to kernel
1072          * mode from an interrupt, iff need_resched is set,
1073          * and preempt_count is 0. otherwise, we continue on
1074          * our merry way back to the current running task.
1075          */
1076 #ifdef CONFIG_PREEMPT
1077         .import preempt_schedule_irq,code
1078 intr_do_preempt:
1079         rsm     PSW_SM_I, %r0           /* disable interrupts */
1080
1081         /* current_thread_info()->preempt_count */
1082         mfctl   %cr30, %r1
1083         LDREG   TI_PRE_COUNT(%r1), %r19
1084         CMPIB<> 0, %r19, intr_restore   /* if preempt_count > 0 */
1085         nop                             /* prev insn branched backwards */
1086
1087         /* check if we interrupted a critical path */
1088         LDREG   PT_PSW(%r16), %r20
1089         bb,<,n  %r20, 31 - PSW_SM_I, intr_restore
1090         nop
1091
1092         BL      preempt_schedule_irq, %r2
1093         nop
1094
1095         b,n     intr_restore            /* ssm PSW_SM_I done by intr_restore */
1096 #endif /* CONFIG_PREEMPT */
1097
1098         /*
1099          * External interrupts.
1100          */
1101
1102 intr_extint:
1103         CMPIB=,n 0,%r16,1f
1104         get_stack_use_cr30
1105         b,n 3f
1106
1107 1:
1108 #if 0  /* Interrupt Stack support not working yet! */
1109         mfctl   %cr31,%r1
1110         copy    %r30,%r17
1111         /* FIXME! depi below has hardcoded idea of interrupt stack size (32k)*/
1112         DEPI    0,31,15,%r17
1113         CMPB=,n %r1,%r17,2f
1114         get_stack_use_cr31
1115         b,n 3f
1116 #endif
1117 2:
1118         get_stack_use_r30
1119
1120 3:
1121         save_specials   %r29
1122         virt_map
1123         save_general    %r29
1124
1125         ldo     PT_FR0(%r29), %r24
1126         save_fp %r24
1127         
1128         loadgp
1129
1130         copy    %r29, %r26      /* arg0 is pt_regs */
1131         copy    %r29, %r16      /* save pt_regs */
1132
1133         ldil    L%intr_return, %r2
1134
1135 #ifdef CONFIG_64BIT
1136         ldo     -16(%r30),%r29  /* Reference param save area */
1137 #endif
1138
1139         b       do_cpu_irq_mask
1140         ldo     R%intr_return(%r2), %r2 /* return to intr_return, not here */
1141 ENDPROC(syscall_exit_rfi)
1142
1143
1144         /* Generic interruptions (illegal insn, unaligned, page fault, etc) */
1145
1146 ENTRY(intr_save)                /* for os_hpmc */
1147         mfsp    %sr7,%r16
1148         CMPIB=,n 0,%r16,1f
1149         get_stack_use_cr30
1150         b       2f
1151         copy    %r8,%r26
1152
1153 1:
1154         get_stack_use_r30
1155         copy    %r8,%r26
1156
1157 2:
1158         save_specials   %r29
1159
1160         /* If this trap is a itlb miss, skip saving/adjusting isr/ior */
1161
1162         /*
1163          * FIXME: 1) Use a #define for the hardwired "6" below (and in
1164          *           traps.c.
1165          *        2) Once we start executing code above 4 Gb, we need
1166          *           to adjust iasq/iaoq here in the same way we
1167          *           adjust isr/ior below.
1168          */
1169
1170         CMPIB=,n        6,%r26,skip_save_ior
1171
1172
1173         mfctl           %cr20, %r16 /* isr */
1174         nop             /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */
1175         mfctl           %cr21, %r17 /* ior */
1176
1177
1178 #ifdef CONFIG_64BIT
1179         /*
1180          * If the interrupted code was running with W bit off (32 bit),
1181          * clear the b bits (bits 0 & 1) in the ior.
1182          * save_specials left ipsw value in r8 for us to test.
1183          */
1184         extrd,u,*<>     %r8,PSW_W_BIT,1,%r0
1185         depdi           0,1,2,%r17
1186
1187         /*
1188          * FIXME: This code has hardwired assumptions about the split
1189          *        between space bits and offset bits. This will change
1190          *        when we allow alternate page sizes.
1191          */
1192
1193         /* adjust isr/ior. */
1194         extrd,u         %r16,63,SPACEID_SHIFT,%r1       /* get high bits from isr for ior */
1195         depd            %r1,31,SPACEID_SHIFT,%r17       /* deposit them into ior */
1196         depdi           0,63,SPACEID_SHIFT,%r16         /* clear them from isr */
1197 #endif
1198         STREG           %r16, PT_ISR(%r29)
1199         STREG           %r17, PT_IOR(%r29)
1200
1201
1202 skip_save_ior:
1203         virt_map
1204         save_general    %r29
1205
1206         ldo             PT_FR0(%r29), %r25
1207         save_fp         %r25
1208         
1209         loadgp
1210
1211         copy            %r29, %r25      /* arg1 is pt_regs */
1212 #ifdef CONFIG_64BIT
1213         ldo             -16(%r30),%r29  /* Reference param save area */
1214 #endif
1215
1216         ldil            L%intr_check_sig, %r2
1217         copy            %r25, %r16      /* save pt_regs */
1218
1219         b               handle_interruption
1220         ldo             R%intr_check_sig(%r2), %r2
1221 ENDPROC(intr_save)
1222
1223
1224         /*
1225          * Note for all tlb miss handlers:
1226          *
1227          * cr24 contains a pointer to the kernel address space
1228          * page directory.
1229          *
1230          * cr25 contains a pointer to the current user address
1231          * space page directory.
1232          *
1233          * sr3 will contain the space id of the user address space
1234          * of the current running thread while that thread is
1235          * running in the kernel.
1236          */
1237
1238         /*
1239          * register number allocations.  Note that these are all
1240          * in the shadowed registers
1241          */
1242
1243         t0 = r1         /* temporary register 0 */
1244         va = r8         /* virtual address for which the trap occured */
1245         t1 = r9         /* temporary register 1 */
1246         pte  = r16      /* pte/phys page # */
1247         prot = r17      /* prot bits */
1248         spc  = r24      /* space for which the trap occured */
1249         ptp = r25       /* page directory/page table pointer */
1250
1251 #ifdef CONFIG_64BIT
1252
1253 dtlb_miss_20w:
1254         space_adjust    spc,va,t0
1255         get_pgd         spc,ptp
1256         space_check     spc,t0,dtlb_fault
1257
1258         L3_ptep         ptp,pte,t0,va,dtlb_check_alias_20w
1259
1260         update_ptep     ptp,pte,t0,t1
1261
1262         make_insert_tlb spc,pte,prot
1263         
1264         idtlbt          pte,prot
1265
1266         rfir
1267         nop
1268
1269 dtlb_check_alias_20w:
1270         do_alias        spc,t0,t1,va,pte,prot,dtlb_fault
1271
1272         idtlbt          pte,prot
1273
1274         rfir
1275         nop
1276
1277 nadtlb_miss_20w:
1278         space_adjust    spc,va,t0
1279         get_pgd         spc,ptp
1280         space_check     spc,t0,nadtlb_fault
1281
1282         L3_ptep         ptp,pte,t0,va,nadtlb_check_flush_20w
1283
1284         update_ptep     ptp,pte,t0,t1
1285
1286         make_insert_tlb spc,pte,prot
1287
1288         idtlbt          pte,prot
1289
1290         rfir
1291         nop
1292
1293 nadtlb_check_flush_20w:
1294         bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
1295
1296         /* Insert a "flush only" translation */
1297
1298         depdi,z         7,7,3,prot
1299         depdi           1,10,1,prot
1300
1301         /* Get rid of prot bits and convert to page addr for idtlbt */
1302
1303         depdi           0,63,12,pte
1304         extrd,u         pte,56,52,pte
1305         idtlbt          pte,prot
1306
1307         rfir
1308         nop
1309
1310 #else
1311
1312 dtlb_miss_11:
1313         get_pgd         spc,ptp
1314
1315         space_check     spc,t0,dtlb_fault
1316
1317         L2_ptep         ptp,pte,t0,va,dtlb_check_alias_11
1318
1319         update_ptep     ptp,pte,t0,t1
1320
1321         make_insert_tlb_11      spc,pte,prot
1322
1323         mfsp            %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
1324         mtsp            spc,%sr1
1325
1326         idtlba          pte,(%sr1,va)
1327         idtlbp          prot,(%sr1,va)
1328
1329         mtsp            t0, %sr1        /* Restore sr1 */
1330
1331         rfir
1332         nop
1333
1334 dtlb_check_alias_11:
1335
1336         /* Check to see if fault is in the temporary alias region */
1337
1338         cmpib,<>,n      0,spc,dtlb_fault /* forward */
1339         ldil            L%(TMPALIAS_MAP_START),t0
1340         copy            va,t1
1341         depwi           0,31,23,t1
1342         cmpb,<>,n       t0,t1,dtlb_fault /* forward */
1343         ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot
1344         depw,z          prot,8,7,prot
1345
1346         /*
1347          * OK, it is in the temp alias region, check whether "from" or "to".
1348          * Check "subtle" note in pacache.S re: r23/r26.
1349          */
1350
1351         extrw,u,=       va,9,1,r0
1352         or,tr           %r23,%r0,pte    /* If "from" use "from" page */
1353         or              %r26,%r0,pte    /* else "to", use "to" page  */
1354
1355         idtlba          pte,(va)
1356         idtlbp          prot,(va)
1357
1358         rfir
1359         nop
1360
1361 nadtlb_miss_11:
1362         get_pgd         spc,ptp
1363
1364         space_check     spc,t0,nadtlb_fault
1365
1366         L2_ptep         ptp,pte,t0,va,nadtlb_check_flush_11
1367
1368         update_ptep     ptp,pte,t0,t1
1369
1370         make_insert_tlb_11      spc,pte,prot
1371
1372
1373         mfsp            %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
1374         mtsp            spc,%sr1
1375
1376         idtlba          pte,(%sr1,va)
1377         idtlbp          prot,(%sr1,va)
1378
1379         mtsp            t0, %sr1        /* Restore sr1 */
1380
1381         rfir
1382         nop
1383
1384 nadtlb_check_flush_11:
1385         bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
1386
1387         /* Insert a "flush only" translation */
1388
1389         zdepi           7,7,3,prot
1390         depi            1,10,1,prot
1391
1392         /* Get rid of prot bits and convert to page addr for idtlba */
1393
1394         depi            0,31,12,pte
1395         extru           pte,24,25,pte
1396
1397         mfsp            %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
1398         mtsp            spc,%sr1
1399
1400         idtlba          pte,(%sr1,va)
1401         idtlbp          prot,(%sr1,va)
1402
1403         mtsp            t0, %sr1        /* Restore sr1 */
1404
1405         rfir
1406         nop
1407
1408 dtlb_miss_20:
1409         space_adjust    spc,va,t0
1410         get_pgd         spc,ptp
1411         space_check     spc,t0,dtlb_fault
1412
1413         L2_ptep         ptp,pte,t0,va,dtlb_check_alias_20
1414
1415         update_ptep     ptp,pte,t0,t1
1416
1417         make_insert_tlb spc,pte,prot
1418
1419         f_extend        pte,t0
1420
1421         idtlbt          pte,prot
1422
1423         rfir
1424         nop
1425
1426 dtlb_check_alias_20:
1427         do_alias        spc,t0,t1,va,pte,prot,dtlb_fault
1428         
1429         idtlbt          pte,prot
1430
1431         rfir
1432         nop
1433
1434 nadtlb_miss_20:
1435         get_pgd         spc,ptp
1436
1437         space_check     spc,t0,nadtlb_fault
1438
1439         L2_ptep         ptp,pte,t0,va,nadtlb_check_flush_20
1440
1441         update_ptep     ptp,pte,t0,t1
1442
1443         make_insert_tlb spc,pte,prot
1444
1445         f_extend        pte,t0
1446         
1447         idtlbt          pte,prot
1448
1449         rfir
1450         nop
1451
1452 nadtlb_check_flush_20:
1453         bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
1454
1455         /* Insert a "flush only" translation */
1456
1457         depdi,z         7,7,3,prot
1458         depdi           1,10,1,prot
1459
1460         /* Get rid of prot bits and convert to page addr for idtlbt */
1461
1462         depdi           0,63,12,pte
1463         extrd,u         pte,56,32,pte
1464         idtlbt          pte,prot
1465
1466         rfir
1467         nop
1468 #endif
1469
1470 nadtlb_emulate:
1471
1472         /*
1473          * Non access misses can be caused by fdc,fic,pdc,lpa,probe and
1474          * probei instructions. We don't want to fault for these
1475          * instructions (not only does it not make sense, it can cause
1476          * deadlocks, since some flushes are done with the mmap
1477          * semaphore held). If the translation doesn't exist, we can't
1478          * insert a translation, so have to emulate the side effects
1479          * of the instruction. Since we don't insert a translation
1480          * we can get a lot of faults during a flush loop, so it makes
1481          * sense to try to do it here with minimum overhead. We only
1482          * emulate fdc,fic,pdc,probew,prober instructions whose base 
1483          * and index registers are not shadowed. We defer everything 
1484          * else to the "slow" path.
1485          */
1486
1487         mfctl           %cr19,%r9 /* Get iir */
1488
1489         /* PA 2.0 Arch Ref. Book pg 382 has a good description of the insn bits.
1490            Checks for fdc,fdce,pdc,"fic,4f",prober,probeir,probew, probeiw */
1491
1492         /* Checks for fdc,fdce,pdc,"fic,4f" only */
1493         ldi             0x280,%r16
1494         and             %r9,%r16,%r17
1495         cmpb,<>,n       %r16,%r17,nadtlb_probe_check
1496         bb,>=,n         %r9,26,nadtlb_nullify  /* m bit not set, just nullify */
1497         BL              get_register,%r25
1498         extrw,u         %r9,15,5,%r8           /* Get index register # */
1499         CMPIB=,n        -1,%r1,nadtlb_fault    /* have to use slow path */
1500         copy            %r1,%r24
1501         BL              get_register,%r25
1502         extrw,u         %r9,10,5,%r8           /* Get base register # */
1503         CMPIB=,n        -1,%r1,nadtlb_fault    /* have to use slow path */
1504         BL              set_register,%r25
1505         add,l           %r1,%r24,%r1           /* doesn't affect c/b bits */
1506
1507 nadtlb_nullify:
1508         mfctl           %ipsw,%r8
1509         ldil            L%PSW_N,%r9
1510         or              %r8,%r9,%r8            /* Set PSW_N */
1511         mtctl           %r8,%ipsw
1512
1513         rfir
1514         nop
1515
1516         /* 
1517                 When there is no translation for the probe address then we
1518                 must nullify the insn and return zero in the target regsiter.
1519                 This will indicate to the calling code that it does not have 
1520                 write/read privileges to this address.
1521
1522                 This should technically work for prober and probew in PA 1.1,
1523                 and also probe,r and probe,w in PA 2.0
1524
1525                 WARNING: USE ONLY NON-SHADOW REGISTERS WITH PROBE INSN!
1526                 THE SLOW-PATH EMULATION HAS NOT BEEN WRITTEN YET.
1527
1528         */
1529 nadtlb_probe_check:
1530         ldi             0x80,%r16
1531         and             %r9,%r16,%r17
1532         cmpb,<>,n       %r16,%r17,nadtlb_fault /* Must be probe,[rw]*/
1533         BL              get_register,%r25      /* Find the target register */
1534         extrw,u         %r9,31,5,%r8           /* Get target register */
1535         CMPIB=,n        -1,%r1,nadtlb_fault    /* have to use slow path */
1536         BL              set_register,%r25
1537         copy            %r0,%r1                /* Write zero to target register */
1538         b nadtlb_nullify                       /* Nullify return insn */
1539         nop
1540
1541
1542 #ifdef CONFIG_64BIT
1543 itlb_miss_20w:
1544
1545         /*
1546          * I miss is a little different, since we allow users to fault
1547          * on the gateway page which is in the kernel address space.
1548          */
1549
1550         space_adjust    spc,va,t0
1551         get_pgd         spc,ptp
1552         space_check     spc,t0,itlb_fault
1553
1554         L3_ptep         ptp,pte,t0,va,itlb_fault
1555
1556         update_ptep     ptp,pte,t0,t1
1557
1558         make_insert_tlb spc,pte,prot
1559         
1560         iitlbt          pte,prot
1561
1562         rfir
1563         nop
1564
1565 #else
1566
1567 itlb_miss_11:
1568         get_pgd         spc,ptp
1569
1570         space_check     spc,t0,itlb_fault
1571
1572         L2_ptep         ptp,pte,t0,va,itlb_fault
1573
1574         update_ptep     ptp,pte,t0,t1
1575
1576         make_insert_tlb_11      spc,pte,prot
1577
1578         mfsp            %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
1579         mtsp            spc,%sr1
1580
1581         iitlba          pte,(%sr1,va)
1582         iitlbp          prot,(%sr1,va)
1583
1584         mtsp            t0, %sr1        /* Restore sr1 */
1585
1586         rfir
1587         nop
1588
1589 itlb_miss_20:
1590         get_pgd         spc,ptp
1591
1592         space_check     spc,t0,itlb_fault
1593
1594         L2_ptep         ptp,pte,t0,va,itlb_fault
1595
1596         update_ptep     ptp,pte,t0,t1
1597
1598         make_insert_tlb spc,pte,prot
1599
1600         f_extend        pte,t0  
1601
1602         iitlbt          pte,prot
1603
1604         rfir
1605         nop
1606
1607 #endif
1608
1609 #ifdef CONFIG_64BIT
1610
1611 dbit_trap_20w:
1612         space_adjust    spc,va,t0
1613         get_pgd         spc,ptp
1614         space_check     spc,t0,dbit_fault
1615
1616         L3_ptep         ptp,pte,t0,va,dbit_fault
1617
1618 #ifdef CONFIG_SMP
1619         CMPIB=,n        0,spc,dbit_nolock_20w
1620         load32          PA(pa_dbit_lock),t0
1621
1622 dbit_spin_20w:
1623         LDCW            0(t0),t1
1624         cmpib,=         0,t1,dbit_spin_20w
1625         nop
1626
1627 dbit_nolock_20w:
1628 #endif
1629         update_dirty    ptp,pte,t1
1630
1631         make_insert_tlb spc,pte,prot
1632                 
1633         idtlbt          pte,prot
1634 #ifdef CONFIG_SMP
1635         CMPIB=,n        0,spc,dbit_nounlock_20w
1636         ldi             1,t1
1637         stw             t1,0(t0)
1638
1639 dbit_nounlock_20w:
1640 #endif
1641
1642         rfir
1643         nop
1644 #else
1645
1646 dbit_trap_11:
1647
1648         get_pgd         spc,ptp
1649
1650         space_check     spc,t0,dbit_fault
1651
1652         L2_ptep         ptp,pte,t0,va,dbit_fault
1653
1654 #ifdef CONFIG_SMP
1655         CMPIB=,n        0,spc,dbit_nolock_11
1656         load32          PA(pa_dbit_lock),t0
1657
1658 dbit_spin_11:
1659         LDCW            0(t0),t1
1660         cmpib,=         0,t1,dbit_spin_11
1661         nop
1662
1663 dbit_nolock_11:
1664 #endif
1665         update_dirty    ptp,pte,t1
1666
1667         make_insert_tlb_11      spc,pte,prot
1668
1669         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1670         mtsp            spc,%sr1
1671
1672         idtlba          pte,(%sr1,va)
1673         idtlbp          prot,(%sr1,va)
1674
1675         mtsp            t1, %sr1     /* Restore sr1 */
1676 #ifdef CONFIG_SMP
1677         CMPIB=,n        0,spc,dbit_nounlock_11
1678         ldi             1,t1
1679         stw             t1,0(t0)
1680
1681 dbit_nounlock_11:
1682 #endif
1683
1684         rfir
1685         nop
1686
1687 dbit_trap_20:
1688         get_pgd         spc,ptp
1689
1690         space_check     spc,t0,dbit_fault
1691
1692         L2_ptep         ptp,pte,t0,va,dbit_fault
1693
1694 #ifdef CONFIG_SMP
1695         CMPIB=,n        0,spc,dbit_nolock_20
1696         load32          PA(pa_dbit_lock),t0
1697
1698 dbit_spin_20:
1699         LDCW            0(t0),t1
1700         cmpib,=         0,t1,dbit_spin_20
1701         nop
1702
1703 dbit_nolock_20:
1704 #endif
1705         update_dirty    ptp,pte,t1
1706
1707         make_insert_tlb spc,pte,prot
1708
1709         f_extend        pte,t1
1710         
1711         idtlbt          pte,prot
1712
1713 #ifdef CONFIG_SMP
1714         CMPIB=,n        0,spc,dbit_nounlock_20
1715         ldi             1,t1
1716         stw             t1,0(t0)
1717
1718 dbit_nounlock_20:
1719 #endif
1720
1721         rfir
1722         nop
1723 #endif
1724
1725         .import handle_interruption,code
1726
1727 kernel_bad_space:
1728         b               intr_save
1729         ldi             31,%r8  /* Use an unused code */
1730
1731 dbit_fault:
1732         b               intr_save
1733         ldi             20,%r8
1734
1735 itlb_fault:
1736         b               intr_save
1737         ldi             6,%r8
1738
1739 nadtlb_fault:
1740         b               intr_save
1741         ldi             17,%r8
1742
1743 dtlb_fault:
1744         b               intr_save
1745         ldi             15,%r8
1746
1747         /* Register saving semantics for system calls:
1748
1749            %r1             clobbered by system call macro in userspace
1750            %r2             saved in PT_REGS by gateway page
1751            %r3  - %r18     preserved by C code (saved by signal code)
1752            %r19 - %r20     saved in PT_REGS by gateway page
1753            %r21 - %r22     non-standard syscall args
1754                            stored in kernel stack by gateway page
1755            %r23 - %r26     arg3-arg0, saved in PT_REGS by gateway page
1756            %r27 - %r30     saved in PT_REGS by gateway page
1757            %r31            syscall return pointer
1758          */
1759
1760         /* Floating point registers (FIXME: what do we do with these?)
1761
1762            %fr0  - %fr3    status/exception, not preserved
1763            %fr4  - %fr7    arguments
1764            %fr8  - %fr11   not preserved by C code
1765            %fr12 - %fr21   preserved by C code
1766            %fr22 - %fr31   not preserved by C code
1767          */
1768
1769         .macro  reg_save regs
1770         STREG   %r3, PT_GR3(\regs)
1771         STREG   %r4, PT_GR4(\regs)
1772         STREG   %r5, PT_GR5(\regs)
1773         STREG   %r6, PT_GR6(\regs)
1774         STREG   %r7, PT_GR7(\regs)
1775         STREG   %r8, PT_GR8(\regs)
1776         STREG   %r9, PT_GR9(\regs)
1777         STREG   %r10,PT_GR10(\regs)
1778         STREG   %r11,PT_GR11(\regs)
1779         STREG   %r12,PT_GR12(\regs)
1780         STREG   %r13,PT_GR13(\regs)
1781         STREG   %r14,PT_GR14(\regs)
1782         STREG   %r15,PT_GR15(\regs)
1783         STREG   %r16,PT_GR16(\regs)
1784         STREG   %r17,PT_GR17(\regs)
1785         STREG   %r18,PT_GR18(\regs)
1786         .endm
1787
1788         .macro  reg_restore regs
1789         LDREG   PT_GR3(\regs), %r3
1790         LDREG   PT_GR4(\regs), %r4
1791         LDREG   PT_GR5(\regs), %r5
1792         LDREG   PT_GR6(\regs), %r6
1793         LDREG   PT_GR7(\regs), %r7
1794         LDREG   PT_GR8(\regs), %r8
1795         LDREG   PT_GR9(\regs), %r9
1796         LDREG   PT_GR10(\regs),%r10
1797         LDREG   PT_GR11(\regs),%r11
1798         LDREG   PT_GR12(\regs),%r12
1799         LDREG   PT_GR13(\regs),%r13
1800         LDREG   PT_GR14(\regs),%r14
1801         LDREG   PT_GR15(\regs),%r15
1802         LDREG   PT_GR16(\regs),%r16
1803         LDREG   PT_GR17(\regs),%r17
1804         LDREG   PT_GR18(\regs),%r18
1805         .endm
1806
1807 ENTRY(sys_fork_wrapper)
1808         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
1809         ldo     TASK_REGS(%r1),%r1
1810         reg_save %r1
1811         mfctl   %cr27, %r3
1812         STREG   %r3, PT_CR27(%r1)
1813
1814         STREG   %r2,-RP_OFFSET(%r30)
1815         ldo     FRAME_SIZE(%r30),%r30
1816 #ifdef CONFIG_64BIT
1817         ldo     -16(%r30),%r29          /* Reference param save area */
1818 #endif
1819
1820         /* These are call-clobbered registers and therefore
1821            also syscall-clobbered (we hope). */
1822         STREG   %r2,PT_GR19(%r1)        /* save for child */
1823         STREG   %r30,PT_GR21(%r1)
1824
1825         LDREG   PT_GR30(%r1),%r25
1826         copy    %r1,%r24
1827         BL      sys_clone,%r2
1828         ldi     SIGCHLD,%r26
1829
1830         LDREG   -RP_OFFSET-FRAME_SIZE(%r30),%r2
1831 wrapper_exit:
1832         ldo     -FRAME_SIZE(%r30),%r30          /* get the stackframe */
1833         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1834         ldo     TASK_REGS(%r1),%r1       /* get pt regs */
1835
1836         LDREG   PT_CR27(%r1), %r3
1837         mtctl   %r3, %cr27
1838         reg_restore %r1
1839
1840         /* strace expects syscall # to be preserved in r20 */
1841         ldi     __NR_fork,%r20
1842         bv %r0(%r2)
1843         STREG   %r20,PT_GR20(%r1)
1844 ENDPROC(sys_fork_wrapper)
1845
1846         /* Set the return value for the child */
1847 ENTRY(child_return)
1848         BL      schedule_tail, %r2
1849         nop
1850
1851         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%r30), %r1
1852         LDREG   TASK_PT_GR19(%r1),%r2
1853         b       wrapper_exit
1854         copy    %r0,%r28
1855 ENDPROC(child_return)
1856
1857
1858 ENTRY(sys_clone_wrapper)
1859         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1860         ldo     TASK_REGS(%r1),%r1      /* get pt regs */
1861         reg_save %r1
1862         mfctl   %cr27, %r3
1863         STREG   %r3, PT_CR27(%r1)
1864
1865         STREG   %r2,-RP_OFFSET(%r30)
1866         ldo     FRAME_SIZE(%r30),%r30
1867 #ifdef CONFIG_64BIT
1868         ldo     -16(%r30),%r29          /* Reference param save area */
1869 #endif
1870
1871         /* WARNING - Clobbers r19 and r21, userspace must save these! */
1872         STREG   %r2,PT_GR19(%r1)        /* save for child */
1873         STREG   %r30,PT_GR21(%r1)
1874         BL      sys_clone,%r2
1875         copy    %r1,%r24
1876
1877         b       wrapper_exit
1878         LDREG   -RP_OFFSET-FRAME_SIZE(%r30),%r2
1879 ENDPROC(sys_clone_wrapper)
1880
1881
1882 ENTRY(sys_vfork_wrapper)
1883         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1884         ldo     TASK_REGS(%r1),%r1      /* get pt regs */
1885         reg_save %r1
1886         mfctl   %cr27, %r3
1887         STREG   %r3, PT_CR27(%r1)
1888
1889         STREG   %r2,-RP_OFFSET(%r30)
1890         ldo     FRAME_SIZE(%r30),%r30
1891 #ifdef CONFIG_64BIT
1892         ldo     -16(%r30),%r29          /* Reference param save area */
1893 #endif
1894
1895         STREG   %r2,PT_GR19(%r1)        /* save for child */
1896         STREG   %r30,PT_GR21(%r1)
1897
1898         BL      sys_vfork,%r2
1899         copy    %r1,%r26
1900
1901         b       wrapper_exit
1902         LDREG   -RP_OFFSET-FRAME_SIZE(%r30),%r2
1903 ENDPROC(sys_vfork_wrapper)
1904
1905         
1906         .macro  execve_wrapper execve
1907         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1908         ldo     TASK_REGS(%r1),%r1      /* get pt regs */
1909
1910         /*
1911          * Do we need to save/restore r3-r18 here?
1912          * I don't think so. why would new thread need old
1913          * threads registers?
1914          */
1915
1916         /* %arg0 - %arg3 are already saved for us. */
1917
1918         STREG %r2,-RP_OFFSET(%r30)
1919         ldo FRAME_SIZE(%r30),%r30
1920 #ifdef CONFIG_64BIT
1921         ldo     -16(%r30),%r29          /* Reference param save area */
1922 #endif
1923         BL \execve,%r2
1924         copy %r1,%arg0
1925
1926         ldo -FRAME_SIZE(%r30),%r30
1927         LDREG -RP_OFFSET(%r30),%r2
1928
1929         /* If exec succeeded we need to load the args */
1930
1931         ldo -1024(%r0),%r1
1932         cmpb,>>= %r28,%r1,error_\execve
1933         copy %r2,%r19
1934
1935 error_\execve:
1936         bv %r0(%r19)
1937         nop
1938         .endm
1939
1940         .import sys_execve
1941 ENTRY(sys_execve_wrapper)
1942         execve_wrapper sys_execve
1943 ENDPROC(sys_execve_wrapper)
1944
1945 #ifdef CONFIG_64BIT
1946         .import sys32_execve
1947 ENTRY(sys32_execve_wrapper)
1948         execve_wrapper sys32_execve
1949 ENDPROC(sys32_execve_wrapper)
1950 #endif
1951
1952 ENTRY(sys_rt_sigreturn_wrapper)
1953         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
1954         ldo     TASK_REGS(%r26),%r26    /* get pt regs */
1955         /* Don't save regs, we are going to restore them from sigcontext. */
1956         STREG   %r2, -RP_OFFSET(%r30)
1957 #ifdef CONFIG_64BIT
1958         ldo     FRAME_SIZE(%r30), %r30
1959         BL      sys_rt_sigreturn,%r2
1960         ldo     -16(%r30),%r29          /* Reference param save area */
1961 #else
1962         BL      sys_rt_sigreturn,%r2
1963         ldo     FRAME_SIZE(%r30), %r30
1964 #endif
1965
1966         ldo     -FRAME_SIZE(%r30), %r30
1967         LDREG   -RP_OFFSET(%r30), %r2
1968
1969         /* FIXME: I think we need to restore a few more things here. */
1970         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1971         ldo     TASK_REGS(%r1),%r1      /* get pt regs */
1972         reg_restore %r1
1973
1974         /* If the signal was received while the process was blocked on a
1975          * syscall, then r2 will take us to syscall_exit; otherwise r2 will
1976          * take us to syscall_exit_rfi and on to intr_return.
1977          */
1978         bv      %r0(%r2)
1979         LDREG   PT_GR28(%r1),%r28  /* reload original r28 for syscall_exit */
1980 ENDPROC(sys_rt_sigreturn_wrapper)
1981
1982 ENTRY(sys_sigaltstack_wrapper)
1983         /* Get the user stack pointer */
1984         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1985         ldo     TASK_REGS(%r1),%r24     /* get pt regs */
1986         LDREG   TASK_PT_GR30(%r24),%r24
1987         STREG   %r2, -RP_OFFSET(%r30)
1988 #ifdef CONFIG_64BIT
1989         ldo     FRAME_SIZE(%r30), %r30
1990         BL      do_sigaltstack,%r2
1991         ldo     -16(%r30),%r29          /* Reference param save area */
1992 #else
1993         BL      do_sigaltstack,%r2
1994         ldo     FRAME_SIZE(%r30), %r30
1995 #endif
1996
1997         ldo     -FRAME_SIZE(%r30), %r30
1998         LDREG   -RP_OFFSET(%r30), %r2
1999         bv      %r0(%r2)
2000         nop
2001 ENDPROC(sys_sigaltstack_wrapper)
2002
2003 #ifdef CONFIG_64BIT
2004 ENTRY(sys32_sigaltstack_wrapper)
2005         /* Get the user stack pointer */
2006         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r24
2007         LDREG   TASK_PT_GR30(%r24),%r24
2008         STREG   %r2, -RP_OFFSET(%r30)
2009         ldo     FRAME_SIZE(%r30), %r30
2010         BL      do_sigaltstack32,%r2
2011         ldo     -16(%r30),%r29          /* Reference param save area */
2012
2013         ldo     -FRAME_SIZE(%r30), %r30
2014         LDREG   -RP_OFFSET(%r30), %r2
2015         bv      %r0(%r2)
2016         nop
2017 ENDPROC(sys32_sigaltstack_wrapper)
2018 #endif
2019
2020 ENTRY(syscall_exit)
2021         /* NOTE: HP-UX syscalls also come through here
2022          * after hpux_syscall_exit fixes up return
2023          * values. */
2024
2025         /* NOTE: Not all syscalls exit this way.  rt_sigreturn will exit
2026          * via syscall_exit_rfi if the signal was received while the process
2027          * was running.
2028          */
2029
2030         /* save return value now */
2031
2032         mfctl     %cr30, %r1
2033         LDREG     TI_TASK(%r1),%r1
2034         STREG     %r28,TASK_PT_GR28(%r1)
2035
2036 #ifdef CONFIG_HPUX
2037
2038 /* <linux/personality.h> cannot be easily included */
2039 #define PER_HPUX 0x10
2040         LDREG     TASK_PERSONALITY(%r1),%r19
2041
2042         /* We can't use "CMPIB<> PER_HPUX" since "im5" field is sign extended */
2043         ldo       -PER_HPUX(%r19), %r19
2044         CMPIB<>,n 0,%r19,1f
2045
2046         /* Save other hpux returns if personality is PER_HPUX */
2047         STREG     %r22,TASK_PT_GR22(%r1)
2048         STREG     %r29,TASK_PT_GR29(%r1)
2049 1:
2050
2051 #endif /* CONFIG_HPUX */
2052
2053         /* Seems to me that dp could be wrong here, if the syscall involved
2054          * calling a module, and nothing got round to restoring dp on return.
2055          */
2056         loadgp
2057
2058 syscall_check_bh:
2059
2060         /* Check for software interrupts */
2061
2062         .import irq_stat,data
2063
2064         load32  irq_stat,%r19
2065
2066 #ifdef CONFIG_SMP
2067         /* sched.h: int processor */
2068         /* %r26 is used as scratch register to index into irq_stat[] */
2069         ldw     TI_CPU-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 /* cpu # */
2070
2071         /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) bits */
2072         SHLREG  %r26,L1_CACHE_SHIFT,%r20
2073         add     %r19,%r20,%r19  /* now have &irq_stat[smp_processor_id()] */
2074 #endif /* CONFIG_SMP */
2075
2076 syscall_check_resched:
2077
2078         /* check for reschedule */
2079
2080         LDREG   TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19   /* long */
2081         bb,<,n  %r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */
2082
2083         .import do_signal,code
2084 syscall_check_sig:
2085         LDREG   TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19
2086         ldi     (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %r26
2087         and,COND(<>)    %r19, %r26, %r0
2088         b,n     syscall_restore /* skip past if we've nothing to do */
2089
2090 syscall_do_signal:
2091         /* Save callee-save registers (for sigcontext).
2092          * FIXME: After this point the process structure should be
2093          * consistent with all the relevant state of the process
2094          * before the syscall.  We need to verify this.
2095          */
2096         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
2097         ldo     TASK_REGS(%r1), %r26            /* struct pt_regs *regs */
2098         reg_save %r26
2099
2100 #ifdef CONFIG_64BIT
2101         ldo     -16(%r30),%r29                  /* Reference param save area */
2102 #endif
2103
2104         BL      do_notify_resume,%r2
2105         ldi     1, %r25                         /* long in_syscall = 1 */
2106
2107         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
2108         ldo     TASK_REGS(%r1), %r20            /* reload pt_regs */
2109         reg_restore %r20
2110
2111         b,n     syscall_check_sig
2112
2113 syscall_restore:
2114         /* Are we being ptraced? */
2115         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
2116
2117         LDREG   TASK_PTRACE(%r1), %r19
2118         bb,<    %r19,31,syscall_restore_rfi
2119         nop
2120
2121         ldo     TASK_PT_FR31(%r1),%r19             /* reload fpregs */
2122         rest_fp %r19
2123
2124         LDREG   TASK_PT_SAR(%r1),%r19              /* restore SAR */
2125         mtsar   %r19
2126
2127         LDREG   TASK_PT_GR2(%r1),%r2               /* restore user rp */
2128         LDREG   TASK_PT_GR19(%r1),%r19
2129         LDREG   TASK_PT_GR20(%r1),%r20
2130         LDREG   TASK_PT_GR21(%r1),%r21
2131         LDREG   TASK_PT_GR22(%r1),%r22
2132         LDREG   TASK_PT_GR23(%r1),%r23
2133         LDREG   TASK_PT_GR24(%r1),%r24
2134         LDREG   TASK_PT_GR25(%r1),%r25
2135         LDREG   TASK_PT_GR26(%r1),%r26
2136         LDREG   TASK_PT_GR27(%r1),%r27     /* restore user dp */
2137         LDREG   TASK_PT_GR28(%r1),%r28     /* syscall return value */
2138         LDREG   TASK_PT_GR29(%r1),%r29
2139         LDREG   TASK_PT_GR31(%r1),%r31     /* restore syscall rp */
2140
2141         /* NOTE: We use rsm/ssm pair to make this operation atomic */
2142         rsm     PSW_SM_I, %r0
2143         LDREG   TASK_PT_GR30(%r1),%r30             /* restore user sp */
2144         mfsp    %sr3,%r1                           /* Get users space id */
2145         mtsp    %r1,%sr7                           /* Restore sr7 */
2146         ssm     PSW_SM_I, %r0
2147
2148         /* Set sr2 to zero for userspace syscalls to work. */
2149         mtsp    %r0,%sr2 
2150         mtsp    %r1,%sr4                           /* Restore sr4 */
2151         mtsp    %r1,%sr5                           /* Restore sr5 */
2152         mtsp    %r1,%sr6                           /* Restore sr6 */
2153
2154         depi    3,31,2,%r31                        /* ensure return to user mode. */
2155
2156 #ifdef CONFIG_64BIT
2157         /* decide whether to reset the wide mode bit
2158          *
2159          * For a syscall, the W bit is stored in the lowest bit
2160          * of sp.  Extract it and reset W if it is zero */
2161         extrd,u,*<>     %r30,63,1,%r1
2162         rsm     PSW_SM_W, %r0
2163         /* now reset the lowest bit of sp if it was set */
2164         xor     %r30,%r1,%r30
2165 #endif
2166         be,n    0(%sr3,%r31)                       /* return to user space */
2167
2168         /* We have to return via an RFI, so that PSW T and R bits can be set
2169          * appropriately.
2170          * This sets up pt_regs so we can return via intr_restore, which is not
2171          * the most efficient way of doing things, but it works.
2172          */
2173 syscall_restore_rfi:
2174         ldo     -1(%r0),%r2                        /* Set recovery cntr to -1 */
2175         mtctl   %r2,%cr0                           /*   for immediate trap */
2176         LDREG   TASK_PT_PSW(%r1),%r2               /* Get old PSW */
2177         ldi     0x0b,%r20                          /* Create new PSW */
2178         depi    -1,13,1,%r20                       /* C, Q, D, and I bits */
2179
2180         /* The values of PA_SINGLESTEP_BIT and PA_BLOCKSTEP_BIT are
2181          * set in include/linux/ptrace.h and converted to PA bitmap
2182          * numbers in asm-offsets.c */
2183
2184         /* if ((%r19.PA_SINGLESTEP_BIT)) { %r20.27=1} */
2185         extru,= %r19,PA_SINGLESTEP_BIT,1,%r0
2186         depi    -1,27,1,%r20                       /* R bit */
2187
2188         /* if ((%r19.PA_BLOCKSTEP_BIT)) { %r20.7=1} */
2189         extru,= %r19,PA_BLOCKSTEP_BIT,1,%r0
2190         depi    -1,7,1,%r20                        /* T bit */
2191
2192         STREG   %r20,TASK_PT_PSW(%r1)
2193
2194         /* Always store space registers, since sr3 can be changed (e.g. fork) */
2195
2196         mfsp    %sr3,%r25
2197         STREG   %r25,TASK_PT_SR3(%r1)
2198         STREG   %r25,TASK_PT_SR4(%r1)
2199         STREG   %r25,TASK_PT_SR5(%r1)
2200         STREG   %r25,TASK_PT_SR6(%r1)
2201         STREG   %r25,TASK_PT_SR7(%r1)
2202         STREG   %r25,TASK_PT_IASQ0(%r1)
2203         STREG   %r25,TASK_PT_IASQ1(%r1)
2204
2205         /* XXX W bit??? */
2206         /* Now if old D bit is clear, it means we didn't save all registers
2207          * on syscall entry, so do that now.  This only happens on TRACEME
2208          * calls, or if someone attached to us while we were on a syscall.
2209          * We could make this more efficient by not saving r3-r18, but
2210          * then we wouldn't be able to use the common intr_restore path.
2211          * It is only for traced processes anyway, so performance is not
2212          * an issue.
2213          */
2214         bb,<    %r2,30,pt_regs_ok                  /* Branch if D set */
2215         ldo     TASK_REGS(%r1),%r25
2216         reg_save %r25                              /* Save r3 to r18 */
2217
2218         /* Save the current sr */
2219         mfsp    %sr0,%r2
2220         STREG   %r2,TASK_PT_SR0(%r1)
2221
2222         /* Save the scratch sr */
2223         mfsp    %sr1,%r2
2224         STREG   %r2,TASK_PT_SR1(%r1)
2225
2226         /* sr2 should be set to zero for userspace syscalls */
2227         STREG   %r0,TASK_PT_SR2(%r1)
2228
2229 pt_regs_ok:
2230         LDREG   TASK_PT_GR31(%r1),%r2
2231         depi    3,31,2,%r2                         /* ensure return to user mode. */
2232         STREG   %r2,TASK_PT_IAOQ0(%r1)
2233         ldo     4(%r2),%r2
2234         STREG   %r2,TASK_PT_IAOQ1(%r1)
2235         copy    %r25,%r16
2236         b       intr_restore
2237         nop
2238
2239         .import schedule,code
2240 syscall_do_resched:
2241         BL      schedule,%r2
2242 #ifdef CONFIG_64BIT
2243         ldo     -16(%r30),%r29          /* Reference param save area */
2244 #else
2245         nop
2246 #endif
2247         b       syscall_check_bh  /* if resched, we start over again */
2248         nop
2249 ENDPROC(syscall_exit)
2250
2251
2252 get_register:
2253         /*
2254          * get_register is used by the non access tlb miss handlers to
2255          * copy the value of the general register specified in r8 into
2256          * r1. This routine can't be used for shadowed registers, since
2257          * the rfir will restore the original value. So, for the shadowed
2258          * registers we put a -1 into r1 to indicate that the register
2259          * should not be used (the register being copied could also have
2260          * a -1 in it, but that is OK, it just means that we will have
2261          * to use the slow path instead).
2262          */
2263         blr     %r8,%r0
2264         nop
2265         bv      %r0(%r25)    /* r0 */
2266         copy    %r0,%r1
2267         bv      %r0(%r25)    /* r1 - shadowed */
2268         ldi     -1,%r1
2269         bv      %r0(%r25)    /* r2 */
2270         copy    %r2,%r1
2271         bv      %r0(%r25)    /* r3 */
2272         copy    %r3,%r1
2273         bv      %r0(%r25)    /* r4 */
2274         copy    %r4,%r1
2275         bv      %r0(%r25)    /* r5 */
2276         copy    %r5,%r1
2277         bv      %r0(%r25)    /* r6 */
2278         copy    %r6,%r1
2279         bv      %r0(%r25)    /* r7 */
2280         copy    %r7,%r1
2281         bv      %r0(%r25)    /* r8 - shadowed */
2282         ldi     -1,%r1
2283         bv      %r0(%r25)    /* r9 - shadowed */
2284         ldi     -1,%r1
2285         bv      %r0(%r25)    /* r10 */
2286         copy    %r10,%r1
2287         bv      %r0(%r25)    /* r11 */
2288         copy    %r11,%r1
2289         bv      %r0(%r25)    /* r12 */
2290         copy    %r12,%r1
2291         bv      %r0(%r25)    /* r13 */
2292         copy    %r13,%r1
2293         bv      %r0(%r25)    /* r14 */
2294         copy    %r14,%r1
2295         bv      %r0(%r25)    /* r15 */
2296         copy    %r15,%r1
2297         bv      %r0(%r25)    /* r16 - shadowed */
2298         ldi     -1,%r1
2299         bv      %r0(%r25)    /* r17 - shadowed */
2300         ldi     -1,%r1
2301         bv      %r0(%r25)    /* r18 */
2302         copy    %r18,%r1
2303         bv      %r0(%r25)    /* r19 */
2304         copy    %r19,%r1
2305         bv      %r0(%r25)    /* r20 */
2306         copy    %r20,%r1
2307         bv      %r0(%r25)    /* r21 */
2308         copy    %r21,%r1
2309         bv      %r0(%r25)    /* r22 */
2310         copy    %r22,%r1
2311         bv      %r0(%r25)    /* r23 */
2312         copy    %r23,%r1
2313         bv      %r0(%r25)    /* r24 - shadowed */
2314         ldi     -1,%r1
2315         bv      %r0(%r25)    /* r25 - shadowed */
2316         ldi     -1,%r1
2317         bv      %r0(%r25)    /* r26 */
2318         copy    %r26,%r1
2319         bv      %r0(%r25)    /* r27 */
2320         copy    %r27,%r1
2321         bv      %r0(%r25)    /* r28 */
2322         copy    %r28,%r1
2323         bv      %r0(%r25)    /* r29 */
2324         copy    %r29,%r1
2325         bv      %r0(%r25)    /* r30 */
2326         copy    %r30,%r1
2327         bv      %r0(%r25)    /* r31 */
2328         copy    %r31,%r1
2329
2330
2331 set_register:
2332         /*
2333          * set_register is used by the non access tlb miss handlers to
2334          * copy the value of r1 into the general register specified in
2335          * r8.
2336          */
2337         blr     %r8,%r0
2338         nop
2339         bv      %r0(%r25)    /* r0 (silly, but it is a place holder) */
2340         copy    %r1,%r0
2341         bv      %r0(%r25)    /* r1 */
2342         copy    %r1,%r1
2343         bv      %r0(%r25)    /* r2 */
2344         copy    %r1,%r2
2345         bv      %r0(%r25)    /* r3 */
2346         copy    %r1,%r3
2347         bv      %r0(%r25)    /* r4 */
2348         copy    %r1,%r4
2349         bv      %r0(%r25)    /* r5 */
2350         copy    %r1,%r5
2351         bv      %r0(%r25)    /* r6 */
2352         copy    %r1,%r6
2353         bv      %r0(%r25)    /* r7 */
2354         copy    %r1,%r7
2355         bv      %r0(%r25)    /* r8 */
2356         copy    %r1,%r8
2357         bv      %r0(%r25)    /* r9 */
2358         copy    %r1,%r9
2359         bv      %r0(%r25)    /* r10 */
2360         copy    %r1,%r10
2361         bv      %r0(%r25)    /* r11 */
2362         copy    %r1,%r11
2363         bv      %r0(%r25)    /* r12 */
2364         copy    %r1,%r12
2365         bv      %r0(%r25)    /* r13 */
2366         copy    %r1,%r13
2367         bv      %r0(%r25)    /* r14 */
2368         copy    %r1,%r14
2369         bv      %r0(%r25)    /* r15 */
2370         copy    %r1,%r15
2371         bv      %r0(%r25)    /* r16 */
2372         copy    %r1,%r16
2373         bv      %r0(%r25)    /* r17 */
2374         copy    %r1,%r17
2375         bv      %r0(%r25)    /* r18 */
2376         copy    %r1,%r18
2377         bv      %r0(%r25)    /* r19 */
2378         copy    %r1,%r19
2379         bv      %r0(%r25)    /* r20 */
2380         copy    %r1,%r20
2381         bv      %r0(%r25)    /* r21 */
2382         copy    %r1,%r21
2383         bv      %r0(%r25)    /* r22 */
2384         copy    %r1,%r22
2385         bv      %r0(%r25)    /* r23 */
2386         copy    %r1,%r23
2387         bv      %r0(%r25)    /* r24 */
2388         copy    %r1,%r24
2389         bv      %r0(%r25)    /* r25 */
2390         copy    %r1,%r25
2391         bv      %r0(%r25)    /* r26 */
2392         copy    %r1,%r26
2393         bv      %r0(%r25)    /* r27 */
2394         copy    %r1,%r27
2395         bv      %r0(%r25)    /* r28 */
2396         copy    %r1,%r28
2397         bv      %r0(%r25)    /* r29 */
2398         copy    %r1,%r29
2399         bv      %r0(%r25)    /* r30 */
2400         copy    %r1,%r30
2401         bv      %r0(%r25)    /* r31 */
2402         copy    %r1,%r31
2403