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