Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / arch / parisc / kernel / entry.S
1 /*
2  * Linux/PA-RISC Project (http://www.parisc-linux.org/)
3  *
4  * kernel entry points (interruptions, system call wrappers)
5  *  Copyright (C) 1999,2000 Philipp Rumpf 
6  *  Copyright (C) 1999 SuSE GmbH Nuernberg 
7  *  Copyright (C) 2000 Hewlett-Packard (John Marvin)
8  *  Copyright (C) 1999 Hewlett-Packard (Frank Rowand)
9  *
10  *    This program is free software; you can redistribute it and/or modify
11  *    it under the terms of the GNU General Public License as published by
12  *    the Free Software Foundation; either version 2, or (at your option)
13  *    any later version.
14  *
15  *    This program is distributed in the hope that it will be useful,
16  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *    GNU General Public License for more details.
19  *
20  *    You should have received a copy of the GNU General Public License
21  *    along with this program; if not, write to the Free Software
22  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25 #include <asm/asm-offsets.h>
26
27 /* we have the following possibilities to act on an interruption:
28  *  - handle in assembly and use shadowed registers only
29  *  - save registers to kernel stack and handle in assembly or C */
30
31
32 #include <asm/psw.h>
33 #include <asm/cache.h>          /* for L1_CACHE_SHIFT */
34 #include <asm/assembly.h>       /* for LDREG/STREG defines */
35 #include <asm/pgtable.h>
36 #include <asm/signal.h>
37 #include <asm/unistd.h>
38 #include <asm/thread_info.h>
39
40 #include <linux/linkage.h>
41
42 #ifdef CONFIG_64BIT
43         .level 2.0w
44 #else
45         .level 2.0
46 #endif
47
48         .import         pa_dbit_lock,data
49
50         /* space_to_prot macro creates a prot id from a space id */
51
52 #if (SPACEID_SHIFT) == 0
53         .macro  space_to_prot spc prot
54         depd,z  \spc,62,31,\prot
55         .endm
56 #else
57         .macro  space_to_prot spc prot
58         extrd,u \spc,(64 - (SPACEID_SHIFT)),32,\prot
59         .endm
60 #endif
61
62         /* Switch to virtual mapping, trashing only %r1 */
63         .macro  virt_map
64         /* pcxt_ssm_bug */
65         rsm     PSW_SM_I, %r0   /* barrier for "Relied upon Translation */
66         mtsp    %r0, %sr4
67         mtsp    %r0, %sr5
68         mfsp    %sr7, %r1
69         or,=    %r0,%r1,%r0     /* Only save sr7 in sr3 if sr7 != 0 */
70         mtsp    %r1, %sr3
71         tovirt_r1 %r29
72         load32  KERNEL_PSW, %r1
73
74         rsm     PSW_SM_QUIET,%r0        /* second "heavy weight" ctl op */
75         mtsp    %r0, %sr6
76         mtsp    %r0, %sr7
77         mtctl   %r0, %cr17      /* Clear IIASQ tail */
78         mtctl   %r0, %cr17      /* Clear IIASQ head */
79         mtctl   %r1, %ipsw
80         load32  4f, %r1
81         mtctl   %r1, %cr18      /* Set IIAOQ tail */
82         ldo     4(%r1), %r1
83         mtctl   %r1, %cr18      /* Set IIAOQ head */
84         rfir
85         nop
86 4:
87         .endm
88
89         /*
90          * The "get_stack" macros are responsible for determining the
91          * kernel stack value.
92          *
93          *      If sr7 == 0
94          *          Already using a kernel stack, so call the
95          *          get_stack_use_r30 macro to push a pt_regs structure
96          *          on the stack, and store registers there.
97          *      else
98          *          Need to set up a kernel stack, so call the
99          *          get_stack_use_cr30 macro to set up a pointer
100          *          to the pt_regs structure contained within the
101          *          task pointer pointed to by cr30. Set the stack
102          *          pointer to point to the end of the task structure.
103          *
104          * Note that we use shadowed registers for temps until
105          * we can save %r26 and %r29. %r26 is used to preserve
106          * %r8 (a shadowed register) which temporarily contained
107          * either the fault type ("code") or the eirr. We need
108          * to use a non-shadowed register to carry the value over
109          * the rfir in virt_map. We use %r26 since this value winds
110          * up being passed as the argument to either do_cpu_irq_mask
111          * or handle_interruption. %r29 is used to hold a pointer
112          * the register save area, and once again, it needs to
113          * be a non-shadowed register so that it survives the rfir.
114          *
115          * N.B. TASK_SZ_ALGN and PT_SZ_ALGN include space for a stack frame.
116          */
117
118         .macro  get_stack_use_cr30
119
120         /* we save the registers in the task struct */
121
122         mfctl   %cr30, %r1
123         tophys  %r1,%r9
124         LDREG   TI_TASK(%r9), %r1       /* thread_info -> task_struct */
125         tophys  %r1,%r9
126         ldo     TASK_REGS(%r9),%r9
127         STREG   %r30, PT_GR30(%r9)
128         STREG   %r29,PT_GR29(%r9)
129         STREG   %r26,PT_GR26(%r9)
130         copy    %r9,%r29
131         mfctl   %cr30, %r1
132         ldo     THREAD_SZ_ALGN(%r1), %r30
133         .endm
134
135         .macro  get_stack_use_r30
136
137         /* we put a struct pt_regs on the stack and save the registers there */
138
139         tophys  %r30,%r9
140         STREG   %r30,PT_GR30(%r9)
141         ldo     PT_SZ_ALGN(%r30),%r30
142         STREG   %r29,PT_GR29(%r9)
143         STREG   %r26,PT_GR26(%r9)
144         copy    %r9,%r29
145         .endm
146
147         .macro  rest_stack
148         LDREG   PT_GR1(%r29), %r1
149         LDREG   PT_GR30(%r29),%r30
150         LDREG   PT_GR29(%r29),%r29
151         .endm
152
153         /* default interruption handler
154          * (calls traps.c:handle_interruption) */
155         .macro  def code
156         b       intr_save
157         ldi     \code, %r8
158         .align  32
159         .endm
160
161         /* Interrupt interruption handler
162          * (calls irq.c:do_cpu_irq_mask) */
163         .macro  extint code
164         b       intr_extint
165         mfsp    %sr7,%r16
166         .align  32
167         .endm   
168
169         .import os_hpmc, code
170
171         /* HPMC handler */
172         .macro  hpmc code
173         nop                     /* must be a NOP, will be patched later */
174         load32  PA(os_hpmc), %r3
175         bv,n    0(%r3)
176         nop
177         .word   0               /* checksum (will be patched) */
178         .word   PA(os_hpmc)     /* address of handler */
179         .word   0               /* length of handler */
180         .endm
181
182         /*
183          * Performance Note: Instructions will be moved up into
184          * this part of the code later on, once we are sure
185          * that the tlb miss handlers are close to final form.
186          */
187
188         /* Register definitions for tlb miss handler macros */
189
190         va  = r8        /* virtual address for which the trap occured */
191         spc = r24       /* space for which the trap occured */
192
193 #ifndef CONFIG_64BIT
194
195         /*
196          * itlb miss interruption handler (parisc 1.1 - 32 bit)
197          */
198
199         .macro  itlb_11 code
200
201         mfctl   %pcsq, spc
202         b       itlb_miss_11
203         mfctl   %pcoq, va
204
205         .align          32
206         .endm
207 #endif
208         
209         /*
210          * itlb miss interruption handler (parisc 2.0)
211          */
212
213         .macro  itlb_20 code
214         mfctl   %pcsq, spc
215 #ifdef CONFIG_64BIT
216         b       itlb_miss_20w
217 #else
218         b       itlb_miss_20
219 #endif
220         mfctl   %pcoq, va
221
222         .align          32
223         .endm
224         
225 #ifndef CONFIG_64BIT
226         /*
227          * naitlb miss interruption handler (parisc 1.1 - 32 bit)
228          *
229          * Note: naitlb misses will be treated
230          * as an ordinary itlb miss for now.
231          * However, note that naitlb misses
232          * have the faulting address in the
233          * IOR/ISR.
234          */
235
236         .macro  naitlb_11 code
237
238         mfctl   %isr,spc
239         b       itlb_miss_11
240         mfctl   %ior,va
241         /* FIXME: If user causes a naitlb miss, the priv level may not be in
242          * lower bits of va, where the itlb miss handler is expecting them
243          */
244
245         .align          32
246         .endm
247 #endif
248         
249         /*
250          * naitlb miss interruption handler (parisc 2.0)
251          *
252          * Note: naitlb misses will be treated
253          * as an ordinary itlb miss for now.
254          * However, note that naitlb misses
255          * have the faulting address in the
256          * IOR/ISR.
257          */
258
259         .macro  naitlb_20 code
260
261         mfctl   %isr,spc
262 #ifdef CONFIG_64BIT
263         b       itlb_miss_20w
264 #else
265         b       itlb_miss_20
266 #endif
267         mfctl   %ior,va
268         /* FIXME: If user causes a naitlb miss, the priv level may not be in
269          * lower bits of va, where the itlb miss handler is expecting them
270          */
271
272         .align          32
273         .endm
274         
275 #ifndef CONFIG_64BIT
276         /*
277          * dtlb miss interruption handler (parisc 1.1 - 32 bit)
278          */
279
280         .macro  dtlb_11 code
281
282         mfctl   %isr, spc
283         b       dtlb_miss_11
284         mfctl   %ior, va
285
286         .align          32
287         .endm
288 #endif
289
290         /*
291          * dtlb miss interruption handler (parisc 2.0)
292          */
293
294         .macro  dtlb_20 code
295
296         mfctl   %isr, spc
297 #ifdef CONFIG_64BIT
298         b       dtlb_miss_20w
299 #else
300         b       dtlb_miss_20
301 #endif
302         mfctl   %ior, va
303
304         .align          32
305         .endm
306         
307 #ifndef CONFIG_64BIT
308         /* nadtlb miss interruption handler (parisc 1.1 - 32 bit) */
309
310         .macro  nadtlb_11 code
311
312         mfctl   %isr,spc
313         b       nadtlb_miss_11
314         mfctl   %ior,va
315
316         .align          32
317         .endm
318 #endif
319         
320         /* nadtlb miss interruption handler (parisc 2.0) */
321
322         .macro  nadtlb_20 code
323
324         mfctl   %isr,spc
325 #ifdef CONFIG_64BIT
326         b       nadtlb_miss_20w
327 #else
328         b       nadtlb_miss_20
329 #endif
330         mfctl   %ior,va
331
332         .align          32
333         .endm
334         
335 #ifndef CONFIG_64BIT
336         /*
337          * dirty bit trap interruption handler (parisc 1.1 - 32 bit)
338          */
339
340         .macro  dbit_11 code
341
342         mfctl   %isr,spc
343         b       dbit_trap_11
344         mfctl   %ior,va
345
346         .align          32
347         .endm
348 #endif
349
350         /*
351          * dirty bit trap interruption handler (parisc 2.0)
352          */
353
354         .macro  dbit_20 code
355
356         mfctl   %isr,spc
357 #ifdef CONFIG_64BIT
358         b       dbit_trap_20w
359 #else
360         b       dbit_trap_20
361 #endif
362         mfctl   %ior,va
363
364         .align          32
365         .endm
366
367         /* The following are simple 32 vs 64 bit instruction
368          * abstractions for the macros */
369         .macro          EXTR    reg1,start,length,reg2
370 #ifdef CONFIG_64BIT
371         extrd,u         \reg1,32+(\start),\length,\reg2
372 #else
373         extrw,u         \reg1,\start,\length,\reg2
374 #endif
375         .endm
376
377         .macro          DEP     reg1,start,length,reg2
378 #ifdef CONFIG_64BIT
379         depd            \reg1,32+(\start),\length,\reg2
380 #else
381         depw            \reg1,\start,\length,\reg2
382 #endif
383         .endm
384
385         .macro          DEPI    val,start,length,reg
386 #ifdef CONFIG_64BIT
387         depdi           \val,32+(\start),\length,\reg
388 #else
389         depwi           \val,\start,\length,\reg
390 #endif
391         .endm
392
393         /* In LP64, the space contains part of the upper 32 bits of the
394          * fault.  We have to extract this and place it in the va,
395          * zeroing the corresponding bits in the space register */
396         .macro          space_adjust    spc,va,tmp
397 #ifdef CONFIG_64BIT
398         extrd,u         \spc,63,SPACEID_SHIFT,\tmp
399         depd            %r0,63,SPACEID_SHIFT,\spc
400         depd            \tmp,31,SPACEID_SHIFT,\va
401 #endif
402         .endm
403
404         .import         swapper_pg_dir,code
405
406         /* Get the pgd.  For faults on space zero (kernel space), this
407          * is simply swapper_pg_dir.  For user space faults, the
408          * pgd is stored in %cr25 */
409         .macro          get_pgd         spc,reg
410         ldil            L%PA(swapper_pg_dir),\reg
411         ldo             R%PA(swapper_pg_dir)(\reg),\reg
412         or,COND(=)      %r0,\spc,%r0
413         mfctl           %cr25,\reg
414         .endm
415
416         /* 
417                 space_check(spc,tmp,fault)
418
419                 spc - The space we saw the fault with.
420                 tmp - The place to store the current space.
421                 fault - Function to call on failure.
422
423                 Only allow faults on different spaces from the
424                 currently active one if we're the kernel 
425
426         */
427         .macro          space_check     spc,tmp,fault
428         mfsp            %sr7,\tmp
429         or,COND(<>)     %r0,\spc,%r0    /* user may execute gateway page
430                                          * as kernel, so defeat the space
431                                          * check if it is */
432         copy            \spc,\tmp
433         or,COND(=)      %r0,\tmp,%r0    /* nullify if executing as kernel */
434         cmpb,COND(<>),n \tmp,\spc,\fault
435         .endm
436
437         /* Look up a PTE in a 2-Level scheme (faulting at each
438          * level if the entry isn't present 
439          *
440          * NOTE: we use ldw even for LP64, since the short pointers
441          * can address up to 1TB
442          */
443         .macro          L2_ptep pmd,pte,index,va,fault
444 #if PT_NLEVELS == 3
445         EXTR            \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index
446 #else
447         EXTR            \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
448 #endif
449         DEP             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
450         copy            %r0,\pte
451         ldw,s           \index(\pmd),\pmd
452         bb,>=,n         \pmd,_PxD_PRESENT_BIT,\fault
453         DEP             %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
454         copy            \pmd,%r9
455         SHLREG          %r9,PxD_VALUE_SHIFT,\pmd
456         EXTR            \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
457         DEP             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
458         shladd          \index,BITS_PER_PTE_ENTRY,\pmd,\pmd
459         LDREG           %r0(\pmd),\pte          /* pmd is now pte */
460         bb,>=,n         \pte,_PAGE_PRESENT_BIT,\fault
461         .endm
462
463         /* Look up PTE in a 3-Level scheme.
464          *
465          * Here we implement a Hybrid L2/L3 scheme: we allocate the
466          * first pmd adjacent to the pgd.  This means that we can
467          * subtract a constant offset to get to it.  The pmd and pgd
468          * sizes are arranged so that a single pmd covers 4GB (giving
469          * a full LP64 process access to 8TB) so our lookups are
470          * effectively L2 for the first 4GB of the kernel (i.e. for
471          * all ILP32 processes and all the kernel for machines with
472          * under 4GB of memory) */
473         .macro          L3_ptep pgd,pte,index,va,fault
474 #if PT_NLEVELS == 3 /* we might have a 2-Level scheme, e.g. with 16kb page size */
475         extrd,u         \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
476         copy            %r0,\pte
477         extrd,u,*=      \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
478         ldw,s           \index(\pgd),\pgd
479         extrd,u,*=      \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
480         bb,>=,n         \pgd,_PxD_PRESENT_BIT,\fault
481         extrd,u,*=      \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
482         shld            \pgd,PxD_VALUE_SHIFT,\index
483         extrd,u,*=      \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
484         copy            \index,\pgd
485         extrd,u,*<>     \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
486         ldo             ASM_PGD_PMD_OFFSET(\pgd),\pgd
487 #endif
488         L2_ptep         \pgd,\pte,\index,\va,\fault
489         .endm
490
491         /* Set the _PAGE_ACCESSED bit of the PTE.  Be clever and
492          * don't needlessly dirty the cache line if it was already set */
493         .macro          update_ptep     ptep,pte,tmp,tmp1
494         ldi             _PAGE_ACCESSED,\tmp1
495         or              \tmp1,\pte,\tmp
496         and,COND(<>)    \tmp1,\pte,%r0
497         STREG           \tmp,0(\ptep)
498         .endm
499
500         /* Set the dirty bit (and accessed bit).  No need to be
501          * clever, this is only used from the dirty fault */
502         .macro          update_dirty    ptep,pte,tmp
503         ldi             _PAGE_ACCESSED|_PAGE_DIRTY,\tmp
504         or              \tmp,\pte,\pte
505         STREG           \pte,0(\ptep)
506         .endm
507
508         /* bitshift difference between a PFN (based on kernel's PAGE_SIZE)
509          * to a CPU TLB 4k PFN (4k => 12 bits to shift) */
510         #define PAGE_ADD_SHIFT  (PAGE_SHIFT-12)
511
512         /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
513         .macro          convert_for_tlb_insert20 pte
514         extrd,u         \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
515                                 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
516         depdi           _PAGE_SIZE_ENCODING_DEFAULT,63,\
517                                 (63-58)+PAGE_ADD_SHIFT,\pte
518         .endm
519
520         /* Convert the pte and prot to tlb insertion values.  How
521          * this happens is quite subtle, read below */
522         .macro          make_insert_tlb spc,pte,prot
523         space_to_prot   \spc \prot        /* create prot id from space */
524         /* The following is the real subtlety.  This is depositing
525          * T <-> _PAGE_REFTRAP
526          * D <-> _PAGE_DIRTY
527          * B <-> _PAGE_DMB (memory break)
528          *
529          * Then incredible subtlety: The access rights are
530          * _PAGE_GATEWAY _PAGE_EXEC _PAGE_READ
531          * See 3-14 of the parisc 2.0 manual
532          *
533          * Finally, _PAGE_READ goes in the top bit of PL1 (so we
534          * trigger an access rights trap in user space if the user
535          * tries to read an unreadable page */
536         depd            \pte,8,7,\prot
537
538         /* PAGE_USER indicates the page can be read with user privileges,
539          * so deposit X1|11 to PL1|PL2 (remember the upper bit of PL1
540          * contains _PAGE_READ */
541         extrd,u,*=      \pte,_PAGE_USER_BIT+32,1,%r0
542         depdi           7,11,3,\prot
543         /* If we're a gateway page, drop PL2 back to zero for promotion
544          * to kernel privilege (so we can execute the page as kernel).
545          * Any privilege promotion page always denys read and write */
546         extrd,u,*=      \pte,_PAGE_GATEWAY_BIT+32,1,%r0
547         depd            %r0,11,2,\prot  /* If Gateway, Set PL2 to 0 */
548
549         /* Enforce uncacheable pages.
550          * This should ONLY be use for MMIO on PA 2.0 machines.
551          * Memory/DMA is cache coherent on all PA2.0 machines we support
552          * (that means T-class is NOT supported) and the memory controllers
553          * on most of those machines only handles cache transactions.
554          */
555         extrd,u,*=      \pte,_PAGE_NO_CACHE_BIT+32,1,%r0
556         depdi           1,12,1,\prot
557
558         /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
559         convert_for_tlb_insert20 \pte
560         .endm
561
562         /* Identical macro to make_insert_tlb above, except it
563          * makes the tlb entry for the differently formatted pa11
564          * insertion instructions */
565         .macro          make_insert_tlb_11      spc,pte,prot
566         zdep            \spc,30,15,\prot
567         dep             \pte,8,7,\prot
568         extru,=         \pte,_PAGE_NO_CACHE_BIT,1,%r0
569         depi            1,12,1,\prot
570         extru,=         \pte,_PAGE_USER_BIT,1,%r0
571         depi            7,11,3,\prot   /* Set for user space (1 rsvd for read) */
572         extru,=         \pte,_PAGE_GATEWAY_BIT,1,%r0
573         depi            0,11,2,\prot    /* If Gateway, Set PL2 to 0 */
574
575         /* Get rid of prot bits and convert to page addr for iitlba */
576
577         depi            0,31,ASM_PFN_PTE_SHIFT,\pte
578         SHRREG          \pte,(ASM_PFN_PTE_SHIFT-(31-26)),\pte
579         .endm
580
581         /* This is for ILP32 PA2.0 only.  The TLB insertion needs
582          * to extend into I/O space if the address is 0xfXXXXXXX
583          * so we extend the f's into the top word of the pte in
584          * this case */
585         .macro          f_extend        pte,tmp
586         extrd,s         \pte,42,4,\tmp
587         addi,<>         1,\tmp,%r0
588         extrd,s         \pte,63,25,\pte
589         .endm
590
591         /* The alias region is an 8MB aligned 16MB to do clear and
592          * copy user pages at addresses congruent with the user
593          * virtual address.
594          *
595          * To use the alias page, you set %r26 up with the to TLB
596          * entry (identifying the physical page) and %r23 up with
597          * the from tlb entry (or nothing if only a to entry---for
598          * clear_user_page_asm) */
599         .macro          do_alias        spc,tmp,tmp1,va,pte,prot,fault
600         cmpib,COND(<>),n 0,\spc,\fault
601         ldil            L%(TMPALIAS_MAP_START),\tmp
602 #if defined(CONFIG_64BIT) && (TMPALIAS_MAP_START >= 0x80000000)
603         /* on LP64, ldi will sign extend into the upper 32 bits,
604          * which is behaviour we don't want */
605         depdi           0,31,32,\tmp
606 #endif
607         copy            \va,\tmp1
608         DEPI            0,31,23,\tmp1
609         cmpb,COND(<>),n \tmp,\tmp1,\fault
610         ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),\prot
611         depd,z          \prot,8,7,\prot
612         /*
613          * OK, it is in the temp alias region, check whether "from" or "to".
614          * Check "subtle" note in pacache.S re: r23/r26.
615          */
616 #ifdef CONFIG_64BIT
617         extrd,u,*=      \va,41,1,%r0
618 #else
619         extrw,u,=       \va,9,1,%r0
620 #endif
621         or,COND(tr)     %r23,%r0,\pte
622         or              %r26,%r0,\pte
623         .endm 
624
625
626         /*
627          * Align fault_vector_20 on 4K boundary so that both
628          * fault_vector_11 and fault_vector_20 are on the
629          * same page. This is only necessary as long as we
630          * write protect the kernel text, which we may stop
631          * doing once we use large page translations to cover
632          * the static part of the kernel address space.
633          */
634
635         .text
636
637         .align  PAGE_SIZE
638
639 ENTRY(fault_vector_20)
640         /* First vector is invalid (0) */
641         .ascii  "cows can fly"
642         .byte 0
643         .align 32
644
645         hpmc             1
646         def              2
647         def              3
648         extint           4
649         def              5
650         itlb_20          6
651         def              7
652         def              8
653         def              9
654         def             10
655         def             11
656         def             12
657         def             13
658         def             14
659         dtlb_20         15
660 #if 0
661         naitlb_20       16
662 #else
663         def             16
664 #endif
665         nadtlb_20       17
666         def             18
667         def             19
668         dbit_20         20
669         def             21
670         def             22
671         def             23
672         def             24
673         def             25
674         def             26
675         def             27
676         def             28
677         def             29
678         def             30
679         def             31
680 END(fault_vector_20)
681
682 #ifndef CONFIG_64BIT
683
684         .align 2048
685
686 ENTRY(fault_vector_11)
687         /* First vector is invalid (0) */
688         .ascii  "cows can fly"
689         .byte 0
690         .align 32
691
692         hpmc             1
693         def              2
694         def              3
695         extint           4
696         def              5
697         itlb_11          6
698         def              7
699         def              8
700         def              9
701         def             10
702         def             11
703         def             12
704         def             13
705         def             14
706         dtlb_11         15
707 #if 0
708         naitlb_11       16
709 #else
710         def             16
711 #endif
712         nadtlb_11       17
713         def             18
714         def             19
715         dbit_11         20
716         def             21
717         def             22
718         def             23
719         def             24
720         def             25
721         def             26
722         def             27
723         def             28
724         def             29
725         def             30
726         def             31
727 END(fault_vector_11)
728
729 #endif
730
731         .import         handle_interruption,code
732         .import         do_cpu_irq_mask,code
733
734         /*
735          * r26 = function to be called
736          * r25 = argument to pass in
737          * r24 = flags for do_fork()
738          *
739          * Kernel threads don't ever return, so they don't need
740          * a true register context. We just save away the arguments
741          * for copy_thread/ret_ to properly set up the child.
742          */
743
744 #define CLONE_VM 0x100  /* Must agree with <linux/sched.h> */
745 #define CLONE_UNTRACED 0x00800000
746
747         .import do_fork
748 ENTRY(__kernel_thread)
749         STREG   %r2, -RP_OFFSET(%r30)
750
751         copy    %r30, %r1
752         ldo     PT_SZ_ALGN(%r30),%r30
753 #ifdef CONFIG_64BIT
754         /* Yo, function pointers in wide mode are little structs... -PB */
755         ldd     24(%r26), %r2
756         STREG   %r2, PT_GR27(%r1)       /* Store childs %dp */
757         ldd     16(%r26), %r26
758
759         STREG   %r22, PT_GR22(%r1)      /* save r22 (arg5) */
760         copy    %r0, %r22               /* user_tid */
761 #endif
762         STREG   %r26, PT_GR26(%r1)  /* Store function & argument for child */
763         STREG   %r25, PT_GR25(%r1)
764         ldil    L%CLONE_UNTRACED, %r26
765         ldo     CLONE_VM(%r26), %r26   /* Force CLONE_VM since only init_mm */
766         or      %r26, %r24, %r26      /* will have kernel mappings.      */
767         ldi     1, %r25                 /* stack_start, signals kernel thread */
768         stw     %r0, -52(%r30)          /* user_tid */
769 #ifdef CONFIG_64BIT
770         ldo     -16(%r30),%r29          /* Reference param save area */
771 #endif
772         BL      do_fork, %r2
773         copy    %r1, %r24               /* pt_regs */
774
775         /* Parent Returns here */
776
777         LDREG   -PT_SZ_ALGN-RP_OFFSET(%r30), %r2
778         ldo     -PT_SZ_ALGN(%r30), %r30
779         bv      %r0(%r2)
780         nop
781 ENDPROC(__kernel_thread)
782
783         /*
784          * Child Returns here
785          *
786          * copy_thread moved args from temp save area set up above
787          * into task save area.
788          */
789
790 ENTRY(ret_from_kernel_thread)
791
792         /* Call schedule_tail first though */
793         BL      schedule_tail, %r2
794         nop
795
796         LDREG   TI_TASK-THREAD_SZ_ALGN(%r30), %r1
797         LDREG   TASK_PT_GR25(%r1), %r26
798 #ifdef CONFIG_64BIT
799         LDREG   TASK_PT_GR27(%r1), %r27
800         LDREG   TASK_PT_GR22(%r1), %r22
801 #endif
802         LDREG   TASK_PT_GR26(%r1), %r1
803         ble     0(%sr7, %r1)
804         copy    %r31, %r2
805
806 #ifdef CONFIG_64BIT
807         ldo     -16(%r30),%r29          /* Reference param save area */
808         loadgp                          /* Thread could have been in a module */
809 #endif
810 #ifndef CONFIG_64BIT
811         b       sys_exit
812 #else
813         load32  sys_exit, %r1
814         bv      %r0(%r1)
815 #endif
816         ldi     0, %r26
817 ENDPROC(ret_from_kernel_thread)
818
819         .import sys_execve, code
820 ENTRY(__execve)
821         copy    %r2, %r15
822         copy    %r30, %r16
823         ldo     PT_SZ_ALGN(%r30), %r30
824         STREG   %r26, PT_GR26(%r16)
825         STREG   %r25, PT_GR25(%r16)
826         STREG   %r24, PT_GR24(%r16)
827 #ifdef CONFIG_64BIT
828         ldo     -16(%r30),%r29          /* Reference param save area */
829 #endif
830         BL      sys_execve, %r2
831         copy    %r16, %r26
832
833         cmpib,=,n 0,%r28,intr_return    /* forward */
834
835         /* yes, this will trap and die. */
836         copy    %r15, %r2
837         copy    %r16, %r30
838         bv      %r0(%r2)
839         nop
840 ENDPROC(__execve)
841
842
843         /*
844          * struct task_struct *_switch_to(struct task_struct *prev,
845          *      struct task_struct *next)
846          *
847          * switch kernel stacks and return prev */
848 ENTRY(_switch_to)
849         STREG    %r2, -RP_OFFSET(%r30)
850
851         callee_save_float
852         callee_save
853
854         load32  _switch_to_ret, %r2
855
856         STREG   %r2, TASK_PT_KPC(%r26)
857         LDREG   TASK_PT_KPC(%r25), %r2
858
859         STREG   %r30, TASK_PT_KSP(%r26)
860         LDREG   TASK_PT_KSP(%r25), %r30
861         LDREG   TASK_THREAD_INFO(%r25), %r25
862         bv      %r0(%r2)
863         mtctl   %r25,%cr30
864
865 _switch_to_ret:
866         mtctl   %r0, %cr0               /* Needed for single stepping */
867         callee_rest
868         callee_rest_float
869
870         LDREG   -RP_OFFSET(%r30), %r2
871         bv      %r0(%r2)
872         copy    %r26, %r28
873 ENDPROC(_switch_to)
874
875         /*
876          * Common rfi return path for interruptions, kernel execve, and
877          * sys_rt_sigreturn (sometimes).  The sys_rt_sigreturn syscall will
878          * return via this path if the signal was received when the process
879          * was running; if the process was blocked on a syscall then the
880          * normal syscall_exit path is used.  All syscalls for traced
881          * proceses exit via intr_restore.
882          *
883          * XXX If any syscalls that change a processes space id ever exit
884          * this way, then we will need to copy %sr3 in to PT_SR[3..7], and
885          * adjust IASQ[0..1].
886          *
887          */
888
889         .align  PAGE_SIZE
890
891 ENTRY(syscall_exit_rfi)
892         mfctl   %cr30,%r16
893         LDREG   TI_TASK(%r16), %r16     /* thread_info -> task_struct */
894         ldo     TASK_REGS(%r16),%r16
895         /* Force iaoq to userspace, as the user has had access to our current
896          * context via sigcontext. Also Filter the PSW for the same reason.
897          */
898         LDREG   PT_IAOQ0(%r16),%r19
899         depi    3,31,2,%r19
900         STREG   %r19,PT_IAOQ0(%r16)
901         LDREG   PT_IAOQ1(%r16),%r19
902         depi    3,31,2,%r19
903         STREG   %r19,PT_IAOQ1(%r16)
904         LDREG   PT_PSW(%r16),%r19
905         load32  USER_PSW_MASK,%r1
906 #ifdef CONFIG_64BIT
907         load32  USER_PSW_HI_MASK,%r20
908         depd    %r20,31,32,%r1
909 #endif
910         and     %r19,%r1,%r19 /* Mask out bits that user shouldn't play with */
911         load32  USER_PSW,%r1
912         or      %r19,%r1,%r19 /* Make sure default USER_PSW bits are set */
913         STREG   %r19,PT_PSW(%r16)
914
915         /*
916          * If we aren't being traced, we never saved space registers
917          * (we don't store them in the sigcontext), so set them
918          * to "proper" values now (otherwise we'll wind up restoring
919          * whatever was last stored in the task structure, which might
920          * be inconsistent if an interrupt occured while on the gateway
921          * page). Note that we may be "trashing" values the user put in
922          * them, but we don't support the user changing them.
923          */
924
925         STREG   %r0,PT_SR2(%r16)
926         mfsp    %sr3,%r19
927         STREG   %r19,PT_SR0(%r16)
928         STREG   %r19,PT_SR1(%r16)
929         STREG   %r19,PT_SR3(%r16)
930         STREG   %r19,PT_SR4(%r16)
931         STREG   %r19,PT_SR5(%r16)
932         STREG   %r19,PT_SR6(%r16)
933         STREG   %r19,PT_SR7(%r16)
934
935 intr_return:
936         /* NOTE: Need to enable interrupts incase we schedule. */
937         ssm     PSW_SM_I, %r0
938
939 intr_check_resched:
940
941         /* check for reschedule */
942         mfctl   %cr30,%r1
943         LDREG   TI_FLAGS(%r1),%r19      /* sched.h: TIF_NEED_RESCHED */
944         bb,<,n  %r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */
945
946         .import do_notify_resume,code
947 intr_check_sig:
948         /* As above */
949         mfctl   %cr30,%r1
950         LDREG   TI_FLAGS(%r1),%r19
951         ldi     (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NOTIFY_RESUME), %r20
952         and,COND(<>)    %r19, %r20, %r0
953         b,n     intr_restore    /* skip past if we've nothing to do */
954
955         /* This check is critical to having LWS
956          * working. The IASQ is zero on the gateway
957          * page and we cannot deliver any signals until
958          * we get off the gateway page.
959          *
960          * Only do signals if we are returning to user space
961          */
962         LDREG   PT_IASQ0(%r16), %r20
963         cmpib,COND(=),n 0,%r20,intr_restore /* backward */
964         LDREG   PT_IASQ1(%r16), %r20
965         cmpib,COND(=),n 0,%r20,intr_restore /* backward */
966
967         copy    %r0, %r25                       /* long in_syscall = 0 */
968 #ifdef CONFIG_64BIT
969         ldo     -16(%r30),%r29                  /* Reference param save area */
970 #endif
971
972         BL      do_notify_resume,%r2
973         copy    %r16, %r26                      /* struct pt_regs *regs */
974
975         b,n     intr_check_sig
976
977 intr_restore:
978         copy            %r16,%r29
979         ldo             PT_FR31(%r29),%r1
980         rest_fp         %r1
981         rest_general    %r29
982
983         /* inverse of virt_map */
984         pcxt_ssm_bug
985         rsm             PSW_SM_QUIET,%r0        /* prepare for rfi */
986         tophys_r1       %r29
987
988         /* Restore space id's and special cr's from PT_REGS
989          * structure pointed to by r29
990          */
991         rest_specials   %r29
992
993         /* IMPORTANT: rest_stack restores r29 last (we are using it)!
994          * It also restores r1 and r30.
995          */
996         rest_stack
997
998         rfi
999         nop
1000         nop
1001         nop
1002         nop
1003         nop
1004         nop
1005         nop
1006         nop
1007
1008 #ifndef CONFIG_PREEMPT
1009 # define intr_do_preempt        intr_restore
1010 #endif /* !CONFIG_PREEMPT */
1011
1012         .import schedule,code
1013 intr_do_resched:
1014         /* Only call schedule on return to userspace. If we're returning
1015          * to kernel space, we may schedule if CONFIG_PREEMPT, otherwise
1016          * we jump back to intr_restore.
1017          */
1018         LDREG   PT_IASQ0(%r16), %r20
1019         cmpib,COND(=)   0, %r20, intr_do_preempt
1020         nop
1021         LDREG   PT_IASQ1(%r16), %r20
1022         cmpib,COND(=)   0, %r20, intr_do_preempt
1023         nop
1024
1025 #ifdef CONFIG_64BIT
1026         ldo     -16(%r30),%r29          /* Reference param save area */
1027 #endif
1028
1029         ldil    L%intr_check_sig, %r2
1030 #ifndef CONFIG_64BIT
1031         b       schedule
1032 #else
1033         load32  schedule, %r20
1034         bv      %r0(%r20)
1035 #endif
1036         ldo     R%intr_check_sig(%r2), %r2
1037
1038         /* preempt the current task on returning to kernel
1039          * mode from an interrupt, iff need_resched is set,
1040          * and preempt_count is 0. otherwise, we continue on
1041          * our merry way back to the current running task.
1042          */
1043 #ifdef CONFIG_PREEMPT
1044         .import preempt_schedule_irq,code
1045 intr_do_preempt:
1046         rsm     PSW_SM_I, %r0           /* disable interrupts */
1047
1048         /* current_thread_info()->preempt_count */
1049         mfctl   %cr30, %r1
1050         LDREG   TI_PRE_COUNT(%r1), %r19
1051         cmpib,COND(<>)  0, %r19, intr_restore   /* if preempt_count > 0 */
1052         nop                             /* prev insn branched backwards */
1053
1054         /* check if we interrupted a critical path */
1055         LDREG   PT_PSW(%r16), %r20
1056         bb,<,n  %r20, 31 - PSW_SM_I, intr_restore
1057         nop
1058
1059         BL      preempt_schedule_irq, %r2
1060         nop
1061
1062         b,n     intr_restore            /* ssm PSW_SM_I done by intr_restore */
1063 #endif /* CONFIG_PREEMPT */
1064
1065         /*
1066          * External interrupts.
1067          */
1068
1069 intr_extint:
1070         cmpib,COND(=),n 0,%r16,1f
1071
1072         get_stack_use_cr30
1073         b,n 2f
1074
1075 1:
1076         get_stack_use_r30
1077 2:
1078         save_specials   %r29
1079         virt_map
1080         save_general    %r29
1081
1082         ldo     PT_FR0(%r29), %r24
1083         save_fp %r24
1084         
1085         loadgp
1086
1087         copy    %r29, %r26      /* arg0 is pt_regs */
1088         copy    %r29, %r16      /* save pt_regs */
1089
1090         ldil    L%intr_return, %r2
1091
1092 #ifdef CONFIG_64BIT
1093         ldo     -16(%r30),%r29  /* Reference param save area */
1094 #endif
1095
1096         b       do_cpu_irq_mask
1097         ldo     R%intr_return(%r2), %r2 /* return to intr_return, not here */
1098 ENDPROC(syscall_exit_rfi)
1099
1100
1101         /* Generic interruptions (illegal insn, unaligned, page fault, etc) */
1102
1103 ENTRY(intr_save)                /* for os_hpmc */
1104         mfsp    %sr7,%r16
1105         cmpib,COND(=),n 0,%r16,1f
1106         get_stack_use_cr30
1107         b       2f
1108         copy    %r8,%r26
1109
1110 1:
1111         get_stack_use_r30
1112         copy    %r8,%r26
1113
1114 2:
1115         save_specials   %r29
1116
1117         /* If this trap is a itlb miss, skip saving/adjusting isr/ior */
1118
1119         /*
1120          * FIXME: 1) Use a #define for the hardwired "6" below (and in
1121          *           traps.c.
1122          *        2) Once we start executing code above 4 Gb, we need
1123          *           to adjust iasq/iaoq here in the same way we
1124          *           adjust isr/ior below.
1125          */
1126
1127         cmpib,COND(=),n        6,%r26,skip_save_ior
1128
1129
1130         mfctl           %cr20, %r16 /* isr */
1131         nop             /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */
1132         mfctl           %cr21, %r17 /* ior */
1133
1134
1135 #ifdef CONFIG_64BIT
1136         /*
1137          * If the interrupted code was running with W bit off (32 bit),
1138          * clear the b bits (bits 0 & 1) in the ior.
1139          * save_specials left ipsw value in r8 for us to test.
1140          */
1141         extrd,u,*<>     %r8,PSW_W_BIT,1,%r0
1142         depdi           0,1,2,%r17
1143
1144         /*
1145          * FIXME: This code has hardwired assumptions about the split
1146          *        between space bits and offset bits. This will change
1147          *        when we allow alternate page sizes.
1148          */
1149
1150         /* adjust isr/ior. */
1151         extrd,u         %r16,63,SPACEID_SHIFT,%r1       /* get high bits from isr for ior */
1152         depd            %r1,31,SPACEID_SHIFT,%r17       /* deposit them into ior */
1153         depdi           0,63,SPACEID_SHIFT,%r16         /* clear them from isr */
1154 #endif
1155         STREG           %r16, PT_ISR(%r29)
1156         STREG           %r17, PT_IOR(%r29)
1157
1158
1159 skip_save_ior:
1160         virt_map
1161         save_general    %r29
1162
1163         ldo             PT_FR0(%r29), %r25
1164         save_fp         %r25
1165         
1166         loadgp
1167
1168         copy            %r29, %r25      /* arg1 is pt_regs */
1169 #ifdef CONFIG_64BIT
1170         ldo             -16(%r30),%r29  /* Reference param save area */
1171 #endif
1172
1173         ldil            L%intr_check_sig, %r2
1174         copy            %r25, %r16      /* save pt_regs */
1175
1176         b               handle_interruption
1177         ldo             R%intr_check_sig(%r2), %r2
1178 ENDPROC(intr_save)
1179
1180
1181         /*
1182          * Note for all tlb miss handlers:
1183          *
1184          * cr24 contains a pointer to the kernel address space
1185          * page directory.
1186          *
1187          * cr25 contains a pointer to the current user address
1188          * space page directory.
1189          *
1190          * sr3 will contain the space id of the user address space
1191          * of the current running thread while that thread is
1192          * running in the kernel.
1193          */
1194
1195         /*
1196          * register number allocations.  Note that these are all
1197          * in the shadowed registers
1198          */
1199
1200         t0 = r1         /* temporary register 0 */
1201         va = r8         /* virtual address for which the trap occured */
1202         t1 = r9         /* temporary register 1 */
1203         pte  = r16      /* pte/phys page # */
1204         prot = r17      /* prot bits */
1205         spc  = r24      /* space for which the trap occured */
1206         ptp = r25       /* page directory/page table pointer */
1207
1208 #ifdef CONFIG_64BIT
1209
1210 dtlb_miss_20w:
1211         space_adjust    spc,va,t0
1212         get_pgd         spc,ptp
1213         space_check     spc,t0,dtlb_fault
1214
1215         L3_ptep         ptp,pte,t0,va,dtlb_check_alias_20w
1216
1217         update_ptep     ptp,pte,t0,t1
1218
1219         make_insert_tlb spc,pte,prot
1220         
1221         idtlbt          pte,prot
1222
1223         rfir
1224         nop
1225
1226 dtlb_check_alias_20w:
1227         do_alias        spc,t0,t1,va,pte,prot,dtlb_fault
1228
1229         idtlbt          pte,prot
1230
1231         rfir
1232         nop
1233
1234 nadtlb_miss_20w:
1235         space_adjust    spc,va,t0
1236         get_pgd         spc,ptp
1237         space_check     spc,t0,nadtlb_fault
1238
1239         L3_ptep         ptp,pte,t0,va,nadtlb_check_flush_20w
1240
1241         update_ptep     ptp,pte,t0,t1
1242
1243         make_insert_tlb spc,pte,prot
1244
1245         idtlbt          pte,prot
1246
1247         rfir
1248         nop
1249
1250 nadtlb_check_flush_20w:
1251         bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
1252
1253         /* Insert a "flush only" translation */
1254
1255         depdi,z         7,7,3,prot
1256         depdi           1,10,1,prot
1257
1258         /* Drop prot bits from pte and convert to page addr for idtlbt */
1259         convert_for_tlb_insert20 pte
1260
1261         idtlbt          pte,prot
1262
1263         rfir
1264         nop
1265
1266 #else
1267
1268 dtlb_miss_11:
1269         get_pgd         spc,ptp
1270
1271         space_check     spc,t0,dtlb_fault
1272
1273         L2_ptep         ptp,pte,t0,va,dtlb_check_alias_11
1274
1275         update_ptep     ptp,pte,t0,t1
1276
1277         make_insert_tlb_11      spc,pte,prot
1278
1279         mfsp            %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
1280         mtsp            spc,%sr1
1281
1282         idtlba          pte,(%sr1,va)
1283         idtlbp          prot,(%sr1,va)
1284
1285         mtsp            t0, %sr1        /* Restore sr1 */
1286
1287         rfir
1288         nop
1289
1290 dtlb_check_alias_11:
1291
1292         /* Check to see if fault is in the temporary alias region */
1293
1294         cmpib,<>,n      0,spc,dtlb_fault /* forward */
1295         ldil            L%(TMPALIAS_MAP_START),t0
1296         copy            va,t1
1297         depwi           0,31,23,t1
1298         cmpb,<>,n       t0,t1,dtlb_fault /* forward */
1299         ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot
1300         depw,z          prot,8,7,prot
1301
1302         /*
1303          * OK, it is in the temp alias region, check whether "from" or "to".
1304          * Check "subtle" note in pacache.S re: r23/r26.
1305          */
1306
1307         extrw,u,=       va,9,1,r0
1308         or,tr           %r23,%r0,pte    /* If "from" use "from" page */
1309         or              %r26,%r0,pte    /* else "to", use "to" page  */
1310
1311         idtlba          pte,(va)
1312         idtlbp          prot,(va)
1313
1314         rfir
1315         nop
1316
1317 nadtlb_miss_11:
1318         get_pgd         spc,ptp
1319
1320         space_check     spc,t0,nadtlb_fault
1321
1322         L2_ptep         ptp,pte,t0,va,nadtlb_check_flush_11
1323
1324         update_ptep     ptp,pte,t0,t1
1325
1326         make_insert_tlb_11      spc,pte,prot
1327
1328
1329         mfsp            %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
1330         mtsp            spc,%sr1
1331
1332         idtlba          pte,(%sr1,va)
1333         idtlbp          prot,(%sr1,va)
1334
1335         mtsp            t0, %sr1        /* Restore sr1 */
1336
1337         rfir
1338         nop
1339
1340 nadtlb_check_flush_11:
1341         bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
1342
1343         /* Insert a "flush only" translation */
1344
1345         zdepi           7,7,3,prot
1346         depi            1,10,1,prot
1347
1348         /* Get rid of prot bits and convert to page addr for idtlba */
1349
1350         depi            0,31,ASM_PFN_PTE_SHIFT,pte
1351         SHRREG          pte,(ASM_PFN_PTE_SHIFT-(31-26)),pte
1352
1353         mfsp            %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
1354         mtsp            spc,%sr1
1355
1356         idtlba          pte,(%sr1,va)
1357         idtlbp          prot,(%sr1,va)
1358
1359         mtsp            t0, %sr1        /* Restore sr1 */
1360
1361         rfir
1362         nop
1363
1364 dtlb_miss_20:
1365         space_adjust    spc,va,t0
1366         get_pgd         spc,ptp
1367         space_check     spc,t0,dtlb_fault
1368
1369         L2_ptep         ptp,pte,t0,va,dtlb_check_alias_20
1370
1371         update_ptep     ptp,pte,t0,t1
1372
1373         make_insert_tlb spc,pte,prot
1374
1375         f_extend        pte,t0
1376
1377         idtlbt          pte,prot
1378
1379         rfir
1380         nop
1381
1382 dtlb_check_alias_20:
1383         do_alias        spc,t0,t1,va,pte,prot,dtlb_fault
1384         
1385         idtlbt          pte,prot
1386
1387         rfir
1388         nop
1389
1390 nadtlb_miss_20:
1391         get_pgd         spc,ptp
1392
1393         space_check     spc,t0,nadtlb_fault
1394
1395         L2_ptep         ptp,pte,t0,va,nadtlb_check_flush_20
1396
1397         update_ptep     ptp,pte,t0,t1
1398
1399         make_insert_tlb spc,pte,prot
1400
1401         f_extend        pte,t0
1402         
1403         idtlbt          pte,prot
1404
1405         rfir
1406         nop
1407
1408 nadtlb_check_flush_20:
1409         bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
1410
1411         /* Insert a "flush only" translation */
1412
1413         depdi,z         7,7,3,prot
1414         depdi           1,10,1,prot
1415
1416         /* Drop prot bits from pte and convert to page addr for idtlbt */
1417         convert_for_tlb_insert20 pte
1418
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,COND(=),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,COND(=),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,COND(=),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,COND(=),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,COND(=)         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,COND(=),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,COND(=),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,COND(=),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,COND(=),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,COND(=),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,COND(<>),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         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
2051
2052         /* Are we being ptraced? */
2053         ldw     TASK_FLAGS(%r1),%r19
2054         ldi     (_TIF_SINGLESTEP|_TIF_BLOCKSTEP),%r2
2055         and,COND(=)     %r19,%r2,%r0
2056         b,n     syscall_restore_rfi
2057
2058         ldo     TASK_PT_FR31(%r1),%r19             /* reload fpregs */
2059         rest_fp %r19
2060
2061         LDREG   TASK_PT_SAR(%r1),%r19              /* restore SAR */
2062         mtsar   %r19
2063
2064         LDREG   TASK_PT_GR2(%r1),%r2               /* restore user rp */
2065         LDREG   TASK_PT_GR19(%r1),%r19
2066         LDREG   TASK_PT_GR20(%r1),%r20
2067         LDREG   TASK_PT_GR21(%r1),%r21
2068         LDREG   TASK_PT_GR22(%r1),%r22
2069         LDREG   TASK_PT_GR23(%r1),%r23
2070         LDREG   TASK_PT_GR24(%r1),%r24
2071         LDREG   TASK_PT_GR25(%r1),%r25
2072         LDREG   TASK_PT_GR26(%r1),%r26
2073         LDREG   TASK_PT_GR27(%r1),%r27     /* restore user dp */
2074         LDREG   TASK_PT_GR28(%r1),%r28     /* syscall return value */
2075         LDREG   TASK_PT_GR29(%r1),%r29
2076         LDREG   TASK_PT_GR31(%r1),%r31     /* restore syscall rp */
2077
2078         /* NOTE: We use rsm/ssm pair to make this operation atomic */
2079         rsm     PSW_SM_I, %r0
2080         LDREG   TASK_PT_GR30(%r1),%r30             /* restore user sp */
2081         mfsp    %sr3,%r1                           /* Get users space id */
2082         mtsp    %r1,%sr7                           /* Restore sr7 */
2083         ssm     PSW_SM_I, %r0
2084
2085         /* Set sr2 to zero for userspace syscalls to work. */
2086         mtsp    %r0,%sr2 
2087         mtsp    %r1,%sr4                           /* Restore sr4 */
2088         mtsp    %r1,%sr5                           /* Restore sr5 */
2089         mtsp    %r1,%sr6                           /* Restore sr6 */
2090
2091         depi    3,31,2,%r31                        /* ensure return to user mode. */
2092
2093 #ifdef CONFIG_64BIT
2094         /* decide whether to reset the wide mode bit
2095          *
2096          * For a syscall, the W bit is stored in the lowest bit
2097          * of sp.  Extract it and reset W if it is zero */
2098         extrd,u,*<>     %r30,63,1,%r1
2099         rsm     PSW_SM_W, %r0
2100         /* now reset the lowest bit of sp if it was set */
2101         xor     %r30,%r1,%r30
2102 #endif
2103         be,n    0(%sr3,%r31)                       /* return to user space */
2104
2105         /* We have to return via an RFI, so that PSW T and R bits can be set
2106          * appropriately.
2107          * This sets up pt_regs so we can return via intr_restore, which is not
2108          * the most efficient way of doing things, but it works.
2109          */
2110 syscall_restore_rfi:
2111         ldo     -1(%r0),%r2                        /* Set recovery cntr to -1 */
2112         mtctl   %r2,%cr0                           /*   for immediate trap */
2113         LDREG   TASK_PT_PSW(%r1),%r2               /* Get old PSW */
2114         ldi     0x0b,%r20                          /* Create new PSW */
2115         depi    -1,13,1,%r20                       /* C, Q, D, and I bits */
2116
2117         /* The values of SINGLESTEP_BIT and BLOCKSTEP_BIT are
2118          * set in thread_info.h and converted to PA bitmap
2119          * numbers in asm-offsets.c */
2120
2121         /* if ((%r19.SINGLESTEP_BIT)) { %r20.27=1} */
2122         extru,= %r19,TIF_SINGLESTEP_PA_BIT,1,%r0
2123         depi    -1,27,1,%r20                       /* R bit */
2124
2125         /* if ((%r19.BLOCKSTEP_BIT)) { %r20.7=1} */
2126         extru,= %r19,TIF_BLOCKSTEP_PA_BIT,1,%r0
2127         depi    -1,7,1,%r20                        /* T bit */
2128
2129         STREG   %r20,TASK_PT_PSW(%r1)
2130
2131         /* Always store space registers, since sr3 can be changed (e.g. fork) */
2132
2133         mfsp    %sr3,%r25
2134         STREG   %r25,TASK_PT_SR3(%r1)
2135         STREG   %r25,TASK_PT_SR4(%r1)
2136         STREG   %r25,TASK_PT_SR5(%r1)
2137         STREG   %r25,TASK_PT_SR6(%r1)
2138         STREG   %r25,TASK_PT_SR7(%r1)
2139         STREG   %r25,TASK_PT_IASQ0(%r1)
2140         STREG   %r25,TASK_PT_IASQ1(%r1)
2141
2142         /* XXX W bit??? */
2143         /* Now if old D bit is clear, it means we didn't save all registers
2144          * on syscall entry, so do that now.  This only happens on TRACEME
2145          * calls, or if someone attached to us while we were on a syscall.
2146          * We could make this more efficient by not saving r3-r18, but
2147          * then we wouldn't be able to use the common intr_restore path.
2148          * It is only for traced processes anyway, so performance is not
2149          * an issue.
2150          */
2151         bb,<    %r2,30,pt_regs_ok                  /* Branch if D set */
2152         ldo     TASK_REGS(%r1),%r25
2153         reg_save %r25                              /* Save r3 to r18 */
2154
2155         /* Save the current sr */
2156         mfsp    %sr0,%r2
2157         STREG   %r2,TASK_PT_SR0(%r1)
2158
2159         /* Save the scratch sr */
2160         mfsp    %sr1,%r2
2161         STREG   %r2,TASK_PT_SR1(%r1)
2162
2163         /* sr2 should be set to zero for userspace syscalls */
2164         STREG   %r0,TASK_PT_SR2(%r1)
2165
2166 pt_regs_ok:
2167         LDREG   TASK_PT_GR31(%r1),%r2
2168         depi    3,31,2,%r2                         /* ensure return to user mode. */
2169         STREG   %r2,TASK_PT_IAOQ0(%r1)
2170         ldo     4(%r2),%r2
2171         STREG   %r2,TASK_PT_IAOQ1(%r1)
2172         copy    %r25,%r16
2173         b       intr_restore
2174         nop
2175
2176         .import schedule,code
2177 syscall_do_resched:
2178         BL      schedule,%r2
2179 #ifdef CONFIG_64BIT
2180         ldo     -16(%r30),%r29          /* Reference param save area */
2181 #else
2182         nop
2183 #endif
2184         b       syscall_check_resched   /* if resched, we start over again */
2185         nop
2186 ENDPROC(syscall_exit)
2187
2188
2189 #ifdef CONFIG_FUNCTION_TRACER
2190         .import ftrace_function_trampoline,code
2191 ENTRY(_mcount)
2192         copy    %r3, %arg2
2193         b       ftrace_function_trampoline
2194         nop
2195 ENDPROC(_mcount)
2196
2197 ENTRY(return_to_handler)
2198         load32  return_trampoline, %rp
2199         copy    %ret0, %arg0
2200         copy    %ret1, %arg1
2201         b       ftrace_return_to_handler
2202         nop
2203 return_trampoline:
2204         copy    %ret0, %rp
2205         copy    %r23, %ret0
2206         copy    %r24, %ret1
2207
2208 .globl ftrace_stub
2209 ftrace_stub:
2210         bv      %r0(%rp)
2211         nop
2212 ENDPROC(return_to_handler)
2213 #endif  /* CONFIG_FUNCTION_TRACER */
2214
2215
2216 get_register:
2217         /*
2218          * get_register is used by the non access tlb miss handlers to
2219          * copy the value of the general register specified in r8 into
2220          * r1. This routine can't be used for shadowed registers, since
2221          * the rfir will restore the original value. So, for the shadowed
2222          * registers we put a -1 into r1 to indicate that the register
2223          * should not be used (the register being copied could also have
2224          * a -1 in it, but that is OK, it just means that we will have
2225          * to use the slow path instead).
2226          */
2227         blr     %r8,%r0
2228         nop
2229         bv      %r0(%r25)    /* r0 */
2230         copy    %r0,%r1
2231         bv      %r0(%r25)    /* r1 - shadowed */
2232         ldi     -1,%r1
2233         bv      %r0(%r25)    /* r2 */
2234         copy    %r2,%r1
2235         bv      %r0(%r25)    /* r3 */
2236         copy    %r3,%r1
2237         bv      %r0(%r25)    /* r4 */
2238         copy    %r4,%r1
2239         bv      %r0(%r25)    /* r5 */
2240         copy    %r5,%r1
2241         bv      %r0(%r25)    /* r6 */
2242         copy    %r6,%r1
2243         bv      %r0(%r25)    /* r7 */
2244         copy    %r7,%r1
2245         bv      %r0(%r25)    /* r8 - shadowed */
2246         ldi     -1,%r1
2247         bv      %r0(%r25)    /* r9 - shadowed */
2248         ldi     -1,%r1
2249         bv      %r0(%r25)    /* r10 */
2250         copy    %r10,%r1
2251         bv      %r0(%r25)    /* r11 */
2252         copy    %r11,%r1
2253         bv      %r0(%r25)    /* r12 */
2254         copy    %r12,%r1
2255         bv      %r0(%r25)    /* r13 */
2256         copy    %r13,%r1
2257         bv      %r0(%r25)    /* r14 */
2258         copy    %r14,%r1
2259         bv      %r0(%r25)    /* r15 */
2260         copy    %r15,%r1
2261         bv      %r0(%r25)    /* r16 - shadowed */
2262         ldi     -1,%r1
2263         bv      %r0(%r25)    /* r17 - shadowed */
2264         ldi     -1,%r1
2265         bv      %r0(%r25)    /* r18 */
2266         copy    %r18,%r1
2267         bv      %r0(%r25)    /* r19 */
2268         copy    %r19,%r1
2269         bv      %r0(%r25)    /* r20 */
2270         copy    %r20,%r1
2271         bv      %r0(%r25)    /* r21 */
2272         copy    %r21,%r1
2273         bv      %r0(%r25)    /* r22 */
2274         copy    %r22,%r1
2275         bv      %r0(%r25)    /* r23 */
2276         copy    %r23,%r1
2277         bv      %r0(%r25)    /* r24 - shadowed */
2278         ldi     -1,%r1
2279         bv      %r0(%r25)    /* r25 - shadowed */
2280         ldi     -1,%r1
2281         bv      %r0(%r25)    /* r26 */
2282         copy    %r26,%r1
2283         bv      %r0(%r25)    /* r27 */
2284         copy    %r27,%r1
2285         bv      %r0(%r25)    /* r28 */
2286         copy    %r28,%r1
2287         bv      %r0(%r25)    /* r29 */
2288         copy    %r29,%r1
2289         bv      %r0(%r25)    /* r30 */
2290         copy    %r30,%r1
2291         bv      %r0(%r25)    /* r31 */
2292         copy    %r31,%r1
2293
2294
2295 set_register:
2296         /*
2297          * set_register is used by the non access tlb miss handlers to
2298          * copy the value of r1 into the general register specified in
2299          * r8.
2300          */
2301         blr     %r8,%r0
2302         nop
2303         bv      %r0(%r25)    /* r0 (silly, but it is a place holder) */
2304         copy    %r1,%r0
2305         bv      %r0(%r25)    /* r1 */
2306         copy    %r1,%r1
2307         bv      %r0(%r25)    /* r2 */
2308         copy    %r1,%r2
2309         bv      %r0(%r25)    /* r3 */
2310         copy    %r1,%r3
2311         bv      %r0(%r25)    /* r4 */
2312         copy    %r1,%r4
2313         bv      %r0(%r25)    /* r5 */
2314         copy    %r1,%r5
2315         bv      %r0(%r25)    /* r6 */
2316         copy    %r1,%r6
2317         bv      %r0(%r25)    /* r7 */
2318         copy    %r1,%r7
2319         bv      %r0(%r25)    /* r8 */
2320         copy    %r1,%r8
2321         bv      %r0(%r25)    /* r9 */
2322         copy    %r1,%r9
2323         bv      %r0(%r25)    /* r10 */
2324         copy    %r1,%r10
2325         bv      %r0(%r25)    /* r11 */
2326         copy    %r1,%r11
2327         bv      %r0(%r25)    /* r12 */
2328         copy    %r1,%r12
2329         bv      %r0(%r25)    /* r13 */
2330         copy    %r1,%r13
2331         bv      %r0(%r25)    /* r14 */
2332         copy    %r1,%r14
2333         bv      %r0(%r25)    /* r15 */
2334         copy    %r1,%r15
2335         bv      %r0(%r25)    /* r16 */
2336         copy    %r1,%r16
2337         bv      %r0(%r25)    /* r17 */
2338         copy    %r1,%r17
2339         bv      %r0(%r25)    /* r18 */
2340         copy    %r1,%r18
2341         bv      %r0(%r25)    /* r19 */
2342         copy    %r1,%r19
2343         bv      %r0(%r25)    /* r20 */
2344         copy    %r1,%r20
2345         bv      %r0(%r25)    /* r21 */
2346         copy    %r1,%r21
2347         bv      %r0(%r25)    /* r22 */
2348         copy    %r1,%r22
2349         bv      %r0(%r25)    /* r23 */
2350         copy    %r1,%r23
2351         bv      %r0(%r25)    /* r24 */
2352         copy    %r1,%r24
2353         bv      %r0(%r25)    /* r25 */
2354         copy    %r1,%r25
2355         bv      %r0(%r25)    /* r26 */
2356         copy    %r1,%r26
2357         bv      %r0(%r25)    /* r27 */
2358         copy    %r1,%r27
2359         bv      %r0(%r25)    /* r28 */
2360         copy    %r1,%r28
2361         bv      %r0(%r25)    /* r29 */
2362         copy    %r1,%r29
2363         bv      %r0(%r25)    /* r30 */
2364         copy    %r1,%r30
2365         bv      %r0(%r25)    /* r31 */
2366         copy    %r1,%r31
2367