Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[cris-mirror.git] / arch / parisc / kernel / entry.S
blobe95207c0565eb12308e12d48c45bd5309ae6e2ae
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  */
25 #include <asm/asm-offsets.h>
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 */
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/ldcw.h>
39 #include <asm/thread_info.h>
41 #include <linux/linkage.h>
43 #ifdef CONFIG_64BIT
44         .level 2.0w
45 #else
46         .level 2.0
47 #endif
49         .import         pa_tlb_lock,data
50         .macro  load_pa_tlb_lock reg
51 #if __PA_LDCW_ALIGNMENT > 4
52         load32  PA(pa_tlb_lock) + __PA_LDCW_ALIGNMENT-1, \reg
53         depi    0,31,__PA_LDCW_ALIGN_ORDER, \reg
54 #else
55         load32  PA(pa_tlb_lock), \reg
56 #endif
57         .endm
59         /* space_to_prot macro creates a prot id from a space id */
61 #if (SPACEID_SHIFT) == 0
62         .macro  space_to_prot spc prot
63         depd,z  \spc,62,31,\prot
64         .endm
65 #else
66         .macro  space_to_prot spc prot
67         extrd,u \spc,(64 - (SPACEID_SHIFT)),32,\prot
68         .endm
69 #endif
71         /* Switch to virtual mapping, trashing only %r1 */
72         .macro  virt_map
73         /* pcxt_ssm_bug */
74         rsm     PSW_SM_I, %r0   /* barrier for "Relied upon Translation */
75         mtsp    %r0, %sr4
76         mtsp    %r0, %sr5
77         mtsp    %r0, %sr6
78         tovirt_r1 %r29
79         load32  KERNEL_PSW, %r1
81         rsm     PSW_SM_QUIET,%r0        /* second "heavy weight" ctl op */
82         mtctl   %r0, %cr17      /* Clear IIASQ tail */
83         mtctl   %r0, %cr17      /* Clear IIASQ head */
84         mtctl   %r1, %ipsw
85         load32  4f, %r1
86         mtctl   %r1, %cr18      /* Set IIAOQ tail */
87         ldo     4(%r1), %r1
88         mtctl   %r1, %cr18      /* Set IIAOQ head */
89         rfir
90         nop
92         .endm
94         /*
95          * The "get_stack" macros are responsible for determining the
96          * kernel stack value.
97          *
98          *      If sr7 == 0
99          *          Already using a kernel stack, so call the
100          *          get_stack_use_r30 macro to push a pt_regs structure
101          *          on the stack, and store registers there.
102          *      else
103          *          Need to set up a kernel stack, so call the
104          *          get_stack_use_cr30 macro to set up a pointer
105          *          to the pt_regs structure contained within the
106          *          task pointer pointed to by cr30. Set the stack
107          *          pointer to point to the end of the task structure.
108          *
109          * Note that we use shadowed registers for temps until
110          * we can save %r26 and %r29. %r26 is used to preserve
111          * %r8 (a shadowed register) which temporarily contained
112          * either the fault type ("code") or the eirr. We need
113          * to use a non-shadowed register to carry the value over
114          * the rfir in virt_map. We use %r26 since this value winds
115          * up being passed as the argument to either do_cpu_irq_mask
116          * or handle_interruption. %r29 is used to hold a pointer
117          * the register save area, and once again, it needs to
118          * be a non-shadowed register so that it survives the rfir.
119          *
120          * N.B. TASK_SZ_ALGN and PT_SZ_ALGN include space for a stack frame.
121          */
123         .macro  get_stack_use_cr30
125         /* we save the registers in the task struct */
127         copy    %r30, %r17
128         mfctl   %cr30, %r1
129         ldo     THREAD_SZ_ALGN(%r1), %r30
130         mtsp    %r0,%sr7
131         mtsp    %r16,%sr3
132         tophys  %r1,%r9
133         LDREG   TI_TASK(%r9), %r1       /* thread_info -> task_struct */
134         tophys  %r1,%r9
135         ldo     TASK_REGS(%r9),%r9
136         STREG   %r17,PT_GR30(%r9)
137         STREG   %r29,PT_GR29(%r9)
138         STREG   %r26,PT_GR26(%r9)
139         STREG   %r16,PT_SR7(%r9)
140         copy    %r9,%r29
141         .endm
143         .macro  get_stack_use_r30
145         /* we put a struct pt_regs on the stack and save the registers there */
147         tophys  %r30,%r9
148         copy    %r30,%r1
149         ldo     PT_SZ_ALGN(%r30),%r30
150         STREG   %r1,PT_GR30(%r9)
151         STREG   %r29,PT_GR29(%r9)
152         STREG   %r26,PT_GR26(%r9)
153         STREG   %r16,PT_SR7(%r9)
154         copy    %r9,%r29
155         .endm
157         .macro  rest_stack
158         LDREG   PT_GR1(%r29), %r1
159         LDREG   PT_GR30(%r29),%r30
160         LDREG   PT_GR29(%r29),%r29
161         .endm
163         /* default interruption handler
164          * (calls traps.c:handle_interruption) */
165         .macro  def code
166         b       intr_save
167         ldi     \code, %r8
168         .align  32
169         .endm
171         /* Interrupt interruption handler
172          * (calls irq.c:do_cpu_irq_mask) */
173         .macro  extint code
174         b       intr_extint
175         mfsp    %sr7,%r16
176         .align  32
177         .endm   
179         .import os_hpmc, code
181         /* HPMC handler */
182         .macro  hpmc code
183         nop                     /* must be a NOP, will be patched later */
184         load32  PA(os_hpmc), %r3
185         bv,n    0(%r3)
186         nop
187         .word   0               /* checksum (will be patched) */
188         .word   PA(os_hpmc)     /* address of handler */
189         .word   0               /* length of handler */
190         .endm
192         /*
193          * Performance Note: Instructions will be moved up into
194          * this part of the code later on, once we are sure
195          * that the tlb miss handlers are close to final form.
196          */
198         /* Register definitions for tlb miss handler macros */
200         va  = r8        /* virtual address for which the trap occurred */
201         spc = r24       /* space for which the trap occurred */
203 #ifndef CONFIG_64BIT
205         /*
206          * itlb miss interruption handler (parisc 1.1 - 32 bit)
207          */
209         .macro  itlb_11 code
211         mfctl   %pcsq, spc
212         b       itlb_miss_11
213         mfctl   %pcoq, va
215         .align          32
216         .endm
217 #endif
218         
219         /*
220          * itlb miss interruption handler (parisc 2.0)
221          */
223         .macro  itlb_20 code
224         mfctl   %pcsq, spc
225 #ifdef CONFIG_64BIT
226         b       itlb_miss_20w
227 #else
228         b       itlb_miss_20
229 #endif
230         mfctl   %pcoq, va
232         .align          32
233         .endm
234         
235 #ifndef CONFIG_64BIT
236         /*
237          * naitlb miss interruption handler (parisc 1.1 - 32 bit)
238          */
240         .macro  naitlb_11 code
242         mfctl   %isr,spc
243         b       naitlb_miss_11
244         mfctl   %ior,va
246         .align          32
247         .endm
248 #endif
249         
250         /*
251          * naitlb miss interruption handler (parisc 2.0)
252          */
254         .macro  naitlb_20 code
256         mfctl   %isr,spc
257 #ifdef CONFIG_64BIT
258         b       naitlb_miss_20w
259 #else
260         b       naitlb_miss_20
261 #endif
262         mfctl   %ior,va
264         .align          32
265         .endm
266         
267 #ifndef CONFIG_64BIT
268         /*
269          * dtlb miss interruption handler (parisc 1.1 - 32 bit)
270          */
272         .macro  dtlb_11 code
274         mfctl   %isr, spc
275         b       dtlb_miss_11
276         mfctl   %ior, va
278         .align          32
279         .endm
280 #endif
282         /*
283          * dtlb miss interruption handler (parisc 2.0)
284          */
286         .macro  dtlb_20 code
288         mfctl   %isr, spc
289 #ifdef CONFIG_64BIT
290         b       dtlb_miss_20w
291 #else
292         b       dtlb_miss_20
293 #endif
294         mfctl   %ior, va
296         .align          32
297         .endm
298         
299 #ifndef CONFIG_64BIT
300         /* nadtlb miss interruption handler (parisc 1.1 - 32 bit) */
302         .macro  nadtlb_11 code
304         mfctl   %isr,spc
305         b       nadtlb_miss_11
306         mfctl   %ior,va
308         .align          32
309         .endm
310 #endif
311         
312         /* nadtlb miss interruption handler (parisc 2.0) */
314         .macro  nadtlb_20 code
316         mfctl   %isr,spc
317 #ifdef CONFIG_64BIT
318         b       nadtlb_miss_20w
319 #else
320         b       nadtlb_miss_20
321 #endif
322         mfctl   %ior,va
324         .align          32
325         .endm
326         
327 #ifndef CONFIG_64BIT
328         /*
329          * dirty bit trap interruption handler (parisc 1.1 - 32 bit)
330          */
332         .macro  dbit_11 code
334         mfctl   %isr,spc
335         b       dbit_trap_11
336         mfctl   %ior,va
338         .align          32
339         .endm
340 #endif
342         /*
343          * dirty bit trap interruption handler (parisc 2.0)
344          */
346         .macro  dbit_20 code
348         mfctl   %isr,spc
349 #ifdef CONFIG_64BIT
350         b       dbit_trap_20w
351 #else
352         b       dbit_trap_20
353 #endif
354         mfctl   %ior,va
356         .align          32
357         .endm
359         /* In LP64, the space contains part of the upper 32 bits of the
360          * fault.  We have to extract this and place it in the va,
361          * zeroing the corresponding bits in the space register */
362         .macro          space_adjust    spc,va,tmp
363 #ifdef CONFIG_64BIT
364         extrd,u         \spc,63,SPACEID_SHIFT,\tmp
365         depd            %r0,63,SPACEID_SHIFT,\spc
366         depd            \tmp,31,SPACEID_SHIFT,\va
367 #endif
368         .endm
370         .import         swapper_pg_dir,code
372         /* Get the pgd.  For faults on space zero (kernel space), this
373          * is simply swapper_pg_dir.  For user space faults, the
374          * pgd is stored in %cr25 */
375         .macro          get_pgd         spc,reg
376         ldil            L%PA(swapper_pg_dir),\reg
377         ldo             R%PA(swapper_pg_dir)(\reg),\reg
378         or,COND(=)      %r0,\spc,%r0
379         mfctl           %cr25,\reg
380         .endm
382         /* 
383                 space_check(spc,tmp,fault)
385                 spc - The space we saw the fault with.
386                 tmp - The place to store the current space.
387                 fault - Function to call on failure.
389                 Only allow faults on different spaces from the
390                 currently active one if we're the kernel 
392         */
393         .macro          space_check     spc,tmp,fault
394         mfsp            %sr7,\tmp
395         or,COND(<>)     %r0,\spc,%r0    /* user may execute gateway page
396                                          * as kernel, so defeat the space
397                                          * check if it is */
398         copy            \spc,\tmp
399         or,COND(=)      %r0,\tmp,%r0    /* nullify if executing as kernel */
400         cmpb,COND(<>),n \tmp,\spc,\fault
401         .endm
403         /* Look up a PTE in a 2-Level scheme (faulting at each
404          * level if the entry isn't present 
405          *
406          * NOTE: we use ldw even for LP64, since the short pointers
407          * can address up to 1TB
408          */
409         .macro          L2_ptep pmd,pte,index,va,fault
410 #if CONFIG_PGTABLE_LEVELS == 3
411         extru           \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index
412 #else
413 # if defined(CONFIG_64BIT)
414         extrd,u         \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
415   #else
416   # if PAGE_SIZE > 4096
417         extru           \va,31-ASM_PGDIR_SHIFT,32-ASM_PGDIR_SHIFT,\index
418   # else
419         extru           \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
420   # endif
421 # endif
422 #endif
423         dep             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
424         copy            %r0,\pte
425         ldw,s           \index(\pmd),\pmd
426         bb,>=,n         \pmd,_PxD_PRESENT_BIT,\fault
427         dep             %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
428         copy            \pmd,%r9
429         SHLREG          %r9,PxD_VALUE_SHIFT,\pmd
430         extru           \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
431         dep             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
432         shladd          \index,BITS_PER_PTE_ENTRY,\pmd,\pmd /* pmd is now pte */
433         LDREG           %r0(\pmd),\pte
434         bb,>=,n         \pte,_PAGE_PRESENT_BIT,\fault
435         .endm
437         /* Look up PTE in a 3-Level scheme.
438          *
439          * Here we implement a Hybrid L2/L3 scheme: we allocate the
440          * first pmd adjacent to the pgd.  This means that we can
441          * subtract a constant offset to get to it.  The pmd and pgd
442          * sizes are arranged so that a single pmd covers 4GB (giving
443          * a full LP64 process access to 8TB) so our lookups are
444          * effectively L2 for the first 4GB of the kernel (i.e. for
445          * all ILP32 processes and all the kernel for machines with
446          * under 4GB of memory) */
447         .macro          L3_ptep pgd,pte,index,va,fault
448 #if CONFIG_PGTABLE_LEVELS == 3 /* we might have a 2-Level scheme, e.g. with 16kb page size */
449         extrd,u         \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
450         copy            %r0,\pte
451         extrd,u,*=      \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
452         ldw,s           \index(\pgd),\pgd
453         extrd,u,*=      \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
454         bb,>=,n         \pgd,_PxD_PRESENT_BIT,\fault
455         extrd,u,*=      \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
456         shld            \pgd,PxD_VALUE_SHIFT,\index
457         extrd,u,*=      \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
458         copy            \index,\pgd
459         extrd,u,*<>     \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
460         ldo             ASM_PGD_PMD_OFFSET(\pgd),\pgd
461 #endif
462         L2_ptep         \pgd,\pte,\index,\va,\fault
463         .endm
465         /* Acquire pa_tlb_lock lock and recheck page is still present. */
466         .macro          tlb_lock        spc,ptp,pte,tmp,tmp1,fault
467 #ifdef CONFIG_SMP
468         cmpib,COND(=),n 0,\spc,2f
469         load_pa_tlb_lock \tmp
470 1:      LDCW            0(\tmp),\tmp1
471         cmpib,COND(=)   0,\tmp1,1b
472         nop
473         LDREG           0(\ptp),\pte
474         bb,<,n          \pte,_PAGE_PRESENT_BIT,2f
475         b               \fault
476         stw              \spc,0(\tmp)
478 #endif
479         .endm
481         /* Release pa_tlb_lock lock without reloading lock address. */
482         .macro          tlb_unlock0     spc,tmp
483 #ifdef CONFIG_SMP
484         or,COND(=)      %r0,\spc,%r0
485         stw             \spc,0(\tmp)
486 #endif
487         .endm
489         /* Release pa_tlb_lock lock. */
490         .macro          tlb_unlock1     spc,tmp
491 #ifdef CONFIG_SMP
492         load_pa_tlb_lock \tmp
493         tlb_unlock0     \spc,\tmp
494 #endif
495         .endm
497         /* Set the _PAGE_ACCESSED bit of the PTE.  Be clever and
498          * don't needlessly dirty the cache line if it was already set */
499         .macro          update_accessed ptp,pte,tmp,tmp1
500         ldi             _PAGE_ACCESSED,\tmp1
501         or              \tmp1,\pte,\tmp
502         and,COND(<>)    \tmp1,\pte,%r0
503         STREG           \tmp,0(\ptp)
504         .endm
506         /* Set the dirty bit (and accessed bit).  No need to be
507          * clever, this is only used from the dirty fault */
508         .macro          update_dirty    ptp,pte,tmp
509         ldi             _PAGE_ACCESSED|_PAGE_DIRTY,\tmp
510         or              \tmp,\pte,\pte
511         STREG           \pte,0(\ptp)
512         .endm
514         /* We have (depending on the page size):
515          * - 38 to 52-bit Physical Page Number
516          * - 12 to 26-bit page offset
517          */
518         /* bitshift difference between a PFN (based on kernel's PAGE_SIZE)
519          * to a CPU TLB 4k PFN (4k => 12 bits to shift) */
520         #define PAGE_ADD_SHIFT          (PAGE_SHIFT-12)
521         #define PAGE_ADD_HUGE_SHIFT     (REAL_HPAGE_SHIFT-12)
523         /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
524         .macro          convert_for_tlb_insert20 pte,tmp
525 #ifdef CONFIG_HUGETLB_PAGE
526         copy            \pte,\tmp
527         extrd,u         \tmp,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
528                                 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
530         depdi           _PAGE_SIZE_ENCODING_DEFAULT,63,\
531                                 (63-58)+PAGE_ADD_SHIFT,\pte
532         extrd,u,*=      \tmp,_PAGE_HPAGE_BIT+32,1,%r0
533         depdi           _HUGE_PAGE_SIZE_ENCODING_DEFAULT,63,\
534                                 (63-58)+PAGE_ADD_HUGE_SHIFT,\pte
535 #else /* Huge pages disabled */
536         extrd,u         \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
537                                 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
538         depdi           _PAGE_SIZE_ENCODING_DEFAULT,63,\
539                                 (63-58)+PAGE_ADD_SHIFT,\pte
540 #endif
541         .endm
543         /* Convert the pte and prot to tlb insertion values.  How
544          * this happens is quite subtle, read below */
545         .macro          make_insert_tlb spc,pte,prot,tmp
546         space_to_prot   \spc \prot        /* create prot id from space */
547         /* The following is the real subtlety.  This is depositing
548          * T <-> _PAGE_REFTRAP
549          * D <-> _PAGE_DIRTY
550          * B <-> _PAGE_DMB (memory break)
551          *
552          * Then incredible subtlety: The access rights are
553          * _PAGE_GATEWAY, _PAGE_EXEC and _PAGE_WRITE
554          * See 3-14 of the parisc 2.0 manual
555          *
556          * Finally, _PAGE_READ goes in the top bit of PL1 (so we
557          * trigger an access rights trap in user space if the user
558          * tries to read an unreadable page */
559         depd            \pte,8,7,\prot
561         /* PAGE_USER indicates the page can be read with user privileges,
562          * so deposit X1|11 to PL1|PL2 (remember the upper bit of PL1
563          * contains _PAGE_READ) */
564         extrd,u,*=      \pte,_PAGE_USER_BIT+32,1,%r0
565         depdi           7,11,3,\prot
566         /* If we're a gateway page, drop PL2 back to zero for promotion
567          * to kernel privilege (so we can execute the page as kernel).
568          * Any privilege promotion page always denys read and write */
569         extrd,u,*=      \pte,_PAGE_GATEWAY_BIT+32,1,%r0
570         depd            %r0,11,2,\prot  /* If Gateway, Set PL2 to 0 */
572         /* Enforce uncacheable pages.
573          * This should ONLY be use for MMIO on PA 2.0 machines.
574          * Memory/DMA is cache coherent on all PA2.0 machines we support
575          * (that means T-class is NOT supported) and the memory controllers
576          * on most of those machines only handles cache transactions.
577          */
578         extrd,u,*=      \pte,_PAGE_NO_CACHE_BIT+32,1,%r0
579         depdi           1,12,1,\prot
581         /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
582         convert_for_tlb_insert20 \pte \tmp
583         .endm
585         /* Identical macro to make_insert_tlb above, except it
586          * makes the tlb entry for the differently formatted pa11
587          * insertion instructions */
588         .macro          make_insert_tlb_11      spc,pte,prot
589         zdep            \spc,30,15,\prot
590         dep             \pte,8,7,\prot
591         extru,=         \pte,_PAGE_NO_CACHE_BIT,1,%r0
592         depi            1,12,1,\prot
593         extru,=         \pte,_PAGE_USER_BIT,1,%r0
594         depi            7,11,3,\prot   /* Set for user space (1 rsvd for read) */
595         extru,=         \pte,_PAGE_GATEWAY_BIT,1,%r0
596         depi            0,11,2,\prot    /* If Gateway, Set PL2 to 0 */
598         /* Get rid of prot bits and convert to page addr for iitlba */
600         depi            0,31,ASM_PFN_PTE_SHIFT,\pte
601         SHRREG          \pte,(ASM_PFN_PTE_SHIFT-(31-26)),\pte
602         .endm
604         /* This is for ILP32 PA2.0 only.  The TLB insertion needs
605          * to extend into I/O space if the address is 0xfXXXXXXX
606          * so we extend the f's into the top word of the pte in
607          * this case */
608         .macro          f_extend        pte,tmp
609         extrd,s         \pte,42,4,\tmp
610         addi,<>         1,\tmp,%r0
611         extrd,s         \pte,63,25,\pte
612         .endm
614         /* The alias region is an 8MB aligned 16MB to do clear and
615          * copy user pages at addresses congruent with the user
616          * virtual address.
617          *
618          * To use the alias page, you set %r26 up with the to TLB
619          * entry (identifying the physical page) and %r23 up with
620          * the from tlb entry (or nothing if only a to entry---for
621          * clear_user_page_asm) */
622         .macro          do_alias        spc,tmp,tmp1,va,pte,prot,fault,patype
623         cmpib,COND(<>),n 0,\spc,\fault
624         ldil            L%(TMPALIAS_MAP_START),\tmp
625 #if defined(CONFIG_64BIT) && (TMPALIAS_MAP_START >= 0x80000000)
626         /* on LP64, ldi will sign extend into the upper 32 bits,
627          * which is behaviour we don't want */
628         depdi           0,31,32,\tmp
629 #endif
630         copy            \va,\tmp1
631         depi            0,31,23,\tmp1
632         cmpb,COND(<>),n \tmp,\tmp1,\fault
633         mfctl           %cr19,\tmp      /* iir */
634         /* get the opcode (first six bits) into \tmp */
635         extrw,u         \tmp,5,6,\tmp
636         /*
637          * Only setting the T bit prevents data cache movein
638          * Setting access rights to zero prevents instruction cache movein
639          *
640          * Note subtlety here: _PAGE_GATEWAY, _PAGE_EXEC and _PAGE_WRITE go
641          * to type field and _PAGE_READ goes to top bit of PL1
642          */
643         ldi             (_PAGE_REFTRAP|_PAGE_READ|_PAGE_WRITE),\prot
644         /*
645          * so if the opcode is one (i.e. this is a memory management
646          * instruction) nullify the next load so \prot is only T.
647          * Otherwise this is a normal data operation
648          */
649         cmpiclr,=       0x01,\tmp,%r0
650         ldi             (_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot
651 .ifc \patype,20
652         depd,z          \prot,8,7,\prot
653 .else
654 .ifc \patype,11
655         depw,z          \prot,8,7,\prot
656 .else
657         .error "undefined PA type to do_alias"
658 .endif
659 .endif
660         /*
661          * OK, it is in the temp alias region, check whether "from" or "to".
662          * Check "subtle" note in pacache.S re: r23/r26.
663          */
664 #ifdef CONFIG_64BIT
665         extrd,u,*=      \va,41,1,%r0
666 #else
667         extrw,u,=       \va,9,1,%r0
668 #endif
669         or,COND(tr)     %r23,%r0,\pte
670         or              %r26,%r0,\pte
671         .endm 
674         /*
675          * Fault_vectors are architecturally required to be aligned on a 2K
676          * boundary
677          */
679         .section .text.hot
680         .align 2048
682 ENTRY(fault_vector_20)
683         /* First vector is invalid (0) */
684         .ascii  "cows can fly"
685         .byte 0
686         .align 32
688         hpmc             1
689         def              2
690         def              3
691         extint           4
692         def              5
693         itlb_20          6
694         def              7
695         def              8
696         def              9
697         def             10
698         def             11
699         def             12
700         def             13
701         def             14
702         dtlb_20         15
703         naitlb_20       16
704         nadtlb_20       17
705         def             18
706         def             19
707         dbit_20         20
708         def             21
709         def             22
710         def             23
711         def             24
712         def             25
713         def             26
714         def             27
715         def             28
716         def             29
717         def             30
718         def             31
719 END(fault_vector_20)
721 #ifndef CONFIG_64BIT
723         .align 2048
725 ENTRY(fault_vector_11)
726         /* First vector is invalid (0) */
727         .ascii  "cows can fly"
728         .byte 0
729         .align 32
731         hpmc             1
732         def              2
733         def              3
734         extint           4
735         def              5
736         itlb_11          6
737         def              7
738         def              8
739         def              9
740         def             10
741         def             11
742         def             12
743         def             13
744         def             14
745         dtlb_11         15
746         naitlb_11       16
747         nadtlb_11       17
748         def             18
749         def             19
750         dbit_11         20
751         def             21
752         def             22
753         def             23
754         def             24
755         def             25
756         def             26
757         def             27
758         def             28
759         def             29
760         def             30
761         def             31
762 END(fault_vector_11)
764 #endif
765         /* Fault vector is separately protected and *must* be on its own page */
766         .align          PAGE_SIZE
767 ENTRY(end_fault_vector)
769         .import         handle_interruption,code
770         .import         do_cpu_irq_mask,code
772         /*
773          * Child Returns here
774          *
775          * copy_thread moved args into task save area.
776          */
778 ENTRY_CFI(ret_from_kernel_thread)
780         /* Call schedule_tail first though */
781         BL      schedule_tail, %r2
782         nop
784         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
785         LDREG   TASK_PT_GR25(%r1), %r26
786 #ifdef CONFIG_64BIT
787         LDREG   TASK_PT_GR27(%r1), %r27
788 #endif
789         LDREG   TASK_PT_GR26(%r1), %r1
790         ble     0(%sr7, %r1)
791         copy    %r31, %r2
792         b       finish_child_return
793         nop
794 ENDPROC_CFI(ret_from_kernel_thread)
797         /*
798          * struct task_struct *_switch_to(struct task_struct *prev,
799          *      struct task_struct *next)
800          *
801          * switch kernel stacks and return prev */
802 ENTRY_CFI(_switch_to)
803         STREG    %r2, -RP_OFFSET(%r30)
805         callee_save_float
806         callee_save
808         load32  _switch_to_ret, %r2
810         STREG   %r2, TASK_PT_KPC(%r26)
811         LDREG   TASK_PT_KPC(%r25), %r2
813         STREG   %r30, TASK_PT_KSP(%r26)
814         LDREG   TASK_PT_KSP(%r25), %r30
815         LDREG   TASK_THREAD_INFO(%r25), %r25
816         bv      %r0(%r2)
817         mtctl   %r25,%cr30
819 _switch_to_ret:
820         mtctl   %r0, %cr0               /* Needed for single stepping */
821         callee_rest
822         callee_rest_float
824         LDREG   -RP_OFFSET(%r30), %r2
825         bv      %r0(%r2)
826         copy    %r26, %r28
827 ENDPROC_CFI(_switch_to)
829         /*
830          * Common rfi return path for interruptions, kernel execve, and
831          * sys_rt_sigreturn (sometimes).  The sys_rt_sigreturn syscall will
832          * return via this path if the signal was received when the process
833          * was running; if the process was blocked on a syscall then the
834          * normal syscall_exit path is used.  All syscalls for traced
835          * proceses exit via intr_restore.
836          *
837          * XXX If any syscalls that change a processes space id ever exit
838          * this way, then we will need to copy %sr3 in to PT_SR[3..7], and
839          * adjust IASQ[0..1].
840          *
841          */
843         .align  PAGE_SIZE
845 ENTRY_CFI(syscall_exit_rfi)
846         mfctl   %cr30,%r16
847         LDREG   TI_TASK(%r16), %r16     /* thread_info -> task_struct */
848         ldo     TASK_REGS(%r16),%r16
849         /* Force iaoq to userspace, as the user has had access to our current
850          * context via sigcontext. Also Filter the PSW for the same reason.
851          */
852         LDREG   PT_IAOQ0(%r16),%r19
853         depi    3,31,2,%r19
854         STREG   %r19,PT_IAOQ0(%r16)
855         LDREG   PT_IAOQ1(%r16),%r19
856         depi    3,31,2,%r19
857         STREG   %r19,PT_IAOQ1(%r16)
858         LDREG   PT_PSW(%r16),%r19
859         load32  USER_PSW_MASK,%r1
860 #ifdef CONFIG_64BIT
861         load32  USER_PSW_HI_MASK,%r20
862         depd    %r20,31,32,%r1
863 #endif
864         and     %r19,%r1,%r19 /* Mask out bits that user shouldn't play with */
865         load32  USER_PSW,%r1
866         or      %r19,%r1,%r19 /* Make sure default USER_PSW bits are set */
867         STREG   %r19,PT_PSW(%r16)
869         /*
870          * If we aren't being traced, we never saved space registers
871          * (we don't store them in the sigcontext), so set them
872          * to "proper" values now (otherwise we'll wind up restoring
873          * whatever was last stored in the task structure, which might
874          * be inconsistent if an interrupt occurred while on the gateway
875          * page). Note that we may be "trashing" values the user put in
876          * them, but we don't support the user changing them.
877          */
879         STREG   %r0,PT_SR2(%r16)
880         mfsp    %sr3,%r19
881         STREG   %r19,PT_SR0(%r16)
882         STREG   %r19,PT_SR1(%r16)
883         STREG   %r19,PT_SR3(%r16)
884         STREG   %r19,PT_SR4(%r16)
885         STREG   %r19,PT_SR5(%r16)
886         STREG   %r19,PT_SR6(%r16)
887         STREG   %r19,PT_SR7(%r16)
889 intr_return:
890         /* check for reschedule */
891         mfctl   %cr30,%r1
892         LDREG   TI_FLAGS(%r1),%r19      /* sched.h: TIF_NEED_RESCHED */
893         bb,<,n  %r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */
895         .import do_notify_resume,code
896 intr_check_sig:
897         /* As above */
898         mfctl   %cr30,%r1
899         LDREG   TI_FLAGS(%r1),%r19
900         ldi     (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), %r20
901         and,COND(<>)    %r19, %r20, %r0
902         b,n     intr_restore    /* skip past if we've nothing to do */
904         /* This check is critical to having LWS
905          * working. The IASQ is zero on the gateway
906          * page and we cannot deliver any signals until
907          * we get off the gateway page.
908          *
909          * Only do signals if we are returning to user space
910          */
911         LDREG   PT_IASQ0(%r16), %r20
912         cmpib,COND(=),n 0,%r20,intr_restore /* backward */
913         LDREG   PT_IASQ1(%r16), %r20
914         cmpib,COND(=),n 0,%r20,intr_restore /* backward */
916         /* NOTE: We need to enable interrupts if we have to deliver
917          * signals. We used to do this earlier but it caused kernel
918          * stack overflows. */
919         ssm     PSW_SM_I, %r0
921         copy    %r0, %r25                       /* long in_syscall = 0 */
922 #ifdef CONFIG_64BIT
923         ldo     -16(%r30),%r29                  /* Reference param save area */
924 #endif
926         BL      do_notify_resume,%r2
927         copy    %r16, %r26                      /* struct pt_regs *regs */
929         b,n     intr_check_sig
931 intr_restore:
932         copy            %r16,%r29
933         ldo             PT_FR31(%r29),%r1
934         rest_fp         %r1
935         rest_general    %r29
937         /* inverse of virt_map */
938         pcxt_ssm_bug
939         rsm             PSW_SM_QUIET,%r0        /* prepare for rfi */
940         tophys_r1       %r29
942         /* Restore space id's and special cr's from PT_REGS
943          * structure pointed to by r29
944          */
945         rest_specials   %r29
947         /* IMPORTANT: rest_stack restores r29 last (we are using it)!
948          * It also restores r1 and r30.
949          */
950         rest_stack
952         rfi
953         nop
955 #ifndef CONFIG_PREEMPT
956 # define intr_do_preempt        intr_restore
957 #endif /* !CONFIG_PREEMPT */
959         .import schedule,code
960 intr_do_resched:
961         /* Only call schedule on return to userspace. If we're returning
962          * to kernel space, we may schedule if CONFIG_PREEMPT, otherwise
963          * we jump back to intr_restore.
964          */
965         LDREG   PT_IASQ0(%r16), %r20
966         cmpib,COND(=)   0, %r20, intr_do_preempt
967         nop
968         LDREG   PT_IASQ1(%r16), %r20
969         cmpib,COND(=)   0, %r20, intr_do_preempt
970         nop
972         /* NOTE: We need to enable interrupts if we schedule.  We used
973          * to do this earlier but it caused kernel stack overflows. */
974         ssm     PSW_SM_I, %r0
976 #ifdef CONFIG_64BIT
977         ldo     -16(%r30),%r29          /* Reference param save area */
978 #endif
980         ldil    L%intr_check_sig, %r2
981 #ifndef CONFIG_64BIT
982         b       schedule
983 #else
984         load32  schedule, %r20
985         bv      %r0(%r20)
986 #endif
987         ldo     R%intr_check_sig(%r2), %r2
989         /* preempt the current task on returning to kernel
990          * mode from an interrupt, iff need_resched is set,
991          * and preempt_count is 0. otherwise, we continue on
992          * our merry way back to the current running task.
993          */
994 #ifdef CONFIG_PREEMPT
995         .import preempt_schedule_irq,code
996 intr_do_preempt:
997         rsm     PSW_SM_I, %r0           /* disable interrupts */
999         /* current_thread_info()->preempt_count */
1000         mfctl   %cr30, %r1
1001         LDREG   TI_PRE_COUNT(%r1), %r19
1002         cmpib,COND(<>)  0, %r19, intr_restore   /* if preempt_count > 0 */
1003         nop                             /* prev insn branched backwards */
1005         /* check if we interrupted a critical path */
1006         LDREG   PT_PSW(%r16), %r20
1007         bb,<,n  %r20, 31 - PSW_SM_I, intr_restore
1008         nop
1010         BL      preempt_schedule_irq, %r2
1011         nop
1013         b,n     intr_restore            /* ssm PSW_SM_I done by intr_restore */
1014 #endif /* CONFIG_PREEMPT */
1016         /*
1017          * External interrupts.
1018          */
1020 intr_extint:
1021         cmpib,COND(=),n 0,%r16,1f
1023         get_stack_use_cr30
1024         b,n 2f
1027         get_stack_use_r30
1029         save_specials   %r29
1030         virt_map
1031         save_general    %r29
1033         ldo     PT_FR0(%r29), %r24
1034         save_fp %r24
1035         
1036         loadgp
1038         copy    %r29, %r26      /* arg0 is pt_regs */
1039         copy    %r29, %r16      /* save pt_regs */
1041         ldil    L%intr_return, %r2
1043 #ifdef CONFIG_64BIT
1044         ldo     -16(%r30),%r29  /* Reference param save area */
1045 #endif
1047         b       do_cpu_irq_mask
1048         ldo     R%intr_return(%r2), %r2 /* return to intr_return, not here */
1049 ENDPROC_CFI(syscall_exit_rfi)
1052         /* Generic interruptions (illegal insn, unaligned, page fault, etc) */
1054 ENTRY_CFI(intr_save)            /* for os_hpmc */
1055         mfsp    %sr7,%r16
1056         cmpib,COND(=),n 0,%r16,1f
1057         get_stack_use_cr30
1058         b       2f
1059         copy    %r8,%r26
1062         get_stack_use_r30
1063         copy    %r8,%r26
1066         save_specials   %r29
1068         /* If this trap is a itlb miss, skip saving/adjusting isr/ior */
1070         /*
1071          * FIXME: 1) Use a #define for the hardwired "6" below (and in
1072          *           traps.c.
1073          *        2) Once we start executing code above 4 Gb, we need
1074          *           to adjust iasq/iaoq here in the same way we
1075          *           adjust isr/ior below.
1076          */
1078         cmpib,COND(=),n        6,%r26,skip_save_ior
1081         mfctl           %cr20, %r16 /* isr */
1082         nop             /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */
1083         mfctl           %cr21, %r17 /* ior */
1086 #ifdef CONFIG_64BIT
1087         /*
1088          * If the interrupted code was running with W bit off (32 bit),
1089          * clear the b bits (bits 0 & 1) in the ior.
1090          * save_specials left ipsw value in r8 for us to test.
1091          */
1092         extrd,u,*<>     %r8,PSW_W_BIT,1,%r0
1093         depdi           0,1,2,%r17
1095         /*
1096          * FIXME: This code has hardwired assumptions about the split
1097          *        between space bits and offset bits. This will change
1098          *        when we allow alternate page sizes.
1099          */
1101         /* adjust isr/ior. */
1102         extrd,u         %r16,63,SPACEID_SHIFT,%r1       /* get high bits from isr for ior */
1103         depd            %r1,31,SPACEID_SHIFT,%r17       /* deposit them into ior */
1104         depdi           0,63,SPACEID_SHIFT,%r16         /* clear them from isr */
1105 #endif
1106         STREG           %r16, PT_ISR(%r29)
1107         STREG           %r17, PT_IOR(%r29)
1110 skip_save_ior:
1111         virt_map
1112         save_general    %r29
1114         ldo             PT_FR0(%r29), %r25
1115         save_fp         %r25
1116         
1117         loadgp
1119         copy            %r29, %r25      /* arg1 is pt_regs */
1120 #ifdef CONFIG_64BIT
1121         ldo             -16(%r30),%r29  /* Reference param save area */
1122 #endif
1124         ldil            L%intr_check_sig, %r2
1125         copy            %r25, %r16      /* save pt_regs */
1127         b               handle_interruption
1128         ldo             R%intr_check_sig(%r2), %r2
1129 ENDPROC_CFI(intr_save)
1132         /*
1133          * Note for all tlb miss handlers:
1134          *
1135          * cr24 contains a pointer to the kernel address space
1136          * page directory.
1137          *
1138          * cr25 contains a pointer to the current user address
1139          * space page directory.
1140          *
1141          * sr3 will contain the space id of the user address space
1142          * of the current running thread while that thread is
1143          * running in the kernel.
1144          */
1146         /*
1147          * register number allocations.  Note that these are all
1148          * in the shadowed registers
1149          */
1151         t0 = r1         /* temporary register 0 */
1152         va = r8         /* virtual address for which the trap occurred */
1153         t1 = r9         /* temporary register 1 */
1154         pte  = r16      /* pte/phys page # */
1155         prot = r17      /* prot bits */
1156         spc  = r24      /* space for which the trap occurred */
1157         ptp = r25       /* page directory/page table pointer */
1159 #ifdef CONFIG_64BIT
1161 dtlb_miss_20w:
1162         space_adjust    spc,va,t0
1163         get_pgd         spc,ptp
1164         space_check     spc,t0,dtlb_fault
1166         L3_ptep         ptp,pte,t0,va,dtlb_check_alias_20w
1168         tlb_lock        spc,ptp,pte,t0,t1,dtlb_check_alias_20w
1169         update_accessed ptp,pte,t0,t1
1171         make_insert_tlb spc,pte,prot,t1
1172         
1173         idtlbt          pte,prot
1175         tlb_unlock1     spc,t0
1176         rfir
1177         nop
1179 dtlb_check_alias_20w:
1180         do_alias        spc,t0,t1,va,pte,prot,dtlb_fault,20
1182         idtlbt          pte,prot
1184         rfir
1185         nop
1187 nadtlb_miss_20w:
1188         space_adjust    spc,va,t0
1189         get_pgd         spc,ptp
1190         space_check     spc,t0,nadtlb_fault
1192         L3_ptep         ptp,pte,t0,va,nadtlb_check_alias_20w
1194         tlb_lock        spc,ptp,pte,t0,t1,nadtlb_check_alias_20w
1195         update_accessed ptp,pte,t0,t1
1197         make_insert_tlb spc,pte,prot,t1
1199         idtlbt          pte,prot
1201         tlb_unlock1     spc,t0
1202         rfir
1203         nop
1205 nadtlb_check_alias_20w:
1206         do_alias        spc,t0,t1,va,pte,prot,nadtlb_emulate,20
1208         idtlbt          pte,prot
1210         rfir
1211         nop
1213 #else
1215 dtlb_miss_11:
1216         get_pgd         spc,ptp
1218         space_check     spc,t0,dtlb_fault
1220         L2_ptep         ptp,pte,t0,va,dtlb_check_alias_11
1222         tlb_lock        spc,ptp,pte,t0,t1,dtlb_check_alias_11
1223         update_accessed ptp,pte,t0,t1
1225         make_insert_tlb_11      spc,pte,prot
1227         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1228         mtsp            spc,%sr1
1230         idtlba          pte,(%sr1,va)
1231         idtlbp          prot,(%sr1,va)
1233         mtsp            t1, %sr1        /* Restore sr1 */
1235         tlb_unlock1     spc,t0
1236         rfir
1237         nop
1239 dtlb_check_alias_11:
1240         do_alias        spc,t0,t1,va,pte,prot,dtlb_fault,11
1242         idtlba          pte,(va)
1243         idtlbp          prot,(va)
1245         rfir
1246         nop
1248 nadtlb_miss_11:
1249         get_pgd         spc,ptp
1251         space_check     spc,t0,nadtlb_fault
1253         L2_ptep         ptp,pte,t0,va,nadtlb_check_alias_11
1255         tlb_lock        spc,ptp,pte,t0,t1,nadtlb_check_alias_11
1256         update_accessed ptp,pte,t0,t1
1258         make_insert_tlb_11      spc,pte,prot
1260         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1261         mtsp            spc,%sr1
1263         idtlba          pte,(%sr1,va)
1264         idtlbp          prot,(%sr1,va)
1266         mtsp            t1, %sr1        /* Restore sr1 */
1268         tlb_unlock1     spc,t0
1269         rfir
1270         nop
1272 nadtlb_check_alias_11:
1273         do_alias        spc,t0,t1,va,pte,prot,nadtlb_emulate,11
1275         idtlba          pte,(va)
1276         idtlbp          prot,(va)
1278         rfir
1279         nop
1281 dtlb_miss_20:
1282         space_adjust    spc,va,t0
1283         get_pgd         spc,ptp
1284         space_check     spc,t0,dtlb_fault
1286         L2_ptep         ptp,pte,t0,va,dtlb_check_alias_20
1288         tlb_lock        spc,ptp,pte,t0,t1,dtlb_check_alias_20
1289         update_accessed ptp,pte,t0,t1
1291         make_insert_tlb spc,pte,prot,t1
1293         f_extend        pte,t1
1295         idtlbt          pte,prot
1297         tlb_unlock1     spc,t0
1298         rfir
1299         nop
1301 dtlb_check_alias_20:
1302         do_alias        spc,t0,t1,va,pte,prot,dtlb_fault,20
1303         
1304         idtlbt          pte,prot
1306         rfir
1307         nop
1309 nadtlb_miss_20:
1310         get_pgd         spc,ptp
1312         space_check     spc,t0,nadtlb_fault
1314         L2_ptep         ptp,pte,t0,va,nadtlb_check_alias_20
1316         tlb_lock        spc,ptp,pte,t0,t1,nadtlb_check_alias_20
1317         update_accessed ptp,pte,t0,t1
1319         make_insert_tlb spc,pte,prot,t1
1321         f_extend        pte,t1
1322         
1323         idtlbt          pte,prot
1325         tlb_unlock1     spc,t0
1326         rfir
1327         nop
1329 nadtlb_check_alias_20:
1330         do_alias        spc,t0,t1,va,pte,prot,nadtlb_emulate,20
1332         idtlbt          pte,prot
1334         rfir
1335         nop
1337 #endif
1339 nadtlb_emulate:
1341         /*
1342          * Non access misses can be caused by fdc,fic,pdc,lpa,probe and
1343          * probei instructions. We don't want to fault for these
1344          * instructions (not only does it not make sense, it can cause
1345          * deadlocks, since some flushes are done with the mmap
1346          * semaphore held). If the translation doesn't exist, we can't
1347          * insert a translation, so have to emulate the side effects
1348          * of the instruction. Since we don't insert a translation
1349          * we can get a lot of faults during a flush loop, so it makes
1350          * sense to try to do it here with minimum overhead. We only
1351          * emulate fdc,fic,pdc,probew,prober instructions whose base 
1352          * and index registers are not shadowed. We defer everything 
1353          * else to the "slow" path.
1354          */
1356         mfctl           %cr19,%r9 /* Get iir */
1358         /* PA 2.0 Arch Ref. Book pg 382 has a good description of the insn bits.
1359            Checks for fdc,fdce,pdc,"fic,4f",prober,probeir,probew, probeiw */
1361         /* Checks for fdc,fdce,pdc,"fic,4f" only */
1362         ldi             0x280,%r16
1363         and             %r9,%r16,%r17
1364         cmpb,<>,n       %r16,%r17,nadtlb_probe_check
1365         bb,>=,n         %r9,26,nadtlb_nullify  /* m bit not set, just nullify */
1366         BL              get_register,%r25
1367         extrw,u         %r9,15,5,%r8           /* Get index register # */
1368         cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
1369         copy            %r1,%r24
1370         BL              get_register,%r25
1371         extrw,u         %r9,10,5,%r8           /* Get base register # */
1372         cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
1373         BL              set_register,%r25
1374         add,l           %r1,%r24,%r1           /* doesn't affect c/b bits */
1376 nadtlb_nullify:
1377         mfctl           %ipsw,%r8
1378         ldil            L%PSW_N,%r9
1379         or              %r8,%r9,%r8            /* Set PSW_N */
1380         mtctl           %r8,%ipsw
1382         rfir
1383         nop
1385         /* 
1386                 When there is no translation for the probe address then we
1387                 must nullify the insn and return zero in the target register.
1388                 This will indicate to the calling code that it does not have 
1389                 write/read privileges to this address.
1391                 This should technically work for prober and probew in PA 1.1,
1392                 and also probe,r and probe,w in PA 2.0
1394                 WARNING: USE ONLY NON-SHADOW REGISTERS WITH PROBE INSN!
1395                 THE SLOW-PATH EMULATION HAS NOT BEEN WRITTEN YET.
1397         */
1398 nadtlb_probe_check:
1399         ldi             0x80,%r16
1400         and             %r9,%r16,%r17
1401         cmpb,<>,n       %r16,%r17,nadtlb_fault /* Must be probe,[rw]*/
1402         BL              get_register,%r25      /* Find the target register */
1403         extrw,u         %r9,31,5,%r8           /* Get target register */
1404         cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
1405         BL              set_register,%r25
1406         copy            %r0,%r1                /* Write zero to target register */
1407         b nadtlb_nullify                       /* Nullify return insn */
1408         nop
1411 #ifdef CONFIG_64BIT
1412 itlb_miss_20w:
1414         /*
1415          * I miss is a little different, since we allow users to fault
1416          * on the gateway page which is in the kernel address space.
1417          */
1419         space_adjust    spc,va,t0
1420         get_pgd         spc,ptp
1421         space_check     spc,t0,itlb_fault
1423         L3_ptep         ptp,pte,t0,va,itlb_fault
1425         tlb_lock        spc,ptp,pte,t0,t1,itlb_fault
1426         update_accessed ptp,pte,t0,t1
1428         make_insert_tlb spc,pte,prot,t1
1429         
1430         iitlbt          pte,prot
1432         tlb_unlock1     spc,t0
1433         rfir
1434         nop
1436 naitlb_miss_20w:
1438         /*
1439          * I miss is a little different, since we allow users to fault
1440          * on the gateway page which is in the kernel address space.
1441          */
1443         space_adjust    spc,va,t0
1444         get_pgd         spc,ptp
1445         space_check     spc,t0,naitlb_fault
1447         L3_ptep         ptp,pte,t0,va,naitlb_check_alias_20w
1449         tlb_lock        spc,ptp,pte,t0,t1,naitlb_check_alias_20w
1450         update_accessed ptp,pte,t0,t1
1452         make_insert_tlb spc,pte,prot,t1
1454         iitlbt          pte,prot
1456         tlb_unlock1     spc,t0
1457         rfir
1458         nop
1460 naitlb_check_alias_20w:
1461         do_alias        spc,t0,t1,va,pte,prot,naitlb_fault,20
1463         iitlbt          pte,prot
1465         rfir
1466         nop
1468 #else
1470 itlb_miss_11:
1471         get_pgd         spc,ptp
1473         space_check     spc,t0,itlb_fault
1475         L2_ptep         ptp,pte,t0,va,itlb_fault
1477         tlb_lock        spc,ptp,pte,t0,t1,itlb_fault
1478         update_accessed ptp,pte,t0,t1
1480         make_insert_tlb_11      spc,pte,prot
1482         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1483         mtsp            spc,%sr1
1485         iitlba          pte,(%sr1,va)
1486         iitlbp          prot,(%sr1,va)
1488         mtsp            t1, %sr1        /* Restore sr1 */
1490         tlb_unlock1     spc,t0
1491         rfir
1492         nop
1494 naitlb_miss_11:
1495         get_pgd         spc,ptp
1497         space_check     spc,t0,naitlb_fault
1499         L2_ptep         ptp,pte,t0,va,naitlb_check_alias_11
1501         tlb_lock        spc,ptp,pte,t0,t1,naitlb_check_alias_11
1502         update_accessed ptp,pte,t0,t1
1504         make_insert_tlb_11      spc,pte,prot
1506         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1507         mtsp            spc,%sr1
1509         iitlba          pte,(%sr1,va)
1510         iitlbp          prot,(%sr1,va)
1512         mtsp            t1, %sr1        /* Restore sr1 */
1514         tlb_unlock1     spc,t0
1515         rfir
1516         nop
1518 naitlb_check_alias_11:
1519         do_alias        spc,t0,t1,va,pte,prot,itlb_fault,11
1521         iitlba          pte,(%sr0, va)
1522         iitlbp          prot,(%sr0, va)
1524         rfir
1525         nop
1528 itlb_miss_20:
1529         get_pgd         spc,ptp
1531         space_check     spc,t0,itlb_fault
1533         L2_ptep         ptp,pte,t0,va,itlb_fault
1535         tlb_lock        spc,ptp,pte,t0,t1,itlb_fault
1536         update_accessed ptp,pte,t0,t1
1538         make_insert_tlb spc,pte,prot,t1
1540         f_extend        pte,t1
1542         iitlbt          pte,prot
1544         tlb_unlock1     spc,t0
1545         rfir
1546         nop
1548 naitlb_miss_20:
1549         get_pgd         spc,ptp
1551         space_check     spc,t0,naitlb_fault
1553         L2_ptep         ptp,pte,t0,va,naitlb_check_alias_20
1555         tlb_lock        spc,ptp,pte,t0,t1,naitlb_check_alias_20
1556         update_accessed ptp,pte,t0,t1
1558         make_insert_tlb spc,pte,prot,t1
1560         f_extend        pte,t1
1562         iitlbt          pte,prot
1564         tlb_unlock1     spc,t0
1565         rfir
1566         nop
1568 naitlb_check_alias_20:
1569         do_alias        spc,t0,t1,va,pte,prot,naitlb_fault,20
1571         iitlbt          pte,prot
1573         rfir
1574         nop
1576 #endif
1578 #ifdef CONFIG_64BIT
1580 dbit_trap_20w:
1581         space_adjust    spc,va,t0
1582         get_pgd         spc,ptp
1583         space_check     spc,t0,dbit_fault
1585         L3_ptep         ptp,pte,t0,va,dbit_fault
1587         tlb_lock        spc,ptp,pte,t0,t1,dbit_fault
1588         update_dirty    ptp,pte,t1
1590         make_insert_tlb spc,pte,prot,t1
1591                 
1592         idtlbt          pte,prot
1594         tlb_unlock0     spc,t0
1595         rfir
1596         nop
1597 #else
1599 dbit_trap_11:
1601         get_pgd         spc,ptp
1603         space_check     spc,t0,dbit_fault
1605         L2_ptep         ptp,pte,t0,va,dbit_fault
1607         tlb_lock        spc,ptp,pte,t0,t1,dbit_fault
1608         update_dirty    ptp,pte,t1
1610         make_insert_tlb_11      spc,pte,prot
1612         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1613         mtsp            spc,%sr1
1615         idtlba          pte,(%sr1,va)
1616         idtlbp          prot,(%sr1,va)
1618         mtsp            t1, %sr1     /* Restore sr1 */
1620         tlb_unlock0     spc,t0
1621         rfir
1622         nop
1624 dbit_trap_20:
1625         get_pgd         spc,ptp
1627         space_check     spc,t0,dbit_fault
1629         L2_ptep         ptp,pte,t0,va,dbit_fault
1631         tlb_lock        spc,ptp,pte,t0,t1,dbit_fault
1632         update_dirty    ptp,pte,t1
1634         make_insert_tlb spc,pte,prot,t1
1636         f_extend        pte,t1
1637         
1638         idtlbt          pte,prot
1640         tlb_unlock0     spc,t0
1641         rfir
1642         nop
1643 #endif
1645         .import handle_interruption,code
1647 kernel_bad_space:
1648         b               intr_save
1649         ldi             31,%r8  /* Use an unused code */
1651 dbit_fault:
1652         b               intr_save
1653         ldi             20,%r8
1655 itlb_fault:
1656         b               intr_save
1657         ldi             6,%r8
1659 nadtlb_fault:
1660         b               intr_save
1661         ldi             17,%r8
1663 naitlb_fault:
1664         b               intr_save
1665         ldi             16,%r8
1667 dtlb_fault:
1668         b               intr_save
1669         ldi             15,%r8
1671         /* Register saving semantics for system calls:
1673            %r1             clobbered by system call macro in userspace
1674            %r2             saved in PT_REGS by gateway page
1675            %r3  - %r18     preserved by C code (saved by signal code)
1676            %r19 - %r20     saved in PT_REGS by gateway page
1677            %r21 - %r22     non-standard syscall args
1678                            stored in kernel stack by gateway page
1679            %r23 - %r26     arg3-arg0, saved in PT_REGS by gateway page
1680            %r27 - %r30     saved in PT_REGS by gateway page
1681            %r31            syscall return pointer
1682          */
1684         /* Floating point registers (FIXME: what do we do with these?)
1686            %fr0  - %fr3    status/exception, not preserved
1687            %fr4  - %fr7    arguments
1688            %fr8  - %fr11   not preserved by C code
1689            %fr12 - %fr21   preserved by C code
1690            %fr22 - %fr31   not preserved by C code
1691          */
1693         .macro  reg_save regs
1694         STREG   %r3, PT_GR3(\regs)
1695         STREG   %r4, PT_GR4(\regs)
1696         STREG   %r5, PT_GR5(\regs)
1697         STREG   %r6, PT_GR6(\regs)
1698         STREG   %r7, PT_GR7(\regs)
1699         STREG   %r8, PT_GR8(\regs)
1700         STREG   %r9, PT_GR9(\regs)
1701         STREG   %r10,PT_GR10(\regs)
1702         STREG   %r11,PT_GR11(\regs)
1703         STREG   %r12,PT_GR12(\regs)
1704         STREG   %r13,PT_GR13(\regs)
1705         STREG   %r14,PT_GR14(\regs)
1706         STREG   %r15,PT_GR15(\regs)
1707         STREG   %r16,PT_GR16(\regs)
1708         STREG   %r17,PT_GR17(\regs)
1709         STREG   %r18,PT_GR18(\regs)
1710         .endm
1712         .macro  reg_restore regs
1713         LDREG   PT_GR3(\regs), %r3
1714         LDREG   PT_GR4(\regs), %r4
1715         LDREG   PT_GR5(\regs), %r5
1716         LDREG   PT_GR6(\regs), %r6
1717         LDREG   PT_GR7(\regs), %r7
1718         LDREG   PT_GR8(\regs), %r8
1719         LDREG   PT_GR9(\regs), %r9
1720         LDREG   PT_GR10(\regs),%r10
1721         LDREG   PT_GR11(\regs),%r11
1722         LDREG   PT_GR12(\regs),%r12
1723         LDREG   PT_GR13(\regs),%r13
1724         LDREG   PT_GR14(\regs),%r14
1725         LDREG   PT_GR15(\regs),%r15
1726         LDREG   PT_GR16(\regs),%r16
1727         LDREG   PT_GR17(\regs),%r17
1728         LDREG   PT_GR18(\regs),%r18
1729         .endm
1731         .macro  fork_like name
1732 ENTRY_CFI(sys_\name\()_wrapper)
1733         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
1734         ldo     TASK_REGS(%r1),%r1
1735         reg_save %r1
1736         mfctl   %cr27, %r28
1737         ldil    L%sys_\name, %r31
1738         be      R%sys_\name(%sr4,%r31)
1739         STREG   %r28, PT_CR27(%r1)
1740 ENDPROC_CFI(sys_\name\()_wrapper)
1741         .endm
1743 fork_like clone
1744 fork_like fork
1745 fork_like vfork
1747         /* Set the return value for the child */
1748 ENTRY_CFI(child_return)
1749         BL      schedule_tail, %r2
1750         nop
1751 finish_child_return:
1752         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
1753         ldo     TASK_REGS(%r1),%r1       /* get pt regs */
1755         LDREG   PT_CR27(%r1), %r3
1756         mtctl   %r3, %cr27
1757         reg_restore %r1
1758         b       syscall_exit
1759         copy    %r0,%r28
1760 ENDPROC_CFI(child_return)
1762 ENTRY_CFI(sys_rt_sigreturn_wrapper)
1763         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
1764         ldo     TASK_REGS(%r26),%r26    /* get pt regs */
1765         /* Don't save regs, we are going to restore them from sigcontext. */
1766         STREG   %r2, -RP_OFFSET(%r30)
1767 #ifdef CONFIG_64BIT
1768         ldo     FRAME_SIZE(%r30), %r30
1769         BL      sys_rt_sigreturn,%r2
1770         ldo     -16(%r30),%r29          /* Reference param save area */
1771 #else
1772         BL      sys_rt_sigreturn,%r2
1773         ldo     FRAME_SIZE(%r30), %r30
1774 #endif
1776         ldo     -FRAME_SIZE(%r30), %r30
1777         LDREG   -RP_OFFSET(%r30), %r2
1779         /* FIXME: I think we need to restore a few more things here. */
1780         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1781         ldo     TASK_REGS(%r1),%r1      /* get pt regs */
1782         reg_restore %r1
1784         /* If the signal was received while the process was blocked on a
1785          * syscall, then r2 will take us to syscall_exit; otherwise r2 will
1786          * take us to syscall_exit_rfi and on to intr_return.
1787          */
1788         bv      %r0(%r2)
1789         LDREG   PT_GR28(%r1),%r28  /* reload original r28 for syscall_exit */
1790 ENDPROC_CFI(sys_rt_sigreturn_wrapper)
1792 ENTRY_CFI(syscall_exit)
1793         /* NOTE: Not all syscalls exit this way.  rt_sigreturn will exit
1794          * via syscall_exit_rfi if the signal was received while the process
1795          * was running.
1796          */
1798         /* save return value now */
1800         mfctl     %cr30, %r1
1801         LDREG     TI_TASK(%r1),%r1
1802         STREG     %r28,TASK_PT_GR28(%r1)
1804         /* Seems to me that dp could be wrong here, if the syscall involved
1805          * calling a module, and nothing got round to restoring dp on return.
1806          */
1807         loadgp
1809 syscall_check_resched:
1811         /* check for reschedule */
1813         LDREG   TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19   /* long */
1814         bb,<,n  %r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */
1816         .import do_signal,code
1817 syscall_check_sig:
1818         LDREG   TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19
1819         ldi     (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), %r26
1820         and,COND(<>)    %r19, %r26, %r0
1821         b,n     syscall_restore /* skip past if we've nothing to do */
1823 syscall_do_signal:
1824         /* Save callee-save registers (for sigcontext).
1825          * FIXME: After this point the process structure should be
1826          * consistent with all the relevant state of the process
1827          * before the syscall.  We need to verify this.
1828          */
1829         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1830         ldo     TASK_REGS(%r1), %r26            /* struct pt_regs *regs */
1831         reg_save %r26
1833 #ifdef CONFIG_64BIT
1834         ldo     -16(%r30),%r29                  /* Reference param save area */
1835 #endif
1837         BL      do_notify_resume,%r2
1838         ldi     1, %r25                         /* long in_syscall = 1 */
1840         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1841         ldo     TASK_REGS(%r1), %r20            /* reload pt_regs */
1842         reg_restore %r20
1844         b,n     syscall_check_sig
1846 syscall_restore:
1847         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1849         /* Are we being ptraced? */
1850         ldw     TASK_FLAGS(%r1),%r19
1851         ldi     _TIF_SYSCALL_TRACE_MASK,%r2
1852         and,COND(=)     %r19,%r2,%r0
1853         b,n     syscall_restore_rfi
1855         ldo     TASK_PT_FR31(%r1),%r19             /* reload fpregs */
1856         rest_fp %r19
1858         LDREG   TASK_PT_SAR(%r1),%r19              /* restore SAR */
1859         mtsar   %r19
1861         LDREG   TASK_PT_GR2(%r1),%r2               /* restore user rp */
1862         LDREG   TASK_PT_GR19(%r1),%r19
1863         LDREG   TASK_PT_GR20(%r1),%r20
1864         LDREG   TASK_PT_GR21(%r1),%r21
1865         LDREG   TASK_PT_GR22(%r1),%r22
1866         LDREG   TASK_PT_GR23(%r1),%r23
1867         LDREG   TASK_PT_GR24(%r1),%r24
1868         LDREG   TASK_PT_GR25(%r1),%r25
1869         LDREG   TASK_PT_GR26(%r1),%r26
1870         LDREG   TASK_PT_GR27(%r1),%r27     /* restore user dp */
1871         LDREG   TASK_PT_GR28(%r1),%r28     /* syscall return value */
1872         LDREG   TASK_PT_GR29(%r1),%r29
1873         LDREG   TASK_PT_GR31(%r1),%r31     /* restore syscall rp */
1875         /* NOTE: We use rsm/ssm pair to make this operation atomic */
1876         LDREG   TASK_PT_GR30(%r1),%r1              /* Get user sp */
1877         rsm     PSW_SM_I, %r0
1878         copy    %r1,%r30                           /* Restore user sp */
1879         mfsp    %sr3,%r1                           /* Get user space id */
1880         mtsp    %r1,%sr7                           /* Restore sr7 */
1881         ssm     PSW_SM_I, %r0
1883         /* Set sr2 to zero for userspace syscalls to work. */
1884         mtsp    %r0,%sr2 
1885         mtsp    %r1,%sr4                           /* Restore sr4 */
1886         mtsp    %r1,%sr5                           /* Restore sr5 */
1887         mtsp    %r1,%sr6                           /* Restore sr6 */
1889         depi    3,31,2,%r31                        /* ensure return to user mode. */
1891 #ifdef CONFIG_64BIT
1892         /* decide whether to reset the wide mode bit
1893          *
1894          * For a syscall, the W bit is stored in the lowest bit
1895          * of sp.  Extract it and reset W if it is zero */
1896         extrd,u,*<>     %r30,63,1,%r1
1897         rsm     PSW_SM_W, %r0
1898         /* now reset the lowest bit of sp if it was set */
1899         xor     %r30,%r1,%r30
1900 #endif
1901         be,n    0(%sr3,%r31)                       /* return to user space */
1903         /* We have to return via an RFI, so that PSW T and R bits can be set
1904          * appropriately.
1905          * This sets up pt_regs so we can return via intr_restore, which is not
1906          * the most efficient way of doing things, but it works.
1907          */
1908 syscall_restore_rfi:
1909         ldo     -1(%r0),%r2                        /* Set recovery cntr to -1 */
1910         mtctl   %r2,%cr0                           /*   for immediate trap */
1911         LDREG   TASK_PT_PSW(%r1),%r2               /* Get old PSW */
1912         ldi     0x0b,%r20                          /* Create new PSW */
1913         depi    -1,13,1,%r20                       /* C, Q, D, and I bits */
1915         /* The values of SINGLESTEP_BIT and BLOCKSTEP_BIT are
1916          * set in thread_info.h and converted to PA bitmap
1917          * numbers in asm-offsets.c */
1919         /* if ((%r19.SINGLESTEP_BIT)) { %r20.27=1} */
1920         extru,= %r19,TIF_SINGLESTEP_PA_BIT,1,%r0
1921         depi    -1,27,1,%r20                       /* R bit */
1923         /* if ((%r19.BLOCKSTEP_BIT)) { %r20.7=1} */
1924         extru,= %r19,TIF_BLOCKSTEP_PA_BIT,1,%r0
1925         depi    -1,7,1,%r20                        /* T bit */
1927         STREG   %r20,TASK_PT_PSW(%r1)
1929         /* Always store space registers, since sr3 can be changed (e.g. fork) */
1931         mfsp    %sr3,%r25
1932         STREG   %r25,TASK_PT_SR3(%r1)
1933         STREG   %r25,TASK_PT_SR4(%r1)
1934         STREG   %r25,TASK_PT_SR5(%r1)
1935         STREG   %r25,TASK_PT_SR6(%r1)
1936         STREG   %r25,TASK_PT_SR7(%r1)
1937         STREG   %r25,TASK_PT_IASQ0(%r1)
1938         STREG   %r25,TASK_PT_IASQ1(%r1)
1940         /* XXX W bit??? */
1941         /* Now if old D bit is clear, it means we didn't save all registers
1942          * on syscall entry, so do that now.  This only happens on TRACEME
1943          * calls, or if someone attached to us while we were on a syscall.
1944          * We could make this more efficient by not saving r3-r18, but
1945          * then we wouldn't be able to use the common intr_restore path.
1946          * It is only for traced processes anyway, so performance is not
1947          * an issue.
1948          */
1949         bb,<    %r2,30,pt_regs_ok                  /* Branch if D set */
1950         ldo     TASK_REGS(%r1),%r25
1951         reg_save %r25                              /* Save r3 to r18 */
1953         /* Save the current sr */
1954         mfsp    %sr0,%r2
1955         STREG   %r2,TASK_PT_SR0(%r1)
1957         /* Save the scratch sr */
1958         mfsp    %sr1,%r2
1959         STREG   %r2,TASK_PT_SR1(%r1)
1961         /* sr2 should be set to zero for userspace syscalls */
1962         STREG   %r0,TASK_PT_SR2(%r1)
1964         LDREG   TASK_PT_GR31(%r1),%r2
1965         depi    3,31,2,%r2                 /* ensure return to user mode. */
1966         STREG   %r2,TASK_PT_IAOQ0(%r1)
1967         ldo     4(%r2),%r2
1968         STREG   %r2,TASK_PT_IAOQ1(%r1)
1969         b       intr_restore
1970         copy    %r25,%r16
1972 pt_regs_ok:
1973         LDREG   TASK_PT_IAOQ0(%r1),%r2
1974         depi    3,31,2,%r2                 /* ensure return to user mode. */
1975         STREG   %r2,TASK_PT_IAOQ0(%r1)
1976         LDREG   TASK_PT_IAOQ1(%r1),%r2
1977         depi    3,31,2,%r2
1978         STREG   %r2,TASK_PT_IAOQ1(%r1)
1979         b       intr_restore
1980         copy    %r25,%r16
1982 syscall_do_resched:
1983         load32  syscall_check_resched,%r2 /* if resched, we start over again */
1984         load32  schedule,%r19
1985         bv      %r0(%r19)               /* jumps to schedule() */
1986 #ifdef CONFIG_64BIT
1987         ldo     -16(%r30),%r29          /* Reference param save area */
1988 #else
1989         nop
1990 #endif
1991 ENDPROC_CFI(syscall_exit)
1994 #ifdef CONFIG_FUNCTION_TRACER
1996         .import ftrace_function_trampoline,code
1997         .align L1_CACHE_BYTES
1998         .globl mcount
1999         .type  mcount, @function
2000 ENTRY(mcount)
2001 _mcount:
2002         .export _mcount,data
2003         .proc
2004         .callinfo caller,frame=0
2005         .entry
2006         /*
2007          * The 64bit mcount() function pointer needs 4 dwords, of which the
2008          * first two are free.  We optimize it here and put 2 instructions for
2009          * calling mcount(), and 2 instructions for ftrace_stub().  That way we
2010          * have all on one L1 cacheline.
2011          */
2012         b       ftrace_function_trampoline
2013         copy    %r3, %arg2      /* caller original %sp */
2014 ftrace_stub:
2015         .globl ftrace_stub
2016         .type  ftrace_stub, @function
2017 #ifdef CONFIG_64BIT
2018         bve     (%rp)
2019 #else
2020         bv      %r0(%rp)
2021 #endif
2022         nop
2023 #ifdef CONFIG_64BIT
2024         .dword mcount
2025         .dword 0 /* code in head.S puts value of global gp here */
2026 #endif
2027         .exit
2028         .procend
2029 ENDPROC(mcount)
2031 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
2032         .align 8
2033         .globl return_to_handler
2034         .type  return_to_handler, @function
2035 ENTRY_CFI(return_to_handler)
2036         .proc
2037         .callinfo caller,frame=FRAME_SIZE
2038         .entry
2039         .export parisc_return_to_handler,data
2040 parisc_return_to_handler:
2041         copy %r3,%r1
2042         STREG %r0,-RP_OFFSET(%sp)       /* store 0 as %rp */
2043         copy %sp,%r3
2044         STREGM %r1,FRAME_SIZE(%sp)
2045         STREG %ret0,8(%r3)
2046         STREG %ret1,16(%r3)
2048 #ifdef CONFIG_64BIT
2049         loadgp
2050 #endif
2052         /* call ftrace_return_to_handler(0) */
2053         .import ftrace_return_to_handler,code
2054         load32 ftrace_return_to_handler,%ret0
2055         load32 .Lftrace_ret,%r2
2056 #ifdef CONFIG_64BIT
2057         ldo -16(%sp),%ret1              /* Reference param save area */
2058         bve     (%ret0)
2059 #else
2060         bv      %r0(%ret0)
2061 #endif
2062         ldi 0,%r26
2063 .Lftrace_ret:
2064         copy %ret0,%rp
2066         /* restore original return values */
2067         LDREG 8(%r3),%ret0
2068         LDREG 16(%r3),%ret1
2070         /* return from function */
2071 #ifdef CONFIG_64BIT
2072         bve     (%rp)
2073 #else
2074         bv      %r0(%rp)
2075 #endif
2076         LDREGM -FRAME_SIZE(%sp),%r3
2077         .exit
2078         .procend
2079 ENDPROC_CFI(return_to_handler)
2081 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
2083 #endif  /* CONFIG_FUNCTION_TRACER */
2085 #ifdef CONFIG_IRQSTACKS
2086 /* void call_on_stack(unsigned long param1, void *func,
2087                       unsigned long new_stack) */
2088 ENTRY_CFI(call_on_stack)
2089         copy    %sp, %r1
2091         /* Regarding the HPPA calling conventions for function pointers,
2092            we assume the PIC register is not changed across call.  For
2093            CONFIG_64BIT, the argument pointer is left to point at the
2094            argument region allocated for the call to call_on_stack. */
2095 # ifdef CONFIG_64BIT
2096         /* Switch to new stack.  We allocate two 128 byte frames.  */
2097         ldo     256(%arg2), %sp
2098         /* Save previous stack pointer and return pointer in frame marker */
2099         STREG   %rp, -144(%sp)
2100         /* Calls always use function descriptor */
2101         LDREG   16(%arg1), %arg1
2102         bve,l   (%arg1), %rp
2103         STREG   %r1, -136(%sp)
2104         LDREG   -144(%sp), %rp
2105         bve     (%rp)
2106         LDREG   -136(%sp), %sp
2107 # else
2108         /* Switch to new stack.  We allocate two 64 byte frames.  */
2109         ldo     128(%arg2), %sp
2110         /* Save previous stack pointer and return pointer in frame marker */
2111         STREG   %r1, -68(%sp)
2112         STREG   %rp, -84(%sp)
2113         /* Calls use function descriptor if PLABEL bit is set */
2114         bb,>=,n %arg1, 30, 1f
2115         depwi   0,31,2, %arg1
2116         LDREG   0(%arg1), %arg1
2118         be,l    0(%sr4,%arg1), %sr0, %r31
2119         copy    %r31, %rp
2120         LDREG   -84(%sp), %rp
2121         bv      (%rp)
2122         LDREG   -68(%sp), %sp
2123 # endif /* CONFIG_64BIT */
2124 ENDPROC_CFI(call_on_stack)
2125 #endif /* CONFIG_IRQSTACKS */
2127 ENTRY_CFI(get_register)
2128         /*
2129          * get_register is used by the non access tlb miss handlers to
2130          * copy the value of the general register specified in r8 into
2131          * r1. This routine can't be used for shadowed registers, since
2132          * the rfir will restore the original value. So, for the shadowed
2133          * registers we put a -1 into r1 to indicate that the register
2134          * should not be used (the register being copied could also have
2135          * a -1 in it, but that is OK, it just means that we will have
2136          * to use the slow path instead).
2137          */
2138         blr     %r8,%r0
2139         nop
2140         bv      %r0(%r25)    /* r0 */
2141         copy    %r0,%r1
2142         bv      %r0(%r25)    /* r1 - shadowed */
2143         ldi     -1,%r1
2144         bv      %r0(%r25)    /* r2 */
2145         copy    %r2,%r1
2146         bv      %r0(%r25)    /* r3 */
2147         copy    %r3,%r1
2148         bv      %r0(%r25)    /* r4 */
2149         copy    %r4,%r1
2150         bv      %r0(%r25)    /* r5 */
2151         copy    %r5,%r1
2152         bv      %r0(%r25)    /* r6 */
2153         copy    %r6,%r1
2154         bv      %r0(%r25)    /* r7 */
2155         copy    %r7,%r1
2156         bv      %r0(%r25)    /* r8 - shadowed */
2157         ldi     -1,%r1
2158         bv      %r0(%r25)    /* r9 - shadowed */
2159         ldi     -1,%r1
2160         bv      %r0(%r25)    /* r10 */
2161         copy    %r10,%r1
2162         bv      %r0(%r25)    /* r11 */
2163         copy    %r11,%r1
2164         bv      %r0(%r25)    /* r12 */
2165         copy    %r12,%r1
2166         bv      %r0(%r25)    /* r13 */
2167         copy    %r13,%r1
2168         bv      %r0(%r25)    /* r14 */
2169         copy    %r14,%r1
2170         bv      %r0(%r25)    /* r15 */
2171         copy    %r15,%r1
2172         bv      %r0(%r25)    /* r16 - shadowed */
2173         ldi     -1,%r1
2174         bv      %r0(%r25)    /* r17 - shadowed */
2175         ldi     -1,%r1
2176         bv      %r0(%r25)    /* r18 */
2177         copy    %r18,%r1
2178         bv      %r0(%r25)    /* r19 */
2179         copy    %r19,%r1
2180         bv      %r0(%r25)    /* r20 */
2181         copy    %r20,%r1
2182         bv      %r0(%r25)    /* r21 */
2183         copy    %r21,%r1
2184         bv      %r0(%r25)    /* r22 */
2185         copy    %r22,%r1
2186         bv      %r0(%r25)    /* r23 */
2187         copy    %r23,%r1
2188         bv      %r0(%r25)    /* r24 - shadowed */
2189         ldi     -1,%r1
2190         bv      %r0(%r25)    /* r25 - shadowed */
2191         ldi     -1,%r1
2192         bv      %r0(%r25)    /* r26 */
2193         copy    %r26,%r1
2194         bv      %r0(%r25)    /* r27 */
2195         copy    %r27,%r1
2196         bv      %r0(%r25)    /* r28 */
2197         copy    %r28,%r1
2198         bv      %r0(%r25)    /* r29 */
2199         copy    %r29,%r1
2200         bv      %r0(%r25)    /* r30 */
2201         copy    %r30,%r1
2202         bv      %r0(%r25)    /* r31 */
2203         copy    %r31,%r1
2204 ENDPROC_CFI(get_register)
2207 ENTRY_CFI(set_register)
2208         /*
2209          * set_register is used by the non access tlb miss handlers to
2210          * copy the value of r1 into the general register specified in
2211          * r8.
2212          */
2213         blr     %r8,%r0
2214         nop
2215         bv      %r0(%r25)    /* r0 (silly, but it is a place holder) */
2216         copy    %r1,%r0
2217         bv      %r0(%r25)    /* r1 */
2218         copy    %r1,%r1
2219         bv      %r0(%r25)    /* r2 */
2220         copy    %r1,%r2
2221         bv      %r0(%r25)    /* r3 */
2222         copy    %r1,%r3
2223         bv      %r0(%r25)    /* r4 */
2224         copy    %r1,%r4
2225         bv      %r0(%r25)    /* r5 */
2226         copy    %r1,%r5
2227         bv      %r0(%r25)    /* r6 */
2228         copy    %r1,%r6
2229         bv      %r0(%r25)    /* r7 */
2230         copy    %r1,%r7
2231         bv      %r0(%r25)    /* r8 */
2232         copy    %r1,%r8
2233         bv      %r0(%r25)    /* r9 */
2234         copy    %r1,%r9
2235         bv      %r0(%r25)    /* r10 */
2236         copy    %r1,%r10
2237         bv      %r0(%r25)    /* r11 */
2238         copy    %r1,%r11
2239         bv      %r0(%r25)    /* r12 */
2240         copy    %r1,%r12
2241         bv      %r0(%r25)    /* r13 */
2242         copy    %r1,%r13
2243         bv      %r0(%r25)    /* r14 */
2244         copy    %r1,%r14
2245         bv      %r0(%r25)    /* r15 */
2246         copy    %r1,%r15
2247         bv      %r0(%r25)    /* r16 */
2248         copy    %r1,%r16
2249         bv      %r0(%r25)    /* r17 */
2250         copy    %r1,%r17
2251         bv      %r0(%r25)    /* r18 */
2252         copy    %r1,%r18
2253         bv      %r0(%r25)    /* r19 */
2254         copy    %r1,%r19
2255         bv      %r0(%r25)    /* r20 */
2256         copy    %r1,%r20
2257         bv      %r0(%r25)    /* r21 */
2258         copy    %r1,%r21
2259         bv      %r0(%r25)    /* r22 */
2260         copy    %r1,%r22
2261         bv      %r0(%r25)    /* r23 */
2262         copy    %r1,%r23
2263         bv      %r0(%r25)    /* r24 */
2264         copy    %r1,%r24
2265         bv      %r0(%r25)    /* r25 */
2266         copy    %r1,%r25
2267         bv      %r0(%r25)    /* r26 */
2268         copy    %r1,%r26
2269         bv      %r0(%r25)    /* r27 */
2270         copy    %r1,%r27
2271         bv      %r0(%r25)    /* r28 */
2272         copy    %r1,%r28
2273         bv      %r0(%r25)    /* r29 */
2274         copy    %r1,%r29
2275         bv      %r0(%r25)    /* r30 */
2276         copy    %r1,%r30
2277         bv      %r0(%r25)    /* r31 */
2278         copy    %r1,%r31
2279 ENDPROC_CFI(set_register)