Linux 4.18.10
[linux/fpc-iii.git] / arch / parisc / kernel / entry.S
blob1b4732e201374adc2721ab7141e5ed9b5bf9bd69
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         sync
486         or,COND(=)      %r0,\spc,%r0
487         stw             \spc,0(\tmp)
488 #endif
489         .endm
491         /* Release pa_tlb_lock lock. */
492         .macro          tlb_unlock1     spc,tmp
493 #ifdef CONFIG_SMP
494         load_pa_tlb_lock \tmp
495         tlb_unlock0     \spc,\tmp
496 #endif
497         .endm
499         /* Set the _PAGE_ACCESSED bit of the PTE.  Be clever and
500          * don't needlessly dirty the cache line if it was already set */
501         .macro          update_accessed ptp,pte,tmp,tmp1
502         ldi             _PAGE_ACCESSED,\tmp1
503         or              \tmp1,\pte,\tmp
504         and,COND(<>)    \tmp1,\pte,%r0
505         STREG           \tmp,0(\ptp)
506         .endm
508         /* Set the dirty bit (and accessed bit).  No need to be
509          * clever, this is only used from the dirty fault */
510         .macro          update_dirty    ptp,pte,tmp
511         ldi             _PAGE_ACCESSED|_PAGE_DIRTY,\tmp
512         or              \tmp,\pte,\pte
513         STREG           \pte,0(\ptp)
514         .endm
516         /* We have (depending on the page size):
517          * - 38 to 52-bit Physical Page Number
518          * - 12 to 26-bit page offset
519          */
520         /* bitshift difference between a PFN (based on kernel's PAGE_SIZE)
521          * to a CPU TLB 4k PFN (4k => 12 bits to shift) */
522         #define PAGE_ADD_SHIFT          (PAGE_SHIFT-12)
523         #define PAGE_ADD_HUGE_SHIFT     (REAL_HPAGE_SHIFT-12)
525         /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
526         .macro          convert_for_tlb_insert20 pte,tmp
527 #ifdef CONFIG_HUGETLB_PAGE
528         copy            \pte,\tmp
529         extrd,u         \tmp,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
530                                 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
532         depdi           _PAGE_SIZE_ENCODING_DEFAULT,63,\
533                                 (63-58)+PAGE_ADD_SHIFT,\pte
534         extrd,u,*=      \tmp,_PAGE_HPAGE_BIT+32,1,%r0
535         depdi           _HUGE_PAGE_SIZE_ENCODING_DEFAULT,63,\
536                                 (63-58)+PAGE_ADD_HUGE_SHIFT,\pte
537 #else /* Huge pages disabled */
538         extrd,u         \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
539                                 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
540         depdi           _PAGE_SIZE_ENCODING_DEFAULT,63,\
541                                 (63-58)+PAGE_ADD_SHIFT,\pte
542 #endif
543         .endm
545         /* Convert the pte and prot to tlb insertion values.  How
546          * this happens is quite subtle, read below */
547         .macro          make_insert_tlb spc,pte,prot,tmp
548         space_to_prot   \spc \prot        /* create prot id from space */
549         /* The following is the real subtlety.  This is depositing
550          * T <-> _PAGE_REFTRAP
551          * D <-> _PAGE_DIRTY
552          * B <-> _PAGE_DMB (memory break)
553          *
554          * Then incredible subtlety: The access rights are
555          * _PAGE_GATEWAY, _PAGE_EXEC and _PAGE_WRITE
556          * See 3-14 of the parisc 2.0 manual
557          *
558          * Finally, _PAGE_READ goes in the top bit of PL1 (so we
559          * trigger an access rights trap in user space if the user
560          * tries to read an unreadable page */
561         depd            \pte,8,7,\prot
563         /* PAGE_USER indicates the page can be read with user privileges,
564          * so deposit X1|11 to PL1|PL2 (remember the upper bit of PL1
565          * contains _PAGE_READ) */
566         extrd,u,*=      \pte,_PAGE_USER_BIT+32,1,%r0
567         depdi           7,11,3,\prot
568         /* If we're a gateway page, drop PL2 back to zero for promotion
569          * to kernel privilege (so we can execute the page as kernel).
570          * Any privilege promotion page always denys read and write */
571         extrd,u,*=      \pte,_PAGE_GATEWAY_BIT+32,1,%r0
572         depd            %r0,11,2,\prot  /* If Gateway, Set PL2 to 0 */
574         /* Enforce uncacheable pages.
575          * This should ONLY be use for MMIO on PA 2.0 machines.
576          * Memory/DMA is cache coherent on all PA2.0 machines we support
577          * (that means T-class is NOT supported) and the memory controllers
578          * on most of those machines only handles cache transactions.
579          */
580         extrd,u,*=      \pte,_PAGE_NO_CACHE_BIT+32,1,%r0
581         depdi           1,12,1,\prot
583         /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
584         convert_for_tlb_insert20 \pte \tmp
585         .endm
587         /* Identical macro to make_insert_tlb above, except it
588          * makes the tlb entry for the differently formatted pa11
589          * insertion instructions */
590         .macro          make_insert_tlb_11      spc,pte,prot
591         zdep            \spc,30,15,\prot
592         dep             \pte,8,7,\prot
593         extru,=         \pte,_PAGE_NO_CACHE_BIT,1,%r0
594         depi            1,12,1,\prot
595         extru,=         \pte,_PAGE_USER_BIT,1,%r0
596         depi            7,11,3,\prot   /* Set for user space (1 rsvd for read) */
597         extru,=         \pte,_PAGE_GATEWAY_BIT,1,%r0
598         depi            0,11,2,\prot    /* If Gateway, Set PL2 to 0 */
600         /* Get rid of prot bits and convert to page addr for iitlba */
602         depi            0,31,ASM_PFN_PTE_SHIFT,\pte
603         SHRREG          \pte,(ASM_PFN_PTE_SHIFT-(31-26)),\pte
604         .endm
606         /* This is for ILP32 PA2.0 only.  The TLB insertion needs
607          * to extend into I/O space if the address is 0xfXXXXXXX
608          * so we extend the f's into the top word of the pte in
609          * this case */
610         .macro          f_extend        pte,tmp
611         extrd,s         \pte,42,4,\tmp
612         addi,<>         1,\tmp,%r0
613         extrd,s         \pte,63,25,\pte
614         .endm
616         /* The alias region is an 8MB aligned 16MB to do clear and
617          * copy user pages at addresses congruent with the user
618          * virtual address.
619          *
620          * To use the alias page, you set %r26 up with the to TLB
621          * entry (identifying the physical page) and %r23 up with
622          * the from tlb entry (or nothing if only a to entry---for
623          * clear_user_page_asm) */
624         .macro          do_alias        spc,tmp,tmp1,va,pte,prot,fault,patype
625         cmpib,COND(<>),n 0,\spc,\fault
626         ldil            L%(TMPALIAS_MAP_START),\tmp
627 #if defined(CONFIG_64BIT) && (TMPALIAS_MAP_START >= 0x80000000)
628         /* on LP64, ldi will sign extend into the upper 32 bits,
629          * which is behaviour we don't want */
630         depdi           0,31,32,\tmp
631 #endif
632         copy            \va,\tmp1
633         depi            0,31,23,\tmp1
634         cmpb,COND(<>),n \tmp,\tmp1,\fault
635         mfctl           %cr19,\tmp      /* iir */
636         /* get the opcode (first six bits) into \tmp */
637         extrw,u         \tmp,5,6,\tmp
638         /*
639          * Only setting the T bit prevents data cache movein
640          * Setting access rights to zero prevents instruction cache movein
641          *
642          * Note subtlety here: _PAGE_GATEWAY, _PAGE_EXEC and _PAGE_WRITE go
643          * to type field and _PAGE_READ goes to top bit of PL1
644          */
645         ldi             (_PAGE_REFTRAP|_PAGE_READ|_PAGE_WRITE),\prot
646         /*
647          * so if the opcode is one (i.e. this is a memory management
648          * instruction) nullify the next load so \prot is only T.
649          * Otherwise this is a normal data operation
650          */
651         cmpiclr,=       0x01,\tmp,%r0
652         ldi             (_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot
653 .ifc \patype,20
654         depd,z          \prot,8,7,\prot
655 .else
656 .ifc \patype,11
657         depw,z          \prot,8,7,\prot
658 .else
659         .error "undefined PA type to do_alias"
660 .endif
661 .endif
662         /*
663          * OK, it is in the temp alias region, check whether "from" or "to".
664          * Check "subtle" note in pacache.S re: r23/r26.
665          */
666 #ifdef CONFIG_64BIT
667         extrd,u,*=      \va,41,1,%r0
668 #else
669         extrw,u,=       \va,9,1,%r0
670 #endif
671         or,COND(tr)     %r23,%r0,\pte
672         or              %r26,%r0,\pte
673         .endm 
676         /*
677          * Fault_vectors are architecturally required to be aligned on a 2K
678          * boundary
679          */
681         .section .text.hot
682         .align 2048
684 ENTRY(fault_vector_20)
685         /* First vector is invalid (0) */
686         .ascii  "cows can fly"
687         .byte 0
688         .align 32
690         hpmc             1
691         def              2
692         def              3
693         extint           4
694         def              5
695         itlb_20          6
696         def              7
697         def              8
698         def              9
699         def             10
700         def             11
701         def             12
702         def             13
703         def             14
704         dtlb_20         15
705         naitlb_20       16
706         nadtlb_20       17
707         def             18
708         def             19
709         dbit_20         20
710         def             21
711         def             22
712         def             23
713         def             24
714         def             25
715         def             26
716         def             27
717         def             28
718         def             29
719         def             30
720         def             31
721 END(fault_vector_20)
723 #ifndef CONFIG_64BIT
725         .align 2048
727 ENTRY(fault_vector_11)
728         /* First vector is invalid (0) */
729         .ascii  "cows can fly"
730         .byte 0
731         .align 32
733         hpmc             1
734         def              2
735         def              3
736         extint           4
737         def              5
738         itlb_11          6
739         def              7
740         def              8
741         def              9
742         def             10
743         def             11
744         def             12
745         def             13
746         def             14
747         dtlb_11         15
748         naitlb_11       16
749         nadtlb_11       17
750         def             18
751         def             19
752         dbit_11         20
753         def             21
754         def             22
755         def             23
756         def             24
757         def             25
758         def             26
759         def             27
760         def             28
761         def             29
762         def             30
763         def             31
764 END(fault_vector_11)
766 #endif
767         /* Fault vector is separately protected and *must* be on its own page */
768         .align          PAGE_SIZE
769 ENTRY(end_fault_vector)
771         .import         handle_interruption,code
772         .import         do_cpu_irq_mask,code
774         /*
775          * Child Returns here
776          *
777          * copy_thread moved args into task save area.
778          */
780 ENTRY_CFI(ret_from_kernel_thread)
782         /* Call schedule_tail first though */
783         BL      schedule_tail, %r2
784         nop
786         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
787         LDREG   TASK_PT_GR25(%r1), %r26
788 #ifdef CONFIG_64BIT
789         LDREG   TASK_PT_GR27(%r1), %r27
790 #endif
791         LDREG   TASK_PT_GR26(%r1), %r1
792         ble     0(%sr7, %r1)
793         copy    %r31, %r2
794         b       finish_child_return
795         nop
796 ENDPROC_CFI(ret_from_kernel_thread)
799         /*
800          * struct task_struct *_switch_to(struct task_struct *prev,
801          *      struct task_struct *next)
802          *
803          * switch kernel stacks and return prev */
804 ENTRY_CFI(_switch_to)
805         STREG    %r2, -RP_OFFSET(%r30)
807         callee_save_float
808         callee_save
810         load32  _switch_to_ret, %r2
812         STREG   %r2, TASK_PT_KPC(%r26)
813         LDREG   TASK_PT_KPC(%r25), %r2
815         STREG   %r30, TASK_PT_KSP(%r26)
816         LDREG   TASK_PT_KSP(%r25), %r30
817         LDREG   TASK_THREAD_INFO(%r25), %r25
818         bv      %r0(%r2)
819         mtctl   %r25,%cr30
821 _switch_to_ret:
822         mtctl   %r0, %cr0               /* Needed for single stepping */
823         callee_rest
824         callee_rest_float
826         LDREG   -RP_OFFSET(%r30), %r2
827         bv      %r0(%r2)
828         copy    %r26, %r28
829 ENDPROC_CFI(_switch_to)
831         /*
832          * Common rfi return path for interruptions, kernel execve, and
833          * sys_rt_sigreturn (sometimes).  The sys_rt_sigreturn syscall will
834          * return via this path if the signal was received when the process
835          * was running; if the process was blocked on a syscall then the
836          * normal syscall_exit path is used.  All syscalls for traced
837          * proceses exit via intr_restore.
838          *
839          * XXX If any syscalls that change a processes space id ever exit
840          * this way, then we will need to copy %sr3 in to PT_SR[3..7], and
841          * adjust IASQ[0..1].
842          *
843          */
845         .align  PAGE_SIZE
847 ENTRY_CFI(syscall_exit_rfi)
848         mfctl   %cr30,%r16
849         LDREG   TI_TASK(%r16), %r16     /* thread_info -> task_struct */
850         ldo     TASK_REGS(%r16),%r16
851         /* Force iaoq to userspace, as the user has had access to our current
852          * context via sigcontext. Also Filter the PSW for the same reason.
853          */
854         LDREG   PT_IAOQ0(%r16),%r19
855         depi    3,31,2,%r19
856         STREG   %r19,PT_IAOQ0(%r16)
857         LDREG   PT_IAOQ1(%r16),%r19
858         depi    3,31,2,%r19
859         STREG   %r19,PT_IAOQ1(%r16)
860         LDREG   PT_PSW(%r16),%r19
861         load32  USER_PSW_MASK,%r1
862 #ifdef CONFIG_64BIT
863         load32  USER_PSW_HI_MASK,%r20
864         depd    %r20,31,32,%r1
865 #endif
866         and     %r19,%r1,%r19 /* Mask out bits that user shouldn't play with */
867         load32  USER_PSW,%r1
868         or      %r19,%r1,%r19 /* Make sure default USER_PSW bits are set */
869         STREG   %r19,PT_PSW(%r16)
871         /*
872          * If we aren't being traced, we never saved space registers
873          * (we don't store them in the sigcontext), so set them
874          * to "proper" values now (otherwise we'll wind up restoring
875          * whatever was last stored in the task structure, which might
876          * be inconsistent if an interrupt occurred while on the gateway
877          * page). Note that we may be "trashing" values the user put in
878          * them, but we don't support the user changing them.
879          */
881         STREG   %r0,PT_SR2(%r16)
882         mfsp    %sr3,%r19
883         STREG   %r19,PT_SR0(%r16)
884         STREG   %r19,PT_SR1(%r16)
885         STREG   %r19,PT_SR3(%r16)
886         STREG   %r19,PT_SR4(%r16)
887         STREG   %r19,PT_SR5(%r16)
888         STREG   %r19,PT_SR6(%r16)
889         STREG   %r19,PT_SR7(%r16)
891 intr_return:
892         /* check for reschedule */
893         mfctl   %cr30,%r1
894         LDREG   TI_FLAGS(%r1),%r19      /* sched.h: TIF_NEED_RESCHED */
895         bb,<,n  %r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */
897         .import do_notify_resume,code
898 intr_check_sig:
899         /* As above */
900         mfctl   %cr30,%r1
901         LDREG   TI_FLAGS(%r1),%r19
902         ldi     (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), %r20
903         and,COND(<>)    %r19, %r20, %r0
904         b,n     intr_restore    /* skip past if we've nothing to do */
906         /* This check is critical to having LWS
907          * working. The IASQ is zero on the gateway
908          * page and we cannot deliver any signals until
909          * we get off the gateway page.
910          *
911          * Only do signals if we are returning to user space
912          */
913         LDREG   PT_IASQ0(%r16), %r20
914         cmpib,COND(=),n 0,%r20,intr_restore /* backward */
915         LDREG   PT_IASQ1(%r16), %r20
916         cmpib,COND(=),n 0,%r20,intr_restore /* backward */
918         /* NOTE: We need to enable interrupts if we have to deliver
919          * signals. We used to do this earlier but it caused kernel
920          * stack overflows. */
921         ssm     PSW_SM_I, %r0
923         copy    %r0, %r25                       /* long in_syscall = 0 */
924 #ifdef CONFIG_64BIT
925         ldo     -16(%r30),%r29                  /* Reference param save area */
926 #endif
928         BL      do_notify_resume,%r2
929         copy    %r16, %r26                      /* struct pt_regs *regs */
931         b,n     intr_check_sig
933 intr_restore:
934         copy            %r16,%r29
935         ldo             PT_FR31(%r29),%r1
936         rest_fp         %r1
937         rest_general    %r29
939         /* inverse of virt_map */
940         pcxt_ssm_bug
941         rsm             PSW_SM_QUIET,%r0        /* prepare for rfi */
942         tophys_r1       %r29
944         /* Restore space id's and special cr's from PT_REGS
945          * structure pointed to by r29
946          */
947         rest_specials   %r29
949         /* IMPORTANT: rest_stack restores r29 last (we are using it)!
950          * It also restores r1 and r30.
951          */
952         rest_stack
954         rfi
955         nop
957 #ifndef CONFIG_PREEMPT
958 # define intr_do_preempt        intr_restore
959 #endif /* !CONFIG_PREEMPT */
961         .import schedule,code
962 intr_do_resched:
963         /* Only call schedule on return to userspace. If we're returning
964          * to kernel space, we may schedule if CONFIG_PREEMPT, otherwise
965          * we jump back to intr_restore.
966          */
967         LDREG   PT_IASQ0(%r16), %r20
968         cmpib,COND(=)   0, %r20, intr_do_preempt
969         nop
970         LDREG   PT_IASQ1(%r16), %r20
971         cmpib,COND(=)   0, %r20, intr_do_preempt
972         nop
974         /* NOTE: We need to enable interrupts if we schedule.  We used
975          * to do this earlier but it caused kernel stack overflows. */
976         ssm     PSW_SM_I, %r0
978 #ifdef CONFIG_64BIT
979         ldo     -16(%r30),%r29          /* Reference param save area */
980 #endif
982         ldil    L%intr_check_sig, %r2
983 #ifndef CONFIG_64BIT
984         b       schedule
985 #else
986         load32  schedule, %r20
987         bv      %r0(%r20)
988 #endif
989         ldo     R%intr_check_sig(%r2), %r2
991         /* preempt the current task on returning to kernel
992          * mode from an interrupt, iff need_resched is set,
993          * and preempt_count is 0. otherwise, we continue on
994          * our merry way back to the current running task.
995          */
996 #ifdef CONFIG_PREEMPT
997         .import preempt_schedule_irq,code
998 intr_do_preempt:
999         rsm     PSW_SM_I, %r0           /* disable interrupts */
1001         /* current_thread_info()->preempt_count */
1002         mfctl   %cr30, %r1
1003         LDREG   TI_PRE_COUNT(%r1), %r19
1004         cmpib,COND(<>)  0, %r19, intr_restore   /* if preempt_count > 0 */
1005         nop                             /* prev insn branched backwards */
1007         /* check if we interrupted a critical path */
1008         LDREG   PT_PSW(%r16), %r20
1009         bb,<,n  %r20, 31 - PSW_SM_I, intr_restore
1010         nop
1012         BL      preempt_schedule_irq, %r2
1013         nop
1015         b,n     intr_restore            /* ssm PSW_SM_I done by intr_restore */
1016 #endif /* CONFIG_PREEMPT */
1018         /*
1019          * External interrupts.
1020          */
1022 intr_extint:
1023         cmpib,COND(=),n 0,%r16,1f
1025         get_stack_use_cr30
1026         b,n 2f
1029         get_stack_use_r30
1031         save_specials   %r29
1032         virt_map
1033         save_general    %r29
1035         ldo     PT_FR0(%r29), %r24
1036         save_fp %r24
1037         
1038         loadgp
1040         copy    %r29, %r26      /* arg0 is pt_regs */
1041         copy    %r29, %r16      /* save pt_regs */
1043         ldil    L%intr_return, %r2
1045 #ifdef CONFIG_64BIT
1046         ldo     -16(%r30),%r29  /* Reference param save area */
1047 #endif
1049         b       do_cpu_irq_mask
1050         ldo     R%intr_return(%r2), %r2 /* return to intr_return, not here */
1051 ENDPROC_CFI(syscall_exit_rfi)
1054         /* Generic interruptions (illegal insn, unaligned, page fault, etc) */
1056 ENTRY_CFI(intr_save)            /* for os_hpmc */
1057         mfsp    %sr7,%r16
1058         cmpib,COND(=),n 0,%r16,1f
1059         get_stack_use_cr30
1060         b       2f
1061         copy    %r8,%r26
1064         get_stack_use_r30
1065         copy    %r8,%r26
1068         save_specials   %r29
1070         /* If this trap is a itlb miss, skip saving/adjusting isr/ior */
1072         /*
1073          * FIXME: 1) Use a #define for the hardwired "6" below (and in
1074          *           traps.c.
1075          *        2) Once we start executing code above 4 Gb, we need
1076          *           to adjust iasq/iaoq here in the same way we
1077          *           adjust isr/ior below.
1078          */
1080         cmpib,COND(=),n        6,%r26,skip_save_ior
1083         mfctl           %cr20, %r16 /* isr */
1084         nop             /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */
1085         mfctl           %cr21, %r17 /* ior */
1088 #ifdef CONFIG_64BIT
1089         /*
1090          * If the interrupted code was running with W bit off (32 bit),
1091          * clear the b bits (bits 0 & 1) in the ior.
1092          * save_specials left ipsw value in r8 for us to test.
1093          */
1094         extrd,u,*<>     %r8,PSW_W_BIT,1,%r0
1095         depdi           0,1,2,%r17
1097         /*
1098          * FIXME: This code has hardwired assumptions about the split
1099          *        between space bits and offset bits. This will change
1100          *        when we allow alternate page sizes.
1101          */
1103         /* adjust isr/ior. */
1104         extrd,u         %r16,63,SPACEID_SHIFT,%r1       /* get high bits from isr for ior */
1105         depd            %r1,31,SPACEID_SHIFT,%r17       /* deposit them into ior */
1106         depdi           0,63,SPACEID_SHIFT,%r16         /* clear them from isr */
1107 #endif
1108         STREG           %r16, PT_ISR(%r29)
1109         STREG           %r17, PT_IOR(%r29)
1112 skip_save_ior:
1113         virt_map
1114         save_general    %r29
1116         ldo             PT_FR0(%r29), %r25
1117         save_fp         %r25
1118         
1119         loadgp
1121         copy            %r29, %r25      /* arg1 is pt_regs */
1122 #ifdef CONFIG_64BIT
1123         ldo             -16(%r30),%r29  /* Reference param save area */
1124 #endif
1126         ldil            L%intr_check_sig, %r2
1127         copy            %r25, %r16      /* save pt_regs */
1129         b               handle_interruption
1130         ldo             R%intr_check_sig(%r2), %r2
1131 ENDPROC_CFI(intr_save)
1134         /*
1135          * Note for all tlb miss handlers:
1136          *
1137          * cr24 contains a pointer to the kernel address space
1138          * page directory.
1139          *
1140          * cr25 contains a pointer to the current user address
1141          * space page directory.
1142          *
1143          * sr3 will contain the space id of the user address space
1144          * of the current running thread while that thread is
1145          * running in the kernel.
1146          */
1148         /*
1149          * register number allocations.  Note that these are all
1150          * in the shadowed registers
1151          */
1153         t0 = r1         /* temporary register 0 */
1154         va = r8         /* virtual address for which the trap occurred */
1155         t1 = r9         /* temporary register 1 */
1156         pte  = r16      /* pte/phys page # */
1157         prot = r17      /* prot bits */
1158         spc  = r24      /* space for which the trap occurred */
1159         ptp = r25       /* page directory/page table pointer */
1161 #ifdef CONFIG_64BIT
1163 dtlb_miss_20w:
1164         space_adjust    spc,va,t0
1165         get_pgd         spc,ptp
1166         space_check     spc,t0,dtlb_fault
1168         L3_ptep         ptp,pte,t0,va,dtlb_check_alias_20w
1170         tlb_lock        spc,ptp,pte,t0,t1,dtlb_check_alias_20w
1171         update_accessed ptp,pte,t0,t1
1173         make_insert_tlb spc,pte,prot,t1
1174         
1175         idtlbt          pte,prot
1177         tlb_unlock1     spc,t0
1178         rfir
1179         nop
1181 dtlb_check_alias_20w:
1182         do_alias        spc,t0,t1,va,pte,prot,dtlb_fault,20
1184         idtlbt          pte,prot
1186         rfir
1187         nop
1189 nadtlb_miss_20w:
1190         space_adjust    spc,va,t0
1191         get_pgd         spc,ptp
1192         space_check     spc,t0,nadtlb_fault
1194         L3_ptep         ptp,pte,t0,va,nadtlb_check_alias_20w
1196         tlb_lock        spc,ptp,pte,t0,t1,nadtlb_check_alias_20w
1197         update_accessed ptp,pte,t0,t1
1199         make_insert_tlb spc,pte,prot,t1
1201         idtlbt          pte,prot
1203         tlb_unlock1     spc,t0
1204         rfir
1205         nop
1207 nadtlb_check_alias_20w:
1208         do_alias        spc,t0,t1,va,pte,prot,nadtlb_emulate,20
1210         idtlbt          pte,prot
1212         rfir
1213         nop
1215 #else
1217 dtlb_miss_11:
1218         get_pgd         spc,ptp
1220         space_check     spc,t0,dtlb_fault
1222         L2_ptep         ptp,pte,t0,va,dtlb_check_alias_11
1224         tlb_lock        spc,ptp,pte,t0,t1,dtlb_check_alias_11
1225         update_accessed ptp,pte,t0,t1
1227         make_insert_tlb_11      spc,pte,prot
1229         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1230         mtsp            spc,%sr1
1232         idtlba          pte,(%sr1,va)
1233         idtlbp          prot,(%sr1,va)
1235         mtsp            t1, %sr1        /* Restore sr1 */
1237         tlb_unlock1     spc,t0
1238         rfir
1239         nop
1241 dtlb_check_alias_11:
1242         do_alias        spc,t0,t1,va,pte,prot,dtlb_fault,11
1244         idtlba          pte,(va)
1245         idtlbp          prot,(va)
1247         rfir
1248         nop
1250 nadtlb_miss_11:
1251         get_pgd         spc,ptp
1253         space_check     spc,t0,nadtlb_fault
1255         L2_ptep         ptp,pte,t0,va,nadtlb_check_alias_11
1257         tlb_lock        spc,ptp,pte,t0,t1,nadtlb_check_alias_11
1258         update_accessed ptp,pte,t0,t1
1260         make_insert_tlb_11      spc,pte,prot
1262         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1263         mtsp            spc,%sr1
1265         idtlba          pte,(%sr1,va)
1266         idtlbp          prot,(%sr1,va)
1268         mtsp            t1, %sr1        /* Restore sr1 */
1270         tlb_unlock1     spc,t0
1271         rfir
1272         nop
1274 nadtlb_check_alias_11:
1275         do_alias        spc,t0,t1,va,pte,prot,nadtlb_emulate,11
1277         idtlba          pte,(va)
1278         idtlbp          prot,(va)
1280         rfir
1281         nop
1283 dtlb_miss_20:
1284         space_adjust    spc,va,t0
1285         get_pgd         spc,ptp
1286         space_check     spc,t0,dtlb_fault
1288         L2_ptep         ptp,pte,t0,va,dtlb_check_alias_20
1290         tlb_lock        spc,ptp,pte,t0,t1,dtlb_check_alias_20
1291         update_accessed ptp,pte,t0,t1
1293         make_insert_tlb spc,pte,prot,t1
1295         f_extend        pte,t1
1297         idtlbt          pte,prot
1299         tlb_unlock1     spc,t0
1300         rfir
1301         nop
1303 dtlb_check_alias_20:
1304         do_alias        spc,t0,t1,va,pte,prot,dtlb_fault,20
1305         
1306         idtlbt          pte,prot
1308         rfir
1309         nop
1311 nadtlb_miss_20:
1312         get_pgd         spc,ptp
1314         space_check     spc,t0,nadtlb_fault
1316         L2_ptep         ptp,pte,t0,va,nadtlb_check_alias_20
1318         tlb_lock        spc,ptp,pte,t0,t1,nadtlb_check_alias_20
1319         update_accessed ptp,pte,t0,t1
1321         make_insert_tlb spc,pte,prot,t1
1323         f_extend        pte,t1
1324         
1325         idtlbt          pte,prot
1327         tlb_unlock1     spc,t0
1328         rfir
1329         nop
1331 nadtlb_check_alias_20:
1332         do_alias        spc,t0,t1,va,pte,prot,nadtlb_emulate,20
1334         idtlbt          pte,prot
1336         rfir
1337         nop
1339 #endif
1341 nadtlb_emulate:
1343         /*
1344          * Non access misses can be caused by fdc,fic,pdc,lpa,probe and
1345          * probei instructions. We don't want to fault for these
1346          * instructions (not only does it not make sense, it can cause
1347          * deadlocks, since some flushes are done with the mmap
1348          * semaphore held). If the translation doesn't exist, we can't
1349          * insert a translation, so have to emulate the side effects
1350          * of the instruction. Since we don't insert a translation
1351          * we can get a lot of faults during a flush loop, so it makes
1352          * sense to try to do it here with minimum overhead. We only
1353          * emulate fdc,fic,pdc,probew,prober instructions whose base 
1354          * and index registers are not shadowed. We defer everything 
1355          * else to the "slow" path.
1356          */
1358         mfctl           %cr19,%r9 /* Get iir */
1360         /* PA 2.0 Arch Ref. Book pg 382 has a good description of the insn bits.
1361            Checks for fdc,fdce,pdc,"fic,4f",prober,probeir,probew, probeiw */
1363         /* Checks for fdc,fdce,pdc,"fic,4f" only */
1364         ldi             0x280,%r16
1365         and             %r9,%r16,%r17
1366         cmpb,<>,n       %r16,%r17,nadtlb_probe_check
1367         bb,>=,n         %r9,26,nadtlb_nullify  /* m bit not set, just nullify */
1368         BL              get_register,%r25
1369         extrw,u         %r9,15,5,%r8           /* Get index register # */
1370         cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
1371         copy            %r1,%r24
1372         BL              get_register,%r25
1373         extrw,u         %r9,10,5,%r8           /* Get base register # */
1374         cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
1375         BL              set_register,%r25
1376         add,l           %r1,%r24,%r1           /* doesn't affect c/b bits */
1378 nadtlb_nullify:
1379         mfctl           %ipsw,%r8
1380         ldil            L%PSW_N,%r9
1381         or              %r8,%r9,%r8            /* Set PSW_N */
1382         mtctl           %r8,%ipsw
1384         rfir
1385         nop
1387         /* 
1388                 When there is no translation for the probe address then we
1389                 must nullify the insn and return zero in the target register.
1390                 This will indicate to the calling code that it does not have 
1391                 write/read privileges to this address.
1393                 This should technically work for prober and probew in PA 1.1,
1394                 and also probe,r and probe,w in PA 2.0
1396                 WARNING: USE ONLY NON-SHADOW REGISTERS WITH PROBE INSN!
1397                 THE SLOW-PATH EMULATION HAS NOT BEEN WRITTEN YET.
1399         */
1400 nadtlb_probe_check:
1401         ldi             0x80,%r16
1402         and             %r9,%r16,%r17
1403         cmpb,<>,n       %r16,%r17,nadtlb_fault /* Must be probe,[rw]*/
1404         BL              get_register,%r25      /* Find the target register */
1405         extrw,u         %r9,31,5,%r8           /* Get target register */
1406         cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
1407         BL              set_register,%r25
1408         copy            %r0,%r1                /* Write zero to target register */
1409         b nadtlb_nullify                       /* Nullify return insn */
1410         nop
1413 #ifdef CONFIG_64BIT
1414 itlb_miss_20w:
1416         /*
1417          * I miss is a little different, since we allow users to fault
1418          * on the gateway page which is in the kernel address space.
1419          */
1421         space_adjust    spc,va,t0
1422         get_pgd         spc,ptp
1423         space_check     spc,t0,itlb_fault
1425         L3_ptep         ptp,pte,t0,va,itlb_fault
1427         tlb_lock        spc,ptp,pte,t0,t1,itlb_fault
1428         update_accessed ptp,pte,t0,t1
1430         make_insert_tlb spc,pte,prot,t1
1431         
1432         iitlbt          pte,prot
1434         tlb_unlock1     spc,t0
1435         rfir
1436         nop
1438 naitlb_miss_20w:
1440         /*
1441          * I miss is a little different, since we allow users to fault
1442          * on the gateway page which is in the kernel address space.
1443          */
1445         space_adjust    spc,va,t0
1446         get_pgd         spc,ptp
1447         space_check     spc,t0,naitlb_fault
1449         L3_ptep         ptp,pte,t0,va,naitlb_check_alias_20w
1451         tlb_lock        spc,ptp,pte,t0,t1,naitlb_check_alias_20w
1452         update_accessed ptp,pte,t0,t1
1454         make_insert_tlb spc,pte,prot,t1
1456         iitlbt          pte,prot
1458         tlb_unlock1     spc,t0
1459         rfir
1460         nop
1462 naitlb_check_alias_20w:
1463         do_alias        spc,t0,t1,va,pte,prot,naitlb_fault,20
1465         iitlbt          pte,prot
1467         rfir
1468         nop
1470 #else
1472 itlb_miss_11:
1473         get_pgd         spc,ptp
1475         space_check     spc,t0,itlb_fault
1477         L2_ptep         ptp,pte,t0,va,itlb_fault
1479         tlb_lock        spc,ptp,pte,t0,t1,itlb_fault
1480         update_accessed ptp,pte,t0,t1
1482         make_insert_tlb_11      spc,pte,prot
1484         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1485         mtsp            spc,%sr1
1487         iitlba          pte,(%sr1,va)
1488         iitlbp          prot,(%sr1,va)
1490         mtsp            t1, %sr1        /* Restore sr1 */
1492         tlb_unlock1     spc,t0
1493         rfir
1494         nop
1496 naitlb_miss_11:
1497         get_pgd         spc,ptp
1499         space_check     spc,t0,naitlb_fault
1501         L2_ptep         ptp,pte,t0,va,naitlb_check_alias_11
1503         tlb_lock        spc,ptp,pte,t0,t1,naitlb_check_alias_11
1504         update_accessed ptp,pte,t0,t1
1506         make_insert_tlb_11      spc,pte,prot
1508         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1509         mtsp            spc,%sr1
1511         iitlba          pte,(%sr1,va)
1512         iitlbp          prot,(%sr1,va)
1514         mtsp            t1, %sr1        /* Restore sr1 */
1516         tlb_unlock1     spc,t0
1517         rfir
1518         nop
1520 naitlb_check_alias_11:
1521         do_alias        spc,t0,t1,va,pte,prot,itlb_fault,11
1523         iitlba          pte,(%sr0, va)
1524         iitlbp          prot,(%sr0, va)
1526         rfir
1527         nop
1530 itlb_miss_20:
1531         get_pgd         spc,ptp
1533         space_check     spc,t0,itlb_fault
1535         L2_ptep         ptp,pte,t0,va,itlb_fault
1537         tlb_lock        spc,ptp,pte,t0,t1,itlb_fault
1538         update_accessed ptp,pte,t0,t1
1540         make_insert_tlb spc,pte,prot,t1
1542         f_extend        pte,t1
1544         iitlbt          pte,prot
1546         tlb_unlock1     spc,t0
1547         rfir
1548         nop
1550 naitlb_miss_20:
1551         get_pgd         spc,ptp
1553         space_check     spc,t0,naitlb_fault
1555         L2_ptep         ptp,pte,t0,va,naitlb_check_alias_20
1557         tlb_lock        spc,ptp,pte,t0,t1,naitlb_check_alias_20
1558         update_accessed ptp,pte,t0,t1
1560         make_insert_tlb spc,pte,prot,t1
1562         f_extend        pte,t1
1564         iitlbt          pte,prot
1566         tlb_unlock1     spc,t0
1567         rfir
1568         nop
1570 naitlb_check_alias_20:
1571         do_alias        spc,t0,t1,va,pte,prot,naitlb_fault,20
1573         iitlbt          pte,prot
1575         rfir
1576         nop
1578 #endif
1580 #ifdef CONFIG_64BIT
1582 dbit_trap_20w:
1583         space_adjust    spc,va,t0
1584         get_pgd         spc,ptp
1585         space_check     spc,t0,dbit_fault
1587         L3_ptep         ptp,pte,t0,va,dbit_fault
1589         tlb_lock        spc,ptp,pte,t0,t1,dbit_fault
1590         update_dirty    ptp,pte,t1
1592         make_insert_tlb spc,pte,prot,t1
1593                 
1594         idtlbt          pte,prot
1596         tlb_unlock0     spc,t0
1597         rfir
1598         nop
1599 #else
1601 dbit_trap_11:
1603         get_pgd         spc,ptp
1605         space_check     spc,t0,dbit_fault
1607         L2_ptep         ptp,pte,t0,va,dbit_fault
1609         tlb_lock        spc,ptp,pte,t0,t1,dbit_fault
1610         update_dirty    ptp,pte,t1
1612         make_insert_tlb_11      spc,pte,prot
1614         mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1615         mtsp            spc,%sr1
1617         idtlba          pte,(%sr1,va)
1618         idtlbp          prot,(%sr1,va)
1620         mtsp            t1, %sr1     /* Restore sr1 */
1622         tlb_unlock0     spc,t0
1623         rfir
1624         nop
1626 dbit_trap_20:
1627         get_pgd         spc,ptp
1629         space_check     spc,t0,dbit_fault
1631         L2_ptep         ptp,pte,t0,va,dbit_fault
1633         tlb_lock        spc,ptp,pte,t0,t1,dbit_fault
1634         update_dirty    ptp,pte,t1
1636         make_insert_tlb spc,pte,prot,t1
1638         f_extend        pte,t1
1639         
1640         idtlbt          pte,prot
1642         tlb_unlock0     spc,t0
1643         rfir
1644         nop
1645 #endif
1647         .import handle_interruption,code
1649 kernel_bad_space:
1650         b               intr_save
1651         ldi             31,%r8  /* Use an unused code */
1653 dbit_fault:
1654         b               intr_save
1655         ldi             20,%r8
1657 itlb_fault:
1658         b               intr_save
1659         ldi             6,%r8
1661 nadtlb_fault:
1662         b               intr_save
1663         ldi             17,%r8
1665 naitlb_fault:
1666         b               intr_save
1667         ldi             16,%r8
1669 dtlb_fault:
1670         b               intr_save
1671         ldi             15,%r8
1673         /* Register saving semantics for system calls:
1675            %r1             clobbered by system call macro in userspace
1676            %r2             saved in PT_REGS by gateway page
1677            %r3  - %r18     preserved by C code (saved by signal code)
1678            %r19 - %r20     saved in PT_REGS by gateway page
1679            %r21 - %r22     non-standard syscall args
1680                            stored in kernel stack by gateway page
1681            %r23 - %r26     arg3-arg0, saved in PT_REGS by gateway page
1682            %r27 - %r30     saved in PT_REGS by gateway page
1683            %r31            syscall return pointer
1684          */
1686         /* Floating point registers (FIXME: what do we do with these?)
1688            %fr0  - %fr3    status/exception, not preserved
1689            %fr4  - %fr7    arguments
1690            %fr8  - %fr11   not preserved by C code
1691            %fr12 - %fr21   preserved by C code
1692            %fr22 - %fr31   not preserved by C code
1693          */
1695         .macro  reg_save regs
1696         STREG   %r3, PT_GR3(\regs)
1697         STREG   %r4, PT_GR4(\regs)
1698         STREG   %r5, PT_GR5(\regs)
1699         STREG   %r6, PT_GR6(\regs)
1700         STREG   %r7, PT_GR7(\regs)
1701         STREG   %r8, PT_GR8(\regs)
1702         STREG   %r9, PT_GR9(\regs)
1703         STREG   %r10,PT_GR10(\regs)
1704         STREG   %r11,PT_GR11(\regs)
1705         STREG   %r12,PT_GR12(\regs)
1706         STREG   %r13,PT_GR13(\regs)
1707         STREG   %r14,PT_GR14(\regs)
1708         STREG   %r15,PT_GR15(\regs)
1709         STREG   %r16,PT_GR16(\regs)
1710         STREG   %r17,PT_GR17(\regs)
1711         STREG   %r18,PT_GR18(\regs)
1712         .endm
1714         .macro  reg_restore regs
1715         LDREG   PT_GR3(\regs), %r3
1716         LDREG   PT_GR4(\regs), %r4
1717         LDREG   PT_GR5(\regs), %r5
1718         LDREG   PT_GR6(\regs), %r6
1719         LDREG   PT_GR7(\regs), %r7
1720         LDREG   PT_GR8(\regs), %r8
1721         LDREG   PT_GR9(\regs), %r9
1722         LDREG   PT_GR10(\regs),%r10
1723         LDREG   PT_GR11(\regs),%r11
1724         LDREG   PT_GR12(\regs),%r12
1725         LDREG   PT_GR13(\regs),%r13
1726         LDREG   PT_GR14(\regs),%r14
1727         LDREG   PT_GR15(\regs),%r15
1728         LDREG   PT_GR16(\regs),%r16
1729         LDREG   PT_GR17(\regs),%r17
1730         LDREG   PT_GR18(\regs),%r18
1731         .endm
1733         .macro  fork_like name
1734 ENTRY_CFI(sys_\name\()_wrapper)
1735         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
1736         ldo     TASK_REGS(%r1),%r1
1737         reg_save %r1
1738         mfctl   %cr27, %r28
1739         ldil    L%sys_\name, %r31
1740         be      R%sys_\name(%sr4,%r31)
1741         STREG   %r28, PT_CR27(%r1)
1742 ENDPROC_CFI(sys_\name\()_wrapper)
1743         .endm
1745 fork_like clone
1746 fork_like fork
1747 fork_like vfork
1749         /* Set the return value for the child */
1750 ENTRY_CFI(child_return)
1751         BL      schedule_tail, %r2
1752         nop
1753 finish_child_return:
1754         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
1755         ldo     TASK_REGS(%r1),%r1       /* get pt regs */
1757         LDREG   PT_CR27(%r1), %r3
1758         mtctl   %r3, %cr27
1759         reg_restore %r1
1760         b       syscall_exit
1761         copy    %r0,%r28
1762 ENDPROC_CFI(child_return)
1764 ENTRY_CFI(sys_rt_sigreturn_wrapper)
1765         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
1766         ldo     TASK_REGS(%r26),%r26    /* get pt regs */
1767         /* Don't save regs, we are going to restore them from sigcontext. */
1768         STREG   %r2, -RP_OFFSET(%r30)
1769 #ifdef CONFIG_64BIT
1770         ldo     FRAME_SIZE(%r30), %r30
1771         BL      sys_rt_sigreturn,%r2
1772         ldo     -16(%r30),%r29          /* Reference param save area */
1773 #else
1774         BL      sys_rt_sigreturn,%r2
1775         ldo     FRAME_SIZE(%r30), %r30
1776 #endif
1778         ldo     -FRAME_SIZE(%r30), %r30
1779         LDREG   -RP_OFFSET(%r30), %r2
1781         /* FIXME: I think we need to restore a few more things here. */
1782         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1783         ldo     TASK_REGS(%r1),%r1      /* get pt regs */
1784         reg_restore %r1
1786         /* If the signal was received while the process was blocked on a
1787          * syscall, then r2 will take us to syscall_exit; otherwise r2 will
1788          * take us to syscall_exit_rfi and on to intr_return.
1789          */
1790         bv      %r0(%r2)
1791         LDREG   PT_GR28(%r1),%r28  /* reload original r28 for syscall_exit */
1792 ENDPROC_CFI(sys_rt_sigreturn_wrapper)
1794 ENTRY_CFI(syscall_exit)
1795         /* NOTE: Not all syscalls exit this way.  rt_sigreturn will exit
1796          * via syscall_exit_rfi if the signal was received while the process
1797          * was running.
1798          */
1800         /* save return value now */
1802         mfctl     %cr30, %r1
1803         LDREG     TI_TASK(%r1),%r1
1804         STREG     %r28,TASK_PT_GR28(%r1)
1806         /* Seems to me that dp could be wrong here, if the syscall involved
1807          * calling a module, and nothing got round to restoring dp on return.
1808          */
1809         loadgp
1811 syscall_check_resched:
1813         /* check for reschedule */
1815         LDREG   TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19   /* long */
1816         bb,<,n  %r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */
1818         .import do_signal,code
1819 syscall_check_sig:
1820         LDREG   TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19
1821         ldi     (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), %r26
1822         and,COND(<>)    %r19, %r26, %r0
1823         b,n     syscall_restore /* skip past if we've nothing to do */
1825 syscall_do_signal:
1826         /* Save callee-save registers (for sigcontext).
1827          * FIXME: After this point the process structure should be
1828          * consistent with all the relevant state of the process
1829          * before the syscall.  We need to verify this.
1830          */
1831         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1832         ldo     TASK_REGS(%r1), %r26            /* struct pt_regs *regs */
1833         reg_save %r26
1835 #ifdef CONFIG_64BIT
1836         ldo     -16(%r30),%r29                  /* Reference param save area */
1837 #endif
1839         BL      do_notify_resume,%r2
1840         ldi     1, %r25                         /* long in_syscall = 1 */
1842         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1843         ldo     TASK_REGS(%r1), %r20            /* reload pt_regs */
1844         reg_restore %r20
1846         b,n     syscall_check_sig
1848 syscall_restore:
1849         LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
1851         /* Are we being ptraced? */
1852         ldw     TASK_FLAGS(%r1),%r19
1853         ldi     _TIF_SYSCALL_TRACE_MASK,%r2
1854         and,COND(=)     %r19,%r2,%r0
1855         b,n     syscall_restore_rfi
1857         ldo     TASK_PT_FR31(%r1),%r19             /* reload fpregs */
1858         rest_fp %r19
1860         LDREG   TASK_PT_SAR(%r1),%r19              /* restore SAR */
1861         mtsar   %r19
1863         LDREG   TASK_PT_GR2(%r1),%r2               /* restore user rp */
1864         LDREG   TASK_PT_GR19(%r1),%r19
1865         LDREG   TASK_PT_GR20(%r1),%r20
1866         LDREG   TASK_PT_GR21(%r1),%r21
1867         LDREG   TASK_PT_GR22(%r1),%r22
1868         LDREG   TASK_PT_GR23(%r1),%r23
1869         LDREG   TASK_PT_GR24(%r1),%r24
1870         LDREG   TASK_PT_GR25(%r1),%r25
1871         LDREG   TASK_PT_GR26(%r1),%r26
1872         LDREG   TASK_PT_GR27(%r1),%r27     /* restore user dp */
1873         LDREG   TASK_PT_GR28(%r1),%r28     /* syscall return value */
1874         LDREG   TASK_PT_GR29(%r1),%r29
1875         LDREG   TASK_PT_GR31(%r1),%r31     /* restore syscall rp */
1877         /* NOTE: We use rsm/ssm pair to make this operation atomic */
1878         LDREG   TASK_PT_GR30(%r1),%r1              /* Get user sp */
1879         rsm     PSW_SM_I, %r0
1880         copy    %r1,%r30                           /* Restore user sp */
1881         mfsp    %sr3,%r1                           /* Get user space id */
1882         mtsp    %r1,%sr7                           /* Restore sr7 */
1883         ssm     PSW_SM_I, %r0
1885         /* Set sr2 to zero for userspace syscalls to work. */
1886         mtsp    %r0,%sr2 
1887         mtsp    %r1,%sr4                           /* Restore sr4 */
1888         mtsp    %r1,%sr5                           /* Restore sr5 */
1889         mtsp    %r1,%sr6                           /* Restore sr6 */
1891         depi    3,31,2,%r31                        /* ensure return to user mode. */
1893 #ifdef CONFIG_64BIT
1894         /* decide whether to reset the wide mode bit
1895          *
1896          * For a syscall, the W bit is stored in the lowest bit
1897          * of sp.  Extract it and reset W if it is zero */
1898         extrd,u,*<>     %r30,63,1,%r1
1899         rsm     PSW_SM_W, %r0
1900         /* now reset the lowest bit of sp if it was set */
1901         xor     %r30,%r1,%r30
1902 #endif
1903         be,n    0(%sr3,%r31)                       /* return to user space */
1905         /* We have to return via an RFI, so that PSW T and R bits can be set
1906          * appropriately.
1907          * This sets up pt_regs so we can return via intr_restore, which is not
1908          * the most efficient way of doing things, but it works.
1909          */
1910 syscall_restore_rfi:
1911         ldo     -1(%r0),%r2                        /* Set recovery cntr to -1 */
1912         mtctl   %r2,%cr0                           /*   for immediate trap */
1913         LDREG   TASK_PT_PSW(%r1),%r2               /* Get old PSW */
1914         ldi     0x0b,%r20                          /* Create new PSW */
1915         depi    -1,13,1,%r20                       /* C, Q, D, and I bits */
1917         /* The values of SINGLESTEP_BIT and BLOCKSTEP_BIT are
1918          * set in thread_info.h and converted to PA bitmap
1919          * numbers in asm-offsets.c */
1921         /* if ((%r19.SINGLESTEP_BIT)) { %r20.27=1} */
1922         extru,= %r19,TIF_SINGLESTEP_PA_BIT,1,%r0
1923         depi    -1,27,1,%r20                       /* R bit */
1925         /* if ((%r19.BLOCKSTEP_BIT)) { %r20.7=1} */
1926         extru,= %r19,TIF_BLOCKSTEP_PA_BIT,1,%r0
1927         depi    -1,7,1,%r20                        /* T bit */
1929         STREG   %r20,TASK_PT_PSW(%r1)
1931         /* Always store space registers, since sr3 can be changed (e.g. fork) */
1933         mfsp    %sr3,%r25
1934         STREG   %r25,TASK_PT_SR3(%r1)
1935         STREG   %r25,TASK_PT_SR4(%r1)
1936         STREG   %r25,TASK_PT_SR5(%r1)
1937         STREG   %r25,TASK_PT_SR6(%r1)
1938         STREG   %r25,TASK_PT_SR7(%r1)
1939         STREG   %r25,TASK_PT_IASQ0(%r1)
1940         STREG   %r25,TASK_PT_IASQ1(%r1)
1942         /* XXX W bit??? */
1943         /* Now if old D bit is clear, it means we didn't save all registers
1944          * on syscall entry, so do that now.  This only happens on TRACEME
1945          * calls, or if someone attached to us while we were on a syscall.
1946          * We could make this more efficient by not saving r3-r18, but
1947          * then we wouldn't be able to use the common intr_restore path.
1948          * It is only for traced processes anyway, so performance is not
1949          * an issue.
1950          */
1951         bb,<    %r2,30,pt_regs_ok                  /* Branch if D set */
1952         ldo     TASK_REGS(%r1),%r25
1953         reg_save %r25                              /* Save r3 to r18 */
1955         /* Save the current sr */
1956         mfsp    %sr0,%r2
1957         STREG   %r2,TASK_PT_SR0(%r1)
1959         /* Save the scratch sr */
1960         mfsp    %sr1,%r2
1961         STREG   %r2,TASK_PT_SR1(%r1)
1963         /* sr2 should be set to zero for userspace syscalls */
1964         STREG   %r0,TASK_PT_SR2(%r1)
1966         LDREG   TASK_PT_GR31(%r1),%r2
1967         depi    3,31,2,%r2                 /* ensure return to user mode. */
1968         STREG   %r2,TASK_PT_IAOQ0(%r1)
1969         ldo     4(%r2),%r2
1970         STREG   %r2,TASK_PT_IAOQ1(%r1)
1971         b       intr_restore
1972         copy    %r25,%r16
1974 pt_regs_ok:
1975         LDREG   TASK_PT_IAOQ0(%r1),%r2
1976         depi    3,31,2,%r2                 /* ensure return to user mode. */
1977         STREG   %r2,TASK_PT_IAOQ0(%r1)
1978         LDREG   TASK_PT_IAOQ1(%r1),%r2
1979         depi    3,31,2,%r2
1980         STREG   %r2,TASK_PT_IAOQ1(%r1)
1981         b       intr_restore
1982         copy    %r25,%r16
1984 syscall_do_resched:
1985         load32  syscall_check_resched,%r2 /* if resched, we start over again */
1986         load32  schedule,%r19
1987         bv      %r0(%r19)               /* jumps to schedule() */
1988 #ifdef CONFIG_64BIT
1989         ldo     -16(%r30),%r29          /* Reference param save area */
1990 #else
1991         nop
1992 #endif
1993 ENDPROC_CFI(syscall_exit)
1996 #ifdef CONFIG_FUNCTION_TRACER
1998         .import ftrace_function_trampoline,code
1999         .align L1_CACHE_BYTES
2000         .globl mcount
2001         .type  mcount, @function
2002 ENTRY(mcount)
2003 _mcount:
2004         .export _mcount,data
2005         .proc
2006         .callinfo caller,frame=0
2007         .entry
2008         /*
2009          * The 64bit mcount() function pointer needs 4 dwords, of which the
2010          * first two are free.  We optimize it here and put 2 instructions for
2011          * calling mcount(), and 2 instructions for ftrace_stub().  That way we
2012          * have all on one L1 cacheline.
2013          */
2014         b       ftrace_function_trampoline
2015         copy    %r3, %arg2      /* caller original %sp */
2016 ftrace_stub:
2017         .globl ftrace_stub
2018         .type  ftrace_stub, @function
2019 #ifdef CONFIG_64BIT
2020         bve     (%rp)
2021 #else
2022         bv      %r0(%rp)
2023 #endif
2024         nop
2025 #ifdef CONFIG_64BIT
2026         .dword mcount
2027         .dword 0 /* code in head.S puts value of global gp here */
2028 #endif
2029         .exit
2030         .procend
2031 ENDPROC(mcount)
2033 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
2034         .align 8
2035         .globl return_to_handler
2036         .type  return_to_handler, @function
2037 ENTRY_CFI(return_to_handler)
2038         .proc
2039         .callinfo caller,frame=FRAME_SIZE
2040         .entry
2041         .export parisc_return_to_handler,data
2042 parisc_return_to_handler:
2043         copy %r3,%r1
2044         STREG %r0,-RP_OFFSET(%sp)       /* store 0 as %rp */
2045         copy %sp,%r3
2046         STREGM %r1,FRAME_SIZE(%sp)
2047         STREG %ret0,8(%r3)
2048         STREG %ret1,16(%r3)
2050 #ifdef CONFIG_64BIT
2051         loadgp
2052 #endif
2054         /* call ftrace_return_to_handler(0) */
2055         .import ftrace_return_to_handler,code
2056         load32 ftrace_return_to_handler,%ret0
2057         load32 .Lftrace_ret,%r2
2058 #ifdef CONFIG_64BIT
2059         ldo -16(%sp),%ret1              /* Reference param save area */
2060         bve     (%ret0)
2061 #else
2062         bv      %r0(%ret0)
2063 #endif
2064         ldi 0,%r26
2065 .Lftrace_ret:
2066         copy %ret0,%rp
2068         /* restore original return values */
2069         LDREG 8(%r3),%ret0
2070         LDREG 16(%r3),%ret1
2072         /* return from function */
2073 #ifdef CONFIG_64BIT
2074         bve     (%rp)
2075 #else
2076         bv      %r0(%rp)
2077 #endif
2078         LDREGM -FRAME_SIZE(%sp),%r3
2079         .exit
2080         .procend
2081 ENDPROC_CFI(return_to_handler)
2083 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
2085 #endif  /* CONFIG_FUNCTION_TRACER */
2087 #ifdef CONFIG_IRQSTACKS
2088 /* void call_on_stack(unsigned long param1, void *func,
2089                       unsigned long new_stack) */
2090 ENTRY_CFI(call_on_stack)
2091         copy    %sp, %r1
2093         /* Regarding the HPPA calling conventions for function pointers,
2094            we assume the PIC register is not changed across call.  For
2095            CONFIG_64BIT, the argument pointer is left to point at the
2096            argument region allocated for the call to call_on_stack. */
2097 # ifdef CONFIG_64BIT
2098         /* Switch to new stack.  We allocate two 128 byte frames.  */
2099         ldo     256(%arg2), %sp
2100         /* Save previous stack pointer and return pointer in frame marker */
2101         STREG   %rp, -144(%sp)
2102         /* Calls always use function descriptor */
2103         LDREG   16(%arg1), %arg1
2104         bve,l   (%arg1), %rp
2105         STREG   %r1, -136(%sp)
2106         LDREG   -144(%sp), %rp
2107         bve     (%rp)
2108         LDREG   -136(%sp), %sp
2109 # else
2110         /* Switch to new stack.  We allocate two 64 byte frames.  */
2111         ldo     128(%arg2), %sp
2112         /* Save previous stack pointer and return pointer in frame marker */
2113         STREG   %r1, -68(%sp)
2114         STREG   %rp, -84(%sp)
2115         /* Calls use function descriptor if PLABEL bit is set */
2116         bb,>=,n %arg1, 30, 1f
2117         depwi   0,31,2, %arg1
2118         LDREG   0(%arg1), %arg1
2120         be,l    0(%sr4,%arg1), %sr0, %r31
2121         copy    %r31, %rp
2122         LDREG   -84(%sp), %rp
2123         bv      (%rp)
2124         LDREG   -68(%sp), %sp
2125 # endif /* CONFIG_64BIT */
2126 ENDPROC_CFI(call_on_stack)
2127 #endif /* CONFIG_IRQSTACKS */
2129 ENTRY_CFI(get_register)
2130         /*
2131          * get_register is used by the non access tlb miss handlers to
2132          * copy the value of the general register specified in r8 into
2133          * r1. This routine can't be used for shadowed registers, since
2134          * the rfir will restore the original value. So, for the shadowed
2135          * registers we put a -1 into r1 to indicate that the register
2136          * should not be used (the register being copied could also have
2137          * a -1 in it, but that is OK, it just means that we will have
2138          * to use the slow path instead).
2139          */
2140         blr     %r8,%r0
2141         nop
2142         bv      %r0(%r25)    /* r0 */
2143         copy    %r0,%r1
2144         bv      %r0(%r25)    /* r1 - shadowed */
2145         ldi     -1,%r1
2146         bv      %r0(%r25)    /* r2 */
2147         copy    %r2,%r1
2148         bv      %r0(%r25)    /* r3 */
2149         copy    %r3,%r1
2150         bv      %r0(%r25)    /* r4 */
2151         copy    %r4,%r1
2152         bv      %r0(%r25)    /* r5 */
2153         copy    %r5,%r1
2154         bv      %r0(%r25)    /* r6 */
2155         copy    %r6,%r1
2156         bv      %r0(%r25)    /* r7 */
2157         copy    %r7,%r1
2158         bv      %r0(%r25)    /* r8 - shadowed */
2159         ldi     -1,%r1
2160         bv      %r0(%r25)    /* r9 - shadowed */
2161         ldi     -1,%r1
2162         bv      %r0(%r25)    /* r10 */
2163         copy    %r10,%r1
2164         bv      %r0(%r25)    /* r11 */
2165         copy    %r11,%r1
2166         bv      %r0(%r25)    /* r12 */
2167         copy    %r12,%r1
2168         bv      %r0(%r25)    /* r13 */
2169         copy    %r13,%r1
2170         bv      %r0(%r25)    /* r14 */
2171         copy    %r14,%r1
2172         bv      %r0(%r25)    /* r15 */
2173         copy    %r15,%r1
2174         bv      %r0(%r25)    /* r16 - shadowed */
2175         ldi     -1,%r1
2176         bv      %r0(%r25)    /* r17 - shadowed */
2177         ldi     -1,%r1
2178         bv      %r0(%r25)    /* r18 */
2179         copy    %r18,%r1
2180         bv      %r0(%r25)    /* r19 */
2181         copy    %r19,%r1
2182         bv      %r0(%r25)    /* r20 */
2183         copy    %r20,%r1
2184         bv      %r0(%r25)    /* r21 */
2185         copy    %r21,%r1
2186         bv      %r0(%r25)    /* r22 */
2187         copy    %r22,%r1
2188         bv      %r0(%r25)    /* r23 */
2189         copy    %r23,%r1
2190         bv      %r0(%r25)    /* r24 - shadowed */
2191         ldi     -1,%r1
2192         bv      %r0(%r25)    /* r25 - shadowed */
2193         ldi     -1,%r1
2194         bv      %r0(%r25)    /* r26 */
2195         copy    %r26,%r1
2196         bv      %r0(%r25)    /* r27 */
2197         copy    %r27,%r1
2198         bv      %r0(%r25)    /* r28 */
2199         copy    %r28,%r1
2200         bv      %r0(%r25)    /* r29 */
2201         copy    %r29,%r1
2202         bv      %r0(%r25)    /* r30 */
2203         copy    %r30,%r1
2204         bv      %r0(%r25)    /* r31 */
2205         copy    %r31,%r1
2206 ENDPROC_CFI(get_register)
2209 ENTRY_CFI(set_register)
2210         /*
2211          * set_register is used by the non access tlb miss handlers to
2212          * copy the value of r1 into the general register specified in
2213          * r8.
2214          */
2215         blr     %r8,%r0
2216         nop
2217         bv      %r0(%r25)    /* r0 (silly, but it is a place holder) */
2218         copy    %r1,%r0
2219         bv      %r0(%r25)    /* r1 */
2220         copy    %r1,%r1
2221         bv      %r0(%r25)    /* r2 */
2222         copy    %r1,%r2
2223         bv      %r0(%r25)    /* r3 */
2224         copy    %r1,%r3
2225         bv      %r0(%r25)    /* r4 */
2226         copy    %r1,%r4
2227         bv      %r0(%r25)    /* r5 */
2228         copy    %r1,%r5
2229         bv      %r0(%r25)    /* r6 */
2230         copy    %r1,%r6
2231         bv      %r0(%r25)    /* r7 */
2232         copy    %r1,%r7
2233         bv      %r0(%r25)    /* r8 */
2234         copy    %r1,%r8
2235         bv      %r0(%r25)    /* r9 */
2236         copy    %r1,%r9
2237         bv      %r0(%r25)    /* r10 */
2238         copy    %r1,%r10
2239         bv      %r0(%r25)    /* r11 */
2240         copy    %r1,%r11
2241         bv      %r0(%r25)    /* r12 */
2242         copy    %r1,%r12
2243         bv      %r0(%r25)    /* r13 */
2244         copy    %r1,%r13
2245         bv      %r0(%r25)    /* r14 */
2246         copy    %r1,%r14
2247         bv      %r0(%r25)    /* r15 */
2248         copy    %r1,%r15
2249         bv      %r0(%r25)    /* r16 */
2250         copy    %r1,%r16
2251         bv      %r0(%r25)    /* r17 */
2252         copy    %r1,%r17
2253         bv      %r0(%r25)    /* r18 */
2254         copy    %r1,%r18
2255         bv      %r0(%r25)    /* r19 */
2256         copy    %r1,%r19
2257         bv      %r0(%r25)    /* r20 */
2258         copy    %r1,%r20
2259         bv      %r0(%r25)    /* r21 */
2260         copy    %r1,%r21
2261         bv      %r0(%r25)    /* r22 */
2262         copy    %r1,%r22
2263         bv      %r0(%r25)    /* r23 */
2264         copy    %r1,%r23
2265         bv      %r0(%r25)    /* r24 */
2266         copy    %r1,%r24
2267         bv      %r0(%r25)    /* r25 */
2268         copy    %r1,%r25
2269         bv      %r0(%r25)    /* r26 */
2270         copy    %r1,%r26
2271         bv      %r0(%r25)    /* r27 */
2272         copy    %r1,%r27
2273         bv      %r0(%r25)    /* r28 */
2274         copy    %r1,%r28
2275         bv      %r0(%r25)    /* r29 */
2276         copy    %r1,%r29
2277         bv      %r0(%r25)    /* r30 */
2278         copy    %r1,%r30
2279         bv      %r0(%r25)    /* r31 */
2280         copy    %r1,%r31
2281 ENDPROC_CFI(set_register)