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