Linux 5.6.13
[linux/fpc-iii.git] / arch / parisc / kernel / entry.S
blob9a03e29c87330f3f00228ccdec62c40f9cbab2aa
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Linux/PA-RISC Project (http://www.parisc-linux.org/)
4  *
5  * kernel entry points (interruptions, system call wrappers)
6  *  Copyright (C) 1999,2000 Philipp Rumpf 
7  *  Copyright (C) 1999 SuSE GmbH Nuernberg 
8  *  Copyright (C) 2000 Hewlett-Packard (John Marvin)
9  *  Copyright (C) 1999 Hewlett-Packard (Frank Rowand)
10  */
12 #include <asm/asm-offsets.h>
14 /* we have the following possibilities to act on an interruption:
15  *  - handle in assembly and use shadowed registers only
16  *  - save registers to kernel stack and handle in assembly or C */
19 #include <asm/psw.h>
20 #include <asm/cache.h>          /* for L1_CACHE_SHIFT */
21 #include <asm/assembly.h>       /* for LDREG/STREG defines */
22 #include <asm/pgtable.h>
23 #include <asm/signal.h>
24 #include <asm/unistd.h>
25 #include <asm/ldcw.h>
26 #include <asm/traps.h>
27 #include <asm/thread_info.h>
28 #include <asm/alternative.h>
30 #include <linux/linkage.h>
32 #ifdef CONFIG_64BIT
33         .level 2.0w
34 #else
35         .level 2.0
36 #endif
38         .import         pa_tlb_lock,data
39         .macro  load_pa_tlb_lock reg
40         mfctl           %cr25,\reg
41         addil           L%(PAGE_SIZE << (PGD_ALLOC_ORDER - 1)),\reg
42         .endm
44         /* space_to_prot macro creates a prot id from a space id */
46 #if (SPACEID_SHIFT) == 0
47         .macro  space_to_prot spc prot
48         depd,z  \spc,62,31,\prot
49         .endm
50 #else
51         .macro  space_to_prot spc prot
52         extrd,u \spc,(64 - (SPACEID_SHIFT)),32,\prot
53         .endm
54 #endif
56         /* Switch to virtual mapping, trashing only %r1 */
57         .macro  virt_map
58         /* pcxt_ssm_bug */
59         rsm     PSW_SM_I, %r0   /* barrier for "Relied upon Translation */
60         mtsp    %r0, %sr4
61         mtsp    %r0, %sr5
62         mtsp    %r0, %sr6
63         tovirt_r1 %r29
64         load32  KERNEL_PSW, %r1
66         rsm     PSW_SM_QUIET,%r0        /* second "heavy weight" ctl op */
67         mtctl   %r0, %cr17      /* Clear IIASQ tail */
68         mtctl   %r0, %cr17      /* Clear IIASQ head */
69         mtctl   %r1, %ipsw
70         load32  4f, %r1
71         mtctl   %r1, %cr18      /* Set IIAOQ tail */
72         ldo     4(%r1), %r1
73         mtctl   %r1, %cr18      /* Set IIAOQ head */
74         rfir
75         nop
77         .endm
79         /*
80          * The "get_stack" macros are responsible for determining the
81          * kernel stack value.
82          *
83          *      If sr7 == 0
84          *          Already using a kernel stack, so call the
85          *          get_stack_use_r30 macro to push a pt_regs structure
86          *          on the stack, and store registers there.
87          *      else
88          *          Need to set up a kernel stack, so call the
89          *          get_stack_use_cr30 macro to set up a pointer
90          *          to the pt_regs structure contained within the
91          *          task pointer pointed to by cr30. Set the stack
92          *          pointer to point to the end of the task structure.
93          *
94          * Note that we use shadowed registers for temps until
95          * we can save %r26 and %r29. %r26 is used to preserve
96          * %r8 (a shadowed register) which temporarily contained
97          * either the fault type ("code") or the eirr. We need
98          * to use a non-shadowed register to carry the value over
99          * the rfir in virt_map. We use %r26 since this value winds
100          * up being passed as the argument to either do_cpu_irq_mask
101          * or handle_interruption. %r29 is used to hold a pointer
102          * the register save area, and once again, it needs to
103          * be a non-shadowed register so that it survives the rfir.
104          *
105          * N.B. TASK_SZ_ALGN and PT_SZ_ALGN include space for a stack frame.
106          */
108         .macro  get_stack_use_cr30
110         /* we save the registers in the task struct */
112         copy    %r30, %r17
113         mfctl   %cr30, %r1
114         ldo     THREAD_SZ_ALGN(%r1), %r30
115         mtsp    %r0,%sr7
116         mtsp    %r16,%sr3
117         tophys  %r1,%r9
118         LDREG   TI_TASK(%r9), %r1       /* thread_info -> task_struct */
119         tophys  %r1,%r9
120         ldo     TASK_REGS(%r9),%r9
121         STREG   %r17,PT_GR30(%r9)
122         STREG   %r29,PT_GR29(%r9)
123         STREG   %r26,PT_GR26(%r9)
124         STREG   %r16,PT_SR7(%r9)
125         copy    %r9,%r29
126         .endm
128         .macro  get_stack_use_r30
130         /* we put a struct pt_regs on the stack and save the registers there */
132         tophys  %r30,%r9
133         copy    %r30,%r1
134         ldo     PT_SZ_ALGN(%r30),%r30
135         STREG   %r1,PT_GR30(%r9)
136         STREG   %r29,PT_GR29(%r9)
137         STREG   %r26,PT_GR26(%r9)
138         STREG   %r16,PT_SR7(%r9)
139         copy    %r9,%r29
140         .endm
142         .macro  rest_stack
143         LDREG   PT_GR1(%r29), %r1
144         LDREG   PT_GR30(%r29),%r30
145         LDREG   PT_GR29(%r29),%r29
146         .endm
148         /* default interruption handler
149          * (calls traps.c:handle_interruption) */
150         .macro  def code
151         b       intr_save
152         ldi     \code, %r8
153         .align  32
154         .endm
156         /* Interrupt interruption handler
157          * (calls irq.c:do_cpu_irq_mask) */
158         .macro  extint code
159         b       intr_extint
160         mfsp    %sr7,%r16
161         .align  32
162         .endm   
164         .import os_hpmc, code
166         /* HPMC handler */
167         .macro  hpmc code
168         nop                     /* must be a NOP, will be patched later */
169         load32  PA(os_hpmc), %r3
170         bv,n    0(%r3)
171         nop
172         .word   0               /* checksum (will be patched) */
173         .word   0               /* address of handler */
174         .word   0               /* length of handler */
175         .endm
177         /*
178          * Performance Note: Instructions will be moved up into
179          * this part of the code later on, once we are sure
180          * that the tlb miss handlers are close to final form.
181          */
183         /* Register definitions for tlb miss handler macros */
185         va  = r8        /* virtual address for which the trap occurred */
186         spc = r24       /* space for which the trap occurred */
188 #ifndef CONFIG_64BIT
190         /*
191          * itlb miss interruption handler (parisc 1.1 - 32 bit)
192          */
194         .macro  itlb_11 code
196         mfctl   %pcsq, spc
197         b       itlb_miss_11
198         mfctl   %pcoq, va
200         .align          32
201         .endm
202 #endif
203         
204         /*
205          * itlb miss interruption handler (parisc 2.0)
206          */
208         .macro  itlb_20 code
209         mfctl   %pcsq, spc
210 #ifdef CONFIG_64BIT
211         b       itlb_miss_20w
212 #else
213         b       itlb_miss_20
214 #endif
215         mfctl   %pcoq, va
217         .align          32
218         .endm
219         
220 #ifndef CONFIG_64BIT
221         /*
222          * naitlb miss interruption handler (parisc 1.1 - 32 bit)
223          */
225         .macro  naitlb_11 code
227         mfctl   %isr,spc
228         b       naitlb_miss_11
229         mfctl   %ior,va
231         .align          32
232         .endm
233 #endif
234         
235         /*
236          * naitlb miss interruption handler (parisc 2.0)
237          */
239         .macro  naitlb_20 code
241         mfctl   %isr,spc
242 #ifdef CONFIG_64BIT
243         b       naitlb_miss_20w
244 #else
245         b       naitlb_miss_20
246 #endif
247         mfctl   %ior,va
249         .align          32
250         .endm
251         
252 #ifndef CONFIG_64BIT
253         /*
254          * dtlb miss interruption handler (parisc 1.1 - 32 bit)
255          */
257         .macro  dtlb_11 code
259         mfctl   %isr, spc
260         b       dtlb_miss_11
261         mfctl   %ior, va
263         .align          32
264         .endm
265 #endif
267         /*
268          * dtlb miss interruption handler (parisc 2.0)
269          */
271         .macro  dtlb_20 code
273         mfctl   %isr, spc
274 #ifdef CONFIG_64BIT
275         b       dtlb_miss_20w
276 #else
277         b       dtlb_miss_20
278 #endif
279         mfctl   %ior, va
281         .align          32
282         .endm
283         
284 #ifndef CONFIG_64BIT
285         /* nadtlb miss interruption handler (parisc 1.1 - 32 bit) */
287         .macro  nadtlb_11 code
289         mfctl   %isr,spc
290         b       nadtlb_miss_11
291         mfctl   %ior,va
293         .align          32
294         .endm
295 #endif
296         
297         /* nadtlb miss interruption handler (parisc 2.0) */
299         .macro  nadtlb_20 code
301         mfctl   %isr,spc
302 #ifdef CONFIG_64BIT
303         b       nadtlb_miss_20w
304 #else
305         b       nadtlb_miss_20
306 #endif
307         mfctl   %ior,va
309         .align          32
310         .endm
311         
312 #ifndef CONFIG_64BIT
313         /*
314          * dirty bit trap interruption handler (parisc 1.1 - 32 bit)
315          */
317         .macro  dbit_11 code
319         mfctl   %isr,spc
320         b       dbit_trap_11
321         mfctl   %ior,va
323         .align          32
324         .endm
325 #endif
327         /*
328          * dirty bit trap interruption handler (parisc 2.0)
329          */
331         .macro  dbit_20 code
333         mfctl   %isr,spc
334 #ifdef CONFIG_64BIT
335         b       dbit_trap_20w
336 #else
337         b       dbit_trap_20
338 #endif
339         mfctl   %ior,va
341         .align          32
342         .endm
344         /* In LP64, the space contains part of the upper 32 bits of the
345          * fault.  We have to extract this and place it in the va,
346          * zeroing the corresponding bits in the space register */
347         .macro          space_adjust    spc,va,tmp
348 #ifdef CONFIG_64BIT
349         extrd,u         \spc,63,SPACEID_SHIFT,\tmp
350         depd            %r0,63,SPACEID_SHIFT,\spc
351         depd            \tmp,31,SPACEID_SHIFT,\va
352 #endif
353         .endm
355         .import         swapper_pg_dir,code
357         /* Get the pgd.  For faults on space zero (kernel space), this
358          * is simply swapper_pg_dir.  For user space faults, the
359          * pgd is stored in %cr25 */
360         .macro          get_pgd         spc,reg
361         ldil            L%PA(swapper_pg_dir),\reg
362         ldo             R%PA(swapper_pg_dir)(\reg),\reg
363         or,COND(=)      %r0,\spc,%r0
364         mfctl           %cr25,\reg
365         .endm
367         /* 
368                 space_check(spc,tmp,fault)
370                 spc - The space we saw the fault with.
371                 tmp - The place to store the current space.
372                 fault - Function to call on failure.
374                 Only allow faults on different spaces from the
375                 currently active one if we're the kernel 
377         */
378         .macro          space_check     spc,tmp,fault
379         mfsp            %sr7,\tmp
380         /* check against %r0 which is same value as LINUX_GATEWAY_SPACE */
381         or,COND(<>)     %r0,\spc,%r0    /* user may execute gateway page
382                                          * as kernel, so defeat the space
383                                          * check if it is */
384         copy            \spc,\tmp
385         or,COND(=)      %r0,\tmp,%r0    /* nullify if executing as kernel */
386         cmpb,COND(<>),n \tmp,\spc,\fault
387         .endm
389         /* Look up a PTE in a 2-Level scheme (faulting at each
390          * level if the entry isn't present 
391          *
392          * NOTE: we use ldw even for LP64, since the short pointers
393          * can address up to 1TB
394          */
395         .macro          L2_ptep pmd,pte,index,va,fault
396 #if CONFIG_PGTABLE_LEVELS == 3
397         extru           \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index
398 #else
399 # if defined(CONFIG_64BIT)
400         extrd,u         \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
401   #else
402   # if PAGE_SIZE > 4096
403         extru           \va,31-ASM_PGDIR_SHIFT,32-ASM_PGDIR_SHIFT,\index
404   # else
405         extru           \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
406   # endif
407 # endif
408 #endif
409         dep             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
410         copy            %r0,\pte
411         ldw,s           \index(\pmd),\pmd
412         bb,>=,n         \pmd,_PxD_PRESENT_BIT,\fault
413         dep             %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
414         SHLREG          \pmd,PxD_VALUE_SHIFT,\pmd
415         extru           \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
416         dep             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
417         shladd          \index,BITS_PER_PTE_ENTRY,\pmd,\pmd /* pmd is now pte */
418         .endm
420         /* Look up PTE in a 3-Level scheme.
421          *
422          * Here we implement a Hybrid L2/L3 scheme: we allocate the
423          * first pmd adjacent to the pgd.  This means that we can
424          * subtract a constant offset to get to it.  The pmd and pgd
425          * sizes are arranged so that a single pmd covers 4GB (giving
426          * a full LP64 process access to 8TB) so our lookups are
427          * effectively L2 for the first 4GB of the kernel (i.e. for
428          * all ILP32 processes and all the kernel for machines with
429          * under 4GB of memory) */
430         .macro          L3_ptep pgd,pte,index,va,fault
431 #if CONFIG_PGTABLE_LEVELS == 3 /* we might have a 2-Level scheme, e.g. with 16kb page size */
432         extrd,u         \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
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
447         /* Acquire pa_tlb_lock lock and check page is present. */
448         .macro          tlb_lock        spc,ptp,pte,tmp,tmp1,fault
449 #ifdef CONFIG_SMP
450 98:     cmpib,COND(=),n 0,\spc,2f
451         load_pa_tlb_lock \tmp
452 1:      LDCW            0(\tmp),\tmp1
453         cmpib,COND(=)   0,\tmp1,1b
454         nop
455         LDREG           0(\ptp),\pte
456         bb,<,n          \pte,_PAGE_PRESENT_BIT,3f
457         LDCW            0(\tmp),\tmp1
458         b               \fault
459         stw             \spc,0(\tmp)
460 99:     ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
461 #endif
462 2:      LDREG           0(\ptp),\pte
463         bb,>=,n         \pte,_PAGE_PRESENT_BIT,\fault
465         .endm
467         /* Release pa_tlb_lock lock without reloading lock address. */
468         .macro          tlb_unlock0     spc,tmp,tmp1
469 #ifdef CONFIG_SMP
470 98:     or,COND(=)      %r0,\spc,%r0
471         LDCW            0(\tmp),\tmp1
472         or,COND(=)      %r0,\spc,%r0
473         stw             \spc,0(\tmp)
474 99:     ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
475 #endif
476         .endm
478         /* Release pa_tlb_lock lock. */
479         .macro          tlb_unlock1     spc,tmp,tmp1
480 #ifdef CONFIG_SMP
481 98:     load_pa_tlb_lock \tmp
482 99:     ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
483         tlb_unlock0     \spc,\tmp,\tmp1
484 #endif
485         .endm
487         /* Set the _PAGE_ACCESSED bit of the PTE.  Be clever and
488          * don't needlessly dirty the cache line if it was already set */
489         .macro          update_accessed ptp,pte,tmp,tmp1
490         ldi             _PAGE_ACCESSED,\tmp1
491         or              \tmp1,\pte,\tmp
492         and,COND(<>)    \tmp1,\pte,%r0
493         STREG           \tmp,0(\ptp)
494         .endm
496         /* Set the dirty bit (and accessed bit).  No need to be
497          * clever, this is only used from the dirty fault */
498         .macro          update_dirty    ptp,pte,tmp
499         ldi             _PAGE_ACCESSED|_PAGE_DIRTY,\tmp
500         or              \tmp,\pte,\pte
501         STREG           \pte,0(\ptp)
502         .endm
504         /* We have (depending on the page size):
505          * - 38 to 52-bit Physical Page Number
506          * - 12 to 26-bit page offset
507          */
508         /* bitshift difference between a PFN (based on kernel's PAGE_SIZE)
509          * to a CPU TLB 4k PFN (4k => 12 bits to shift) */
510         #define PAGE_ADD_SHIFT          (PAGE_SHIFT-12)
511         #define PAGE_ADD_HUGE_SHIFT     (REAL_HPAGE_SHIFT-12)
513         /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
514         .macro          convert_for_tlb_insert20 pte,tmp
515 #ifdef CONFIG_HUGETLB_PAGE
516         copy            \pte,\tmp
517         extrd,u         \tmp,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
518                                 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
520         depdi           _PAGE_SIZE_ENCODING_DEFAULT,63,\
521                                 (63-58)+PAGE_ADD_SHIFT,\pte
522         extrd,u,*=      \tmp,_PAGE_HPAGE_BIT+32,1,%r0
523         depdi           _HUGE_PAGE_SIZE_ENCODING_DEFAULT,63,\
524                                 (63-58)+PAGE_ADD_HUGE_SHIFT,\pte
525 #else /* Huge pages disabled */
526         extrd,u         \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
527                                 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
528         depdi           _PAGE_SIZE_ENCODING_DEFAULT,63,\
529                                 (63-58)+PAGE_ADD_SHIFT,\pte
530 #endif
531         .endm
533         /* Convert the pte and prot to tlb insertion values.  How
534          * this happens is quite subtle, read below */
535         .macro          make_insert_tlb spc,pte,prot,tmp
536         space_to_prot   \spc \prot        /* create prot id from space */
537         /* The following is the real subtlety.  This is depositing
538          * T <-> _PAGE_REFTRAP
539          * D <-> _PAGE_DIRTY
540          * B <-> _PAGE_DMB (memory break)
541          *
542          * Then incredible subtlety: The access rights are
543          * _PAGE_GATEWAY, _PAGE_EXEC and _PAGE_WRITE
544          * See 3-14 of the parisc 2.0 manual
545          *
546          * Finally, _PAGE_READ goes in the top bit of PL1 (so we
547          * trigger an access rights trap in user space if the user
548          * tries to read an unreadable page */
549         depd            \pte,8,7,\prot
551         /* PAGE_USER indicates the page can be read with user privileges,
552          * so deposit X1|11 to PL1|PL2 (remember the upper bit of PL1
553          * contains _PAGE_READ) */
554         extrd,u,*=      \pte,_PAGE_USER_BIT+32,1,%r0
555         depdi           7,11,3,\prot
556         /* If we're a gateway page, drop PL2 back to zero for promotion
557          * to kernel privilege (so we can execute the page as kernel).
558          * Any privilege promotion page always denys read and write */
559         extrd,u,*=      \pte,_PAGE_GATEWAY_BIT+32,1,%r0
560         depd            %r0,11,2,\prot  /* If Gateway, Set PL2 to 0 */
562         /* Enforce uncacheable pages.
563          * This should ONLY be use for MMIO on PA 2.0 machines.
564          * Memory/DMA is cache coherent on all PA2.0 machines we support
565          * (that means T-class is NOT supported) and the memory controllers
566          * on most of those machines only handles cache transactions.
567          */
568         extrd,u,*=      \pte,_PAGE_NO_CACHE_BIT+32,1,%r0
569         depdi           1,12,1,\prot
571         /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
572         convert_for_tlb_insert20 \pte \tmp
573         .endm
575         /* Identical macro to make_insert_tlb above, except it
576          * makes the tlb entry for the differently formatted pa11
577          * insertion instructions */
578         .macro          make_insert_tlb_11      spc,pte,prot
579         zdep            \spc,30,15,\prot
580         dep             \pte,8,7,\prot
581         extru,=         \pte,_PAGE_NO_CACHE_BIT,1,%r0
582         depi            1,12,1,\prot
583         extru,=         \pte,_PAGE_USER_BIT,1,%r0
584         depi            7,11,3,\prot   /* Set for user space (1 rsvd for read) */
585         extru,=         \pte,_PAGE_GATEWAY_BIT,1,%r0
586         depi            0,11,2,\prot    /* If Gateway, Set PL2 to 0 */
588         /* Get rid of prot bits and convert to page addr for iitlba */
590         depi            0,31,ASM_PFN_PTE_SHIFT,\pte
591         SHRREG          \pte,(ASM_PFN_PTE_SHIFT-(31-26)),\pte
592         .endm
594         /* This is for ILP32 PA2.0 only.  The TLB insertion needs
595          * to extend into I/O space if the address is 0xfXXXXXXX
596          * so we extend the f's into the top word of the pte in
597          * this case */
598         .macro          f_extend        pte,tmp
599         extrd,s         \pte,42,4,\tmp
600         addi,<>         1,\tmp,%r0
601         extrd,s         \pte,63,25,\pte
602         .endm
604         /* The alias region is an 8MB aligned 16MB to do clear and
605          * copy user pages at addresses congruent with the user
606          * virtual address.
607          *
608          * To use the alias page, you set %r26 up with the to TLB
609          * entry (identifying the physical page) and %r23 up with
610          * the from tlb entry (or nothing if only a to entry---for
611          * clear_user_page_asm) */
612         .macro          do_alias        spc,tmp,tmp1,va,pte,prot,fault,patype
613         cmpib,COND(<>),n 0,\spc,\fault
614         ldil            L%(TMPALIAS_MAP_START),\tmp
615 #if defined(CONFIG_64BIT) && (TMPALIAS_MAP_START >= 0x80000000)
616         /* on LP64, ldi will sign extend into the upper 32 bits,
617          * which is behaviour we don't want */
618         depdi           0,31,32,\tmp
619 #endif
620         copy            \va,\tmp1
621         depi            0,31,23,\tmp1
622         cmpb,COND(<>),n \tmp,\tmp1,\fault
623         mfctl           %cr19,\tmp      /* iir */
624         /* get the opcode (first six bits) into \tmp */
625         extrw,u         \tmp,5,6,\tmp
626         /*
627          * Only setting the T bit prevents data cache movein
628          * Setting access rights to zero prevents instruction cache movein
629          *
630          * Note subtlety here: _PAGE_GATEWAY, _PAGE_EXEC and _PAGE_WRITE go
631          * to type field and _PAGE_READ goes to top bit of PL1
632          */
633         ldi             (_PAGE_REFTRAP|_PAGE_READ|_PAGE_WRITE),\prot
634         /*
635          * so if the opcode is one (i.e. this is a memory management
636          * instruction) nullify the next load so \prot is only T.
637          * Otherwise this is a normal data operation
638          */
639         cmpiclr,=       0x01,\tmp,%r0
640         ldi             (_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot
641 .ifc \patype,20
642         depd,z          \prot,8,7,\prot
643 .else
644 .ifc \patype,11
645         depw,z          \prot,8,7,\prot
646 .else
647         .error "undefined PA type to do_alias"
648 .endif
649 .endif
650         /*
651          * OK, it is in the temp alias region, check whether "from" or "to".
652          * Check "subtle" note in pacache.S re: r23/r26.
653          */
654 #ifdef CONFIG_64BIT
655         extrd,u,*=      \va,41,1,%r0
656 #else
657         extrw,u,=       \va,9,1,%r0
658 #endif
659         or,COND(tr)     %r23,%r0,\pte
660         or              %r26,%r0,\pte
661         .endm 
664         /*
665          * Fault_vectors are architecturally required to be aligned on a 2K
666          * boundary
667          */
669         .section .text.hot
670         .align 2048
672 ENTRY(fault_vector_20)
673         /* First vector is invalid (0) */
674         .ascii  "cows can fly"
675         .byte 0
676         .align 32
678         hpmc             1
679         def              2
680         def              3
681         extint           4
682         def              5
683         itlb_20          PARISC_ITLB_TRAP
684         def              7
685         def              8
686         def              9
687         def             10
688         def             11
689         def             12
690         def             13
691         def             14
692         dtlb_20         15
693         naitlb_20       16
694         nadtlb_20       17
695         def             18
696         def             19
697         dbit_20         20
698         def             21
699         def             22
700         def             23
701         def             24
702         def             25
703         def             26
704         def             27
705         def             28
706         def             29
707         def             30
708         def             31
709 END(fault_vector_20)
711 #ifndef CONFIG_64BIT
713         .align 2048
715 ENTRY(fault_vector_11)
716         /* First vector is invalid (0) */
717         .ascii  "cows can fly"
718         .byte 0
719         .align 32
721         hpmc             1
722         def              2
723         def              3
724         extint           4
725         def              5
726         itlb_11          PARISC_ITLB_TRAP
727         def              7
728         def              8
729         def              9
730         def             10
731         def             11
732         def             12
733         def             13
734         def             14
735         dtlb_11         15
736         naitlb_11       16
737         nadtlb_11       17
738         def             18
739         def             19
740         dbit_11         20
741         def             21
742         def             22
743         def             23
744         def             24
745         def             25
746         def             26
747         def             27
748         def             28
749         def             29
750         def             30
751         def             31
752 END(fault_vector_11)
754 #endif
755         /* Fault vector is separately protected and *must* be on its own page */
756         .align          PAGE_SIZE
758         .import         handle_interruption,code
759         .import         do_cpu_irq_mask,code
761         /*
762          * Child Returns here
763          *
764          * copy_thread moved args into task save area.
765          */
767 ENTRY(ret_from_kernel_thread)
768         /* Call schedule_tail first though */
769         BL      schedule_tail, %r2
770         nop
772         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
773         LDREG   TASK_PT_GR25(%r1), %r26
774 #ifdef CONFIG_64BIT
775         LDREG   TASK_PT_GR27(%r1), %r27
776 #endif
777         LDREG   TASK_PT_GR26(%r1), %r1
778         ble     0(%sr7, %r1)
779         copy    %r31, %r2
780         b       finish_child_return
781         nop
782 END(ret_from_kernel_thread)
785         /*
786          * struct task_struct *_switch_to(struct task_struct *prev,
787          *      struct task_struct *next)
788          *
789          * switch kernel stacks and return prev */
790 ENTRY_CFI(_switch_to)
791         STREG    %r2, -RP_OFFSET(%r30)
793         callee_save_float
794         callee_save
796         load32  _switch_to_ret, %r2
798         STREG   %r2, TASK_PT_KPC(%r26)
799         LDREG   TASK_PT_KPC(%r25), %r2
801         STREG   %r30, TASK_PT_KSP(%r26)
802         LDREG   TASK_PT_KSP(%r25), %r30
803         LDREG   TASK_THREAD_INFO(%r25), %r25
804         bv      %r0(%r2)
805         mtctl   %r25,%cr30
807 ENTRY(_switch_to_ret)
808         mtctl   %r0, %cr0               /* Needed for single stepping */
809         callee_rest
810         callee_rest_float
812         LDREG   -RP_OFFSET(%r30), %r2
813         bv      %r0(%r2)
814         copy    %r26, %r28
815 ENDPROC_CFI(_switch_to)
817         /*
818          * Common rfi return path for interruptions, kernel execve, and
819          * sys_rt_sigreturn (sometimes).  The sys_rt_sigreturn syscall will
820          * return via this path if the signal was received when the process
821          * was running; if the process was blocked on a syscall then the
822          * normal syscall_exit path is used.  All syscalls for traced
823          * proceses exit via intr_restore.
824          *
825          * XXX If any syscalls that change a processes space id ever exit
826          * this way, then we will need to copy %sr3 in to PT_SR[3..7], and
827          * adjust IASQ[0..1].
828          *
829          */
831         .align  PAGE_SIZE
833 ENTRY_CFI(syscall_exit_rfi)
834         mfctl   %cr30,%r16
835         LDREG   TI_TASK(%r16), %r16     /* thread_info -> task_struct */
836         ldo     TASK_REGS(%r16),%r16
837         /* Force iaoq to userspace, as the user has had access to our current
838          * context via sigcontext. Also Filter the PSW for the same reason.
839          */
840         LDREG   PT_IAOQ0(%r16),%r19
841         depi    3,31,2,%r19
842         STREG   %r19,PT_IAOQ0(%r16)
843         LDREG   PT_IAOQ1(%r16),%r19
844         depi    3,31,2,%r19
845         STREG   %r19,PT_IAOQ1(%r16)
846         LDREG   PT_PSW(%r16),%r19
847         load32  USER_PSW_MASK,%r1
848 #ifdef CONFIG_64BIT
849         load32  USER_PSW_HI_MASK,%r20
850         depd    %r20,31,32,%r1
851 #endif
852         and     %r19,%r1,%r19 /* Mask out bits that user shouldn't play with */
853         load32  USER_PSW,%r1
854         or      %r19,%r1,%r19 /* Make sure default USER_PSW bits are set */
855         STREG   %r19,PT_PSW(%r16)
857         /*
858          * If we aren't being traced, we never saved space registers
859          * (we don't store them in the sigcontext), so set them
860          * to "proper" values now (otherwise we'll wind up restoring
861          * whatever was last stored in the task structure, which might
862          * be inconsistent if an interrupt occurred while on the gateway
863          * page). Note that we may be "trashing" values the user put in
864          * them, but we don't support the user changing them.
865          */
867         STREG   %r0,PT_SR2(%r16)
868         mfsp    %sr3,%r19
869         STREG   %r19,PT_SR0(%r16)
870         STREG   %r19,PT_SR1(%r16)
871         STREG   %r19,PT_SR3(%r16)
872         STREG   %r19,PT_SR4(%r16)
873         STREG   %r19,PT_SR5(%r16)
874         STREG   %r19,PT_SR6(%r16)
875         STREG   %r19,PT_SR7(%r16)
877 ENTRY(intr_return)
878         /* check for reschedule */
879         mfctl   %cr30,%r1
880         LDREG   TI_FLAGS(%r1),%r19      /* sched.h: TIF_NEED_RESCHED */
881         bb,<,n  %r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */
883         .import do_notify_resume,code
884 intr_check_sig:
885         /* As above */
886         mfctl   %cr30,%r1
887         LDREG   TI_FLAGS(%r1),%r19
888         ldi     (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), %r20
889         and,COND(<>)    %r19, %r20, %r0
890         b,n     intr_restore    /* skip past if we've nothing to do */
892         /* This check is critical to having LWS
893          * working. The IASQ is zero on the gateway
894          * page and we cannot deliver any signals until
895          * we get off the gateway page.
896          *
897          * Only do signals if we are returning to user space
898          */
899         LDREG   PT_IASQ0(%r16), %r20
900         cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* backward */
901         LDREG   PT_IASQ1(%r16), %r20
902         cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* backward */
904         /* NOTE: We need to enable interrupts if we have to deliver
905          * signals. We used to do this earlier but it caused kernel
906          * stack overflows. */
907         ssm     PSW_SM_I, %r0
909         copy    %r0, %r25                       /* long in_syscall = 0 */
910 #ifdef CONFIG_64BIT
911         ldo     -16(%r30),%r29                  /* Reference param save area */
912 #endif
914         BL      do_notify_resume,%r2
915         copy    %r16, %r26                      /* struct pt_regs *regs */
917         b,n     intr_check_sig
919 intr_restore:
920         copy            %r16,%r29
921         ldo             PT_FR31(%r29),%r1
922         rest_fp         %r1
923         rest_general    %r29
925         /* inverse of virt_map */
926         pcxt_ssm_bug
927         rsm             PSW_SM_QUIET,%r0        /* prepare for rfi */
928         tophys_r1       %r29
930         /* Restore space id's and special cr's from PT_REGS
931          * structure pointed to by r29
932          */
933         rest_specials   %r29
935         /* IMPORTANT: rest_stack restores r29 last (we are using it)!
936          * It also restores r1 and r30.
937          */
938         rest_stack
940         rfi
941         nop
943 #ifndef CONFIG_PREEMPTION
944 # define intr_do_preempt        intr_restore
945 #endif /* !CONFIG_PREEMPTION */
947         .import schedule,code
948 intr_do_resched:
949         /* Only call schedule on return to userspace. If we're returning
950          * to kernel space, we may schedule if CONFIG_PREEMPTION, otherwise
951          * we jump back to intr_restore.
952          */
953         LDREG   PT_IASQ0(%r16), %r20
954         cmpib,COND(=)   0, %r20, intr_do_preempt
955         nop
956         LDREG   PT_IASQ1(%r16), %r20
957         cmpib,COND(=)   0, %r20, intr_do_preempt
958         nop
960         /* NOTE: We need to enable interrupts if we schedule.  We used
961          * to do this earlier but it caused kernel stack overflows. */
962         ssm     PSW_SM_I, %r0
964 #ifdef CONFIG_64BIT
965         ldo     -16(%r30),%r29          /* Reference param save area */
966 #endif
968         ldil    L%intr_check_sig, %r2
969 #ifndef CONFIG_64BIT
970         b       schedule
971 #else
972         load32  schedule, %r20
973         bv      %r0(%r20)
974 #endif
975         ldo     R%intr_check_sig(%r2), %r2
977         /* preempt the current task on returning to kernel
978          * mode from an interrupt, iff need_resched is set,
979          * and preempt_count is 0. otherwise, we continue on
980          * our merry way back to the current running task.
981          */
982 #ifdef CONFIG_PREEMPTION
983         .import preempt_schedule_irq,code
984 intr_do_preempt:
985         rsm     PSW_SM_I, %r0           /* disable interrupts */
987         /* current_thread_info()->preempt_count */
988         mfctl   %cr30, %r1
989         LDREG   TI_PRE_COUNT(%r1), %r19
990         cmpib,COND(<>)  0, %r19, intr_restore   /* if preempt_count > 0 */
991         nop                             /* prev insn branched backwards */
993         /* check if we interrupted a critical path */
994         LDREG   PT_PSW(%r16), %r20
995         bb,<,n  %r20, 31 - PSW_SM_I, intr_restore
996         nop
998         BL      preempt_schedule_irq, %r2
999         nop
1001         b,n     intr_restore            /* ssm PSW_SM_I done by intr_restore */
1002 #endif /* CONFIG_PREEMPTION */
1004         /*
1005          * External interrupts.
1006          */
1008 intr_extint:
1009         cmpib,COND(=),n 0,%r16,1f
1011         get_stack_use_cr30
1012         b,n 2f
1015         get_stack_use_r30
1017         save_specials   %r29
1018         virt_map
1019         save_general    %r29
1021         ldo     PT_FR0(%r29), %r24
1022         save_fp %r24
1023         
1024         loadgp
1026         copy    %r29, %r26      /* arg0 is pt_regs */
1027         copy    %r29, %r16      /* save pt_regs */
1029         ldil    L%intr_return, %r2
1031 #ifdef CONFIG_64BIT
1032         ldo     -16(%r30),%r29  /* Reference param save area */
1033 #endif
1035         b       do_cpu_irq_mask
1036         ldo     R%intr_return(%r2), %r2 /* return to intr_return, not here */
1037 ENDPROC_CFI(syscall_exit_rfi)
1040         /* Generic interruptions (illegal insn, unaligned, page fault, etc) */
1042 ENTRY_CFI(intr_save)            /* for os_hpmc */
1043         mfsp    %sr7,%r16
1044         cmpib,COND(=),n 0,%r16,1f
1045         get_stack_use_cr30
1046         b       2f
1047         copy    %r8,%r26
1050         get_stack_use_r30
1051         copy    %r8,%r26
1054         save_specials   %r29
1056         /* If this trap is a itlb miss, skip saving/adjusting isr/ior */
1057         cmpib,COND(=),n        PARISC_ITLB_TRAP,%r26,skip_save_ior
1060         mfctl           %isr, %r16
1061         nop             /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */
1062         mfctl           %ior, %r17
1065 #ifdef CONFIG_64BIT
1066         /*
1067          * If the interrupted code was running with W bit off (32 bit),
1068          * clear the b bits (bits 0 & 1) in the ior.
1069          * save_specials left ipsw value in r8 for us to test.
1070          */
1071         extrd,u,*<>     %r8,PSW_W_BIT,1,%r0
1072         depdi           0,1,2,%r17
1074         /* adjust isr/ior: get high bits from isr and deposit in ior */
1075         space_adjust    %r16,%r17,%r1
1076 #endif
1077         STREG           %r16, PT_ISR(%r29)
1078         STREG           %r17, PT_IOR(%r29)
1080 #if 0 && defined(CONFIG_64BIT)
1081         /* Revisit when we have 64-bit code above 4Gb */
1082         b,n             intr_save2
1084 skip_save_ior:
1085         /* We have a itlb miss, and when executing code above 4 Gb on ILP64, we
1086          * need to adjust iasq/iaoq here in the same way we adjusted isr/ior
1087          * above.
1088          */
1089         extrd,u,*       %r8,PSW_W_BIT,1,%r1
1090         cmpib,COND(=),n 1,%r1,intr_save2
1091         LDREG           PT_IASQ0(%r29), %r16
1092         LDREG           PT_IAOQ0(%r29), %r17
1093         /* adjust iasq/iaoq */
1094         space_adjust    %r16,%r17,%r1
1095         STREG           %r16, PT_IASQ0(%r29)
1096         STREG           %r17, PT_IAOQ0(%r29)
1097 #else
1098 skip_save_ior:
1099 #endif
1101 intr_save2:
1102         virt_map
1103         save_general    %r29
1105         ldo             PT_FR0(%r29), %r25
1106         save_fp         %r25
1107         
1108         loadgp
1110         copy            %r29, %r25      /* arg1 is pt_regs */
1111 #ifdef CONFIG_64BIT
1112         ldo             -16(%r30),%r29  /* Reference param save area */
1113 #endif
1115         ldil            L%intr_check_sig, %r2
1116         copy            %r25, %r16      /* save pt_regs */
1118         b               handle_interruption
1119         ldo             R%intr_check_sig(%r2), %r2
1120 ENDPROC_CFI(intr_save)
1123         /*
1124          * Note for all tlb miss handlers:
1125          *
1126          * cr24 contains a pointer to the kernel address space
1127          * page directory.
1128          *
1129          * cr25 contains a pointer to the current user address
1130          * space page directory.
1131          *
1132          * sr3 will contain the space id of the user address space
1133          * of the current running thread while that thread is
1134          * running in the kernel.
1135          */
1137         /*
1138          * register number allocations.  Note that these are all
1139          * in the shadowed registers
1140          */
1142         t0 = r1         /* temporary register 0 */
1143         va = r8         /* virtual address for which the trap occurred */
1144         t1 = r9         /* temporary register 1 */
1145         pte  = r16      /* pte/phys page # */
1146         prot = r17      /* prot bits */
1147         spc  = r24      /* space for which the trap occurred */
1148         ptp = r25       /* page directory/page table pointer */
1150 #ifdef CONFIG_64BIT
1152 dtlb_miss_20w:
1153         space_adjust    spc,va,t0
1154         get_pgd         spc,ptp
1155         space_check     spc,t0,dtlb_fault
1157         L3_ptep         ptp,pte,t0,va,dtlb_check_alias_20w
1159         tlb_lock        spc,ptp,pte,t0,t1,dtlb_check_alias_20w
1160         update_accessed ptp,pte,t0,t1
1162         make_insert_tlb spc,pte,prot,t1
1163         
1164         idtlbt          pte,prot
1166         tlb_unlock1     spc,t0,t1
1167         rfir
1168         nop
1170 dtlb_check_alias_20w:
1171         do_alias        spc,t0,t1,va,pte,prot,dtlb_fault,20
1173         idtlbt          pte,prot
1175         rfir
1176         nop
1178 nadtlb_miss_20w:
1179         space_adjust    spc,va,t0
1180         get_pgd         spc,ptp
1181         space_check     spc,t0,nadtlb_fault
1183         L3_ptep         ptp,pte,t0,va,nadtlb_check_alias_20w
1185         tlb_lock        spc,ptp,pte,t0,t1,nadtlb_check_alias_20w
1186         update_accessed ptp,pte,t0,t1
1188         make_insert_tlb spc,pte,prot,t1
1190         idtlbt          pte,prot
1192         tlb_unlock1     spc,t0,t1
1193         rfir
1194         nop
1196 nadtlb_check_alias_20w:
1197         do_alias        spc,t0,t1,va,pte,prot,nadtlb_emulate,20
1199         idtlbt          pte,prot
1201         rfir
1202         nop
1204 #else
1206 dtlb_miss_11:
1207         get_pgd         spc,ptp
1209         space_check     spc,t0,dtlb_fault
1211         L2_ptep         ptp,pte,t0,va,dtlb_check_alias_11
1213         tlb_lock        spc,ptp,pte,t0,t1,dtlb_check_alias_11
1214         update_accessed ptp,pte,t0,t1
1216         make_insert_tlb_11      spc,pte,prot
1218         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1219         mtsp            spc,%sr1
1221         idtlba          pte,(%sr1,va)
1222         idtlbp          prot,(%sr1,va)
1224         mtsp            t1, %sr1        /* Restore sr1 */
1226         tlb_unlock1     spc,t0,t1
1227         rfir
1228         nop
1230 dtlb_check_alias_11:
1231         do_alias        spc,t0,t1,va,pte,prot,dtlb_fault,11
1233         idtlba          pte,(va)
1234         idtlbp          prot,(va)
1236         rfir
1237         nop
1239 nadtlb_miss_11:
1240         get_pgd         spc,ptp
1242         space_check     spc,t0,nadtlb_fault
1244         L2_ptep         ptp,pte,t0,va,nadtlb_check_alias_11
1246         tlb_lock        spc,ptp,pte,t0,t1,nadtlb_check_alias_11
1247         update_accessed ptp,pte,t0,t1
1249         make_insert_tlb_11      spc,pte,prot
1251         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1252         mtsp            spc,%sr1
1254         idtlba          pte,(%sr1,va)
1255         idtlbp          prot,(%sr1,va)
1257         mtsp            t1, %sr1        /* Restore sr1 */
1259         tlb_unlock1     spc,t0,t1
1260         rfir
1261         nop
1263 nadtlb_check_alias_11:
1264         do_alias        spc,t0,t1,va,pte,prot,nadtlb_emulate,11
1266         idtlba          pte,(va)
1267         idtlbp          prot,(va)
1269         rfir
1270         nop
1272 dtlb_miss_20:
1273         space_adjust    spc,va,t0
1274         get_pgd         spc,ptp
1275         space_check     spc,t0,dtlb_fault
1277         L2_ptep         ptp,pte,t0,va,dtlb_check_alias_20
1279         tlb_lock        spc,ptp,pte,t0,t1,dtlb_check_alias_20
1280         update_accessed ptp,pte,t0,t1
1282         make_insert_tlb spc,pte,prot,t1
1284         f_extend        pte,t1
1286         idtlbt          pte,prot
1288         tlb_unlock1     spc,t0,t1
1289         rfir
1290         nop
1292 dtlb_check_alias_20:
1293         do_alias        spc,t0,t1,va,pte,prot,dtlb_fault,20
1294         
1295         idtlbt          pte,prot
1297         rfir
1298         nop
1300 nadtlb_miss_20:
1301         get_pgd         spc,ptp
1303         space_check     spc,t0,nadtlb_fault
1305         L2_ptep         ptp,pte,t0,va,nadtlb_check_alias_20
1307         tlb_lock        spc,ptp,pte,t0,t1,nadtlb_check_alias_20
1308         update_accessed ptp,pte,t0,t1
1310         make_insert_tlb spc,pte,prot,t1
1312         f_extend        pte,t1
1313         
1314         idtlbt          pte,prot
1316         tlb_unlock1     spc,t0,t1
1317         rfir
1318         nop
1320 nadtlb_check_alias_20:
1321         do_alias        spc,t0,t1,va,pte,prot,nadtlb_emulate,20
1323         idtlbt          pte,prot
1325         rfir
1326         nop
1328 #endif
1330 nadtlb_emulate:
1332         /*
1333          * Non access misses can be caused by fdc,fic,pdc,lpa,probe and
1334          * probei instructions. We don't want to fault for these
1335          * instructions (not only does it not make sense, it can cause
1336          * deadlocks, since some flushes are done with the mmap
1337          * semaphore held). If the translation doesn't exist, we can't
1338          * insert a translation, so have to emulate the side effects
1339          * of the instruction. Since we don't insert a translation
1340          * we can get a lot of faults during a flush loop, so it makes
1341          * sense to try to do it here with minimum overhead. We only
1342          * emulate fdc,fic,pdc,probew,prober instructions whose base 
1343          * and index registers are not shadowed. We defer everything 
1344          * else to the "slow" path.
1345          */
1347         mfctl           %cr19,%r9 /* Get iir */
1349         /* PA 2.0 Arch Ref. Book pg 382 has a good description of the insn bits.
1350            Checks for fdc,fdce,pdc,"fic,4f",prober,probeir,probew, probeiw */
1352         /* Checks for fdc,fdce,pdc,"fic,4f" only */
1353         ldi             0x280,%r16
1354         and             %r9,%r16,%r17
1355         cmpb,<>,n       %r16,%r17,nadtlb_probe_check
1356         bb,>=,n         %r9,26,nadtlb_nullify  /* m bit not set, just nullify */
1357         BL              get_register,%r25
1358         extrw,u         %r9,15,5,%r8           /* Get index register # */
1359         cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
1360         copy            %r1,%r24
1361         BL              get_register,%r25
1362         extrw,u         %r9,10,5,%r8           /* Get base register # */
1363         cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
1364         BL              set_register,%r25
1365         add,l           %r1,%r24,%r1           /* doesn't affect c/b bits */
1367 nadtlb_nullify:
1368         mfctl           %ipsw,%r8
1369         ldil            L%PSW_N,%r9
1370         or              %r8,%r9,%r8            /* Set PSW_N */
1371         mtctl           %r8,%ipsw
1373         rfir
1374         nop
1376         /* 
1377                 When there is no translation for the probe address then we
1378                 must nullify the insn and return zero in the target register.
1379                 This will indicate to the calling code that it does not have 
1380                 write/read privileges to this address.
1382                 This should technically work for prober and probew in PA 1.1,
1383                 and also probe,r and probe,w in PA 2.0
1385                 WARNING: USE ONLY NON-SHADOW REGISTERS WITH PROBE INSN!
1386                 THE SLOW-PATH EMULATION HAS NOT BEEN WRITTEN YET.
1388         */
1389 nadtlb_probe_check:
1390         ldi             0x80,%r16
1391         and             %r9,%r16,%r17
1392         cmpb,<>,n       %r16,%r17,nadtlb_fault /* Must be probe,[rw]*/
1393         BL              get_register,%r25      /* Find the target register */
1394         extrw,u         %r9,31,5,%r8           /* Get target register */
1395         cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
1396         BL              set_register,%r25
1397         copy            %r0,%r1                /* Write zero to target register */
1398         b nadtlb_nullify                       /* Nullify return insn */
1399         nop
1402 #ifdef CONFIG_64BIT
1403 itlb_miss_20w:
1405         /*
1406          * I miss is a little different, since we allow users to fault
1407          * on the gateway page which is in the kernel address space.
1408          */
1410         space_adjust    spc,va,t0
1411         get_pgd         spc,ptp
1412         space_check     spc,t0,itlb_fault
1414         L3_ptep         ptp,pte,t0,va,itlb_fault
1416         tlb_lock        spc,ptp,pte,t0,t1,itlb_fault
1417         update_accessed ptp,pte,t0,t1
1419         make_insert_tlb spc,pte,prot,t1
1420         
1421         iitlbt          pte,prot
1423         tlb_unlock1     spc,t0,t1
1424         rfir
1425         nop
1427 naitlb_miss_20w:
1429         /*
1430          * I miss is a little different, since we allow users to fault
1431          * on the gateway page which is in the kernel address space.
1432          */
1434         space_adjust    spc,va,t0
1435         get_pgd         spc,ptp
1436         space_check     spc,t0,naitlb_fault
1438         L3_ptep         ptp,pte,t0,va,naitlb_check_alias_20w
1440         tlb_lock        spc,ptp,pte,t0,t1,naitlb_check_alias_20w
1441         update_accessed ptp,pte,t0,t1
1443         make_insert_tlb spc,pte,prot,t1
1445         iitlbt          pte,prot
1447         tlb_unlock1     spc,t0,t1
1448         rfir
1449         nop
1451 naitlb_check_alias_20w:
1452         do_alias        spc,t0,t1,va,pte,prot,naitlb_fault,20
1454         iitlbt          pte,prot
1456         rfir
1457         nop
1459 #else
1461 itlb_miss_11:
1462         get_pgd         spc,ptp
1464         space_check     spc,t0,itlb_fault
1466         L2_ptep         ptp,pte,t0,va,itlb_fault
1468         tlb_lock        spc,ptp,pte,t0,t1,itlb_fault
1469         update_accessed ptp,pte,t0,t1
1471         make_insert_tlb_11      spc,pte,prot
1473         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1474         mtsp            spc,%sr1
1476         iitlba          pte,(%sr1,va)
1477         iitlbp          prot,(%sr1,va)
1479         mtsp            t1, %sr1        /* Restore sr1 */
1481         tlb_unlock1     spc,t0,t1
1482         rfir
1483         nop
1485 naitlb_miss_11:
1486         get_pgd         spc,ptp
1488         space_check     spc,t0,naitlb_fault
1490         L2_ptep         ptp,pte,t0,va,naitlb_check_alias_11
1492         tlb_lock        spc,ptp,pte,t0,t1,naitlb_check_alias_11
1493         update_accessed ptp,pte,t0,t1
1495         make_insert_tlb_11      spc,pte,prot
1497         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1498         mtsp            spc,%sr1
1500         iitlba          pte,(%sr1,va)
1501         iitlbp          prot,(%sr1,va)
1503         mtsp            t1, %sr1        /* Restore sr1 */
1505         tlb_unlock1     spc,t0,t1
1506         rfir
1507         nop
1509 naitlb_check_alias_11:
1510         do_alias        spc,t0,t1,va,pte,prot,itlb_fault,11
1512         iitlba          pte,(%sr0, va)
1513         iitlbp          prot,(%sr0, va)
1515         rfir
1516         nop
1519 itlb_miss_20:
1520         get_pgd         spc,ptp
1522         space_check     spc,t0,itlb_fault
1524         L2_ptep         ptp,pte,t0,va,itlb_fault
1526         tlb_lock        spc,ptp,pte,t0,t1,itlb_fault
1527         update_accessed ptp,pte,t0,t1
1529         make_insert_tlb spc,pte,prot,t1
1531         f_extend        pte,t1
1533         iitlbt          pte,prot
1535         tlb_unlock1     spc,t0,t1
1536         rfir
1537         nop
1539 naitlb_miss_20:
1540         get_pgd         spc,ptp
1542         space_check     spc,t0,naitlb_fault
1544         L2_ptep         ptp,pte,t0,va,naitlb_check_alias_20
1546         tlb_lock        spc,ptp,pte,t0,t1,naitlb_check_alias_20
1547         update_accessed ptp,pte,t0,t1
1549         make_insert_tlb spc,pte,prot,t1
1551         f_extend        pte,t1
1553         iitlbt          pte,prot
1555         tlb_unlock1     spc,t0,t1
1556         rfir
1557         nop
1559 naitlb_check_alias_20:
1560         do_alias        spc,t0,t1,va,pte,prot,naitlb_fault,20
1562         iitlbt          pte,prot
1564         rfir
1565         nop
1567 #endif
1569 #ifdef CONFIG_64BIT
1571 dbit_trap_20w:
1572         space_adjust    spc,va,t0
1573         get_pgd         spc,ptp
1574         space_check     spc,t0,dbit_fault
1576         L3_ptep         ptp,pte,t0,va,dbit_fault
1578         tlb_lock        spc,ptp,pte,t0,t1,dbit_fault
1579         update_dirty    ptp,pte,t1
1581         make_insert_tlb spc,pte,prot,t1
1582                 
1583         idtlbt          pte,prot
1585         tlb_unlock0     spc,t0,t1
1586         rfir
1587         nop
1588 #else
1590 dbit_trap_11:
1592         get_pgd         spc,ptp
1594         space_check     spc,t0,dbit_fault
1596         L2_ptep         ptp,pte,t0,va,dbit_fault
1598         tlb_lock        spc,ptp,pte,t0,t1,dbit_fault
1599         update_dirty    ptp,pte,t1
1601         make_insert_tlb_11      spc,pte,prot
1603         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1604         mtsp            spc,%sr1
1606         idtlba          pte,(%sr1,va)
1607         idtlbp          prot,(%sr1,va)
1609         mtsp            t1, %sr1     /* Restore sr1 */
1611         tlb_unlock0     spc,t0,t1
1612         rfir
1613         nop
1615 dbit_trap_20:
1616         get_pgd         spc,ptp
1618         space_check     spc,t0,dbit_fault
1620         L2_ptep         ptp,pte,t0,va,dbit_fault
1622         tlb_lock        spc,ptp,pte,t0,t1,dbit_fault
1623         update_dirty    ptp,pte,t1
1625         make_insert_tlb spc,pte,prot,t1
1627         f_extend        pte,t1
1628         
1629         idtlbt          pte,prot
1631         tlb_unlock0     spc,t0,t1
1632         rfir
1633         nop
1634 #endif
1636         .import handle_interruption,code
1638 kernel_bad_space:
1639         b               intr_save
1640         ldi             31,%r8  /* Use an unused code */
1642 dbit_fault:
1643         b               intr_save
1644         ldi             20,%r8
1646 itlb_fault:
1647         b               intr_save
1648         ldi             PARISC_ITLB_TRAP,%r8
1650 nadtlb_fault:
1651         b               intr_save
1652         ldi             17,%r8
1654 naitlb_fault:
1655         b               intr_save
1656         ldi             16,%r8
1658 dtlb_fault:
1659         b               intr_save
1660         ldi             15,%r8
1662         /* Register saving semantics for system calls:
1664            %r1             clobbered by system call macro in userspace
1665            %r2             saved in PT_REGS by gateway page
1666            %r3  - %r18     preserved by C code (saved by signal code)
1667            %r19 - %r20     saved in PT_REGS by gateway page
1668            %r21 - %r22     non-standard syscall args
1669                            stored in kernel stack by gateway page
1670            %r23 - %r26     arg3-arg0, saved in PT_REGS by gateway page
1671            %r27 - %r30     saved in PT_REGS by gateway page
1672            %r31            syscall return pointer
1673          */
1675         /* Floating point registers (FIXME: what do we do with these?)
1677            %fr0  - %fr3    status/exception, not preserved
1678            %fr4  - %fr7    arguments
1679            %fr8  - %fr11   not preserved by C code
1680            %fr12 - %fr21   preserved by C code
1681            %fr22 - %fr31   not preserved by C code
1682          */
1684         .macro  reg_save regs
1685         STREG   %r3, PT_GR3(\regs)
1686         STREG   %r4, PT_GR4(\regs)
1687         STREG   %r5, PT_GR5(\regs)
1688         STREG   %r6, PT_GR6(\regs)
1689         STREG   %r7, PT_GR7(\regs)
1690         STREG   %r8, PT_GR8(\regs)
1691         STREG   %r9, PT_GR9(\regs)
1692         STREG   %r10,PT_GR10(\regs)
1693         STREG   %r11,PT_GR11(\regs)
1694         STREG   %r12,PT_GR12(\regs)
1695         STREG   %r13,PT_GR13(\regs)
1696         STREG   %r14,PT_GR14(\regs)
1697         STREG   %r15,PT_GR15(\regs)
1698         STREG   %r16,PT_GR16(\regs)
1699         STREG   %r17,PT_GR17(\regs)
1700         STREG   %r18,PT_GR18(\regs)
1701         .endm
1703         .macro  reg_restore regs
1704         LDREG   PT_GR3(\regs), %r3
1705         LDREG   PT_GR4(\regs), %r4
1706         LDREG   PT_GR5(\regs), %r5
1707         LDREG   PT_GR6(\regs), %r6
1708         LDREG   PT_GR7(\regs), %r7
1709         LDREG   PT_GR8(\regs), %r8
1710         LDREG   PT_GR9(\regs), %r9
1711         LDREG   PT_GR10(\regs),%r10
1712         LDREG   PT_GR11(\regs),%r11
1713         LDREG   PT_GR12(\regs),%r12
1714         LDREG   PT_GR13(\regs),%r13
1715         LDREG   PT_GR14(\regs),%r14
1716         LDREG   PT_GR15(\regs),%r15
1717         LDREG   PT_GR16(\regs),%r16
1718         LDREG   PT_GR17(\regs),%r17
1719         LDREG   PT_GR18(\regs),%r18
1720         .endm
1722         .macro  fork_like name
1723 ENTRY_CFI(sys_\name\()_wrapper)
1724         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
1725         ldo     TASK_REGS(%r1),%r1
1726         reg_save %r1
1727         mfctl   %cr27, %r28
1728         ldil    L%sys_\name, %r31
1729         be      R%sys_\name(%sr4,%r31)
1730         STREG   %r28, PT_CR27(%r1)
1731 ENDPROC_CFI(sys_\name\()_wrapper)
1732         .endm
1734 fork_like clone
1735 fork_like clone3
1736 fork_like fork
1737 fork_like vfork
1739         /* Set the return value for the child */
1740 ENTRY(child_return)
1741         BL      schedule_tail, %r2
1742         nop
1743 finish_child_return:
1744         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
1745         ldo     TASK_REGS(%r1),%r1       /* get pt regs */
1747         LDREG   PT_CR27(%r1), %r3
1748         mtctl   %r3, %cr27
1749         reg_restore %r1
1750         b       syscall_exit
1751         copy    %r0,%r28
1752 END(child_return)
1754 ENTRY_CFI(sys_rt_sigreturn_wrapper)
1755         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
1756         ldo     TASK_REGS(%r26),%r26    /* get pt regs */
1757         /* Don't save regs, we are going to restore them from sigcontext. */
1758         STREG   %r2, -RP_OFFSET(%r30)
1759 #ifdef CONFIG_64BIT
1760         ldo     FRAME_SIZE(%r30), %r30
1761         BL      sys_rt_sigreturn,%r2
1762         ldo     -16(%r30),%r29          /* Reference param save area */
1763 #else
1764         BL      sys_rt_sigreturn,%r2
1765         ldo     FRAME_SIZE(%r30), %r30
1766 #endif
1768         ldo     -FRAME_SIZE(%r30), %r30
1769         LDREG   -RP_OFFSET(%r30), %r2
1771         /* FIXME: I think we need to restore a few more things here. */
1772         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1773         ldo     TASK_REGS(%r1),%r1      /* get pt regs */
1774         reg_restore %r1
1776         /* If the signal was received while the process was blocked on a
1777          * syscall, then r2 will take us to syscall_exit; otherwise r2 will
1778          * take us to syscall_exit_rfi and on to intr_return.
1779          */
1780         bv      %r0(%r2)
1781         LDREG   PT_GR28(%r1),%r28  /* reload original r28 for syscall_exit */
1782 ENDPROC_CFI(sys_rt_sigreturn_wrapper)
1784 ENTRY(syscall_exit)
1785         /* NOTE: Not all syscalls exit this way.  rt_sigreturn will exit
1786          * via syscall_exit_rfi if the signal was received while the process
1787          * was running.
1788          */
1790         /* save return value now */
1792         mfctl     %cr30, %r1
1793         LDREG     TI_TASK(%r1),%r1
1794         STREG     %r28,TASK_PT_GR28(%r1)
1796         /* Seems to me that dp could be wrong here, if the syscall involved
1797          * calling a module, and nothing got round to restoring dp on return.
1798          */
1799         loadgp
1801 syscall_check_resched:
1803         /* check for reschedule */
1805         LDREG   TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19   /* long */
1806         bb,<,n  %r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */
1808         .import do_signal,code
1809 syscall_check_sig:
1810         LDREG   TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19
1811         ldi     (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), %r26
1812         and,COND(<>)    %r19, %r26, %r0
1813         b,n     syscall_restore /* skip past if we've nothing to do */
1815 syscall_do_signal:
1816         /* Save callee-save registers (for sigcontext).
1817          * FIXME: After this point the process structure should be
1818          * consistent with all the relevant state of the process
1819          * before the syscall.  We need to verify this.
1820          */
1821         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1822         ldo     TASK_REGS(%r1), %r26            /* struct pt_regs *regs */
1823         reg_save %r26
1825 #ifdef CONFIG_64BIT
1826         ldo     -16(%r30),%r29                  /* Reference param save area */
1827 #endif
1829         BL      do_notify_resume,%r2
1830         ldi     1, %r25                         /* long in_syscall = 1 */
1832         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1833         ldo     TASK_REGS(%r1), %r20            /* reload pt_regs */
1834         reg_restore %r20
1836         b,n     syscall_check_sig
1838 syscall_restore:
1839         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1841         /* Are we being ptraced? */
1842         ldw     TASK_FLAGS(%r1),%r19
1843         ldi     _TIF_SYSCALL_TRACE_MASK,%r2
1844         and,COND(=)     %r19,%r2,%r0
1845         b,n     syscall_restore_rfi
1847         ldo     TASK_PT_FR31(%r1),%r19             /* reload fpregs */
1848         rest_fp %r19
1850         LDREG   TASK_PT_SAR(%r1),%r19              /* restore SAR */
1851         mtsar   %r19
1853         LDREG   TASK_PT_GR2(%r1),%r2               /* restore user rp */
1854         LDREG   TASK_PT_GR19(%r1),%r19
1855         LDREG   TASK_PT_GR20(%r1),%r20
1856         LDREG   TASK_PT_GR21(%r1),%r21
1857         LDREG   TASK_PT_GR22(%r1),%r22
1858         LDREG   TASK_PT_GR23(%r1),%r23
1859         LDREG   TASK_PT_GR24(%r1),%r24
1860         LDREG   TASK_PT_GR25(%r1),%r25
1861         LDREG   TASK_PT_GR26(%r1),%r26
1862         LDREG   TASK_PT_GR27(%r1),%r27     /* restore user dp */
1863         LDREG   TASK_PT_GR28(%r1),%r28     /* syscall return value */
1864         LDREG   TASK_PT_GR29(%r1),%r29
1865         LDREG   TASK_PT_GR31(%r1),%r31     /* restore syscall rp */
1867         /* NOTE: We use rsm/ssm pair to make this operation atomic */
1868         LDREG   TASK_PT_GR30(%r1),%r1              /* Get user sp */
1869         rsm     PSW_SM_I, %r0
1870         copy    %r1,%r30                           /* Restore user sp */
1871         mfsp    %sr3,%r1                           /* Get user space id */
1872         mtsp    %r1,%sr7                           /* Restore sr7 */
1873         ssm     PSW_SM_I, %r0
1875         /* Set sr2 to zero for userspace syscalls to work. */
1876         mtsp    %r0,%sr2 
1877         mtsp    %r1,%sr4                           /* Restore sr4 */
1878         mtsp    %r1,%sr5                           /* Restore sr5 */
1879         mtsp    %r1,%sr6                           /* Restore sr6 */
1881         depi    3,31,2,%r31                        /* ensure return to user mode. */
1883 #ifdef CONFIG_64BIT
1884         /* decide whether to reset the wide mode bit
1885          *
1886          * For a syscall, the W bit is stored in the lowest bit
1887          * of sp.  Extract it and reset W if it is zero */
1888         extrd,u,*<>     %r30,63,1,%r1
1889         rsm     PSW_SM_W, %r0
1890         /* now reset the lowest bit of sp if it was set */
1891         xor     %r30,%r1,%r30
1892 #endif
1893         be,n    0(%sr3,%r31)                       /* return to user space */
1895         /* We have to return via an RFI, so that PSW T and R bits can be set
1896          * appropriately.
1897          * This sets up pt_regs so we can return via intr_restore, which is not
1898          * the most efficient way of doing things, but it works.
1899          */
1900 syscall_restore_rfi:
1901         ldo     -1(%r0),%r2                        /* Set recovery cntr to -1 */
1902         mtctl   %r2,%cr0                           /*   for immediate trap */
1903         LDREG   TASK_PT_PSW(%r1),%r2               /* Get old PSW */
1904         ldi     0x0b,%r20                          /* Create new PSW */
1905         depi    -1,13,1,%r20                       /* C, Q, D, and I bits */
1907         /* The values of SINGLESTEP_BIT and BLOCKSTEP_BIT are
1908          * set in thread_info.h and converted to PA bitmap
1909          * numbers in asm-offsets.c */
1911         /* if ((%r19.SINGLESTEP_BIT)) { %r20.27=1} */
1912         extru,= %r19,TIF_SINGLESTEP_PA_BIT,1,%r0
1913         depi    -1,27,1,%r20                       /* R bit */
1915         /* if ((%r19.BLOCKSTEP_BIT)) { %r20.7=1} */
1916         extru,= %r19,TIF_BLOCKSTEP_PA_BIT,1,%r0
1917         depi    -1,7,1,%r20                        /* T bit */
1919         STREG   %r20,TASK_PT_PSW(%r1)
1921         /* Always store space registers, since sr3 can be changed (e.g. fork) */
1923         mfsp    %sr3,%r25
1924         STREG   %r25,TASK_PT_SR3(%r1)
1925         STREG   %r25,TASK_PT_SR4(%r1)
1926         STREG   %r25,TASK_PT_SR5(%r1)
1927         STREG   %r25,TASK_PT_SR6(%r1)
1928         STREG   %r25,TASK_PT_SR7(%r1)
1929         STREG   %r25,TASK_PT_IASQ0(%r1)
1930         STREG   %r25,TASK_PT_IASQ1(%r1)
1932         /* XXX W bit??? */
1933         /* Now if old D bit is clear, it means we didn't save all registers
1934          * on syscall entry, so do that now.  This only happens on TRACEME
1935          * calls, or if someone attached to us while we were on a syscall.
1936          * We could make this more efficient by not saving r3-r18, but
1937          * then we wouldn't be able to use the common intr_restore path.
1938          * It is only for traced processes anyway, so performance is not
1939          * an issue.
1940          */
1941         bb,<    %r2,30,pt_regs_ok                  /* Branch if D set */
1942         ldo     TASK_REGS(%r1),%r25
1943         reg_save %r25                              /* Save r3 to r18 */
1945         /* Save the current sr */
1946         mfsp    %sr0,%r2
1947         STREG   %r2,TASK_PT_SR0(%r1)
1949         /* Save the scratch sr */
1950         mfsp    %sr1,%r2
1951         STREG   %r2,TASK_PT_SR1(%r1)
1953         /* sr2 should be set to zero for userspace syscalls */
1954         STREG   %r0,TASK_PT_SR2(%r1)
1956         LDREG   TASK_PT_GR31(%r1),%r2
1957         depi    3,31,2,%r2                 /* ensure return to user mode. */
1958         STREG   %r2,TASK_PT_IAOQ0(%r1)
1959         ldo     4(%r2),%r2
1960         STREG   %r2,TASK_PT_IAOQ1(%r1)
1961         b       intr_restore
1962         copy    %r25,%r16
1964 pt_regs_ok:
1965         LDREG   TASK_PT_IAOQ0(%r1),%r2
1966         depi    3,31,2,%r2                 /* ensure return to user mode. */
1967         STREG   %r2,TASK_PT_IAOQ0(%r1)
1968         LDREG   TASK_PT_IAOQ1(%r1),%r2
1969         depi    3,31,2,%r2
1970         STREG   %r2,TASK_PT_IAOQ1(%r1)
1971         b       intr_restore
1972         copy    %r25,%r16
1974 syscall_do_resched:
1975         load32  syscall_check_resched,%r2 /* if resched, we start over again */
1976         load32  schedule,%r19
1977         bv      %r0(%r19)               /* jumps to schedule() */
1978 #ifdef CONFIG_64BIT
1979         ldo     -16(%r30),%r29          /* Reference param save area */
1980 #else
1981         nop
1982 #endif
1983 END(syscall_exit)
1986 #ifdef CONFIG_FUNCTION_TRACER
1988         .import ftrace_function_trampoline,code
1989         .align L1_CACHE_BYTES
1990 ENTRY_CFI(mcount, caller)
1991 _mcount:
1992         .export _mcount,data
1993         /*
1994          * The 64bit mcount() function pointer needs 4 dwords, of which the
1995          * first two are free.  We optimize it here and put 2 instructions for
1996          * calling mcount(), and 2 instructions for ftrace_stub().  That way we
1997          * have all on one L1 cacheline.
1998          */
1999         ldi     0, %arg3
2000         b       ftrace_function_trampoline
2001         copy    %r3, %arg2      /* caller original %sp */
2002 ftrace_stub:
2003         .globl ftrace_stub
2004         .type  ftrace_stub, @function
2005 #ifdef CONFIG_64BIT
2006         bve     (%rp)
2007 #else
2008         bv      %r0(%rp)
2009 #endif
2010         nop
2011 #ifdef CONFIG_64BIT
2012         .dword mcount
2013         .dword 0 /* code in head.S puts value of global gp here */
2014 #endif
2015 ENDPROC_CFI(mcount)
2017 #ifdef CONFIG_DYNAMIC_FTRACE
2019 #ifdef CONFIG_64BIT
2020 #define FTRACE_FRAME_SIZE (2*FRAME_SIZE)
2021 #else
2022 #define FTRACE_FRAME_SIZE FRAME_SIZE
2023 #endif
2024 ENTRY_CFI(ftrace_caller, caller,frame=FTRACE_FRAME_SIZE,CALLS,SAVE_RP,SAVE_SP)
2025 ftrace_caller:
2026         .global ftrace_caller
2028         STREG   %r3, -FTRACE_FRAME_SIZE+1*REG_SZ(%sp)
2029         ldo     -FTRACE_FRAME_SIZE(%sp), %r3
2030         STREG   %rp, -RP_OFFSET(%r3)
2032         /* Offset 0 is already allocated for %r1 */
2033         STREG   %r23, 2*REG_SZ(%r3)
2034         STREG   %r24, 3*REG_SZ(%r3)
2035         STREG   %r25, 4*REG_SZ(%r3)
2036         STREG   %r26, 5*REG_SZ(%r3)
2037         STREG   %r28, 6*REG_SZ(%r3)
2038         STREG   %r29, 7*REG_SZ(%r3)
2039 #ifdef CONFIG_64BIT
2040         STREG   %r19, 8*REG_SZ(%r3)
2041         STREG   %r20, 9*REG_SZ(%r3)
2042         STREG   %r21, 10*REG_SZ(%r3)
2043         STREG   %r22, 11*REG_SZ(%r3)
2044         STREG   %r27, 12*REG_SZ(%r3)
2045         STREG   %r31, 13*REG_SZ(%r3)
2046         loadgp
2047         ldo     -16(%sp),%r29
2048 #endif
2049         LDREG   0(%r3), %r25
2050         copy    %rp, %r26
2051         ldo     -8(%r25), %r25
2052         ldi     0, %r23         /* no pt_regs */
2053         b,l     ftrace_function_trampoline, %rp
2054         copy    %r3, %r24
2056         LDREG   -RP_OFFSET(%r3), %rp
2057         LDREG   2*REG_SZ(%r3), %r23
2058         LDREG   3*REG_SZ(%r3), %r24
2059         LDREG   4*REG_SZ(%r3), %r25
2060         LDREG   5*REG_SZ(%r3), %r26
2061         LDREG   6*REG_SZ(%r3), %r28
2062         LDREG   7*REG_SZ(%r3), %r29
2063 #ifdef CONFIG_64BIT
2064         LDREG   8*REG_SZ(%r3), %r19
2065         LDREG   9*REG_SZ(%r3), %r20
2066         LDREG   10*REG_SZ(%r3), %r21
2067         LDREG   11*REG_SZ(%r3), %r22
2068         LDREG   12*REG_SZ(%r3), %r27
2069         LDREG   13*REG_SZ(%r3), %r31
2070 #endif
2071         LDREG   1*REG_SZ(%r3), %r3
2073         LDREGM  -FTRACE_FRAME_SIZE(%sp), %r1
2074         /* Adjust return point to jump back to beginning of traced function */
2075         ldo     -4(%r1), %r1
2076         bv,n    (%r1)
2078 ENDPROC_CFI(ftrace_caller)
2080 #ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS
2081 ENTRY_CFI(ftrace_regs_caller,caller,frame=FTRACE_FRAME_SIZE+PT_SZ_ALGN,
2082         CALLS,SAVE_RP,SAVE_SP)
2083 ftrace_regs_caller:
2084         .global ftrace_regs_caller
2086         ldo     -FTRACE_FRAME_SIZE(%sp), %r1
2087         STREG   %rp, -RP_OFFSET(%r1)
2089         copy    %sp, %r1
2090         ldo     PT_SZ_ALGN(%sp), %sp
2092         STREG   %rp, PT_GR2(%r1)
2093         STREG   %r3, PT_GR3(%r1)
2094         STREG   %r4, PT_GR4(%r1)
2095         STREG   %r5, PT_GR5(%r1)
2096         STREG   %r6, PT_GR6(%r1)
2097         STREG   %r7, PT_GR7(%r1)
2098         STREG   %r8, PT_GR8(%r1)
2099         STREG   %r9, PT_GR9(%r1)
2100         STREG   %r10, PT_GR10(%r1)
2101         STREG   %r11, PT_GR11(%r1)
2102         STREG   %r12, PT_GR12(%r1)
2103         STREG   %r13, PT_GR13(%r1)
2104         STREG   %r14, PT_GR14(%r1)
2105         STREG   %r15, PT_GR15(%r1)
2106         STREG   %r16, PT_GR16(%r1)
2107         STREG   %r17, PT_GR17(%r1)
2108         STREG   %r18, PT_GR18(%r1)
2109         STREG   %r19, PT_GR19(%r1)
2110         STREG   %r20, PT_GR20(%r1)
2111         STREG   %r21, PT_GR21(%r1)
2112         STREG   %r22, PT_GR22(%r1)
2113         STREG   %r23, PT_GR23(%r1)
2114         STREG   %r24, PT_GR24(%r1)
2115         STREG   %r25, PT_GR25(%r1)
2116         STREG   %r26, PT_GR26(%r1)
2117         STREG   %r27, PT_GR27(%r1)
2118         STREG   %r28, PT_GR28(%r1)
2119         STREG   %r29, PT_GR29(%r1)
2120         STREG   %r30, PT_GR30(%r1)
2121         STREG   %r31, PT_GR31(%r1)
2122         mfctl   %cr11, %r26
2123         STREG   %r26, PT_SAR(%r1)
2125         copy    %rp, %r26
2126         LDREG   -FTRACE_FRAME_SIZE-PT_SZ_ALGN(%sp), %r25
2127         ldo     -8(%r25), %r25
2128         ldo     -FTRACE_FRAME_SIZE(%r1), %arg2
2129         b,l     ftrace_function_trampoline, %rp
2130         copy    %r1, %arg3 /* struct pt_regs */
2132         ldo     -PT_SZ_ALGN(%sp), %r1
2134         LDREG   PT_SAR(%r1), %rp
2135         mtctl   %rp, %cr11
2137         LDREG   PT_GR2(%r1), %rp
2138         LDREG   PT_GR3(%r1), %r3
2139         LDREG   PT_GR4(%r1), %r4
2140         LDREG   PT_GR5(%r1), %r5
2141         LDREG   PT_GR6(%r1), %r6
2142         LDREG   PT_GR7(%r1), %r7
2143         LDREG   PT_GR8(%r1), %r8
2144         LDREG   PT_GR9(%r1), %r9
2145         LDREG   PT_GR10(%r1),%r10
2146         LDREG   PT_GR11(%r1),%r11
2147         LDREG   PT_GR12(%r1),%r12
2148         LDREG   PT_GR13(%r1),%r13
2149         LDREG   PT_GR14(%r1),%r14
2150         LDREG   PT_GR15(%r1),%r15
2151         LDREG   PT_GR16(%r1),%r16
2152         LDREG   PT_GR17(%r1),%r17
2153         LDREG   PT_GR18(%r1),%r18
2154         LDREG   PT_GR19(%r1),%r19
2155         LDREG   PT_GR20(%r1),%r20
2156         LDREG   PT_GR21(%r1),%r21
2157         LDREG   PT_GR22(%r1),%r22
2158         LDREG   PT_GR23(%r1),%r23
2159         LDREG   PT_GR24(%r1),%r24
2160         LDREG   PT_GR25(%r1),%r25
2161         LDREG   PT_GR26(%r1),%r26
2162         LDREG   PT_GR27(%r1),%r27
2163         LDREG   PT_GR28(%r1),%r28
2164         LDREG   PT_GR29(%r1),%r29
2165         LDREG   PT_GR30(%r1),%r30
2166         LDREG   PT_GR31(%r1),%r31
2168         ldo     -PT_SZ_ALGN(%sp), %sp
2169         LDREGM  -FTRACE_FRAME_SIZE(%sp), %r1
2170         /* Adjust return point to jump back to beginning of traced function */
2171         ldo     -4(%r1), %r1
2172         bv,n    (%r1)
2174 ENDPROC_CFI(ftrace_regs_caller)
2176 #endif
2177 #endif
2179 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
2180         .align 8
2181 ENTRY_CFI(return_to_handler, caller,frame=FRAME_SIZE)
2182         .export parisc_return_to_handler,data
2183 parisc_return_to_handler:
2184         copy %r3,%r1
2185         STREG %r0,-RP_OFFSET(%sp)       /* store 0 as %rp */
2186         copy %sp,%r3
2187         STREGM %r1,FRAME_SIZE(%sp)
2188         STREG %ret0,8(%r3)
2189         STREG %ret1,16(%r3)
2191 #ifdef CONFIG_64BIT
2192         loadgp
2193 #endif
2195         /* call ftrace_return_to_handler(0) */
2196         .import ftrace_return_to_handler,code
2197         load32 ftrace_return_to_handler,%ret0
2198         load32 .Lftrace_ret,%r2
2199 #ifdef CONFIG_64BIT
2200         ldo -16(%sp),%ret1              /* Reference param save area */
2201         bve     (%ret0)
2202 #else
2203         bv      %r0(%ret0)
2204 #endif
2205         ldi 0,%r26
2206 .Lftrace_ret:
2207         copy %ret0,%rp
2209         /* restore original return values */
2210         LDREG 8(%r3),%ret0
2211         LDREG 16(%r3),%ret1
2213         /* return from function */
2214 #ifdef CONFIG_64BIT
2215         bve     (%rp)
2216 #else
2217         bv      %r0(%rp)
2218 #endif
2219         LDREGM -FRAME_SIZE(%sp),%r3
2220 ENDPROC_CFI(return_to_handler)
2222 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
2224 #endif  /* CONFIG_FUNCTION_TRACER */
2226 #ifdef CONFIG_IRQSTACKS
2227 /* void call_on_stack(unsigned long param1, void *func,
2228                       unsigned long new_stack) */
2229 ENTRY_CFI(call_on_stack, FRAME=2*FRAME_SIZE,CALLS,SAVE_RP,SAVE_SP)
2230 ENTRY(_call_on_stack)
2231         copy    %sp, %r1
2233         /* Regarding the HPPA calling conventions for function pointers,
2234            we assume the PIC register is not changed across call.  For
2235            CONFIG_64BIT, the argument pointer is left to point at the
2236            argument region allocated for the call to call_on_stack. */
2238         /* Switch to new stack.  We allocate two frames.  */
2239         ldo     2*FRAME_SIZE(%arg2), %sp
2240 # ifdef CONFIG_64BIT
2241         /* Save previous stack pointer and return pointer in frame marker */
2242         STREG   %rp, -FRAME_SIZE-RP_OFFSET(%sp)
2243         /* Calls always use function descriptor */
2244         LDREG   16(%arg1), %arg1
2245         bve,l   (%arg1), %rp
2246         STREG   %r1, -FRAME_SIZE-REG_SZ(%sp)
2247         LDREG   -FRAME_SIZE-RP_OFFSET(%sp), %rp
2248         bve     (%rp)
2249         LDREG   -FRAME_SIZE-REG_SZ(%sp), %sp
2250 # else
2251         /* Save previous stack pointer and return pointer in frame marker */
2252         STREG   %r1, -FRAME_SIZE-REG_SZ(%sp)
2253         STREG   %rp, -FRAME_SIZE-RP_OFFSET(%sp)
2254         /* Calls use function descriptor if PLABEL bit is set */
2255         bb,>=,n %arg1, 30, 1f
2256         depwi   0,31,2, %arg1
2257         LDREG   0(%arg1), %arg1
2259         be,l    0(%sr4,%arg1), %sr0, %r31
2260         copy    %r31, %rp
2261         LDREG   -FRAME_SIZE-RP_OFFSET(%sp), %rp
2262         bv      (%rp)
2263         LDREG   -FRAME_SIZE-REG_SZ(%sp), %sp
2264 # endif /* CONFIG_64BIT */
2265 ENDPROC_CFI(call_on_stack)
2266 #endif /* CONFIG_IRQSTACKS */
2268 ENTRY_CFI(get_register)
2269         /*
2270          * get_register is used by the non access tlb miss handlers to
2271          * copy the value of the general register specified in r8 into
2272          * r1. This routine can't be used for shadowed registers, since
2273          * the rfir will restore the original value. So, for the shadowed
2274          * registers we put a -1 into r1 to indicate that the register
2275          * should not be used (the register being copied could also have
2276          * a -1 in it, but that is OK, it just means that we will have
2277          * to use the slow path instead).
2278          */
2279         blr     %r8,%r0
2280         nop
2281         bv      %r0(%r25)    /* r0 */
2282         copy    %r0,%r1
2283         bv      %r0(%r25)    /* r1 - shadowed */
2284         ldi     -1,%r1
2285         bv      %r0(%r25)    /* r2 */
2286         copy    %r2,%r1
2287         bv      %r0(%r25)    /* r3 */
2288         copy    %r3,%r1
2289         bv      %r0(%r25)    /* r4 */
2290         copy    %r4,%r1
2291         bv      %r0(%r25)    /* r5 */
2292         copy    %r5,%r1
2293         bv      %r0(%r25)    /* r6 */
2294         copy    %r6,%r1
2295         bv      %r0(%r25)    /* r7 */
2296         copy    %r7,%r1
2297         bv      %r0(%r25)    /* r8 - shadowed */
2298         ldi     -1,%r1
2299         bv      %r0(%r25)    /* r9 - shadowed */
2300         ldi     -1,%r1
2301         bv      %r0(%r25)    /* r10 */
2302         copy    %r10,%r1
2303         bv      %r0(%r25)    /* r11 */
2304         copy    %r11,%r1
2305         bv      %r0(%r25)    /* r12 */
2306         copy    %r12,%r1
2307         bv      %r0(%r25)    /* r13 */
2308         copy    %r13,%r1
2309         bv      %r0(%r25)    /* r14 */
2310         copy    %r14,%r1
2311         bv      %r0(%r25)    /* r15 */
2312         copy    %r15,%r1
2313         bv      %r0(%r25)    /* r16 - shadowed */
2314         ldi     -1,%r1
2315         bv      %r0(%r25)    /* r17 - shadowed */
2316         ldi     -1,%r1
2317         bv      %r0(%r25)    /* r18 */
2318         copy    %r18,%r1
2319         bv      %r0(%r25)    /* r19 */
2320         copy    %r19,%r1
2321         bv      %r0(%r25)    /* r20 */
2322         copy    %r20,%r1
2323         bv      %r0(%r25)    /* r21 */
2324         copy    %r21,%r1
2325         bv      %r0(%r25)    /* r22 */
2326         copy    %r22,%r1
2327         bv      %r0(%r25)    /* r23 */
2328         copy    %r23,%r1
2329         bv      %r0(%r25)    /* r24 - shadowed */
2330         ldi     -1,%r1
2331         bv      %r0(%r25)    /* r25 - shadowed */
2332         ldi     -1,%r1
2333         bv      %r0(%r25)    /* r26 */
2334         copy    %r26,%r1
2335         bv      %r0(%r25)    /* r27 */
2336         copy    %r27,%r1
2337         bv      %r0(%r25)    /* r28 */
2338         copy    %r28,%r1
2339         bv      %r0(%r25)    /* r29 */
2340         copy    %r29,%r1
2341         bv      %r0(%r25)    /* r30 */
2342         copy    %r30,%r1
2343         bv      %r0(%r25)    /* r31 */
2344         copy    %r31,%r1
2345 ENDPROC_CFI(get_register)
2348 ENTRY_CFI(set_register)
2349         /*
2350          * set_register is used by the non access tlb miss handlers to
2351          * copy the value of r1 into the general register specified in
2352          * r8.
2353          */
2354         blr     %r8,%r0
2355         nop
2356         bv      %r0(%r25)    /* r0 (silly, but it is a place holder) */
2357         copy    %r1,%r0
2358         bv      %r0(%r25)    /* r1 */
2359         copy    %r1,%r1
2360         bv      %r0(%r25)    /* r2 */
2361         copy    %r1,%r2
2362         bv      %r0(%r25)    /* r3 */
2363         copy    %r1,%r3
2364         bv      %r0(%r25)    /* r4 */
2365         copy    %r1,%r4
2366         bv      %r0(%r25)    /* r5 */
2367         copy    %r1,%r5
2368         bv      %r0(%r25)    /* r6 */
2369         copy    %r1,%r6
2370         bv      %r0(%r25)    /* r7 */
2371         copy    %r1,%r7
2372         bv      %r0(%r25)    /* r8 */
2373         copy    %r1,%r8
2374         bv      %r0(%r25)    /* r9 */
2375         copy    %r1,%r9
2376         bv      %r0(%r25)    /* r10 */
2377         copy    %r1,%r10
2378         bv      %r0(%r25)    /* r11 */
2379         copy    %r1,%r11
2380         bv      %r0(%r25)    /* r12 */
2381         copy    %r1,%r12
2382         bv      %r0(%r25)    /* r13 */
2383         copy    %r1,%r13
2384         bv      %r0(%r25)    /* r14 */
2385         copy    %r1,%r14
2386         bv      %r0(%r25)    /* r15 */
2387         copy    %r1,%r15
2388         bv      %r0(%r25)    /* r16 */
2389         copy    %r1,%r16
2390         bv      %r0(%r25)    /* r17 */
2391         copy    %r1,%r17
2392         bv      %r0(%r25)    /* r18 */
2393         copy    %r1,%r18
2394         bv      %r0(%r25)    /* r19 */
2395         copy    %r1,%r19
2396         bv      %r0(%r25)    /* r20 */
2397         copy    %r1,%r20
2398         bv      %r0(%r25)    /* r21 */
2399         copy    %r1,%r21
2400         bv      %r0(%r25)    /* r22 */
2401         copy    %r1,%r22
2402         bv      %r0(%r25)    /* r23 */
2403         copy    %r1,%r23
2404         bv      %r0(%r25)    /* r24 */
2405         copy    %r1,%r24
2406         bv      %r0(%r25)    /* r25 */
2407         copy    %r1,%r25
2408         bv      %r0(%r25)    /* r26 */
2409         copy    %r1,%r26
2410         bv      %r0(%r25)    /* r27 */
2411         copy    %r1,%r27
2412         bv      %r0(%r25)    /* r28 */
2413         copy    %r1,%r28
2414         bv      %r0(%r25)    /* r29 */
2415         copy    %r1,%r29
2416         bv      %r0(%r25)    /* r30 */
2417         copy    %r1,%r30
2418         bv      %r0(%r25)    /* r31 */
2419         copy    %r1,%r31
2420 ENDPROC_CFI(set_register)