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