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