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