xref: /openbmc/linux/arch/parisc/kernel/entry.S (revision fac59652993f075d57860769c99045b3ca18780d)
1de6cc651SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-or-later */
21da177e4SLinus Torvalds/*
31da177e4SLinus Torvalds * Linux/PA-RISC Project (http://www.parisc-linux.org/)
41da177e4SLinus Torvalds *
51da177e4SLinus Torvalds * kernel entry points (interruptions, system call wrappers)
61da177e4SLinus Torvalds *  Copyright (C) 1999,2000 Philipp Rumpf
71da177e4SLinus Torvalds *  Copyright (C) 1999 SuSE GmbH Nuernberg
81da177e4SLinus Torvalds *  Copyright (C) 2000 Hewlett-Packard (John Marvin)
91da177e4SLinus Torvalds *  Copyright (C) 1999 Hewlett-Packard (Frank Rowand)
101da177e4SLinus Torvalds */
111da177e4SLinus Torvalds
120013a854SSam Ravnborg#include <asm/asm-offsets.h>
131da177e4SLinus Torvalds
141da177e4SLinus Torvalds/* we have the following possibilities to act on an interruption:
151da177e4SLinus Torvalds *  - handle in assembly and use shadowed registers only
161da177e4SLinus Torvalds *  - save registers to kernel stack and handle in assembly or C */
171da177e4SLinus Torvalds
181da177e4SLinus Torvalds
19896a3756SGrant Grundler#include <asm/psw.h>
203d73cf5eSKyle McMartin#include <asm/cache.h>		/* for L1_CACHE_SHIFT */
211da177e4SLinus Torvalds#include <asm/assembly.h>	/* for LDREG/STREG defines */
221da177e4SLinus Torvalds#include <asm/signal.h>
231da177e4SLinus Torvalds#include <asm/unistd.h>
2488776c0eSHelge Deller#include <asm/ldcw.h>
255b00ca0bSHelge Deller#include <asm/traps.h>
261da177e4SLinus Torvalds#include <asm/thread_info.h>
273847dab7SHelge Deller#include <asm/alternative.h>
287a894c87SHelge Deller#include <asm/spinlock_types.h>
291da177e4SLinus Torvalds
30c5e76552SHelge Deller#include <linux/linkage.h>
3165fddcfcSMike Rapoport#include <linux/pgtable.h>
32c5e76552SHelge Deller
33413059f2SGrant Grundler#ifdef CONFIG_64BIT
341da177e4SLinus Torvalds	.level 2.0w
351da177e4SLinus Torvalds#else
361da177e4SLinus Torvalds	.level 2.0
371da177e4SLinus Torvalds#endif
381da177e4SLinus Torvalds
39c3b5552bSJohn David Anglin/*
40c3b5552bSJohn David Anglin * We need seven instructions after a TLB insert for it to take effect.
41c3b5552bSJohn David Anglin * The PA8800/PA8900 processors are an exception and need 12 instructions.
42c3b5552bSJohn David Anglin * The RFI changes both IAOQ_Back and IAOQ_Front, so it counts as one.
43c3b5552bSJohn David Anglin */
44c3b5552bSJohn David Anglin#ifdef CONFIG_64BIT
45c3b5552bSJohn David Anglin#define NUM_PIPELINE_INSNS    12
46c3b5552bSJohn David Anglin#else
47c3b5552bSJohn David Anglin#define NUM_PIPELINE_INSNS    7
48c3b5552bSJohn David Anglin#endif
49c3b5552bSJohn David Anglin
50c3b5552bSJohn David Anglin	/* Insert num nops */
51c3b5552bSJohn David Anglin	.macro	insert_nops num
52c3b5552bSJohn David Anglin	.rept \num
53c3b5552bSJohn David Anglin	nop
54c3b5552bSJohn David Anglin	.endr
55c3b5552bSJohn David Anglin	.endm
56c3b5552bSJohn David Anglin
57b7795074SHelge Deller	/* Get aligned page_table_lock address for this mm from cr28/tr4 */
58b7795074SHelge Deller	.macro  get_ptl reg
59b7795074SHelge Deller	mfctl	%cr28,\reg
6088776c0eSHelge Deller	.endm
611da177e4SLinus Torvalds
621da177e4SLinus Torvalds	/* space_to_prot macro creates a prot id from a space id */
631da177e4SLinus Torvalds
641da177e4SLinus Torvalds#if (SPACEID_SHIFT) == 0
651da177e4SLinus Torvalds	.macro  space_to_prot spc prot
661da177e4SLinus Torvalds	depd,z  \spc,62,31,\prot
671da177e4SLinus Torvalds	.endm
681da177e4SLinus Torvalds#else
691da177e4SLinus Torvalds	.macro  space_to_prot spc prot
701da177e4SLinus Torvalds	extrd,u \spc,(64 - (SPACEID_SHIFT)),32,\prot
711da177e4SLinus Torvalds	.endm
721da177e4SLinus Torvalds#endif
731da177e4SLinus Torvalds	/*
741da177e4SLinus Torvalds	 * The "get_stack" macros are responsible for determining the
751da177e4SLinus Torvalds	 * kernel stack value.
761da177e4SLinus Torvalds	 *
771da177e4SLinus Torvalds	 *      If sr7 == 0
781da177e4SLinus Torvalds	 *          Already using a kernel stack, so call the
791da177e4SLinus Torvalds	 *          get_stack_use_r30 macro to push a pt_regs structure
801da177e4SLinus Torvalds	 *          on the stack, and store registers there.
811da177e4SLinus Torvalds	 *      else
821da177e4SLinus Torvalds	 *          Need to set up a kernel stack, so call the
831da177e4SLinus Torvalds	 *          get_stack_use_cr30 macro to set up a pointer
841da177e4SLinus Torvalds	 *          to the pt_regs structure contained within the
852214c0e7SHelge Deller	 *          task pointer pointed to by cr30. Load the stack
862214c0e7SHelge Deller	 *          pointer from the task structure.
871da177e4SLinus Torvalds	 *
881da177e4SLinus Torvalds	 * Note that we use shadowed registers for temps until
891da177e4SLinus Torvalds	 * we can save %r26 and %r29. %r26 is used to preserve
901da177e4SLinus Torvalds	 * %r8 (a shadowed register) which temporarily contained
911da177e4SLinus Torvalds	 * either the fault type ("code") or the eirr. We need
921da177e4SLinus Torvalds	 * to use a non-shadowed register to carry the value over
931da177e4SLinus Torvalds	 * the rfir in virt_map. We use %r26 since this value winds
941da177e4SLinus Torvalds	 * up being passed as the argument to either do_cpu_irq_mask
951da177e4SLinus Torvalds	 * or handle_interruption. %r29 is used to hold a pointer
961da177e4SLinus Torvalds	 * the register save area, and once again, it needs to
971da177e4SLinus Torvalds	 * be a non-shadowed register so that it survives the rfir.
981da177e4SLinus Torvalds	 */
991da177e4SLinus Torvalds
1001da177e4SLinus Torvalds	.macro  get_stack_use_cr30
1011da177e4SLinus Torvalds
1021da177e4SLinus Torvalds	/* we save the registers in the task struct */
1031da177e4SLinus Torvalds
104b63a2bbcSJohn David Anglin	copy	%r30, %r17
1051da177e4SLinus Torvalds	mfctl   %cr30, %r1
1062214c0e7SHelge Deller	tophys  %r1,%r9		/* task_struct */
1072214c0e7SHelge Deller	LDREG	TASK_STACK(%r9),%r30
1082214c0e7SHelge Deller	ldo	PT_SZ_ALGN(%r30),%r30
1092214c0e7SHelge Deller	mtsp	%r0,%sr7	/* clear sr7 after kernel stack was set! */
110b63a2bbcSJohn David Anglin	mtsp	%r16,%sr3
1111da177e4SLinus Torvalds	ldo     TASK_REGS(%r9),%r9
112b63a2bbcSJohn David Anglin	STREG   %r17,PT_GR30(%r9)
1131da177e4SLinus Torvalds	STREG   %r29,PT_GR29(%r9)
1141da177e4SLinus Torvalds	STREG   %r26,PT_GR26(%r9)
115b63a2bbcSJohn David Anglin	STREG	%r16,PT_SR7(%r9)
1161da177e4SLinus Torvalds	copy    %r9,%r29
1171da177e4SLinus Torvalds	.endm
1181da177e4SLinus Torvalds
1191da177e4SLinus Torvalds	.macro  get_stack_use_r30
1201da177e4SLinus Torvalds
1211da177e4SLinus Torvalds	/* we put a struct pt_regs on the stack and save the registers there */
1221da177e4SLinus Torvalds
1231da177e4SLinus Torvalds	tophys  %r30,%r9
124b63a2bbcSJohn David Anglin	copy	%r30,%r1
1251da177e4SLinus Torvalds	ldo	PT_SZ_ALGN(%r30),%r30
126b63a2bbcSJohn David Anglin	STREG   %r1,PT_GR30(%r9)
1271da177e4SLinus Torvalds	STREG   %r29,PT_GR29(%r9)
1281da177e4SLinus Torvalds	STREG   %r26,PT_GR26(%r9)
129b63a2bbcSJohn David Anglin	STREG	%r16,PT_SR7(%r9)
1301da177e4SLinus Torvalds	copy    %r9,%r29
1311da177e4SLinus Torvalds	.endm
1321da177e4SLinus Torvalds
1331da177e4SLinus Torvalds	.macro  rest_stack
1341da177e4SLinus Torvalds	LDREG   PT_GR1(%r29), %r1
1351da177e4SLinus Torvalds	LDREG   PT_GR30(%r29),%r30
1361da177e4SLinus Torvalds	LDREG   PT_GR29(%r29),%r29
1371da177e4SLinus Torvalds	.endm
1381da177e4SLinus Torvalds
1391da177e4SLinus Torvalds	/* default interruption handler
1401da177e4SLinus Torvalds	 * (calls traps.c:handle_interruption) */
1411da177e4SLinus Torvalds	.macro	def code
1421da177e4SLinus Torvalds	b	intr_save
1431da177e4SLinus Torvalds	ldi     \code, %r8
1441da177e4SLinus Torvalds	.align	32
1451da177e4SLinus Torvalds	.endm
1461da177e4SLinus Torvalds
1471da177e4SLinus Torvalds	/* Interrupt interruption handler
1481da177e4SLinus Torvalds	 * (calls irq.c:do_cpu_irq_mask) */
1491da177e4SLinus Torvalds	.macro	extint code
1501da177e4SLinus Torvalds	b	intr_extint
1511da177e4SLinus Torvalds	mfsp    %sr7,%r16
1521da177e4SLinus Torvalds	.align	32
1531da177e4SLinus Torvalds	.endm
1541da177e4SLinus Torvalds
1551da177e4SLinus Torvalds	.import	os_hpmc, code
1561da177e4SLinus Torvalds
1571da177e4SLinus Torvalds	/* HPMC handler */
1581da177e4SLinus Torvalds	.macro	hpmc code
1591da177e4SLinus Torvalds	nop			/* must be a NOP, will be patched later */
1601da177e4SLinus Torvalds	load32	PA(os_hpmc), %r3
1611da177e4SLinus Torvalds	bv,n	0(%r3)
1621da177e4SLinus Torvalds	nop
1631da177e4SLinus Torvalds	.word	0		/* checksum (will be patched) */
1641138b671SJohn David Anglin	.word	0		/* address of handler */
1651da177e4SLinus Torvalds	.word	0		/* length of handler */
1661da177e4SLinus Torvalds	.endm
1671da177e4SLinus Torvalds
1681da177e4SLinus Torvalds	/*
1691da177e4SLinus Torvalds	 * Performance Note: Instructions will be moved up into
1701da177e4SLinus Torvalds	 * this part of the code later on, once we are sure
1711da177e4SLinus Torvalds	 * that the tlb miss handlers are close to final form.
1721da177e4SLinus Torvalds	 */
1731da177e4SLinus Torvalds
1741da177e4SLinus Torvalds	/* Register definitions for tlb miss handler macros */
1751da177e4SLinus Torvalds
17625985edcSLucas De Marchi	va  = r8	/* virtual address for which the trap occurred */
17725985edcSLucas De Marchi	spc = r24	/* space for which the trap occurred */
1781da177e4SLinus Torvalds
179413059f2SGrant Grundler#ifndef CONFIG_64BIT
1801da177e4SLinus Torvalds
1811da177e4SLinus Torvalds	/*
1821da177e4SLinus Torvalds	 * itlb miss interruption handler (parisc 1.1 - 32 bit)
1831da177e4SLinus Torvalds	 */
1841da177e4SLinus Torvalds
1851da177e4SLinus Torvalds	.macro	itlb_11 code
1861da177e4SLinus Torvalds
1871da177e4SLinus Torvalds	mfctl	%pcsq, spc
1881da177e4SLinus Torvalds	b	itlb_miss_11
1891da177e4SLinus Torvalds	mfctl	%pcoq, va
1901da177e4SLinus Torvalds
1911da177e4SLinus Torvalds	.align		32
1921da177e4SLinus Torvalds	.endm
1931da177e4SLinus Torvalds#endif
1941da177e4SLinus Torvalds
1951da177e4SLinus Torvalds	/*
1961da177e4SLinus Torvalds	 * itlb miss interruption handler (parisc 2.0)
1971da177e4SLinus Torvalds	 */
1981da177e4SLinus Torvalds
1991da177e4SLinus Torvalds	.macro	itlb_20 code
2001da177e4SLinus Torvalds	mfctl	%pcsq, spc
201413059f2SGrant Grundler#ifdef CONFIG_64BIT
2021da177e4SLinus Torvalds	b       itlb_miss_20w
2031da177e4SLinus Torvalds#else
2041da177e4SLinus Torvalds	b	itlb_miss_20
2051da177e4SLinus Torvalds#endif
2061da177e4SLinus Torvalds	mfctl	%pcoq, va
2071da177e4SLinus Torvalds
2081da177e4SLinus Torvalds	.align		32
2091da177e4SLinus Torvalds	.endm
2101da177e4SLinus Torvalds
211413059f2SGrant Grundler#ifndef CONFIG_64BIT
2121da177e4SLinus Torvalds	/*
2131da177e4SLinus Torvalds	 * naitlb miss interruption handler (parisc 1.1 - 32 bit)
2141da177e4SLinus Torvalds	 */
2151da177e4SLinus Torvalds
2161da177e4SLinus Torvalds	.macro	naitlb_11 code
2171da177e4SLinus Torvalds
2181da177e4SLinus Torvalds	mfctl	%isr,spc
219f311847cSJames Bottomley	b	naitlb_miss_11
2201da177e4SLinus Torvalds	mfctl 	%ior,va
2211da177e4SLinus Torvalds
2221da177e4SLinus Torvalds	.align		32
2231da177e4SLinus Torvalds	.endm
2241da177e4SLinus Torvalds#endif
2251da177e4SLinus Torvalds
2261da177e4SLinus Torvalds	/*
2271da177e4SLinus Torvalds	 * naitlb miss interruption handler (parisc 2.0)
2281da177e4SLinus Torvalds	 */
2291da177e4SLinus Torvalds
2301da177e4SLinus Torvalds	.macro	naitlb_20 code
2311da177e4SLinus Torvalds
2321da177e4SLinus Torvalds	mfctl	%isr,spc
233413059f2SGrant Grundler#ifdef CONFIG_64BIT
234f311847cSJames Bottomley	b       naitlb_miss_20w
2351da177e4SLinus Torvalds#else
236f311847cSJames Bottomley	b	naitlb_miss_20
2371da177e4SLinus Torvalds#endif
2381da177e4SLinus Torvalds	mfctl 	%ior,va
2391da177e4SLinus Torvalds
2401da177e4SLinus Torvalds	.align		32
2411da177e4SLinus Torvalds	.endm
2421da177e4SLinus Torvalds
243413059f2SGrant Grundler#ifndef CONFIG_64BIT
2441da177e4SLinus Torvalds	/*
2451da177e4SLinus Torvalds	 * dtlb miss interruption handler (parisc 1.1 - 32 bit)
2461da177e4SLinus Torvalds	 */
2471da177e4SLinus Torvalds
2481da177e4SLinus Torvalds	.macro	dtlb_11 code
2491da177e4SLinus Torvalds
2501da177e4SLinus Torvalds	mfctl	%isr, spc
2511da177e4SLinus Torvalds	b	dtlb_miss_11
2521da177e4SLinus Torvalds	mfctl	%ior, va
2531da177e4SLinus Torvalds
2541da177e4SLinus Torvalds	.align		32
2551da177e4SLinus Torvalds	.endm
2561da177e4SLinus Torvalds#endif
2571da177e4SLinus Torvalds
2581da177e4SLinus Torvalds	/*
2591da177e4SLinus Torvalds	 * dtlb miss interruption handler (parisc 2.0)
2601da177e4SLinus Torvalds	 */
2611da177e4SLinus Torvalds
2621da177e4SLinus Torvalds	.macro	dtlb_20 code
2631da177e4SLinus Torvalds
2641da177e4SLinus Torvalds	mfctl	%isr, spc
265413059f2SGrant Grundler#ifdef CONFIG_64BIT
2661da177e4SLinus Torvalds	b       dtlb_miss_20w
2671da177e4SLinus Torvalds#else
2681da177e4SLinus Torvalds	b	dtlb_miss_20
2691da177e4SLinus Torvalds#endif
2701da177e4SLinus Torvalds	mfctl	%ior, va
2711da177e4SLinus Torvalds
2721da177e4SLinus Torvalds	.align		32
2731da177e4SLinus Torvalds	.endm
2741da177e4SLinus Torvalds
275413059f2SGrant Grundler#ifndef CONFIG_64BIT
2761da177e4SLinus Torvalds	/* nadtlb miss interruption handler (parisc 1.1 - 32 bit) */
2771da177e4SLinus Torvalds
2781da177e4SLinus Torvalds	.macro	nadtlb_11 code
2791da177e4SLinus Torvalds
2801da177e4SLinus Torvalds	mfctl	%isr,spc
2811da177e4SLinus Torvalds	b       nadtlb_miss_11
2821da177e4SLinus Torvalds	mfctl	%ior,va
2831da177e4SLinus Torvalds
2841da177e4SLinus Torvalds	.align		32
2851da177e4SLinus Torvalds	.endm
2861da177e4SLinus Torvalds#endif
2871da177e4SLinus Torvalds
2881da177e4SLinus Torvalds	/* nadtlb miss interruption handler (parisc 2.0) */
2891da177e4SLinus Torvalds
2901da177e4SLinus Torvalds	.macro	nadtlb_20 code
2911da177e4SLinus Torvalds
2921da177e4SLinus Torvalds	mfctl	%isr,spc
293413059f2SGrant Grundler#ifdef CONFIG_64BIT
2941da177e4SLinus Torvalds	b       nadtlb_miss_20w
2951da177e4SLinus Torvalds#else
2961da177e4SLinus Torvalds	b       nadtlb_miss_20
2971da177e4SLinus Torvalds#endif
2981da177e4SLinus Torvalds	mfctl	%ior,va
2991da177e4SLinus Torvalds
3001da177e4SLinus Torvalds	.align		32
3011da177e4SLinus Torvalds	.endm
3021da177e4SLinus Torvalds
303413059f2SGrant Grundler#ifndef CONFIG_64BIT
3041da177e4SLinus Torvalds	/*
3051da177e4SLinus Torvalds	 * dirty bit trap interruption handler (parisc 1.1 - 32 bit)
3061da177e4SLinus Torvalds	 */
3071da177e4SLinus Torvalds
3081da177e4SLinus Torvalds	.macro	dbit_11 code
3091da177e4SLinus Torvalds
3101da177e4SLinus Torvalds	mfctl	%isr,spc
3111da177e4SLinus Torvalds	b	dbit_trap_11
3121da177e4SLinus Torvalds	mfctl	%ior,va
3131da177e4SLinus Torvalds
3141da177e4SLinus Torvalds	.align		32
3151da177e4SLinus Torvalds	.endm
3161da177e4SLinus Torvalds#endif
3171da177e4SLinus Torvalds
3181da177e4SLinus Torvalds	/*
3191da177e4SLinus Torvalds	 * dirty bit trap interruption handler (parisc 2.0)
3201da177e4SLinus Torvalds	 */
3211da177e4SLinus Torvalds
3221da177e4SLinus Torvalds	.macro	dbit_20 code
3231da177e4SLinus Torvalds
3241da177e4SLinus Torvalds	mfctl	%isr,spc
325413059f2SGrant Grundler#ifdef CONFIG_64BIT
3261da177e4SLinus Torvalds	b       dbit_trap_20w
3271da177e4SLinus Torvalds#else
3281da177e4SLinus Torvalds	b	dbit_trap_20
3291da177e4SLinus Torvalds#endif
3301da177e4SLinus Torvalds	mfctl	%ior,va
3311da177e4SLinus Torvalds
3321da177e4SLinus Torvalds	.align		32
3331da177e4SLinus Torvalds	.endm
3341da177e4SLinus Torvalds
3351da177e4SLinus Torvalds	/* In LP64, the space contains part of the upper 32 bits of the
3361da177e4SLinus Torvalds	 * fault.  We have to extract this and place it in the va,
3371da177e4SLinus Torvalds	 * zeroing the corresponding bits in the space register */
3381da177e4SLinus Torvalds	.macro		space_adjust	spc,va,tmp
339413059f2SGrant Grundler#ifdef CONFIG_64BIT
3401da177e4SLinus Torvalds	extrd,u		\spc,63,SPACEID_SHIFT,\tmp
3411da177e4SLinus Torvalds	depd		%r0,63,SPACEID_SHIFT,\spc
3421da177e4SLinus Torvalds	depd		\tmp,31,SPACEID_SHIFT,\va
3431da177e4SLinus Torvalds#endif
3441da177e4SLinus Torvalds	.endm
3451da177e4SLinus Torvalds
3461da177e4SLinus Torvalds	.import		swapper_pg_dir,code
3471da177e4SLinus Torvalds
3481da177e4SLinus Torvalds	/* Get the pgd.  For faults on space zero (kernel space), this
3491da177e4SLinus Torvalds	 * is simply swapper_pg_dir.  For user space faults, the
3501da177e4SLinus Torvalds	 * pgd is stored in %cr25 */
3511da177e4SLinus Torvalds	.macro		get_pgd		spc,reg
3521da177e4SLinus Torvalds	ldil		L%PA(swapper_pg_dir),\reg
3531da177e4SLinus Torvalds	ldo		R%PA(swapper_pg_dir)(\reg),\reg
3541da177e4SLinus Torvalds	or,COND(=)	%r0,\spc,%r0
3551da177e4SLinus Torvalds	mfctl		%cr25,\reg
3561da177e4SLinus Torvalds	.endm
3571da177e4SLinus Torvalds
3581da177e4SLinus Torvalds	/*
3591da177e4SLinus Torvalds		space_check(spc,tmp,fault)
3601da177e4SLinus Torvalds
3611da177e4SLinus Torvalds		spc - The space we saw the fault with.
3621da177e4SLinus Torvalds		tmp - The place to store the current space.
3631da177e4SLinus Torvalds		fault - Function to call on failure.
3641da177e4SLinus Torvalds
3651da177e4SLinus Torvalds		Only allow faults on different spaces from the
3661da177e4SLinus Torvalds		currently active one if we're the kernel
3671da177e4SLinus Torvalds
3681da177e4SLinus Torvalds	*/
3691da177e4SLinus Torvalds	.macro		space_check	spc,tmp,fault
3701da177e4SLinus Torvalds	mfsp		%sr7,\tmp
37187613bb9SHelge Deller	/* check against %r0 which is same value as LINUX_GATEWAY_SPACE */
3721da177e4SLinus Torvalds	or,COND(<>)	%r0,\spc,%r0	/* user may execute gateway page
3731da177e4SLinus Torvalds					 * as kernel, so defeat the space
3741da177e4SLinus Torvalds					 * check if it is */
3751da177e4SLinus Torvalds	copy		\spc,\tmp
3761da177e4SLinus Torvalds	or,COND(=)	%r0,\tmp,%r0	/* nullify if executing as kernel */
3771da177e4SLinus Torvalds	cmpb,COND(<>),n	\tmp,\spc,\fault
3781da177e4SLinus Torvalds	.endm
3791da177e4SLinus Torvalds
3801da177e4SLinus Torvalds	/* Look up a PTE in a 2-Level scheme (faulting at each
3811da177e4SLinus Torvalds	 * level if the entry isn't present
3821da177e4SLinus Torvalds	 *
3831da177e4SLinus Torvalds	 * NOTE: we use ldw even for LP64, since the short pointers
3841da177e4SLinus Torvalds	 * can address up to 1TB
3851da177e4SLinus Torvalds	 */
3861da177e4SLinus Torvalds	.macro		L2_ptep	pmd,pte,index,va,fault
387f24ffde4SKirill A. Shutemov#if CONFIG_PGTABLE_LEVELS == 3
3883fbdc121SHelge Deller	extru_safe	\va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index
3891da177e4SLinus Torvalds#else
3903fbdc121SHelge Deller	extru_safe	\va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
3916a45716aSHelge Deller#endif
3929b437bcaSJohn David Anglin	dep             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
393b7795074SHelge Deller#if CONFIG_PGTABLE_LEVELS < 3
3941da177e4SLinus Torvalds	copy		%r0,\pte
395b7795074SHelge Deller#endif
3961da177e4SLinus Torvalds	ldw,s		\index(\pmd),\pmd
3971da177e4SLinus Torvalds	bb,>=,n		\pmd,_PxD_PRESENT_BIT,\fault
3989b437bcaSJohn David Anglin	dep		%r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
39932c1ceeaSHelge Deller	SHLREG		\pmd,PxD_VALUE_SHIFT,\pmd
4003fbdc121SHelge Deller	extru_safe	\va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
4019b437bcaSJohn David Anglin	dep		%r0,31,PAGE_SHIFT,\pmd  /* clear offset */
40201ab6057SJohn David Anglin	shladd		\index,BITS_PER_PTE_ENTRY,\pmd,\pmd /* pmd is now pte */
4031da177e4SLinus Torvalds	.endm
4041da177e4SLinus Torvalds
405b7795074SHelge Deller	/* Look up PTE in a 3-Level scheme. */
4061da177e4SLinus Torvalds	.macro		L3_ptep pgd,pte,index,va,fault
407b7795074SHelge Deller#if CONFIG_PGTABLE_LEVELS == 3
408b7795074SHelge Deller	copy		%r0,\pte
4091da177e4SLinus Torvalds	extrd,u		\va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
4101da177e4SLinus Torvalds	ldw,s		\index(\pgd),\pgd
4111da177e4SLinus Torvalds	bb,>=,n		\pgd,_PxD_PRESENT_BIT,\fault
412b7795074SHelge Deller	shld		\pgd,PxD_VALUE_SHIFT,\pgd
4132fd83038SHelge Deller#endif
4141da177e4SLinus Torvalds	L2_ptep		\pgd,\pte,\index,\va,\fault
4151da177e4SLinus Torvalds	.endm
4161da177e4SLinus Torvalds
417b7795074SHelge Deller	/* Acquire page_table_lock and check page is present. */
418b7795074SHelge Deller	.macro		ptl_lock	spc,ptp,pte,tmp,tmp1,fault
419b7795074SHelge Deller#ifdef CONFIG_TLB_PTLOCK
4203847dab7SHelge Deller98:	cmpib,COND(=),n	0,\spc,2f
421b7795074SHelge Deller	get_ptl		\tmp
422f0a18819SJohn David Anglin1:	LDCW		0(\tmp),\tmp1
423f0a18819SJohn David Anglin	cmpib,COND(=)	0,\tmp1,1b
424f0a18819SJohn David Anglin	nop
42501ab6057SJohn David Anglin	LDREG		0(\ptp),\pte
42632a7901fSJohn David Anglin	bb,<,n		\pte,_PAGE_PRESENT_BIT,3f
42701ab6057SJohn David Anglin	b		\fault
4287a894c87SHelge Deller	stw		\tmp1,0(\tmp)
4293847dab7SHelge Deller99:	ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
430f0a18819SJohn David Anglin#endif
43132a7901fSJohn David Anglin2:	LDREG		0(\ptp),\pte
43232a7901fSJohn David Anglin	bb,>=,n		\pte,_PAGE_PRESENT_BIT,\fault
43332a7901fSJohn David Anglin3:
434f0a18819SJohn David Anglin	.endm
435f0a18819SJohn David Anglin
436c3b5552bSJohn David Anglin	/* Release page_table_lock if for user space. We use an ordered
437c3b5552bSJohn David Anglin	   store to ensure all prior accesses are performed prior to
438c3b5552bSJohn David Anglin	   releasing the lock. Note stw may not be executed, so we
439c3b5552bSJohn David Anglin	   provide one extra nop when CONFIG_TLB_PTLOCK is defined. */
440c3b5552bSJohn David Anglin	.macro		ptl_unlock	spc,tmp,tmp2
441b7795074SHelge Deller#ifdef CONFIG_TLB_PTLOCK
442c3b5552bSJohn David Anglin98:	get_ptl		\tmp
443c3b5552bSJohn David Anglin	ldi		__ARCH_SPIN_LOCK_UNLOCKED_VAL, \tmp2
4447a894c87SHelge Deller	or,COND(=)	%r0,\spc,%r0
4457a894c87SHelge Deller	stw,ma		\tmp2,0(\tmp)
4463847dab7SHelge Deller99:	ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
447c3b5552bSJohn David Anglin	insert_nops	NUM_PIPELINE_INSNS - 4
448c3b5552bSJohn David Anglin#else
449c3b5552bSJohn David Anglin	insert_nops	NUM_PIPELINE_INSNS - 1
450f0a18819SJohn David Anglin#endif
451f0a18819SJohn David Anglin	.endm
452f0a18819SJohn David Anglin
4531da177e4SLinus Torvalds	/* Set the _PAGE_ACCESSED bit of the PTE.  Be clever and
4541da177e4SLinus Torvalds	 * don't needlessly dirty the cache line if it was already set */
45501ab6057SJohn David Anglin	.macro		update_accessed	ptp,pte,tmp,tmp1
4561da177e4SLinus Torvalds	ldi		_PAGE_ACCESSED,\tmp1
4571da177e4SLinus Torvalds	or		\tmp1,\pte,\tmp
4581da177e4SLinus Torvalds	and,COND(<>)	\tmp1,\pte,%r0
45901ab6057SJohn David Anglin	STREG		\tmp,0(\ptp)
4601da177e4SLinus Torvalds	.endm
4611da177e4SLinus Torvalds
4621da177e4SLinus Torvalds	/* Set the dirty bit (and accessed bit).  No need to be
4631da177e4SLinus Torvalds	 * clever, this is only used from the dirty fault */
46401ab6057SJohn David Anglin	.macro		update_dirty	ptp,pte,tmp
4651da177e4SLinus Torvalds	ldi		_PAGE_ACCESSED|_PAGE_DIRTY,\tmp
4661da177e4SLinus Torvalds	or		\tmp,\pte,\pte
46701ab6057SJohn David Anglin	STREG		\pte,0(\ptp)
4681da177e4SLinus Torvalds	.endm
4691da177e4SLinus Torvalds
470736d2169SHelge Deller	/* We have (depending on the page size):
471736d2169SHelge Deller	 * - 38 to 52-bit Physical Page Number
472736d2169SHelge Deller	 * - 12 to 26-bit page offset
473736d2169SHelge Deller	 */
474afca2523SHelge Deller	/* bitshift difference between a PFN (based on kernel's PAGE_SIZE)
475afca2523SHelge Deller	 * to a CPU TLB 4k PFN (4k => 12 bits to shift) */
476afca2523SHelge Deller	#define PAGE_ADD_SHIFT		(PAGE_SHIFT-12)
477736d2169SHelge Deller	#define PAGE_ADD_HUGE_SHIFT	(REAL_HPAGE_SHIFT-12)
4785ff2daf7SHelge Deller	#define PFN_START_BIT	(63-ASM_PFN_PTE_SHIFT+(63-58)-PAGE_ADD_SHIFT)
479afca2523SHelge Deller
480afca2523SHelge Deller	/* Drop prot bits and convert to page addr for iitlbt and idtlbt */
481736d2169SHelge Deller	.macro		convert_for_tlb_insert20 pte,tmp
482736d2169SHelge Deller#ifdef CONFIG_HUGETLB_PAGE
483736d2169SHelge Deller	copy		\pte,\tmp
4845ff2daf7SHelge Deller	extrd,u		\tmp,PFN_START_BIT,PFN_START_BIT+1,\pte
485736d2169SHelge Deller
486736d2169SHelge Deller	depdi		_PAGE_SIZE_ENCODING_DEFAULT,63,\
487736d2169SHelge Deller				(63-58)+PAGE_ADD_SHIFT,\pte
488736d2169SHelge Deller	extrd,u,*=	\tmp,_PAGE_HPAGE_BIT+32,1,%r0
489736d2169SHelge Deller	depdi		_HUGE_PAGE_SIZE_ENCODING_DEFAULT,63,\
490736d2169SHelge Deller				(63-58)+PAGE_ADD_HUGE_SHIFT,\pte
491736d2169SHelge Deller#else /* Huge pages disabled */
4925ff2daf7SHelge Deller	extrd,u		\pte,PFN_START_BIT,PFN_START_BIT+1,\pte
493afca2523SHelge Deller	depdi		_PAGE_SIZE_ENCODING_DEFAULT,63,\
494afca2523SHelge Deller				(63-58)+PAGE_ADD_SHIFT,\pte
495736d2169SHelge Deller#endif
496afca2523SHelge Deller	.endm
497afca2523SHelge Deller
4981da177e4SLinus Torvalds	/* Convert the pte and prot to tlb insertion values.  How
4991da177e4SLinus Torvalds	 * this happens is quite subtle, read below */
500736d2169SHelge Deller	.macro		make_insert_tlb	spc,pte,prot,tmp
5011da177e4SLinus Torvalds	space_to_prot   \spc \prot        /* create prot id from space */
5021da177e4SLinus Torvalds	/* The following is the real subtlety.  This is depositing
5031da177e4SLinus Torvalds	 * T <-> _PAGE_REFTRAP
5041da177e4SLinus Torvalds	 * D <-> _PAGE_DIRTY
5051da177e4SLinus Torvalds	 * B <-> _PAGE_DMB (memory break)
5061da177e4SLinus Torvalds	 *
5071da177e4SLinus Torvalds	 * Then incredible subtlety: The access rights are
5081c4c6597SJohn David Anglin	 * _PAGE_GATEWAY, _PAGE_EXEC and _PAGE_WRITE
5091da177e4SLinus Torvalds	 * See 3-14 of the parisc 2.0 manual
5101da177e4SLinus Torvalds	 *
5111da177e4SLinus Torvalds	 * Finally, _PAGE_READ goes in the top bit of PL1 (so we
5121da177e4SLinus Torvalds	 * trigger an access rights trap in user space if the user
5131da177e4SLinus Torvalds	 * tries to read an unreadable page */
51470be49f2SHelge Deller#if _PAGE_SPECIAL_BIT == _PAGE_DMB_BIT
51570be49f2SHelge Deller	/* need to drop DMB bit, as it's used as SPECIAL flag */
51670be49f2SHelge Deller	depi		0,_PAGE_SPECIAL_BIT,1,\pte
51770be49f2SHelge Deller#endif
5181da177e4SLinus Torvalds	depd            \pte,8,7,\prot
5191da177e4SLinus Torvalds
5201da177e4SLinus Torvalds	/* PAGE_USER indicates the page can be read with user privileges,
5211da177e4SLinus Torvalds	 * so deposit X1|11 to PL1|PL2 (remember the upper bit of PL1
5221c4c6597SJohn David Anglin	 * contains _PAGE_READ) */
5231da177e4SLinus Torvalds	extrd,u,*=      \pte,_PAGE_USER_BIT+32,1,%r0
5241da177e4SLinus Torvalds	depdi		7,11,3,\prot
5251da177e4SLinus Torvalds	/* If we're a gateway page, drop PL2 back to zero for promotion
5261da177e4SLinus Torvalds	 * to kernel privilege (so we can execute the page as kernel).
5271da177e4SLinus Torvalds	 * Any privilege promotion page always denys read and write */
5281da177e4SLinus Torvalds	extrd,u,*= 	\pte,_PAGE_GATEWAY_BIT+32,1,%r0
5291da177e4SLinus Torvalds	depd		%r0,11,2,\prot	/* If Gateway, Set PL2 to 0 */
5301da177e4SLinus Torvalds
5312fd83038SHelge Deller	/* Enforce uncacheable pages.
5322fd83038SHelge Deller	 * This should ONLY be use for MMIO on PA 2.0 machines.
5332fd83038SHelge Deller	 * Memory/DMA is cache coherent on all PA2.0 machines we support
5342fd83038SHelge Deller	 * (that means T-class is NOT supported) and the memory controllers
5352fd83038SHelge Deller	 * on most of those machines only handles cache transactions.
5362fd83038SHelge Deller	 */
5372fd83038SHelge Deller	extrd,u,*=	\pte,_PAGE_NO_CACHE_BIT+32,1,%r0
5382678251bSJohn David Anglin	depdi		1,12,1,\prot
5391da177e4SLinus Torvalds
5402fd83038SHelge Deller	/* Drop prot bits and convert to page addr for iitlbt and idtlbt */
541736d2169SHelge Deller	convert_for_tlb_insert20 \pte \tmp
5421da177e4SLinus Torvalds	.endm
5431da177e4SLinus Torvalds
5441da177e4SLinus Torvalds	/* Identical macro to make_insert_tlb above, except it
5451da177e4SLinus Torvalds	 * makes the tlb entry for the differently formatted pa11
5461da177e4SLinus Torvalds	 * insertion instructions */
5471da177e4SLinus Torvalds	.macro		make_insert_tlb_11	spc,pte,prot
54870be49f2SHelge Deller#if _PAGE_SPECIAL_BIT == _PAGE_DMB_BIT
54970be49f2SHelge Deller	/* need to drop DMB bit, as it's used as SPECIAL flag */
55070be49f2SHelge Deller	depi		0,_PAGE_SPECIAL_BIT,1,\pte
55170be49f2SHelge Deller#endif
5521da177e4SLinus Torvalds	zdep		\spc,30,15,\prot
5531da177e4SLinus Torvalds	dep		\pte,8,7,\prot
5541da177e4SLinus Torvalds	extru,=		\pte,_PAGE_NO_CACHE_BIT,1,%r0
5551da177e4SLinus Torvalds	depi		1,12,1,\prot
5561da177e4SLinus Torvalds	extru,=         \pte,_PAGE_USER_BIT,1,%r0
5571da177e4SLinus Torvalds	depi		7,11,3,\prot   /* Set for user space (1 rsvd for read) */
5581da177e4SLinus Torvalds	extru,= 	\pte,_PAGE_GATEWAY_BIT,1,%r0
5591da177e4SLinus Torvalds	depi		0,11,2,\prot	/* If Gateway, Set PL2 to 0 */
5601da177e4SLinus Torvalds
5611da177e4SLinus Torvalds	/* Get rid of prot bits and convert to page addr for iitlba */
5621da177e4SLinus Torvalds
5631152a68cSHelge Deller	depi		0,31,ASM_PFN_PTE_SHIFT,\pte
5641152a68cSHelge Deller	SHRREG		\pte,(ASM_PFN_PTE_SHIFT-(31-26)),\pte
5651da177e4SLinus Torvalds	.endm
5661da177e4SLinus Torvalds
5671da177e4SLinus Torvalds	/* This is for ILP32 PA2.0 only.  The TLB insertion needs
5681da177e4SLinus Torvalds	 * to extend into I/O space if the address is 0xfXXXXXXX
5691da177e4SLinus Torvalds	 * so we extend the f's into the top word of the pte in
5701da177e4SLinus Torvalds	 * this case */
5711da177e4SLinus Torvalds	.macro		f_extend	pte,tmp
5721da177e4SLinus Torvalds	extrd,s		\pte,42,4,\tmp
5731da177e4SLinus Torvalds	addi,<>		1,\tmp,%r0
5741da177e4SLinus Torvalds	extrd,s		\pte,63,25,\pte
5751da177e4SLinus Torvalds	.endm
5761da177e4SLinus Torvalds
577c64c782eSJohn David Anglin	/* The alias region is comprised of a pair of 4 MB regions
578c64c782eSJohn David Anglin	 * aligned to 8 MB. It is used to clear/copy/flush user pages
579c64c782eSJohn David Anglin	 * using kernel virtual addresses congruent with the user
5801da177e4SLinus Torvalds	 * virtual address.
5811da177e4SLinus Torvalds	 *
5821da177e4SLinus Torvalds	 * To use the alias page, you set %r26 up with the to TLB
5831da177e4SLinus Torvalds	 * entry (identifying the physical page) and %r23 up with
5841da177e4SLinus Torvalds	 * the from tlb entry (or nothing if only a to entry---for
5851da177e4SLinus Torvalds	 * clear_user_page_asm) */
5862f649c1fSJames Bottomley	.macro		do_alias	spc,tmp,tmp1,va,pte,prot,fault,patype
5871da177e4SLinus Torvalds	cmpib,COND(<>),n 0,\spc,\fault
5881da177e4SLinus Torvalds	ldil		L%(TMPALIAS_MAP_START),\tmp
5891da177e4SLinus Torvalds	copy		\va,\tmp1
590c64c782eSJohn David Anglin	depi_safe	0,31,TMPALIAS_SIZE_BITS+1,\tmp1
5911da177e4SLinus Torvalds	cmpb,COND(<>),n	\tmp,\tmp1,\fault
592f311847cSJames Bottomley	mfctl		%cr19,\tmp	/* iir */
593f311847cSJames Bottomley	/* get the opcode (first six bits) into \tmp */
594f311847cSJames Bottomley	extrw,u		\tmp,5,6,\tmp
595f311847cSJames Bottomley	/*
596f311847cSJames Bottomley	 * Only setting the T bit prevents data cache movein
597f311847cSJames Bottomley	 * Setting access rights to zero prevents instruction cache movein
598f311847cSJames Bottomley	 *
599f311847cSJames Bottomley	 * Note subtlety here: _PAGE_GATEWAY, _PAGE_EXEC and _PAGE_WRITE go
600f311847cSJames Bottomley	 * to type field and _PAGE_READ goes to top bit of PL1
601f311847cSJames Bottomley	 */
602f311847cSJames Bottomley	ldi		(_PAGE_REFTRAP|_PAGE_READ|_PAGE_WRITE),\prot
603f311847cSJames Bottomley	/*
604f311847cSJames Bottomley	 * so if the opcode is one (i.e. this is a memory management
605f311847cSJames Bottomley	 * instruction) nullify the next load so \prot is only T.
606f311847cSJames Bottomley	 * Otherwise this is a normal data operation
607f311847cSJames Bottomley	 */
608f311847cSJames Bottomley	cmpiclr,=	0x01,\tmp,%r0
609f311847cSJames Bottomley	ldi		(_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot
6102f649c1fSJames Bottomley.ifc \patype,20
6111da177e4SLinus Torvalds	depd,z		\prot,8,7,\prot
6122f649c1fSJames Bottomley.else
6132f649c1fSJames Bottomley.ifc \patype,11
6145e185581SJames Bottomley	depw,z		\prot,8,7,\prot
6152f649c1fSJames Bottomley.else
6162f649c1fSJames Bottomley	.error "undefined PA type to do_alias"
6172f649c1fSJames Bottomley.endif
6182f649c1fSJames Bottomley.endif
6191da177e4SLinus Torvalds	/*
6201da177e4SLinus Torvalds	 * OK, it is in the temp alias region, check whether "from" or "to".
6211da177e4SLinus Torvalds	 * Check "subtle" note in pacache.S re: r23/r26.
6221da177e4SLinus Torvalds	 */
623c64c782eSJohn David Anglin	extrw,u,=	\va,31-TMPALIAS_SIZE_BITS,1,%r0
6241da177e4SLinus Torvalds	or,COND(tr)	%r23,%r0,\pte
6251da177e4SLinus Torvalds	or		%r26,%r0,\pte
626c1770918SHelge Deller
627c1770918SHelge Deller	/* convert phys addr in \pte (from r23 or r26) to tlb insert format */
628c1770918SHelge Deller	SHRREG		\pte,PAGE_SHIFT+PAGE_ADD_SHIFT-5, \pte
629c1770918SHelge Deller	depi_safe	_PAGE_SIZE_ENCODING_DEFAULT, 31,5, \pte
6301da177e4SLinus Torvalds	.endm
6311da177e4SLinus Torvalds
6321da177e4SLinus Torvalds
6331da177e4SLinus Torvalds	/*
6344182d0cdSHelge Deller	 * Fault_vectors are architecturally required to be aligned on a 2K
6354182d0cdSHelge Deller	 * boundary
6361da177e4SLinus Torvalds	 */
6371da177e4SLinus Torvalds
6384df3c9ecSHelge Deller	.section .text.hot
6394182d0cdSHelge Deller	.align 2048
6401da177e4SLinus Torvalds
641c5e76552SHelge DellerENTRY(fault_vector_20)
6421da177e4SLinus Torvalds	/* First vector is invalid (0) */
6431da177e4SLinus Torvalds	.ascii	"cows can fly"
6441da177e4SLinus Torvalds	.byte 0
6451da177e4SLinus Torvalds	.align 32
6461da177e4SLinus Torvalds
6471da177e4SLinus Torvalds	hpmc		 1
6481da177e4SLinus Torvalds	def		 2
6491da177e4SLinus Torvalds	def		 3
6501da177e4SLinus Torvalds	extint		 4
6511da177e4SLinus Torvalds	def		 5
6525b00ca0bSHelge Deller	itlb_20		 PARISC_ITLB_TRAP
6531da177e4SLinus Torvalds	def		 7
6541da177e4SLinus Torvalds	def		 8
6551da177e4SLinus Torvalds	def              9
6561da177e4SLinus Torvalds	def		10
6571da177e4SLinus Torvalds	def		11
6581da177e4SLinus Torvalds	def		12
6591da177e4SLinus Torvalds	def		13
6601da177e4SLinus Torvalds	def		14
6611da177e4SLinus Torvalds	dtlb_20		15
6621da177e4SLinus Torvalds	naitlb_20	16
6631da177e4SLinus Torvalds	nadtlb_20	17
6641da177e4SLinus Torvalds	def		18
6651da177e4SLinus Torvalds	def		19
6661da177e4SLinus Torvalds	dbit_20		20
6671da177e4SLinus Torvalds	def		21
6681da177e4SLinus Torvalds	def		22
6691da177e4SLinus Torvalds	def		23
6701da177e4SLinus Torvalds	def		24
6711da177e4SLinus Torvalds	def		25
6721da177e4SLinus Torvalds	def		26
6731da177e4SLinus Torvalds	def		27
6741da177e4SLinus Torvalds	def		28
6751da177e4SLinus Torvalds	def		29
6761da177e4SLinus Torvalds	def		30
6771da177e4SLinus Torvalds	def		31
678c5e76552SHelge DellerEND(fault_vector_20)
6791da177e4SLinus Torvalds
680413059f2SGrant Grundler#ifndef CONFIG_64BIT
6811da177e4SLinus Torvalds
6821da177e4SLinus Torvalds	.align 2048
6831da177e4SLinus Torvalds
684c5e76552SHelge DellerENTRY(fault_vector_11)
6851da177e4SLinus Torvalds	/* First vector is invalid (0) */
6861da177e4SLinus Torvalds	.ascii	"cows can fly"
6871da177e4SLinus Torvalds	.byte 0
6881da177e4SLinus Torvalds	.align 32
6891da177e4SLinus Torvalds
6901da177e4SLinus Torvalds	hpmc		 1
6911da177e4SLinus Torvalds	def		 2
6921da177e4SLinus Torvalds	def		 3
6931da177e4SLinus Torvalds	extint		 4
6941da177e4SLinus Torvalds	def		 5
6955b00ca0bSHelge Deller	itlb_11		 PARISC_ITLB_TRAP
6961da177e4SLinus Torvalds	def		 7
6971da177e4SLinus Torvalds	def		 8
6981da177e4SLinus Torvalds	def              9
6991da177e4SLinus Torvalds	def		10
7001da177e4SLinus Torvalds	def		11
7011da177e4SLinus Torvalds	def		12
7021da177e4SLinus Torvalds	def		13
7031da177e4SLinus Torvalds	def		14
7041da177e4SLinus Torvalds	dtlb_11		15
7051da177e4SLinus Torvalds	naitlb_11	16
7061da177e4SLinus Torvalds	nadtlb_11	17
7071da177e4SLinus Torvalds	def		18
7081da177e4SLinus Torvalds	def		19
7091da177e4SLinus Torvalds	dbit_11		20
7101da177e4SLinus Torvalds	def		21
7111da177e4SLinus Torvalds	def		22
7121da177e4SLinus Torvalds	def		23
7131da177e4SLinus Torvalds	def		24
7141da177e4SLinus Torvalds	def		25
7151da177e4SLinus Torvalds	def		26
7161da177e4SLinus Torvalds	def		27
7171da177e4SLinus Torvalds	def		28
7181da177e4SLinus Torvalds	def		29
7191da177e4SLinus Torvalds	def		30
7201da177e4SLinus Torvalds	def		31
721c5e76552SHelge DellerEND(fault_vector_11)
7221da177e4SLinus Torvalds
7231da177e4SLinus Torvalds#endif
724d7dd2ff1SJames Bottomley	/* Fault vector is separately protected and *must* be on its own page */
725d7dd2ff1SJames Bottomley	.align		PAGE_SIZE
7261da177e4SLinus Torvalds
7271da177e4SLinus Torvalds	.import		handle_interruption,code
7281da177e4SLinus Torvalds	.import		do_cpu_irq_mask,code
7291da177e4SLinus Torvalds
7301da177e4SLinus Torvalds	/*
7311da177e4SLinus Torvalds	 * Child Returns here
7321da177e4SLinus Torvalds	 *
733a44e060fSAl Viro	 * copy_thread moved args into task save area.
7341da177e4SLinus Torvalds	 */
7351da177e4SLinus Torvalds
7368801ccb9SHelge DellerENTRY(ret_from_kernel_thread)
7371da177e4SLinus Torvalds	/* Call schedule_tail first though */
7381da177e4SLinus Torvalds	BL	schedule_tail, %r2
7391da177e4SLinus Torvalds	nop
7401da177e4SLinus Torvalds
7412214c0e7SHelge Deller	mfctl	%cr30,%r1	/* task_struct */
7421da177e4SLinus Torvalds	LDREG	TASK_PT_GR25(%r1), %r26
743413059f2SGrant Grundler#ifdef CONFIG_64BIT
7441da177e4SLinus Torvalds	LDREG	TASK_PT_GR27(%r1), %r27
7451da177e4SLinus Torvalds#endif
7461da177e4SLinus Torvalds	LDREG	TASK_PT_GR26(%r1), %r1
7471da177e4SLinus Torvalds	ble	0(%sr7, %r1)
7481da177e4SLinus Torvalds	copy	%r31, %r2
749363806ddSAl Viro	b	finish_child_return
750363806ddSAl Viro	nop
7518801ccb9SHelge DellerEND(ret_from_kernel_thread)
7521da177e4SLinus Torvalds
7531da177e4SLinus Torvalds
7541da177e4SLinus Torvalds	/*
7551da177e4SLinus Torvalds	 * struct task_struct *_switch_to(struct task_struct *prev,
7561da177e4SLinus Torvalds	 *	struct task_struct *next)
7571da177e4SLinus Torvalds	 *
7581da177e4SLinus Torvalds	 * switch kernel stacks and return prev */
759f39cce65SHelge DellerENTRY_CFI(_switch_to)
7601da177e4SLinus Torvalds	STREG	 %r2, -RP_OFFSET(%r30)
7611da177e4SLinus Torvalds
762618febd6SJames Bottomley	callee_save_float
7631da177e4SLinus Torvalds	callee_save
7641da177e4SLinus Torvalds
7651da177e4SLinus Torvalds	load32	_switch_to_ret, %r2
7661da177e4SLinus Torvalds
7671da177e4SLinus Torvalds	STREG	%r2, TASK_PT_KPC(%r26)
7681da177e4SLinus Torvalds	LDREG	TASK_PT_KPC(%r25), %r2
7691da177e4SLinus Torvalds
7701da177e4SLinus Torvalds	STREG	%r30, TASK_PT_KSP(%r26)
7711da177e4SLinus Torvalds	LDREG	TASK_PT_KSP(%r25), %r30
7721da177e4SLinus Torvalds	bv	%r0(%r2)
7731da177e4SLinus Torvalds	mtctl   %r25,%cr30
7741da177e4SLinus Torvalds
7758801ccb9SHelge DellerENTRY(_switch_to_ret)
7761da177e4SLinus Torvalds	mtctl	%r0, %cr0		/* Needed for single stepping */
7771da177e4SLinus Torvalds	callee_rest
778618febd6SJames Bottomley	callee_rest_float
7791da177e4SLinus Torvalds
7801da177e4SLinus Torvalds	LDREG	-RP_OFFSET(%r30), %r2
7811da177e4SLinus Torvalds	bv	%r0(%r2)
7821da177e4SLinus Torvalds	copy	%r26, %r28
7838801ccb9SHelge DellerENDPROC_CFI(_switch_to)
7841da177e4SLinus Torvalds
7851da177e4SLinus Torvalds	/*
7861da177e4SLinus Torvalds	 * Common rfi return path for interruptions, kernel execve, and
7871da177e4SLinus Torvalds	 * sys_rt_sigreturn (sometimes).  The sys_rt_sigreturn syscall will
7881da177e4SLinus Torvalds	 * return via this path if the signal was received when the process
7891da177e4SLinus Torvalds	 * was running; if the process was blocked on a syscall then the
7901da177e4SLinus Torvalds	 * normal syscall_exit path is used.  All syscalls for traced
7911da177e4SLinus Torvalds	 * proceses exit via intr_restore.
7921da177e4SLinus Torvalds	 *
7931da177e4SLinus Torvalds	 * XXX If any syscalls that change a processes space id ever exit
7941da177e4SLinus Torvalds	 * this way, then we will need to copy %sr3 in to PT_SR[3..7], and
7951da177e4SLinus Torvalds	 * adjust IASQ[0..1].
7961da177e4SLinus Torvalds	 *
7971da177e4SLinus Torvalds	 */
7981da177e4SLinus Torvalds
799873d50e2SKyle McMartin	.align	PAGE_SIZE
8001da177e4SLinus Torvalds
801f39cce65SHelge DellerENTRY_CFI(syscall_exit_rfi)
8022214c0e7SHelge Deller	mfctl	%cr30,%r16		/* task_struct */
8031da177e4SLinus Torvalds	ldo	TASK_REGS(%r16),%r16
8041da177e4SLinus Torvalds	/* Force iaoq to userspace, as the user has had access to our current
8051da177e4SLinus Torvalds	 * context via sigcontext. Also Filter the PSW for the same reason.
8061da177e4SLinus Torvalds	 */
8071da177e4SLinus Torvalds	LDREG	PT_IAOQ0(%r16),%r19
808f06d6e92SHelge Deller	depi	PRIV_USER,31,2,%r19
8091da177e4SLinus Torvalds	STREG	%r19,PT_IAOQ0(%r16)
8101da177e4SLinus Torvalds	LDREG	PT_IAOQ1(%r16),%r19
811f06d6e92SHelge Deller	depi	PRIV_USER,31,2,%r19
8121da177e4SLinus Torvalds	STREG	%r19,PT_IAOQ1(%r16)
8131da177e4SLinus Torvalds	LDREG   PT_PSW(%r16),%r19
8141da177e4SLinus Torvalds	load32	USER_PSW_MASK,%r1
815413059f2SGrant Grundler#ifdef CONFIG_64BIT
8161da177e4SLinus Torvalds	load32	USER_PSW_HI_MASK,%r20
8171da177e4SLinus Torvalds	depd    %r20,31,32,%r1
8181da177e4SLinus Torvalds#endif
8191da177e4SLinus Torvalds	and     %r19,%r1,%r19 /* Mask out bits that user shouldn't play with */
8201da177e4SLinus Torvalds	load32	USER_PSW,%r1
8211da177e4SLinus Torvalds	or      %r19,%r1,%r19 /* Make sure default USER_PSW bits are set */
8221da177e4SLinus Torvalds	STREG   %r19,PT_PSW(%r16)
8231da177e4SLinus Torvalds
8241da177e4SLinus Torvalds	/*
8251da177e4SLinus Torvalds	 * If we aren't being traced, we never saved space registers
8261da177e4SLinus Torvalds	 * (we don't store them in the sigcontext), so set them
8271da177e4SLinus Torvalds	 * to "proper" values now (otherwise we'll wind up restoring
8281da177e4SLinus Torvalds	 * whatever was last stored in the task structure, which might
82925985edcSLucas De Marchi	 * be inconsistent if an interrupt occurred while on the gateway
8304b3f686dSMatt LaPlante	 * page). Note that we may be "trashing" values the user put in
8314b3f686dSMatt LaPlante	 * them, but we don't support the user changing them.
8321da177e4SLinus Torvalds	 */
8331da177e4SLinus Torvalds
8341da177e4SLinus Torvalds	STREG   %r0,PT_SR2(%r16)
8351da177e4SLinus Torvalds	mfsp    %sr3,%r19
8361da177e4SLinus Torvalds	STREG   %r19,PT_SR0(%r16)
8371da177e4SLinus Torvalds	STREG   %r19,PT_SR1(%r16)
8381da177e4SLinus Torvalds	STREG   %r19,PT_SR3(%r16)
8391da177e4SLinus Torvalds	STREG   %r19,PT_SR4(%r16)
8401da177e4SLinus Torvalds	STREG   %r19,PT_SR5(%r16)
8411da177e4SLinus Torvalds	STREG   %r19,PT_SR6(%r16)
8421da177e4SLinus Torvalds	STREG   %r19,PT_SR7(%r16)
8431da177e4SLinus Torvalds
8448801ccb9SHelge DellerENTRY(intr_return)
8451da177e4SLinus Torvalds	/* check for reschedule */
8461da177e4SLinus Torvalds	mfctl   %cr30,%r1
8472214c0e7SHelge Deller	LDREG   TASK_TI_FLAGS(%r1),%r19	/* sched.h: TIF_NEED_RESCHED */
8481da177e4SLinus Torvalds	bb,<,n	%r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */
8491da177e4SLinus Torvalds
8504650f0a5SKyle McMartin	.import do_notify_resume,code
8511da177e4SLinus Torvaldsintr_check_sig:
8521da177e4SLinus Torvalds	/* As above */
8531da177e4SLinus Torvalds	mfctl   %cr30,%r1
8542214c0e7SHelge Deller	LDREG	TASK_TI_FLAGS(%r1),%r19
855c984baadSHelge Deller	ldi	(_TIF_USER_WORK_MASK & ~_TIF_NEED_RESCHED), %r20
8564650f0a5SKyle McMartin	and,COND(<>)	%r19, %r20, %r0
8574650f0a5SKyle McMartin	b,n	intr_restore	/* skip past if we've nothing to do */
8584650f0a5SKyle McMartin
8594650f0a5SKyle McMartin	/* This check is critical to having LWS
8604650f0a5SKyle McMartin	 * working. The IASQ is zero on the gateway
8614650f0a5SKyle McMartin	 * page and we cannot deliver any signals until
8624650f0a5SKyle McMartin	 * we get off the gateway page.
8634650f0a5SKyle McMartin	 *
8644650f0a5SKyle McMartin	 * Only do signals if we are returning to user space
8654650f0a5SKyle McMartin	 */
8664650f0a5SKyle McMartin	LDREG	PT_IASQ0(%r16), %r20
8674df82ce7SJohn David Anglin	cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* forward */
8684650f0a5SKyle McMartin	LDREG	PT_IASQ1(%r16), %r20
8694df82ce7SJohn David Anglin	cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* forward */
8709352aeadSJohn David Anglin
8714650f0a5SKyle McMartin	copy	%r0, %r25			/* long in_syscall = 0 */
8724650f0a5SKyle McMartin#ifdef CONFIG_64BIT
8734650f0a5SKyle McMartin	ldo	-16(%r30),%r29			/* Reference param save area */
8744650f0a5SKyle McMartin#endif
8754650f0a5SKyle McMartin
8764df82ce7SJohn David Anglin	/* NOTE: We need to enable interrupts if we have to deliver
8774df82ce7SJohn David Anglin	 * signals. We used to do this earlier but it caused kernel
8784df82ce7SJohn David Anglin	 * stack overflows. */
8794df82ce7SJohn David Anglin	ssm	PSW_SM_I, %r0
8804df82ce7SJohn David Anglin
8814650f0a5SKyle McMartin	BL	do_notify_resume,%r2
8824650f0a5SKyle McMartin	copy	%r16, %r26			/* struct pt_regs *regs */
8834650f0a5SKyle McMartin
8843fe4c55eSHelge Deller	b,n	intr_check_sig
8851da177e4SLinus Torvalds
8861da177e4SLinus Torvaldsintr_restore:
8871da177e4SLinus Torvalds	copy            %r16,%r29
8881da177e4SLinus Torvalds	ldo             PT_FR31(%r29),%r1
8891da177e4SLinus Torvalds	rest_fp         %r1
8901da177e4SLinus Torvalds	rest_general    %r29
8911da177e4SLinus Torvalds
892896a3756SGrant Grundler	/* inverse of virt_map */
893896a3756SGrant Grundler	pcxt_ssm_bug
894896a3756SGrant Grundler	rsm             PSW_SM_QUIET,%r0	/* prepare for rfi */
8951da177e4SLinus Torvalds	tophys_r1       %r29
8961da177e4SLinus Torvalds
8971da177e4SLinus Torvalds	/* Restore space id's and special cr's from PT_REGS
898896a3756SGrant Grundler	 * structure pointed to by r29
899896a3756SGrant Grundler	 */
9001da177e4SLinus Torvalds	rest_specials	%r29
9011da177e4SLinus Torvalds
902896a3756SGrant Grundler	/* IMPORTANT: rest_stack restores r29 last (we are using it)!
903896a3756SGrant Grundler	 * It also restores r1 and r30.
904896a3756SGrant Grundler	 */
9051da177e4SLinus Torvalds	rest_stack
9061da177e4SLinus Torvalds
9071da177e4SLinus Torvalds	rfi
9081da177e4SLinus Torvalds	nop
9091da177e4SLinus Torvalds
91009613e83SThomas Gleixner#ifndef CONFIG_PREEMPTION
91150a34dbdSKyle McMartin# define intr_do_preempt	intr_restore
91209613e83SThomas Gleixner#endif /* !CONFIG_PREEMPTION */
91350a34dbdSKyle McMartin
9141da177e4SLinus Torvalds	.import schedule,code
9151da177e4SLinus Torvaldsintr_do_resched:
91650a34dbdSKyle McMartin	/* Only call schedule on return to userspace. If we're returning
91709613e83SThomas Gleixner	 * to kernel space, we may schedule if CONFIG_PREEMPTION, otherwise
91850a34dbdSKyle McMartin	 * we jump back to intr_restore.
91950a34dbdSKyle McMartin	 */
9201da177e4SLinus Torvalds	LDREG	PT_IASQ0(%r16), %r20
921872f6debSKyle McMartin	cmpib,COND(=)	0, %r20, intr_do_preempt
9221da177e4SLinus Torvalds	nop
9231da177e4SLinus Torvalds	LDREG	PT_IASQ1(%r16), %r20
924872f6debSKyle McMartin	cmpib,COND(=)	0, %r20, intr_do_preempt
9251da177e4SLinus Torvalds	nop
9261da177e4SLinus Torvalds
9279352aeadSJohn David Anglin	/* NOTE: We need to enable interrupts if we schedule.  We used
9289352aeadSJohn David Anglin	 * to do this earlier but it caused kernel stack overflows. */
9299352aeadSJohn David Anglin	ssm     PSW_SM_I, %r0
9309352aeadSJohn David Anglin
931413059f2SGrant Grundler#ifdef CONFIG_64BIT
9321da177e4SLinus Torvalds	ldo	-16(%r30),%r29		/* Reference param save area */
9331da177e4SLinus Torvalds#endif
9341da177e4SLinus Torvalds
9351da177e4SLinus Torvalds	ldil	L%intr_check_sig, %r2
93699ac7947SRandolph Chung#ifndef CONFIG_64BIT
9371da177e4SLinus Torvalds	b	schedule
93899ac7947SRandolph Chung#else
93999ac7947SRandolph Chung	load32	schedule, %r20
94099ac7947SRandolph Chung	bv	%r0(%r20)
94199ac7947SRandolph Chung#endif
9421da177e4SLinus Torvalds	ldo	R%intr_check_sig(%r2), %r2
9431da177e4SLinus Torvalds
94450a34dbdSKyle McMartin	/* preempt the current task on returning to kernel
94550a34dbdSKyle McMartin	 * mode from an interrupt, iff need_resched is set,
94650a34dbdSKyle McMartin	 * and preempt_count is 0. otherwise, we continue on
94750a34dbdSKyle McMartin	 * our merry way back to the current running task.
94850a34dbdSKyle McMartin	 */
94909613e83SThomas Gleixner#ifdef CONFIG_PREEMPTION
95050a34dbdSKyle McMartin	.import preempt_schedule_irq,code
95150a34dbdSKyle McMartinintr_do_preempt:
95250a34dbdSKyle McMartin	rsm	PSW_SM_I, %r0		/* disable interrupts */
95350a34dbdSKyle McMartin
95450a34dbdSKyle McMartin	/* current_thread_info()->preempt_count */
95550a34dbdSKyle McMartin	mfctl	%cr30, %r1
9563fb28e19SSven Schnelle	ldw	TI_PRE_COUNT(%r1), %r19
9573fb28e19SSven Schnelle	cmpib,<>	0, %r19, intr_restore	/* if preempt_count > 0 */
95850a34dbdSKyle McMartin	nop				/* prev insn branched backwards */
95950a34dbdSKyle McMartin
96050a34dbdSKyle McMartin	/* check if we interrupted a critical path */
96150a34dbdSKyle McMartin	LDREG	PT_PSW(%r16), %r20
96250a34dbdSKyle McMartin	bb,<,n	%r20, 31 - PSW_SM_I, intr_restore
96350a34dbdSKyle McMartin	nop
96450a34dbdSKyle McMartin
96500e35f2bSHelge Deller	/* ssm PSW_SM_I done later in intr_restore */
96600e35f2bSHelge Deller#ifdef CONFIG_MLONGCALLS
96700e35f2bSHelge Deller	ldil	L%intr_restore, %r2
96800e35f2bSHelge Deller	load32	preempt_schedule_irq, %r1
96900e35f2bSHelge Deller	bv	%r0(%r1)
97000e35f2bSHelge Deller	ldo	R%intr_restore(%r2), %r2
97100e35f2bSHelge Deller#else
97200e35f2bSHelge Deller	ldil	L%intr_restore, %r1
97350a34dbdSKyle McMartin	BL	preempt_schedule_irq, %r2
97400e35f2bSHelge Deller	ldo	R%intr_restore(%r1), %r2
97500e35f2bSHelge Deller#endif
97609613e83SThomas Gleixner#endif /* CONFIG_PREEMPTION */
9771da177e4SLinus Torvalds
9781da177e4SLinus Torvalds	/*
9791da177e4SLinus Torvalds	 * External interrupts.
9801da177e4SLinus Torvalds	 */
9811da177e4SLinus Torvalds
9821da177e4SLinus Torvaldsintr_extint:
983872f6debSKyle McMartin	cmpib,COND(=),n 0,%r16,1f
9846cc4525dSKyle McMartin
9851da177e4SLinus Torvalds	get_stack_use_cr30
9866cc4525dSKyle McMartin	b,n 2f
9871da177e4SLinus Torvalds
9881da177e4SLinus Torvalds1:
9891da177e4SLinus Torvalds	get_stack_use_r30
9906cc4525dSKyle McMartin2:
9911da177e4SLinus Torvalds	save_specials	%r29
9921da177e4SLinus Torvalds	virt_map
9931da177e4SLinus Torvalds	save_general	%r29
9941da177e4SLinus Torvalds
9951da177e4SLinus Torvalds	ldo	PT_FR0(%r29), %r24
9961da177e4SLinus Torvalds	save_fp	%r24
9971da177e4SLinus Torvalds
9981da177e4SLinus Torvalds	loadgp
9991da177e4SLinus Torvalds
10001da177e4SLinus Torvalds	copy	%r29, %r26	/* arg0 is pt_regs */
10011da177e4SLinus Torvalds	copy	%r29, %r16	/* save pt_regs */
10021da177e4SLinus Torvalds
10031da177e4SLinus Torvalds	ldil	L%intr_return, %r2
10041da177e4SLinus Torvalds
1005413059f2SGrant Grundler#ifdef CONFIG_64BIT
10061da177e4SLinus Torvalds	ldo	-16(%r30),%r29	/* Reference param save area */
10071da177e4SLinus Torvalds#endif
10081da177e4SLinus Torvalds
10091da177e4SLinus Torvalds	b	do_cpu_irq_mask
10101da177e4SLinus Torvalds	ldo	R%intr_return(%r2), %r2	/* return to intr_return, not here */
10118801ccb9SHelge DellerENDPROC_CFI(syscall_exit_rfi)
10121da177e4SLinus Torvalds
10131da177e4SLinus Torvalds
10141da177e4SLinus Torvalds	/* Generic interruptions (illegal insn, unaligned, page fault, etc) */
10151da177e4SLinus Torvalds
1016f39cce65SHelge DellerENTRY_CFI(intr_save)		/* for os_hpmc */
10171da177e4SLinus Torvalds	mfsp    %sr7,%r16
1018872f6debSKyle McMartin	cmpib,COND(=),n 0,%r16,1f
10191da177e4SLinus Torvalds	get_stack_use_cr30
10201da177e4SLinus Torvalds	b	2f
10211da177e4SLinus Torvalds	copy    %r8,%r26
10221da177e4SLinus Torvalds
10231da177e4SLinus Torvalds1:
10241da177e4SLinus Torvalds	get_stack_use_r30
10251da177e4SLinus Torvalds	copy    %r8,%r26
10261da177e4SLinus Torvalds
10271da177e4SLinus Torvalds2:
10281da177e4SLinus Torvalds	save_specials	%r29
10291da177e4SLinus Torvalds
10301da177e4SLinus Torvalds	/* If this trap is a itlb miss, skip saving/adjusting isr/ior */
10315b00ca0bSHelge Deller	cmpib,COND(=),n        PARISC_ITLB_TRAP,%r26,skip_save_ior
10321da177e4SLinus Torvalds
10331da177e4SLinus Torvalds
10345b00ca0bSHelge Deller	mfctl           %isr, %r16
1035896a3756SGrant Grundler	nop		/* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */
10365b00ca0bSHelge Deller	mfctl           %ior, %r17
10371da177e4SLinus Torvalds
1038896a3756SGrant Grundler
1039413059f2SGrant Grundler#ifdef CONFIG_64BIT
10401da177e4SLinus Torvalds	/*
10411da177e4SLinus Torvalds	 * If the interrupted code was running with W bit off (32 bit),
10421da177e4SLinus Torvalds	 * clear the b bits (bits 0 & 1) in the ior.
1043896a3756SGrant Grundler	 * save_specials left ipsw value in r8 for us to test.
10441da177e4SLinus Torvalds	 */
10451da177e4SLinus Torvalds	extrd,u,*<>     %r8,PSW_W_BIT,1,%r0
10461da177e4SLinus Torvalds	depdi           0,1,2,%r17
10471da177e4SLinus Torvalds
10485b00ca0bSHelge Deller	/* adjust isr/ior: get high bits from isr and deposit in ior */
10495b00ca0bSHelge Deller	space_adjust	%r16,%r17,%r1
10501da177e4SLinus Torvalds#endif
10511da177e4SLinus Torvalds	STREG           %r16, PT_ISR(%r29)
10521da177e4SLinus Torvalds	STREG           %r17, PT_IOR(%r29)
10531da177e4SLinus Torvalds
1054*3eff30f2SHelge Deller#if defined(CONFIG_64BIT)
10555b00ca0bSHelge Deller	b,n		intr_save2
10561da177e4SLinus Torvalds
10571da177e4SLinus Torvaldsskip_save_ior:
10585b00ca0bSHelge Deller	/* We have a itlb miss, and when executing code above 4 Gb on ILP64, we
10595b00ca0bSHelge Deller	 * need to adjust iasq/iaoq here in the same way we adjusted isr/ior
10605b00ca0bSHelge Deller	 * above.
10615b00ca0bSHelge Deller	 */
1062*3eff30f2SHelge Deller	bb,COND(>=),n	%r8,PSW_W_BIT,intr_save2
10635b00ca0bSHelge Deller	LDREG		PT_IASQ0(%r29), %r16
10645b00ca0bSHelge Deller	LDREG		PT_IAOQ0(%r29), %r17
10655b00ca0bSHelge Deller	/* adjust iasq/iaoq */
10665b00ca0bSHelge Deller	space_adjust	%r16,%r17,%r1
10675b00ca0bSHelge Deller	STREG           %r16, PT_IASQ0(%r29)
10685b00ca0bSHelge Deller	STREG           %r17, PT_IAOQ0(%r29)
10695b00ca0bSHelge Deller#else
10705b00ca0bSHelge Dellerskip_save_ior:
10715b00ca0bSHelge Deller#endif
10725b00ca0bSHelge Deller
10735b00ca0bSHelge Dellerintr_save2:
10741da177e4SLinus Torvalds	virt_map
10751da177e4SLinus Torvalds	save_general	%r29
10761da177e4SLinus Torvalds
10771da177e4SLinus Torvalds	ldo		PT_FR0(%r29), %r25
10781da177e4SLinus Torvalds	save_fp		%r25
10791da177e4SLinus Torvalds
10801da177e4SLinus Torvalds	loadgp
10811da177e4SLinus Torvalds
10821da177e4SLinus Torvalds	copy		%r29, %r25	/* arg1 is pt_regs */
1083413059f2SGrant Grundler#ifdef CONFIG_64BIT
10841da177e4SLinus Torvalds	ldo		-16(%r30),%r29	/* Reference param save area */
10851da177e4SLinus Torvalds#endif
10861da177e4SLinus Torvalds
10871da177e4SLinus Torvalds	ldil		L%intr_check_sig, %r2
10881da177e4SLinus Torvalds	copy		%r25, %r16	/* save pt_regs */
10891da177e4SLinus Torvalds
10901da177e4SLinus Torvalds	b		handle_interruption
10911da177e4SLinus Torvalds	ldo		R%intr_check_sig(%r2), %r2
1092f39cce65SHelge DellerENDPROC_CFI(intr_save)
10931da177e4SLinus Torvalds
10941da177e4SLinus Torvalds
10951da177e4SLinus Torvalds	/*
10961da177e4SLinus Torvalds	 * Note for all tlb miss handlers:
10971da177e4SLinus Torvalds	 *
10981da177e4SLinus Torvalds	 * cr24 contains a pointer to the kernel address space
10991da177e4SLinus Torvalds	 * page directory.
11001da177e4SLinus Torvalds	 *
11011da177e4SLinus Torvalds	 * cr25 contains a pointer to the current user address
11021da177e4SLinus Torvalds	 * space page directory.
11031da177e4SLinus Torvalds	 *
11041da177e4SLinus Torvalds	 * sr3 will contain the space id of the user address space
11051da177e4SLinus Torvalds	 * of the current running thread while that thread is
11061da177e4SLinus Torvalds	 * running in the kernel.
11071da177e4SLinus Torvalds	 */
11081da177e4SLinus Torvalds
11091da177e4SLinus Torvalds	/*
11101da177e4SLinus Torvalds	 * register number allocations.  Note that these are all
11111da177e4SLinus Torvalds	 * in the shadowed registers
11121da177e4SLinus Torvalds	 */
11131da177e4SLinus Torvalds
11141da177e4SLinus Torvalds	t0 = r1		/* temporary register 0 */
111525985edcSLucas De Marchi	va = r8		/* virtual address for which the trap occurred */
11161da177e4SLinus Torvalds	t1 = r9		/* temporary register 1 */
11171da177e4SLinus Torvalds	pte  = r16	/* pte/phys page # */
11181da177e4SLinus Torvalds	prot = r17	/* prot bits */
111925985edcSLucas De Marchi	spc  = r24	/* space for which the trap occurred */
11201da177e4SLinus Torvalds	ptp = r25	/* page directory/page table pointer */
11211da177e4SLinus Torvalds
1122413059f2SGrant Grundler#ifdef CONFIG_64BIT
11231da177e4SLinus Torvalds
11241da177e4SLinus Torvaldsdtlb_miss_20w:
11251da177e4SLinus Torvalds	space_adjust	spc,va,t0
11261da177e4SLinus Torvalds	get_pgd		spc,ptp
11271da177e4SLinus Torvalds	space_check	spc,t0,dtlb_fault
11281da177e4SLinus Torvalds
11291da177e4SLinus Torvalds	L3_ptep		ptp,pte,t0,va,dtlb_check_alias_20w
11301da177e4SLinus Torvalds
1131b7795074SHelge Deller	ptl_lock	spc,ptp,pte,t0,t1,dtlb_check_alias_20w
113201ab6057SJohn David Anglin	update_accessed	ptp,pte,t0,t1
11331da177e4SLinus Torvalds
1134736d2169SHelge Deller	make_insert_tlb	spc,pte,prot,t1
11351da177e4SLinus Torvalds
11361da177e4SLinus Torvalds	idtlbt          pte,prot
11371da177e4SLinus Torvalds
1138c3b5552bSJohn David Anglin	ptl_unlock	spc,t0,t1
11391da177e4SLinus Torvalds	rfir
11401da177e4SLinus Torvalds	nop
11411da177e4SLinus Torvalds
11421da177e4SLinus Torvaldsdtlb_check_alias_20w:
11432f649c1fSJames Bottomley	do_alias	spc,t0,t1,va,pte,prot,dtlb_fault,20
11441da177e4SLinus Torvalds
11451da177e4SLinus Torvalds	idtlbt          pte,prot
11461da177e4SLinus Torvalds
1147c3b5552bSJohn David Anglin	insert_nops	NUM_PIPELINE_INSNS - 1
11481da177e4SLinus Torvalds	rfir
11491da177e4SLinus Torvalds	nop
11501da177e4SLinus Torvalds
11511da177e4SLinus Torvaldsnadtlb_miss_20w:
11521da177e4SLinus Torvalds	space_adjust	spc,va,t0
11531da177e4SLinus Torvalds	get_pgd		spc,ptp
11541da177e4SLinus Torvalds	space_check	spc,t0,nadtlb_fault
11551da177e4SLinus Torvalds
1156f311847cSJames Bottomley	L3_ptep		ptp,pte,t0,va,nadtlb_check_alias_20w
11571da177e4SLinus Torvalds
1158b7795074SHelge Deller	ptl_lock	spc,ptp,pte,t0,t1,nadtlb_check_alias_20w
115901ab6057SJohn David Anglin	update_accessed	ptp,pte,t0,t1
11601da177e4SLinus Torvalds
1161736d2169SHelge Deller	make_insert_tlb	spc,pte,prot,t1
11621da177e4SLinus Torvalds
11631da177e4SLinus Torvalds	idtlbt          pte,prot
11641da177e4SLinus Torvalds
1165c3b5552bSJohn David Anglin	ptl_unlock	spc,t0,t1
11661da177e4SLinus Torvalds	rfir
11671da177e4SLinus Torvalds	nop
11681da177e4SLinus Torvalds
1169f311847cSJames Bottomleynadtlb_check_alias_20w:
11702f649c1fSJames Bottomley	do_alias	spc,t0,t1,va,pte,prot,nadtlb_emulate,20
11711da177e4SLinus Torvalds
11721da177e4SLinus Torvalds	idtlbt          pte,prot
11731da177e4SLinus Torvalds
1174c3b5552bSJohn David Anglin	insert_nops	NUM_PIPELINE_INSNS - 1
11751da177e4SLinus Torvalds	rfir
11761da177e4SLinus Torvalds	nop
11771da177e4SLinus Torvalds
11781da177e4SLinus Torvalds#else
11791da177e4SLinus Torvalds
11801da177e4SLinus Torvaldsdtlb_miss_11:
11811da177e4SLinus Torvalds	get_pgd		spc,ptp
11821da177e4SLinus Torvalds
11831da177e4SLinus Torvalds	space_check	spc,t0,dtlb_fault
11841da177e4SLinus Torvalds
11851da177e4SLinus Torvalds	L2_ptep		ptp,pte,t0,va,dtlb_check_alias_11
11861da177e4SLinus Torvalds
1187b7795074SHelge Deller	ptl_lock	spc,ptp,pte,t0,t1,dtlb_check_alias_11
118801ab6057SJohn David Anglin	update_accessed	ptp,pte,t0,t1
11891da177e4SLinus Torvalds
11901da177e4SLinus Torvalds	make_insert_tlb_11	spc,pte,prot
11911da177e4SLinus Torvalds
119201ab6057SJohn David Anglin	mfsp		%sr1,t1  /* Save sr1 so we can use it in tlb inserts */
11931da177e4SLinus Torvalds	mtsp		spc,%sr1
11941da177e4SLinus Torvalds
11951da177e4SLinus Torvalds	idtlba		pte,(%sr1,va)
11961da177e4SLinus Torvalds	idtlbp		prot,(%sr1,va)
11971da177e4SLinus Torvalds
119801ab6057SJohn David Anglin	mtsp		t1, %sr1	/* Restore sr1 */
11991da177e4SLinus Torvalds
1200c3b5552bSJohn David Anglin	ptl_unlock	spc,t0,t1
12011da177e4SLinus Torvalds	rfir
12021da177e4SLinus Torvalds	nop
12031da177e4SLinus Torvalds
12041da177e4SLinus Torvaldsdtlb_check_alias_11:
12052f649c1fSJames Bottomley	do_alias	spc,t0,t1,va,pte,prot,dtlb_fault,11
12061da177e4SLinus Torvalds
12071da177e4SLinus Torvalds	idtlba          pte,(va)
12081da177e4SLinus Torvalds	idtlbp          prot,(va)
12091da177e4SLinus Torvalds
1210c3b5552bSJohn David Anglin	insert_nops	NUM_PIPELINE_INSNS - 1
12111da177e4SLinus Torvalds	rfir
12121da177e4SLinus Torvalds	nop
12131da177e4SLinus Torvalds
12141da177e4SLinus Torvaldsnadtlb_miss_11:
12151da177e4SLinus Torvalds	get_pgd		spc,ptp
12161da177e4SLinus Torvalds
12171da177e4SLinus Torvalds	space_check	spc,t0,nadtlb_fault
12181da177e4SLinus Torvalds
1219f311847cSJames Bottomley	L2_ptep		ptp,pte,t0,va,nadtlb_check_alias_11
12201da177e4SLinus Torvalds
1221b7795074SHelge Deller	ptl_lock	spc,ptp,pte,t0,t1,nadtlb_check_alias_11
122201ab6057SJohn David Anglin	update_accessed	ptp,pte,t0,t1
12231da177e4SLinus Torvalds
12241da177e4SLinus Torvalds	make_insert_tlb_11	spc,pte,prot
12251da177e4SLinus Torvalds
122601ab6057SJohn David Anglin	mfsp		%sr1,t1  /* Save sr1 so we can use it in tlb inserts */
12271da177e4SLinus Torvalds	mtsp		spc,%sr1
12281da177e4SLinus Torvalds
12291da177e4SLinus Torvalds	idtlba		pte,(%sr1,va)
12301da177e4SLinus Torvalds	idtlbp		prot,(%sr1,va)
12311da177e4SLinus Torvalds
123201ab6057SJohn David Anglin	mtsp		t1, %sr1	/* Restore sr1 */
12331da177e4SLinus Torvalds
1234c3b5552bSJohn David Anglin	ptl_unlock	spc,t0,t1
12351da177e4SLinus Torvalds	rfir
12361da177e4SLinus Torvalds	nop
12371da177e4SLinus Torvalds
1238f311847cSJames Bottomleynadtlb_check_alias_11:
12392f649c1fSJames Bottomley	do_alias	spc,t0,t1,va,pte,prot,nadtlb_emulate,11
1240f311847cSJames Bottomley
1241f311847cSJames Bottomley	idtlba          pte,(va)
1242f311847cSJames Bottomley	idtlbp          prot,(va)
1243f311847cSJames Bottomley
1244c3b5552bSJohn David Anglin	insert_nops	NUM_PIPELINE_INSNS - 1
1245f311847cSJames Bottomley	rfir
1246f311847cSJames Bottomley	nop
1247f311847cSJames Bottomley
12481da177e4SLinus Torvaldsdtlb_miss_20:
12491da177e4SLinus Torvalds	space_adjust	spc,va,t0
12501da177e4SLinus Torvalds	get_pgd		spc,ptp
12511da177e4SLinus Torvalds	space_check	spc,t0,dtlb_fault
12521da177e4SLinus Torvalds
12531da177e4SLinus Torvalds	L2_ptep		ptp,pte,t0,va,dtlb_check_alias_20
12541da177e4SLinus Torvalds
1255b7795074SHelge Deller	ptl_lock	spc,ptp,pte,t0,t1,dtlb_check_alias_20
125601ab6057SJohn David Anglin	update_accessed	ptp,pte,t0,t1
12571da177e4SLinus Torvalds
1258736d2169SHelge Deller	make_insert_tlb	spc,pte,prot,t1
12591da177e4SLinus Torvalds
126001ab6057SJohn David Anglin	f_extend	pte,t1
12611da177e4SLinus Torvalds
12621da177e4SLinus Torvalds	idtlbt          pte,prot
12631da177e4SLinus Torvalds
1264c3b5552bSJohn David Anglin	ptl_unlock	spc,t0,t1
12651da177e4SLinus Torvalds	rfir
12661da177e4SLinus Torvalds	nop
12671da177e4SLinus Torvalds
12681da177e4SLinus Torvaldsdtlb_check_alias_20:
12692f649c1fSJames Bottomley	do_alias	spc,t0,t1,va,pte,prot,dtlb_fault,20
12701da177e4SLinus Torvalds
12711da177e4SLinus Torvalds	idtlbt          pte,prot
12721da177e4SLinus Torvalds
1273c3b5552bSJohn David Anglin	insert_nops	NUM_PIPELINE_INSNS - 1
12741da177e4SLinus Torvalds	rfir
12751da177e4SLinus Torvalds	nop
12761da177e4SLinus Torvalds
12771da177e4SLinus Torvaldsnadtlb_miss_20:
12781da177e4SLinus Torvalds	get_pgd		spc,ptp
12791da177e4SLinus Torvalds
12801da177e4SLinus Torvalds	space_check	spc,t0,nadtlb_fault
12811da177e4SLinus Torvalds
1282f311847cSJames Bottomley	L2_ptep		ptp,pte,t0,va,nadtlb_check_alias_20
12831da177e4SLinus Torvalds
1284b7795074SHelge Deller	ptl_lock	spc,ptp,pte,t0,t1,nadtlb_check_alias_20
128501ab6057SJohn David Anglin	update_accessed	ptp,pte,t0,t1
12861da177e4SLinus Torvalds
1287736d2169SHelge Deller	make_insert_tlb	spc,pte,prot,t1
12881da177e4SLinus Torvalds
128901ab6057SJohn David Anglin	f_extend	pte,t1
12901da177e4SLinus Torvalds
12911da177e4SLinus Torvalds	idtlbt		pte,prot
12921da177e4SLinus Torvalds
1293c3b5552bSJohn David Anglin	ptl_unlock	spc,t0,t1
12941da177e4SLinus Torvalds	rfir
12951da177e4SLinus Torvalds	nop
12961da177e4SLinus Torvalds
1297f311847cSJames Bottomleynadtlb_check_alias_20:
12982f649c1fSJames Bottomley	do_alias	spc,t0,t1,va,pte,prot,nadtlb_emulate,20
1299f311847cSJames Bottomley
1300f311847cSJames Bottomley	idtlbt          pte,prot
1301f311847cSJames Bottomley
1302c3b5552bSJohn David Anglin	insert_nops	NUM_PIPELINE_INSNS - 1
1303f311847cSJames Bottomley	rfir
1304f311847cSJames Bottomley	nop
1305f311847cSJames Bottomley
13061da177e4SLinus Torvalds#endif
13071da177e4SLinus Torvalds
13081da177e4SLinus Torvaldsnadtlb_emulate:
13091da177e4SLinus Torvalds
13101da177e4SLinus Torvalds	/*
131114615eccSJohn David Anglin	 * Non-access misses can be caused by fdc,fic,pdc,lpa,probe and
131214615eccSJohn David Anglin	 * probei instructions. The kernel no longer faults doing flushes.
131314615eccSJohn David Anglin	 * Use of lpa and probe instructions is rare. Given the issue
131414615eccSJohn David Anglin	 * with shadow registers, we defer everything to the "slow" path.
13151da177e4SLinus Torvalds	 */
131614615eccSJohn David Anglin	b,n		nadtlb_fault
13171da177e4SLinus Torvalds
1318413059f2SGrant Grundler#ifdef CONFIG_64BIT
13191da177e4SLinus Torvaldsitlb_miss_20w:
13201da177e4SLinus Torvalds
13211da177e4SLinus Torvalds	/*
13221da177e4SLinus Torvalds	 * I miss is a little different, since we allow users to fault
13231da177e4SLinus Torvalds	 * on the gateway page which is in the kernel address space.
13241da177e4SLinus Torvalds	 */
13251da177e4SLinus Torvalds
13261da177e4SLinus Torvalds	space_adjust	spc,va,t0
13271da177e4SLinus Torvalds	get_pgd		spc,ptp
13281da177e4SLinus Torvalds	space_check	spc,t0,itlb_fault
13291da177e4SLinus Torvalds
13301da177e4SLinus Torvalds	L3_ptep		ptp,pte,t0,va,itlb_fault
13311da177e4SLinus Torvalds
1332b7795074SHelge Deller	ptl_lock	spc,ptp,pte,t0,t1,itlb_fault
133301ab6057SJohn David Anglin	update_accessed	ptp,pte,t0,t1
13341da177e4SLinus Torvalds
1335736d2169SHelge Deller	make_insert_tlb	spc,pte,prot,t1
13361da177e4SLinus Torvalds
13371da177e4SLinus Torvalds	iitlbt          pte,prot
13381da177e4SLinus Torvalds
1339c3b5552bSJohn David Anglin	ptl_unlock	spc,t0,t1
13401da177e4SLinus Torvalds	rfir
13411da177e4SLinus Torvalds	nop
13421da177e4SLinus Torvalds
1343f311847cSJames Bottomleynaitlb_miss_20w:
1344f311847cSJames Bottomley
1345f311847cSJames Bottomley	/*
1346f311847cSJames Bottomley	 * I miss is a little different, since we allow users to fault
1347f311847cSJames Bottomley	 * on the gateway page which is in the kernel address space.
1348f311847cSJames Bottomley	 */
1349f311847cSJames Bottomley
1350f311847cSJames Bottomley	space_adjust	spc,va,t0
1351f311847cSJames Bottomley	get_pgd		spc,ptp
1352f311847cSJames Bottomley	space_check	spc,t0,naitlb_fault
1353f311847cSJames Bottomley
1354f311847cSJames Bottomley	L3_ptep		ptp,pte,t0,va,naitlb_check_alias_20w
1355f311847cSJames Bottomley
1356b7795074SHelge Deller	ptl_lock	spc,ptp,pte,t0,t1,naitlb_check_alias_20w
135701ab6057SJohn David Anglin	update_accessed	ptp,pte,t0,t1
1358f311847cSJames Bottomley
1359736d2169SHelge Deller	make_insert_tlb	spc,pte,prot,t1
1360f311847cSJames Bottomley
1361f311847cSJames Bottomley	iitlbt          pte,prot
1362f311847cSJames Bottomley
1363c3b5552bSJohn David Anglin	ptl_unlock	spc,t0,t1
1364f311847cSJames Bottomley	rfir
1365f311847cSJames Bottomley	nop
1366f311847cSJames Bottomley
1367f311847cSJames Bottomleynaitlb_check_alias_20w:
13682f649c1fSJames Bottomley	do_alias	spc,t0,t1,va,pte,prot,naitlb_fault,20
1369f311847cSJames Bottomley
1370f311847cSJames Bottomley	iitlbt		pte,prot
1371f311847cSJames Bottomley
1372c3b5552bSJohn David Anglin	insert_nops	NUM_PIPELINE_INSNS - 1
1373f311847cSJames Bottomley	rfir
1374f311847cSJames Bottomley	nop
1375f311847cSJames Bottomley
13761da177e4SLinus Torvalds#else
13771da177e4SLinus Torvalds
13781da177e4SLinus Torvaldsitlb_miss_11:
13791da177e4SLinus Torvalds	get_pgd		spc,ptp
13801da177e4SLinus Torvalds
13811da177e4SLinus Torvalds	space_check	spc,t0,itlb_fault
13821da177e4SLinus Torvalds
13831da177e4SLinus Torvalds	L2_ptep		ptp,pte,t0,va,itlb_fault
13841da177e4SLinus Torvalds
1385b7795074SHelge Deller	ptl_lock	spc,ptp,pte,t0,t1,itlb_fault
138601ab6057SJohn David Anglin	update_accessed	ptp,pte,t0,t1
13871da177e4SLinus Torvalds
13881da177e4SLinus Torvalds	make_insert_tlb_11	spc,pte,prot
13891da177e4SLinus Torvalds
139001ab6057SJohn David Anglin	mfsp		%sr1,t1  /* Save sr1 so we can use it in tlb inserts */
13911da177e4SLinus Torvalds	mtsp		spc,%sr1
13921da177e4SLinus Torvalds
13931da177e4SLinus Torvalds	iitlba		pte,(%sr1,va)
13941da177e4SLinus Torvalds	iitlbp		prot,(%sr1,va)
13951da177e4SLinus Torvalds
139601ab6057SJohn David Anglin	mtsp		t1, %sr1	/* Restore sr1 */
13971da177e4SLinus Torvalds
1398c3b5552bSJohn David Anglin	ptl_unlock	spc,t0,t1
13991da177e4SLinus Torvalds	rfir
14001da177e4SLinus Torvalds	nop
14011da177e4SLinus Torvalds
1402f311847cSJames Bottomleynaitlb_miss_11:
1403f311847cSJames Bottomley	get_pgd		spc,ptp
1404f311847cSJames Bottomley
1405f311847cSJames Bottomley	space_check	spc,t0,naitlb_fault
1406f311847cSJames Bottomley
1407f311847cSJames Bottomley	L2_ptep		ptp,pte,t0,va,naitlb_check_alias_11
1408f311847cSJames Bottomley
1409b7795074SHelge Deller	ptl_lock	spc,ptp,pte,t0,t1,naitlb_check_alias_11
141001ab6057SJohn David Anglin	update_accessed	ptp,pte,t0,t1
1411f311847cSJames Bottomley
1412f311847cSJames Bottomley	make_insert_tlb_11	spc,pte,prot
1413f311847cSJames Bottomley
141401ab6057SJohn David Anglin	mfsp		%sr1,t1  /* Save sr1 so we can use it in tlb inserts */
1415f311847cSJames Bottomley	mtsp		spc,%sr1
1416f311847cSJames Bottomley
1417f311847cSJames Bottomley	iitlba		pte,(%sr1,va)
1418f311847cSJames Bottomley	iitlbp		prot,(%sr1,va)
1419f311847cSJames Bottomley
142001ab6057SJohn David Anglin	mtsp		t1, %sr1	/* Restore sr1 */
1421f311847cSJames Bottomley
1422c3b5552bSJohn David Anglin	ptl_unlock	spc,t0,t1
1423f311847cSJames Bottomley	rfir
1424f311847cSJames Bottomley	nop
1425f311847cSJames Bottomley
1426f311847cSJames Bottomleynaitlb_check_alias_11:
14272f649c1fSJames Bottomley	do_alias	spc,t0,t1,va,pte,prot,itlb_fault,11
1428f311847cSJames Bottomley
1429f311847cSJames Bottomley	iitlba          pte,(%sr0, va)
1430f311847cSJames Bottomley	iitlbp          prot,(%sr0, va)
1431f311847cSJames Bottomley
1432c3b5552bSJohn David Anglin	insert_nops	NUM_PIPELINE_INSNS - 1
1433f311847cSJames Bottomley	rfir
1434f311847cSJames Bottomley	nop
1435f311847cSJames Bottomley
1436f311847cSJames Bottomley
14371da177e4SLinus Torvaldsitlb_miss_20:
14381da177e4SLinus Torvalds	get_pgd		spc,ptp
14391da177e4SLinus Torvalds
14401da177e4SLinus Torvalds	space_check	spc,t0,itlb_fault
14411da177e4SLinus Torvalds
14421da177e4SLinus Torvalds	L2_ptep		ptp,pte,t0,va,itlb_fault
14431da177e4SLinus Torvalds
1444b7795074SHelge Deller	ptl_lock	spc,ptp,pte,t0,t1,itlb_fault
144501ab6057SJohn David Anglin	update_accessed	ptp,pte,t0,t1
14461da177e4SLinus Torvalds
1447736d2169SHelge Deller	make_insert_tlb	spc,pte,prot,t1
14481da177e4SLinus Torvalds
144901ab6057SJohn David Anglin	f_extend	pte,t1
14501da177e4SLinus Torvalds
14511da177e4SLinus Torvalds	iitlbt          pte,prot
14521da177e4SLinus Torvalds
1453c3b5552bSJohn David Anglin	ptl_unlock	spc,t0,t1
14541da177e4SLinus Torvalds	rfir
14551da177e4SLinus Torvalds	nop
14561da177e4SLinus Torvalds
1457f311847cSJames Bottomleynaitlb_miss_20:
1458f311847cSJames Bottomley	get_pgd		spc,ptp
1459f311847cSJames Bottomley
1460f311847cSJames Bottomley	space_check	spc,t0,naitlb_fault
1461f311847cSJames Bottomley
1462f311847cSJames Bottomley	L2_ptep		ptp,pte,t0,va,naitlb_check_alias_20
1463f311847cSJames Bottomley
1464b7795074SHelge Deller	ptl_lock	spc,ptp,pte,t0,t1,naitlb_check_alias_20
146501ab6057SJohn David Anglin	update_accessed	ptp,pte,t0,t1
1466f311847cSJames Bottomley
1467736d2169SHelge Deller	make_insert_tlb	spc,pte,prot,t1
1468f311847cSJames Bottomley
146901ab6057SJohn David Anglin	f_extend	pte,t1
1470f311847cSJames Bottomley
1471f311847cSJames Bottomley	iitlbt          pte,prot
1472f311847cSJames Bottomley
1473c3b5552bSJohn David Anglin	ptl_unlock	spc,t0,t1
1474f311847cSJames Bottomley	rfir
1475f311847cSJames Bottomley	nop
1476f311847cSJames Bottomley
1477f311847cSJames Bottomleynaitlb_check_alias_20:
14782f649c1fSJames Bottomley	do_alias	spc,t0,t1,va,pte,prot,naitlb_fault,20
1479f311847cSJames Bottomley
1480f311847cSJames Bottomley	iitlbt          pte,prot
1481f311847cSJames Bottomley
1482c3b5552bSJohn David Anglin	insert_nops	NUM_PIPELINE_INSNS - 1
1483f311847cSJames Bottomley	rfir
1484f311847cSJames Bottomley	nop
1485f311847cSJames Bottomley
14861da177e4SLinus Torvalds#endif
14871da177e4SLinus Torvalds
1488413059f2SGrant Grundler#ifdef CONFIG_64BIT
14891da177e4SLinus Torvalds
14901da177e4SLinus Torvaldsdbit_trap_20w:
14911da177e4SLinus Torvalds	space_adjust	spc,va,t0
14921da177e4SLinus Torvalds	get_pgd		spc,ptp
14931da177e4SLinus Torvalds	space_check	spc,t0,dbit_fault
14941da177e4SLinus Torvalds
14951da177e4SLinus Torvalds	L3_ptep		ptp,pte,t0,va,dbit_fault
14961da177e4SLinus Torvalds
1497b7795074SHelge Deller	ptl_lock	spc,ptp,pte,t0,t1,dbit_fault
149801ab6057SJohn David Anglin	update_dirty	ptp,pte,t1
14991da177e4SLinus Torvalds
1500736d2169SHelge Deller	make_insert_tlb	spc,pte,prot,t1
15011da177e4SLinus Torvalds
15021da177e4SLinus Torvalds	idtlbt          pte,prot
15031da177e4SLinus Torvalds
1504c3b5552bSJohn David Anglin	ptl_unlock	spc,t0,t1
15051da177e4SLinus Torvalds	rfir
15061da177e4SLinus Torvalds	nop
15071da177e4SLinus Torvalds#else
15081da177e4SLinus Torvalds
15091da177e4SLinus Torvaldsdbit_trap_11:
15101da177e4SLinus Torvalds
15111da177e4SLinus Torvalds	get_pgd		spc,ptp
15121da177e4SLinus Torvalds
15131da177e4SLinus Torvalds	space_check	spc,t0,dbit_fault
15141da177e4SLinus Torvalds
15151da177e4SLinus Torvalds	L2_ptep		ptp,pte,t0,va,dbit_fault
15161da177e4SLinus Torvalds
1517b7795074SHelge Deller	ptl_lock	spc,ptp,pte,t0,t1,dbit_fault
151801ab6057SJohn David Anglin	update_dirty	ptp,pte,t1
15191da177e4SLinus Torvalds
15201da177e4SLinus Torvalds	make_insert_tlb_11	spc,pte,prot
15211da177e4SLinus Torvalds
15221da177e4SLinus Torvalds	mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
15231da177e4SLinus Torvalds	mtsp		spc,%sr1
15241da177e4SLinus Torvalds
15251da177e4SLinus Torvalds	idtlba		pte,(%sr1,va)
15261da177e4SLinus Torvalds	idtlbp		prot,(%sr1,va)
15271da177e4SLinus Torvalds
15281da177e4SLinus Torvalds	mtsp            t1, %sr1     /* Restore sr1 */
15291da177e4SLinus Torvalds
1530c3b5552bSJohn David Anglin	ptl_unlock	spc,t0,t1
15311da177e4SLinus Torvalds	rfir
15321da177e4SLinus Torvalds	nop
15331da177e4SLinus Torvalds
15341da177e4SLinus Torvaldsdbit_trap_20:
15351da177e4SLinus Torvalds	get_pgd		spc,ptp
15361da177e4SLinus Torvalds
15371da177e4SLinus Torvalds	space_check	spc,t0,dbit_fault
15381da177e4SLinus Torvalds
15391da177e4SLinus Torvalds	L2_ptep		ptp,pte,t0,va,dbit_fault
15401da177e4SLinus Torvalds
1541b7795074SHelge Deller	ptl_lock	spc,ptp,pte,t0,t1,dbit_fault
154201ab6057SJohn David Anglin	update_dirty	ptp,pte,t1
15431da177e4SLinus Torvalds
1544736d2169SHelge Deller	make_insert_tlb	spc,pte,prot,t1
15451da177e4SLinus Torvalds
15461da177e4SLinus Torvalds	f_extend	pte,t1
15471da177e4SLinus Torvalds
15481da177e4SLinus Torvalds	idtlbt		pte,prot
15491da177e4SLinus Torvalds
1550c3b5552bSJohn David Anglin	ptl_unlock	spc,t0,t1
15511da177e4SLinus Torvalds	rfir
15521da177e4SLinus Torvalds	nop
15531da177e4SLinus Torvalds#endif
15541da177e4SLinus Torvalds
15551da177e4SLinus Torvalds	.import handle_interruption,code
15561da177e4SLinus Torvalds
15571da177e4SLinus Torvaldskernel_bad_space:
15581da177e4SLinus Torvalds	b               intr_save
15591da177e4SLinus Torvalds	ldi             31,%r8  /* Use an unused code */
15601da177e4SLinus Torvalds
15611da177e4SLinus Torvaldsdbit_fault:
15621da177e4SLinus Torvalds	b               intr_save
15631da177e4SLinus Torvalds	ldi             20,%r8
15641da177e4SLinus Torvalds
15651da177e4SLinus Torvaldsitlb_fault:
15661da177e4SLinus Torvalds	b               intr_save
1567cd2b8520SHelge Deller	ldi             PARISC_ITLB_TRAP,%r8
15681da177e4SLinus Torvalds
15691da177e4SLinus Torvaldsnadtlb_fault:
15701da177e4SLinus Torvalds	b               intr_save
15711da177e4SLinus Torvalds	ldi             17,%r8
15721da177e4SLinus Torvalds
1573f311847cSJames Bottomleynaitlb_fault:
1574f311847cSJames Bottomley	b               intr_save
1575f311847cSJames Bottomley	ldi             16,%r8
1576f311847cSJames Bottomley
15771da177e4SLinus Torvaldsdtlb_fault:
15781da177e4SLinus Torvalds	b               intr_save
15791da177e4SLinus Torvalds	ldi             15,%r8
15801da177e4SLinus Torvalds
15811da177e4SLinus Torvalds	/* Register saving semantics for system calls:
15821da177e4SLinus Torvalds
15831da177e4SLinus Torvalds	   %r1		   clobbered by system call macro in userspace
15841da177e4SLinus Torvalds	   %r2		   saved in PT_REGS by gateway page
15851da177e4SLinus Torvalds	   %r3  - %r18	   preserved by C code (saved by signal code)
15861da177e4SLinus Torvalds	   %r19 - %r20	   saved in PT_REGS by gateway page
15871da177e4SLinus Torvalds	   %r21 - %r22	   non-standard syscall args
15881da177e4SLinus Torvalds			   stored in kernel stack by gateway page
15891da177e4SLinus Torvalds	   %r23 - %r26	   arg3-arg0, saved in PT_REGS by gateway page
15901da177e4SLinus Torvalds	   %r27 - %r30	   saved in PT_REGS by gateway page
15911da177e4SLinus Torvalds	   %r31		   syscall return pointer
15921da177e4SLinus Torvalds	 */
15931da177e4SLinus Torvalds
15941da177e4SLinus Torvalds	/* Floating point registers (FIXME: what do we do with these?)
15951da177e4SLinus Torvalds
15961da177e4SLinus Torvalds	   %fr0  - %fr3	   status/exception, not preserved
15971da177e4SLinus Torvalds	   %fr4  - %fr7	   arguments
15981da177e4SLinus Torvalds	   %fr8	 - %fr11   not preserved by C code
15991da177e4SLinus Torvalds	   %fr12 - %fr21   preserved by C code
16001da177e4SLinus Torvalds	   %fr22 - %fr31   not preserved by C code
16011da177e4SLinus Torvalds	 */
16021da177e4SLinus Torvalds
16031da177e4SLinus Torvalds	.macro	reg_save regs
16041da177e4SLinus Torvalds	STREG	%r3, PT_GR3(\regs)
16051da177e4SLinus Torvalds	STREG	%r4, PT_GR4(\regs)
16061da177e4SLinus Torvalds	STREG	%r5, PT_GR5(\regs)
16071da177e4SLinus Torvalds	STREG	%r6, PT_GR6(\regs)
16081da177e4SLinus Torvalds	STREG	%r7, PT_GR7(\regs)
16091da177e4SLinus Torvalds	STREG	%r8, PT_GR8(\regs)
16101da177e4SLinus Torvalds	STREG	%r9, PT_GR9(\regs)
16111da177e4SLinus Torvalds	STREG   %r10,PT_GR10(\regs)
16121da177e4SLinus Torvalds	STREG   %r11,PT_GR11(\regs)
16131da177e4SLinus Torvalds	STREG   %r12,PT_GR12(\regs)
16141da177e4SLinus Torvalds	STREG   %r13,PT_GR13(\regs)
16151da177e4SLinus Torvalds	STREG   %r14,PT_GR14(\regs)
16161da177e4SLinus Torvalds	STREG   %r15,PT_GR15(\regs)
16171da177e4SLinus Torvalds	STREG   %r16,PT_GR16(\regs)
16181da177e4SLinus Torvalds	STREG   %r17,PT_GR17(\regs)
16191da177e4SLinus Torvalds	STREG   %r18,PT_GR18(\regs)
16201da177e4SLinus Torvalds	.endm
16211da177e4SLinus Torvalds
16221da177e4SLinus Torvalds	.macro	reg_restore regs
16231da177e4SLinus Torvalds	LDREG	PT_GR3(\regs), %r3
16241da177e4SLinus Torvalds	LDREG	PT_GR4(\regs), %r4
16251da177e4SLinus Torvalds	LDREG	PT_GR5(\regs), %r5
16261da177e4SLinus Torvalds	LDREG	PT_GR6(\regs), %r6
16271da177e4SLinus Torvalds	LDREG	PT_GR7(\regs), %r7
16281da177e4SLinus Torvalds	LDREG	PT_GR8(\regs), %r8
16291da177e4SLinus Torvalds	LDREG	PT_GR9(\regs), %r9
16301da177e4SLinus Torvalds	LDREG   PT_GR10(\regs),%r10
16311da177e4SLinus Torvalds	LDREG   PT_GR11(\regs),%r11
16321da177e4SLinus Torvalds	LDREG   PT_GR12(\regs),%r12
16331da177e4SLinus Torvalds	LDREG   PT_GR13(\regs),%r13
16341da177e4SLinus Torvalds	LDREG   PT_GR14(\regs),%r14
16351da177e4SLinus Torvalds	LDREG   PT_GR15(\regs),%r15
16361da177e4SLinus Torvalds	LDREG   PT_GR16(\regs),%r16
16371da177e4SLinus Torvalds	LDREG   PT_GR17(\regs),%r17
16381da177e4SLinus Torvalds	LDREG   PT_GR18(\regs),%r18
16391da177e4SLinus Torvalds	.endm
16401da177e4SLinus Torvalds
1641415bfae9SAl Viro	.macro	fork_like name
1642f39cce65SHelge DellerENTRY_CFI(sys_\name\()_wrapper)
16432214c0e7SHelge Deller	mfctl	%cr30,%r1
16441da177e4SLinus Torvalds	ldo	TASK_REGS(%r1),%r1
16451da177e4SLinus Torvalds	reg_save %r1
1646ff0ab8afSAl Viro	mfctl	%cr27, %r28
1647bbbfde78SJohn David Anglin	ldil	L%sys_\name, %r31
1648bbbfde78SJohn David Anglin	be	R%sys_\name(%sr4,%r31)
1649ff0ab8afSAl Viro	STREG	%r28, PT_CR27(%r1)
1650f39cce65SHelge DellerENDPROC_CFI(sys_\name\()_wrapper)
1651415bfae9SAl Viro	.endm
16521da177e4SLinus Torvalds
1653415bfae9SAl Virofork_like clone
165445800fb4SHelge Dellerfork_like clone3
1655415bfae9SAl Virofork_like fork
1656415bfae9SAl Virofork_like vfork
16571da177e4SLinus Torvalds
16581da177e4SLinus Torvalds	/* Set the return value for the child */
16598801ccb9SHelge DellerENTRY(child_return)
16601da177e4SLinus Torvalds	BL	schedule_tail, %r2
16611da177e4SLinus Torvalds	nop
1662363806ddSAl Virofinish_child_return:
16632214c0e7SHelge Deller	mfctl	%cr30,%r1
1664ff0ab8afSAl Viro	ldo	TASK_REGS(%r1),%r1	 /* get pt regs */
1665ff0ab8afSAl Viro
1666ff0ab8afSAl Viro	LDREG	PT_CR27(%r1), %r3
1667ff0ab8afSAl Viro	mtctl	%r3, %cr27
1668ff0ab8afSAl Viro	reg_restore %r1
1669ff0ab8afSAl Viro	b	syscall_exit
16701da177e4SLinus Torvalds	copy	%r0,%r28
16718801ccb9SHelge DellerEND(child_return)
16721da177e4SLinus Torvalds
1673f39cce65SHelge DellerENTRY_CFI(sys_rt_sigreturn_wrapper)
16742214c0e7SHelge Deller	mfctl	%cr30,%r26
16751da177e4SLinus Torvalds	ldo	TASK_REGS(%r26),%r26	/* get pt regs */
16761da177e4SLinus Torvalds	/* Don't save regs, we are going to restore them from sigcontext. */
16771da177e4SLinus Torvalds	STREG	%r2, -RP_OFFSET(%r30)
1678413059f2SGrant Grundler#ifdef CONFIG_64BIT
16791da177e4SLinus Torvalds	ldo	FRAME_SIZE(%r30), %r30
16801da177e4SLinus Torvalds	BL	sys_rt_sigreturn,%r2
16811da177e4SLinus Torvalds	ldo	-16(%r30),%r29		/* Reference param save area */
16821da177e4SLinus Torvalds#else
16831da177e4SLinus Torvalds	BL	sys_rt_sigreturn,%r2
16841da177e4SLinus Torvalds	ldo	FRAME_SIZE(%r30), %r30
16851da177e4SLinus Torvalds#endif
16861da177e4SLinus Torvalds
16871da177e4SLinus Torvalds	ldo	-FRAME_SIZE(%r30), %r30
16881da177e4SLinus Torvalds	LDREG	-RP_OFFSET(%r30), %r2
16891da177e4SLinus Torvalds
16901da177e4SLinus Torvalds	/* FIXME: I think we need to restore a few more things here. */
16912214c0e7SHelge Deller	mfctl	%cr30,%r1
16921da177e4SLinus Torvalds	ldo	TASK_REGS(%r1),%r1	/* get pt regs */
16931da177e4SLinus Torvalds	reg_restore %r1
16941da177e4SLinus Torvalds
16951da177e4SLinus Torvalds	/* If the signal was received while the process was blocked on a
16961da177e4SLinus Torvalds	 * syscall, then r2 will take us to syscall_exit; otherwise r2 will
16971da177e4SLinus Torvalds	 * take us to syscall_exit_rfi and on to intr_return.
16981da177e4SLinus Torvalds	 */
16991da177e4SLinus Torvalds	bv	%r0(%r2)
17001da177e4SLinus Torvalds	LDREG	PT_GR28(%r1),%r28  /* reload original r28 for syscall_exit */
1701f39cce65SHelge DellerENDPROC_CFI(sys_rt_sigreturn_wrapper)
17021da177e4SLinus Torvalds
17038801ccb9SHelge DellerENTRY(syscall_exit)
17041da177e4SLinus Torvalds	/* NOTE: Not all syscalls exit this way.  rt_sigreturn will exit
17051da177e4SLinus Torvalds	 * via syscall_exit_rfi if the signal was received while the process
17061da177e4SLinus Torvalds	 * was running.
17071da177e4SLinus Torvalds	 */
17081da177e4SLinus Torvalds
17091da177e4SLinus Torvalds	/* save return value now */
17101da177e4SLinus Torvalds	mfctl     %cr30, %r1
17111da177e4SLinus Torvalds	STREG     %r28,TASK_PT_GR28(%r1)
17121da177e4SLinus Torvalds
17131da177e4SLinus Torvalds	/* Seems to me that dp could be wrong here, if the syscall involved
17141da177e4SLinus Torvalds	 * calling a module, and nothing got round to restoring dp on return.
17151da177e4SLinus Torvalds	 */
17161da177e4SLinus Torvalds	loadgp
17171da177e4SLinus Torvalds
17181da177e4SLinus Torvaldssyscall_check_resched:
17191da177e4SLinus Torvalds
17201da177e4SLinus Torvalds	/* check for reschedule */
17212214c0e7SHelge Deller	mfctl	%cr30,%r19
17222214c0e7SHelge Deller	LDREG	TASK_TI_FLAGS(%r19),%r19	/* long */
17231da177e4SLinus Torvalds	bb,<,n	%r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */
17241da177e4SLinus Torvalds
17254650f0a5SKyle McMartin	.import do_signal,code
17261da177e4SLinus Torvaldssyscall_check_sig:
17272214c0e7SHelge Deller	mfctl	%cr30,%r19
17282214c0e7SHelge Deller	LDREG	TASK_TI_FLAGS(%r19),%r19
1729c984baadSHelge Deller	ldi	(_TIF_USER_WORK_MASK & ~_TIF_NEED_RESCHED), %r26
17304650f0a5SKyle McMartin	and,COND(<>)	%r19, %r26, %r0
17314650f0a5SKyle McMartin	b,n	syscall_restore	/* skip past if we've nothing to do */
17324650f0a5SKyle McMartin
17334650f0a5SKyle McMartinsyscall_do_signal:
17344650f0a5SKyle McMartin	/* Save callee-save registers (for sigcontext).
17354650f0a5SKyle McMartin	 * FIXME: After this point the process structure should be
17364650f0a5SKyle McMartin	 * consistent with all the relevant state of the process
17374650f0a5SKyle McMartin	 * before the syscall.  We need to verify this.
17384650f0a5SKyle McMartin	 */
17392214c0e7SHelge Deller	mfctl	%cr30,%r1
17404650f0a5SKyle McMartin	ldo	TASK_REGS(%r1), %r26		/* struct pt_regs *regs */
17414650f0a5SKyle McMartin	reg_save %r26
17424650f0a5SKyle McMartin
17434650f0a5SKyle McMartin#ifdef CONFIG_64BIT
17444650f0a5SKyle McMartin	ldo	-16(%r30),%r29			/* Reference param save area */
17454650f0a5SKyle McMartin#endif
17464650f0a5SKyle McMartin
17474650f0a5SKyle McMartin	BL	do_notify_resume,%r2
17484650f0a5SKyle McMartin	ldi	1, %r25				/* long in_syscall = 1 */
17494650f0a5SKyle McMartin
17502214c0e7SHelge Deller	mfctl	%cr30,%r1
17514650f0a5SKyle McMartin	ldo	TASK_REGS(%r1), %r20		/* reload pt_regs */
17524650f0a5SKyle McMartin	reg_restore %r20
17534650f0a5SKyle McMartin
17544650f0a5SKyle McMartin	b,n     syscall_check_sig
17551da177e4SLinus Torvalds
17561da177e4SLinus Torvaldssyscall_restore:
17572214c0e7SHelge Deller	mfctl	%cr30,%r1
17581da177e4SLinus Torvalds
1759ecd3d4bcSKyle McMartin	/* Are we being ptraced? */
17602214c0e7SHelge Deller	LDREG	TASK_TI_FLAGS(%r1),%r19
17613ec18fc7SSven Schnelle	ldi	_TIF_SINGLESTEP|_TIF_BLOCKSTEP,%r2
1762ecd3d4bcSKyle McMartin	and,COND(=)	%r19,%r2,%r0
1763ecd3d4bcSKyle McMartin	b,n	syscall_restore_rfi
17641da177e4SLinus Torvalds
17651da177e4SLinus Torvalds	ldo	TASK_PT_FR31(%r1),%r19		   /* reload fpregs */
17661da177e4SLinus Torvalds	rest_fp	%r19
17671da177e4SLinus Torvalds
17681da177e4SLinus Torvalds	LDREG	TASK_PT_SAR(%r1),%r19		   /* restore SAR */
17691da177e4SLinus Torvalds	mtsar	%r19
17701da177e4SLinus Torvalds
17711da177e4SLinus Torvalds	LDREG	TASK_PT_GR2(%r1),%r2		   /* restore user rp */
17721da177e4SLinus Torvalds	LDREG	TASK_PT_GR19(%r1),%r19
17731da177e4SLinus Torvalds	LDREG   TASK_PT_GR20(%r1),%r20
17741da177e4SLinus Torvalds	LDREG	TASK_PT_GR21(%r1),%r21
17751da177e4SLinus Torvalds	LDREG	TASK_PT_GR22(%r1),%r22
17761da177e4SLinus Torvalds	LDREG	TASK_PT_GR23(%r1),%r23
17771da177e4SLinus Torvalds	LDREG	TASK_PT_GR24(%r1),%r24
17781da177e4SLinus Torvalds	LDREG	TASK_PT_GR25(%r1),%r25
17791da177e4SLinus Torvalds	LDREG	TASK_PT_GR26(%r1),%r26
17801da177e4SLinus Torvalds	LDREG	TASK_PT_GR27(%r1),%r27	   /* restore user dp */
17811da177e4SLinus Torvalds	LDREG	TASK_PT_GR28(%r1),%r28	   /* syscall return value */
17821da177e4SLinus Torvalds	LDREG	TASK_PT_GR29(%r1),%r29
17831da177e4SLinus Torvalds	LDREG	TASK_PT_GR31(%r1),%r31	   /* restore syscall rp */
17841da177e4SLinus Torvalds
17851da177e4SLinus Torvalds	/* NOTE: We use rsm/ssm pair to make this operation atomic */
17868f6c0c2bSJohn David Anglin	LDREG   TASK_PT_GR30(%r1),%r1              /* Get user sp */
17871da177e4SLinus Torvalds	rsm     PSW_SM_I, %r0
17888f6c0c2bSJohn David Anglin	copy    %r1,%r30                           /* Restore user sp */
17898f6c0c2bSJohn David Anglin	mfsp    %sr3,%r1                           /* Get user space id */
17901da177e4SLinus Torvalds	mtsp    %r1,%sr7                           /* Restore sr7 */
17911da177e4SLinus Torvalds	ssm     PSW_SM_I, %r0
17921da177e4SLinus Torvalds
17931da177e4SLinus Torvalds	/* Set sr2 to zero for userspace syscalls to work. */
17941da177e4SLinus Torvalds	mtsp	%r0,%sr2
17951da177e4SLinus Torvalds	mtsp	%r1,%sr4			   /* Restore sr4 */
17961da177e4SLinus Torvalds	mtsp	%r1,%sr5			   /* Restore sr5 */
17971da177e4SLinus Torvalds	mtsp	%r1,%sr6			   /* Restore sr6 */
17981da177e4SLinus Torvalds
1799f06d6e92SHelge Deller	depi	PRIV_USER,31,2,%r31	/* ensure return to user mode. */
18001da177e4SLinus Torvalds
1801413059f2SGrant Grundler#ifdef CONFIG_64BIT
18021da177e4SLinus Torvalds	/* decide whether to reset the wide mode bit
18031da177e4SLinus Torvalds	 *
18041da177e4SLinus Torvalds	 * For a syscall, the W bit is stored in the lowest bit
18051da177e4SLinus Torvalds	 * of sp.  Extract it and reset W if it is zero */
18061da177e4SLinus Torvalds	extrd,u,*<>	%r30,63,1,%r1
18071da177e4SLinus Torvalds	rsm	PSW_SM_W, %r0
18081da177e4SLinus Torvalds	/* now reset the lowest bit of sp if it was set */
18091da177e4SLinus Torvalds	xor	%r30,%r1,%r30
18101da177e4SLinus Torvalds#endif
18111da177e4SLinus Torvalds	be,n    0(%sr3,%r31)                       /* return to user space */
18121da177e4SLinus Torvalds
18131da177e4SLinus Torvalds	/* We have to return via an RFI, so that PSW T and R bits can be set
18141da177e4SLinus Torvalds	 * appropriately.
18151da177e4SLinus Torvalds	 * This sets up pt_regs so we can return via intr_restore, which is not
18161da177e4SLinus Torvalds	 * the most efficient way of doing things, but it works.
18171da177e4SLinus Torvalds	 */
18181da177e4SLinus Torvaldssyscall_restore_rfi:
18191da177e4SLinus Torvalds	ldo	-1(%r0),%r2			   /* Set recovery cntr to -1 */
18201da177e4SLinus Torvalds	mtctl	%r2,%cr0			   /*   for immediate trap */
18211da177e4SLinus Torvalds	LDREG	TASK_PT_PSW(%r1),%r2		   /* Get old PSW */
18221da177e4SLinus Torvalds	ldi	0x0b,%r20			   /* Create new PSW */
18231da177e4SLinus Torvalds	depi	-1,13,1,%r20			   /* C, Q, D, and I bits */
18241da177e4SLinus Torvalds
1825ecd3d4bcSKyle McMartin	/* The values of SINGLESTEP_BIT and BLOCKSTEP_BIT are
1826ecd3d4bcSKyle McMartin	 * set in thread_info.h and converted to PA bitmap
18271da177e4SLinus Torvalds	 * numbers in asm-offsets.c */
18281da177e4SLinus Torvalds
1829ecd3d4bcSKyle McMartin	/* if ((%r19.SINGLESTEP_BIT)) { %r20.27=1} */
1830ecd3d4bcSKyle McMartin	extru,=	%r19,TIF_SINGLESTEP_PA_BIT,1,%r0
18311da177e4SLinus Torvalds	depi	-1,27,1,%r20			   /* R bit */
18321da177e4SLinus Torvalds
1833ecd3d4bcSKyle McMartin	/* if ((%r19.BLOCKSTEP_BIT)) { %r20.7=1} */
1834ecd3d4bcSKyle McMartin	extru,= %r19,TIF_BLOCKSTEP_PA_BIT,1,%r0
18351da177e4SLinus Torvalds	depi	-1,7,1,%r20			   /* T bit */
18361da177e4SLinus Torvalds
18371da177e4SLinus Torvalds	STREG	%r20,TASK_PT_PSW(%r1)
18381da177e4SLinus Torvalds
18391da177e4SLinus Torvalds	/* Always store space registers, since sr3 can be changed (e.g. fork) */
18401da177e4SLinus Torvalds
18411da177e4SLinus Torvalds	mfsp    %sr3,%r25
18421da177e4SLinus Torvalds	STREG   %r25,TASK_PT_SR3(%r1)
18431da177e4SLinus Torvalds	STREG   %r25,TASK_PT_SR4(%r1)
18441da177e4SLinus Torvalds	STREG   %r25,TASK_PT_SR5(%r1)
18451da177e4SLinus Torvalds	STREG   %r25,TASK_PT_SR6(%r1)
18461da177e4SLinus Torvalds	STREG   %r25,TASK_PT_SR7(%r1)
18471da177e4SLinus Torvalds	STREG   %r25,TASK_PT_IASQ0(%r1)
18481da177e4SLinus Torvalds	STREG   %r25,TASK_PT_IASQ1(%r1)
18491da177e4SLinus Torvalds
18501da177e4SLinus Torvalds	/* XXX W bit??? */
18511da177e4SLinus Torvalds	/* Now if old D bit is clear, it means we didn't save all registers
18521da177e4SLinus Torvalds	 * on syscall entry, so do that now.  This only happens on TRACEME
18531da177e4SLinus Torvalds	 * calls, or if someone attached to us while we were on a syscall.
18541da177e4SLinus Torvalds	 * We could make this more efficient by not saving r3-r18, but
18551da177e4SLinus Torvalds	 * then we wouldn't be able to use the common intr_restore path.
18561da177e4SLinus Torvalds	 * It is only for traced processes anyway, so performance is not
18571da177e4SLinus Torvalds	 * an issue.
18581da177e4SLinus Torvalds	 */
18591da177e4SLinus Torvalds	bb,<	%r2,30,pt_regs_ok		   /* Branch if D set */
18601da177e4SLinus Torvalds	ldo	TASK_REGS(%r1),%r25
18611da177e4SLinus Torvalds	reg_save %r25				   /* Save r3 to r18 */
18621da177e4SLinus Torvalds
18631da177e4SLinus Torvalds	/* Save the current sr */
18641da177e4SLinus Torvalds	mfsp	%sr0,%r2
18651da177e4SLinus Torvalds	STREG	%r2,TASK_PT_SR0(%r1)
18661da177e4SLinus Torvalds
18671da177e4SLinus Torvalds	/* Save the scratch sr */
18681da177e4SLinus Torvalds	mfsp	%sr1,%r2
18691da177e4SLinus Torvalds	STREG	%r2,TASK_PT_SR1(%r1)
18701da177e4SLinus Torvalds
18711da177e4SLinus Torvalds	/* sr2 should be set to zero for userspace syscalls */
18721da177e4SLinus Torvalds	STREG	%r0,TASK_PT_SR2(%r1)
18731da177e4SLinus Torvalds
18741da177e4SLinus Torvalds	LDREG	TASK_PT_GR31(%r1),%r2
1875f06d6e92SHelge Deller	depi	PRIV_USER,31,2,%r2	/* ensure return to user mode. */
18761da177e4SLinus Torvalds	STREG   %r2,TASK_PT_IAOQ0(%r1)
18771da177e4SLinus Torvalds	ldo	4(%r2),%r2
18781da177e4SLinus Torvalds	STREG	%r2,TASK_PT_IAOQ1(%r1)
18791da177e4SLinus Torvalds	b	intr_restore
188034360f08SJohn David Anglin	copy	%r25,%r16
188134360f08SJohn David Anglin
188234360f08SJohn David Anglinpt_regs_ok:
188334360f08SJohn David Anglin	LDREG	TASK_PT_IAOQ0(%r1),%r2
1884f06d6e92SHelge Deller	depi	PRIV_USER,31,2,%r2	/* ensure return to user mode. */
188534360f08SJohn David Anglin	STREG	%r2,TASK_PT_IAOQ0(%r1)
188634360f08SJohn David Anglin	LDREG	TASK_PT_IAOQ1(%r1),%r2
1887f06d6e92SHelge Deller	depi	PRIV_USER,31,2,%r2
188834360f08SJohn David Anglin	STREG	%r2,TASK_PT_IAOQ1(%r1)
188934360f08SJohn David Anglin	b	intr_restore
189034360f08SJohn David Anglin	copy	%r25,%r16
18911da177e4SLinus Torvalds
18921da177e4SLinus Torvaldssyscall_do_resched:
1893366dd4eaSHelge Deller	load32	syscall_check_resched,%r2 /* if resched, we start over again */
1894366dd4eaSHelge Deller	load32	schedule,%r19
1895366dd4eaSHelge Deller	bv	%r0(%r19)		/* jumps to schedule() */
1896413059f2SGrant Grundler#ifdef CONFIG_64BIT
18971da177e4SLinus Torvalds	ldo	-16(%r30),%r29		/* Reference param save area */
18981da177e4SLinus Torvalds#else
18991da177e4SLinus Torvalds	nop
19001da177e4SLinus Torvalds#endif
19018801ccb9SHelge DellerEND(syscall_exit)
19021da177e4SLinus Torvalds
1903c5e76552SHelge Deller
1904d75f054aSHelge Deller#ifdef CONFIG_FUNCTION_TRACER
1905366dd4eaSHelge Deller
1906d75f054aSHelge Deller	.import ftrace_function_trampoline,code
1907366dd4eaSHelge Deller	.align L1_CACHE_BYTES
1908c8921d72SHelge DellerENTRY_CFI(mcount, caller)
1909366dd4eaSHelge Deller_mcount:
1910366dd4eaSHelge Deller	.export _mcount,data
1911366dd4eaSHelge Deller	/*
1912366dd4eaSHelge Deller	 * The 64bit mcount() function pointer needs 4 dwords, of which the
1913366dd4eaSHelge Deller	 * first two are free.  We optimize it here and put 2 instructions for
1914366dd4eaSHelge Deller	 * calling mcount(), and 2 instructions for ftrace_stub().  That way we
1915366dd4eaSHelge Deller	 * have all on one L1 cacheline.
1916366dd4eaSHelge Deller	 */
191752a22e6cSSven Schnelle	ldi	0, %arg3
1918d75f054aSHelge Deller	b	ftrace_function_trampoline
1919366dd4eaSHelge Deller	copy	%r3, %arg2	/* caller original %sp */
1920d75f054aSHelge Dellerftrace_stub:
1921366dd4eaSHelge Deller	.globl ftrace_stub
1922366dd4eaSHelge Deller        .type  ftrace_stub, @function
1923366dd4eaSHelge Deller#ifdef CONFIG_64BIT
1924366dd4eaSHelge Deller	bve	(%rp)
1925366dd4eaSHelge Deller#else
1926d75f054aSHelge Deller	bv	%r0(%rp)
1927366dd4eaSHelge Deller#endif
1928d75f054aSHelge Deller	nop
1929366dd4eaSHelge Deller#ifdef CONFIG_64BIT
1930366dd4eaSHelge Deller	.dword mcount
1931366dd4eaSHelge Deller	.dword 0 /* code in head.S puts value of global gp here */
1932366dd4eaSHelge Deller#endif
1933c8921d72SHelge DellerENDPROC_CFI(mcount)
1934366dd4eaSHelge Deller
19356ca63662SSven Schnelle#ifdef CONFIG_DYNAMIC_FTRACE
19366ca63662SSven Schnelle
19376ca63662SSven Schnelle#ifdef CONFIG_64BIT
19386ca63662SSven Schnelle#define FTRACE_FRAME_SIZE (2*FRAME_SIZE)
19396ca63662SSven Schnelle#else
19406ca63662SSven Schnelle#define FTRACE_FRAME_SIZE FRAME_SIZE
19416ca63662SSven Schnelle#endif
19426ca63662SSven SchnelleENTRY_CFI(ftrace_caller, caller,frame=FTRACE_FRAME_SIZE,CALLS,SAVE_RP,SAVE_SP)
19436ca63662SSven Schnelleftrace_caller:
19446ca63662SSven Schnelle	.global ftrace_caller
19456ca63662SSven Schnelle
19466ca63662SSven Schnelle	STREG	%r3, -FTRACE_FRAME_SIZE+1*REG_SZ(%sp)
19476ca63662SSven Schnelle	ldo	-FTRACE_FRAME_SIZE(%sp), %r3
19486ca63662SSven Schnelle	STREG	%rp, -RP_OFFSET(%r3)
19496ca63662SSven Schnelle
19506ca63662SSven Schnelle	/* Offset 0 is already allocated for %r1 */
19516ca63662SSven Schnelle	STREG	%r23, 2*REG_SZ(%r3)
19526ca63662SSven Schnelle	STREG	%r24, 3*REG_SZ(%r3)
19536ca63662SSven Schnelle	STREG	%r25, 4*REG_SZ(%r3)
19546ca63662SSven Schnelle	STREG	%r26, 5*REG_SZ(%r3)
19556ca63662SSven Schnelle	STREG	%r28, 6*REG_SZ(%r3)
19566ca63662SSven Schnelle	STREG	%r29, 7*REG_SZ(%r3)
19576ca63662SSven Schnelle#ifdef CONFIG_64BIT
19586ca63662SSven Schnelle	STREG	%r19, 8*REG_SZ(%r3)
19596ca63662SSven Schnelle	STREG	%r20, 9*REG_SZ(%r3)
19606ca63662SSven Schnelle	STREG	%r21, 10*REG_SZ(%r3)
19616ca63662SSven Schnelle	STREG	%r22, 11*REG_SZ(%r3)
19626ca63662SSven Schnelle	STREG	%r27, 12*REG_SZ(%r3)
19636ca63662SSven Schnelle	STREG	%r31, 13*REG_SZ(%r3)
19646ca63662SSven Schnelle	loadgp
19656ca63662SSven Schnelle	ldo	-16(%sp),%r29
19666ca63662SSven Schnelle#endif
19676ca63662SSven Schnelle	LDREG	0(%r3), %r25
19686ca63662SSven Schnelle	copy	%rp, %r26
19696ca63662SSven Schnelle	ldo	-8(%r25), %r25
197052a22e6cSSven Schnelle	ldi	0, %r23		/* no pt_regs */
19716ca63662SSven Schnelle	b,l	ftrace_function_trampoline, %rp
19726ca63662SSven Schnelle	copy	%r3, %r24
19736ca63662SSven Schnelle
19746ca63662SSven Schnelle	LDREG	-RP_OFFSET(%r3), %rp
19756ca63662SSven Schnelle	LDREG	2*REG_SZ(%r3), %r23
19766ca63662SSven Schnelle	LDREG	3*REG_SZ(%r3), %r24
19776ca63662SSven Schnelle	LDREG	4*REG_SZ(%r3), %r25
19786ca63662SSven Schnelle	LDREG	5*REG_SZ(%r3), %r26
19796ca63662SSven Schnelle	LDREG	6*REG_SZ(%r3), %r28
19806ca63662SSven Schnelle	LDREG	7*REG_SZ(%r3), %r29
19816ca63662SSven Schnelle#ifdef CONFIG_64BIT
19826ca63662SSven Schnelle	LDREG	8*REG_SZ(%r3), %r19
19836ca63662SSven Schnelle	LDREG	9*REG_SZ(%r3), %r20
19846ca63662SSven Schnelle	LDREG	10*REG_SZ(%r3), %r21
19856ca63662SSven Schnelle	LDREG	11*REG_SZ(%r3), %r22
19866ca63662SSven Schnelle	LDREG	12*REG_SZ(%r3), %r27
19876ca63662SSven Schnelle	LDREG	13*REG_SZ(%r3), %r31
19886ca63662SSven Schnelle#endif
19896ca63662SSven Schnelle	LDREG	1*REG_SZ(%r3), %r3
19906ca63662SSven Schnelle
19916ca63662SSven Schnelle	LDREGM	-FTRACE_FRAME_SIZE(%sp), %r1
19926ca63662SSven Schnelle	/* Adjust return point to jump back to beginning of traced function */
19936ca63662SSven Schnelle	ldo	-4(%r1), %r1
19946ca63662SSven Schnelle	bv,n	(%r1)
19956ca63662SSven Schnelle
19966ca63662SSven SchnelleENDPROC_CFI(ftrace_caller)
19976ca63662SSven Schnelle
199852a22e6cSSven Schnelle#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS
199952a22e6cSSven SchnelleENTRY_CFI(ftrace_regs_caller,caller,frame=FTRACE_FRAME_SIZE+PT_SZ_ALGN,
200052a22e6cSSven Schnelle	CALLS,SAVE_RP,SAVE_SP)
200152a22e6cSSven Schnelleftrace_regs_caller:
200252a22e6cSSven Schnelle	.global ftrace_regs_caller
200352a22e6cSSven Schnelle
200452a22e6cSSven Schnelle	ldo	-FTRACE_FRAME_SIZE(%sp), %r1
200552a22e6cSSven Schnelle	STREG	%rp, -RP_OFFSET(%r1)
200652a22e6cSSven Schnelle
200752a22e6cSSven Schnelle	copy	%sp, %r1
200852a22e6cSSven Schnelle	ldo	PT_SZ_ALGN(%sp), %sp
200952a22e6cSSven Schnelle
201052a22e6cSSven Schnelle	STREG	%rp, PT_GR2(%r1)
201152a22e6cSSven Schnelle	STREG	%r3, PT_GR3(%r1)
201252a22e6cSSven Schnelle	STREG	%r4, PT_GR4(%r1)
201352a22e6cSSven Schnelle	STREG	%r5, PT_GR5(%r1)
201452a22e6cSSven Schnelle	STREG	%r6, PT_GR6(%r1)
201552a22e6cSSven Schnelle	STREG	%r7, PT_GR7(%r1)
201652a22e6cSSven Schnelle	STREG	%r8, PT_GR8(%r1)
201752a22e6cSSven Schnelle	STREG	%r9, PT_GR9(%r1)
201852a22e6cSSven Schnelle	STREG   %r10, PT_GR10(%r1)
201952a22e6cSSven Schnelle	STREG   %r11, PT_GR11(%r1)
202052a22e6cSSven Schnelle	STREG   %r12, PT_GR12(%r1)
202152a22e6cSSven Schnelle	STREG   %r13, PT_GR13(%r1)
202252a22e6cSSven Schnelle	STREG   %r14, PT_GR14(%r1)
202352a22e6cSSven Schnelle	STREG   %r15, PT_GR15(%r1)
202452a22e6cSSven Schnelle	STREG   %r16, PT_GR16(%r1)
202552a22e6cSSven Schnelle	STREG   %r17, PT_GR17(%r1)
202652a22e6cSSven Schnelle	STREG   %r18, PT_GR18(%r1)
202752a22e6cSSven Schnelle	STREG	%r19, PT_GR19(%r1)
202852a22e6cSSven Schnelle	STREG	%r20, PT_GR20(%r1)
202952a22e6cSSven Schnelle	STREG	%r21, PT_GR21(%r1)
203052a22e6cSSven Schnelle	STREG	%r22, PT_GR22(%r1)
203152a22e6cSSven Schnelle	STREG	%r23, PT_GR23(%r1)
203252a22e6cSSven Schnelle	STREG	%r24, PT_GR24(%r1)
203352a22e6cSSven Schnelle	STREG	%r25, PT_GR25(%r1)
203452a22e6cSSven Schnelle	STREG	%r26, PT_GR26(%r1)
203552a22e6cSSven Schnelle	STREG	%r27, PT_GR27(%r1)
203652a22e6cSSven Schnelle	STREG	%r28, PT_GR28(%r1)
203752a22e6cSSven Schnelle	STREG	%r29, PT_GR29(%r1)
203852a22e6cSSven Schnelle	STREG	%r30, PT_GR30(%r1)
203952a22e6cSSven Schnelle	STREG	%r31, PT_GR31(%r1)
204052a22e6cSSven Schnelle	mfctl	%cr11, %r26
204152a22e6cSSven Schnelle	STREG	%r26, PT_SAR(%r1)
204252a22e6cSSven Schnelle
204352a22e6cSSven Schnelle	copy	%rp, %r26
204452a22e6cSSven Schnelle	LDREG	-FTRACE_FRAME_SIZE-PT_SZ_ALGN(%sp), %r25
204552a22e6cSSven Schnelle	ldo	-8(%r25), %r25
20463d252454SSven Schnelle	ldo	-FTRACE_FRAME_SIZE(%r1), %arg2
204752a22e6cSSven Schnelle	b,l	ftrace_function_trampoline, %rp
204852a22e6cSSven Schnelle	copy	%r1, %arg3 /* struct pt_regs */
204952a22e6cSSven Schnelle
205052a22e6cSSven Schnelle	ldo	-PT_SZ_ALGN(%sp), %r1
205152a22e6cSSven Schnelle
205252a22e6cSSven Schnelle	LDREG	PT_SAR(%r1), %rp
205352a22e6cSSven Schnelle	mtctl	%rp, %cr11
205452a22e6cSSven Schnelle
205552a22e6cSSven Schnelle	LDREG	PT_GR2(%r1), %rp
205652a22e6cSSven Schnelle	LDREG	PT_GR3(%r1), %r3
205752a22e6cSSven Schnelle	LDREG	PT_GR4(%r1), %r4
205852a22e6cSSven Schnelle	LDREG	PT_GR5(%r1), %r5
205952a22e6cSSven Schnelle	LDREG	PT_GR6(%r1), %r6
206052a22e6cSSven Schnelle	LDREG	PT_GR7(%r1), %r7
206152a22e6cSSven Schnelle	LDREG	PT_GR8(%r1), %r8
206252a22e6cSSven Schnelle	LDREG	PT_GR9(%r1), %r9
206352a22e6cSSven Schnelle	LDREG   PT_GR10(%r1),%r10
206452a22e6cSSven Schnelle	LDREG   PT_GR11(%r1),%r11
206552a22e6cSSven Schnelle	LDREG   PT_GR12(%r1),%r12
206652a22e6cSSven Schnelle	LDREG   PT_GR13(%r1),%r13
206752a22e6cSSven Schnelle	LDREG   PT_GR14(%r1),%r14
206852a22e6cSSven Schnelle	LDREG   PT_GR15(%r1),%r15
206952a22e6cSSven Schnelle	LDREG   PT_GR16(%r1),%r16
207052a22e6cSSven Schnelle	LDREG   PT_GR17(%r1),%r17
207152a22e6cSSven Schnelle	LDREG   PT_GR18(%r1),%r18
207252a22e6cSSven Schnelle	LDREG   PT_GR19(%r1),%r19
207352a22e6cSSven Schnelle	LDREG   PT_GR20(%r1),%r20
207452a22e6cSSven Schnelle	LDREG   PT_GR21(%r1),%r21
207552a22e6cSSven Schnelle	LDREG   PT_GR22(%r1),%r22
207652a22e6cSSven Schnelle	LDREG   PT_GR23(%r1),%r23
207752a22e6cSSven Schnelle	LDREG   PT_GR24(%r1),%r24
207852a22e6cSSven Schnelle	LDREG   PT_GR25(%r1),%r25
207952a22e6cSSven Schnelle	LDREG   PT_GR26(%r1),%r26
208052a22e6cSSven Schnelle	LDREG   PT_GR27(%r1),%r27
208152a22e6cSSven Schnelle	LDREG   PT_GR28(%r1),%r28
208252a22e6cSSven Schnelle	LDREG   PT_GR29(%r1),%r29
208352a22e6cSSven Schnelle	LDREG   PT_GR30(%r1),%r30
208452a22e6cSSven Schnelle	LDREG   PT_GR31(%r1),%r31
208552a22e6cSSven Schnelle
208652a22e6cSSven Schnelle	ldo	-PT_SZ_ALGN(%sp), %sp
208752a22e6cSSven Schnelle	LDREGM	-FTRACE_FRAME_SIZE(%sp), %r1
208852a22e6cSSven Schnelle	/* Adjust return point to jump back to beginning of traced function */
208952a22e6cSSven Schnelle	ldo	-4(%r1), %r1
209052a22e6cSSven Schnelle	bv,n	(%r1)
209152a22e6cSSven Schnelle
209252a22e6cSSven SchnelleENDPROC_CFI(ftrace_regs_caller)
209352a22e6cSSven Schnelle
209452a22e6cSSven Schnelle#endif
20956ca63662SSven Schnelle#endif
20966ca63662SSven Schnelle
20975fece5adSHelge Deller#ifdef CONFIG_FUNCTION_GRAPH_TRACER
2098366dd4eaSHelge Deller	.align 8
2099c8921d72SHelge DellerENTRY_CFI(return_to_handler, caller,frame=FRAME_SIZE)
2100366dd4eaSHelge Deller	.export parisc_return_to_handler,data
2101366dd4eaSHelge Dellerparisc_return_to_handler:
2102366dd4eaSHelge Deller	copy %r3,%r1
2103366dd4eaSHelge Deller	STREG %r0,-RP_OFFSET(%sp)	/* store 0 as %rp */
2104366dd4eaSHelge Deller	copy %sp,%r3
2105366dd4eaSHelge Deller	STREGM %r1,FRAME_SIZE(%sp)
2106366dd4eaSHelge Deller	STREG %ret0,8(%r3)
2107366dd4eaSHelge Deller	STREG %ret1,16(%r3)
2108366dd4eaSHelge Deller
2109366dd4eaSHelge Deller#ifdef CONFIG_64BIT
2110366dd4eaSHelge Deller	loadgp
2111366dd4eaSHelge Deller#endif
2112366dd4eaSHelge Deller
2113366dd4eaSHelge Deller	/* call ftrace_return_to_handler(0) */
21145fece5adSHelge Deller	.import ftrace_return_to_handler,code
21155fece5adSHelge Deller	load32 ftrace_return_to_handler,%ret0
21165fece5adSHelge Deller	load32 .Lftrace_ret,%r2
2117366dd4eaSHelge Deller#ifdef CONFIG_64BIT
2118366dd4eaSHelge Deller	ldo -16(%sp),%ret1		/* Reference param save area */
21195fece5adSHelge Deller	bve	(%ret0)
21205fece5adSHelge Deller#else
21215fece5adSHelge Deller	bv	%r0(%ret0)
2122366dd4eaSHelge Deller#endif
2123366dd4eaSHelge Deller	ldi 0,%r26
21245fece5adSHelge Deller.Lftrace_ret:
2125366dd4eaSHelge Deller	copy %ret0,%rp
2126366dd4eaSHelge Deller
2127366dd4eaSHelge Deller	/* restore original return values */
2128366dd4eaSHelge Deller	LDREG 8(%r3),%ret0
2129366dd4eaSHelge Deller	LDREG 16(%r3),%ret1
2130366dd4eaSHelge Deller
2131366dd4eaSHelge Deller	/* return from function */
2132366dd4eaSHelge Deller#ifdef CONFIG_64BIT
2133366dd4eaSHelge Deller	bve	(%rp)
2134366dd4eaSHelge Deller#else
2135366dd4eaSHelge Deller	bv	%r0(%rp)
2136366dd4eaSHelge Deller#endif
2137366dd4eaSHelge Deller	LDREGM -FRAME_SIZE(%sp),%r3
2138f39cce65SHelge DellerENDPROC_CFI(return_to_handler)
2139366dd4eaSHelge Deller
21405fece5adSHelge Deller#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
21415fece5adSHelge Deller
2142d75f054aSHelge Deller#endif	/* CONFIG_FUNCTION_TRACER */
2143d75f054aSHelge Deller
2144200c8804SHelge Deller#ifdef CONFIG_IRQSTACKS
2145200c8804SHelge Deller/* void call_on_stack(unsigned long param1, void *func,
2146200c8804SHelge Deller		      unsigned long new_stack) */
2147c8921d72SHelge DellerENTRY_CFI(call_on_stack, FRAME=2*FRAME_SIZE,CALLS,SAVE_RP,SAVE_SP)
21488801ccb9SHelge DellerENTRY(_call_on_stack)
2149200c8804SHelge Deller	copy	%sp, %r1
2150200c8804SHelge Deller
2151200c8804SHelge Deller	/* Regarding the HPPA calling conventions for function pointers,
2152200c8804SHelge Deller	   we assume the PIC register is not changed across call.  For
2153200c8804SHelge Deller	   CONFIG_64BIT, the argument pointer is left to point at the
2154200c8804SHelge Deller	   argument region allocated for the call to call_on_stack. */
2155c8921d72SHelge Deller
2156c8921d72SHelge Deller	/* Switch to new stack.  We allocate two frames.  */
2157c8921d72SHelge Deller	ldo	2*FRAME_SIZE(%arg2), %sp
2158200c8804SHelge Deller# ifdef CONFIG_64BIT
2159200c8804SHelge Deller	/* Save previous stack pointer and return pointer in frame marker */
2160c8921d72SHelge Deller	STREG	%rp, -FRAME_SIZE-RP_OFFSET(%sp)
2161200c8804SHelge Deller	/* Calls always use function descriptor */
2162200c8804SHelge Deller	LDREG	16(%arg1), %arg1
2163200c8804SHelge Deller	bve,l	(%arg1), %rp
2164c8921d72SHelge Deller	STREG	%r1, -FRAME_SIZE-REG_SZ(%sp)
2165c8921d72SHelge Deller	LDREG	-FRAME_SIZE-RP_OFFSET(%sp), %rp
2166200c8804SHelge Deller	bve	(%rp)
2167c8921d72SHelge Deller	LDREG	-FRAME_SIZE-REG_SZ(%sp), %sp
2168200c8804SHelge Deller# else
2169200c8804SHelge Deller	/* Save previous stack pointer and return pointer in frame marker */
2170c8921d72SHelge Deller	STREG	%r1, -FRAME_SIZE-REG_SZ(%sp)
2171c8921d72SHelge Deller	STREG	%rp, -FRAME_SIZE-RP_OFFSET(%sp)
2172200c8804SHelge Deller	/* Calls use function descriptor if PLABEL bit is set */
2173200c8804SHelge Deller	bb,>=,n	%arg1, 30, 1f
2174200c8804SHelge Deller	depwi	0,31,2, %arg1
2175200c8804SHelge Deller	LDREG	0(%arg1), %arg1
2176200c8804SHelge Deller1:
2177200c8804SHelge Deller	be,l	0(%sr4,%arg1), %sr0, %r31
2178200c8804SHelge Deller	copy	%r31, %rp
2179c8921d72SHelge Deller	LDREG	-FRAME_SIZE-RP_OFFSET(%sp), %rp
2180200c8804SHelge Deller	bv	(%rp)
2181c8921d72SHelge Deller	LDREG	-FRAME_SIZE-REG_SZ(%sp), %sp
2182200c8804SHelge Deller# endif /* CONFIG_64BIT */
2183f39cce65SHelge DellerENDPROC_CFI(call_on_stack)
2184200c8804SHelge Deller#endif /* CONFIG_IRQSTACKS */
2185d75f054aSHelge Deller
2186f39cce65SHelge DellerENTRY_CFI(get_register)
21871da177e4SLinus Torvalds	/*
21881da177e4SLinus Torvalds	 * get_register is used by the non access tlb miss handlers to
21891da177e4SLinus Torvalds	 * copy the value of the general register specified in r8 into
21901da177e4SLinus Torvalds	 * r1. This routine can't be used for shadowed registers, since
21911da177e4SLinus Torvalds	 * the rfir will restore the original value. So, for the shadowed
21921da177e4SLinus Torvalds	 * registers we put a -1 into r1 to indicate that the register
21931da177e4SLinus Torvalds	 * should not be used (the register being copied could also have
21941da177e4SLinus Torvalds	 * a -1 in it, but that is OK, it just means that we will have
21951da177e4SLinus Torvalds	 * to use the slow path instead).
21961da177e4SLinus Torvalds	 */
21971da177e4SLinus Torvalds	blr     %r8,%r0
21981da177e4SLinus Torvalds	nop
21991da177e4SLinus Torvalds	bv      %r0(%r25)    /* r0 */
22001da177e4SLinus Torvalds	copy    %r0,%r1
22011da177e4SLinus Torvalds	bv      %r0(%r25)    /* r1 - shadowed */
22021da177e4SLinus Torvalds	ldi     -1,%r1
22031da177e4SLinus Torvalds	bv      %r0(%r25)    /* r2 */
22041da177e4SLinus Torvalds	copy    %r2,%r1
22051da177e4SLinus Torvalds	bv      %r0(%r25)    /* r3 */
22061da177e4SLinus Torvalds	copy    %r3,%r1
22071da177e4SLinus Torvalds	bv      %r0(%r25)    /* r4 */
22081da177e4SLinus Torvalds	copy    %r4,%r1
22091da177e4SLinus Torvalds	bv      %r0(%r25)    /* r5 */
22101da177e4SLinus Torvalds	copy    %r5,%r1
22111da177e4SLinus Torvalds	bv      %r0(%r25)    /* r6 */
22121da177e4SLinus Torvalds	copy    %r6,%r1
22131da177e4SLinus Torvalds	bv      %r0(%r25)    /* r7 */
22141da177e4SLinus Torvalds	copy    %r7,%r1
22151da177e4SLinus Torvalds	bv      %r0(%r25)    /* r8 - shadowed */
22161da177e4SLinus Torvalds	ldi     -1,%r1
22171da177e4SLinus Torvalds	bv      %r0(%r25)    /* r9 - shadowed */
22181da177e4SLinus Torvalds	ldi     -1,%r1
22191da177e4SLinus Torvalds	bv      %r0(%r25)    /* r10 */
22201da177e4SLinus Torvalds	copy    %r10,%r1
22211da177e4SLinus Torvalds	bv      %r0(%r25)    /* r11 */
22221da177e4SLinus Torvalds	copy    %r11,%r1
22231da177e4SLinus Torvalds	bv      %r0(%r25)    /* r12 */
22241da177e4SLinus Torvalds	copy    %r12,%r1
22251da177e4SLinus Torvalds	bv      %r0(%r25)    /* r13 */
22261da177e4SLinus Torvalds	copy    %r13,%r1
22271da177e4SLinus Torvalds	bv      %r0(%r25)    /* r14 */
22281da177e4SLinus Torvalds	copy    %r14,%r1
22291da177e4SLinus Torvalds	bv      %r0(%r25)    /* r15 */
22301da177e4SLinus Torvalds	copy    %r15,%r1
22311da177e4SLinus Torvalds	bv      %r0(%r25)    /* r16 - shadowed */
22321da177e4SLinus Torvalds	ldi     -1,%r1
22331da177e4SLinus Torvalds	bv      %r0(%r25)    /* r17 - shadowed */
22341da177e4SLinus Torvalds	ldi     -1,%r1
22351da177e4SLinus Torvalds	bv      %r0(%r25)    /* r18 */
22361da177e4SLinus Torvalds	copy    %r18,%r1
22371da177e4SLinus Torvalds	bv      %r0(%r25)    /* r19 */
22381da177e4SLinus Torvalds	copy    %r19,%r1
22391da177e4SLinus Torvalds	bv      %r0(%r25)    /* r20 */
22401da177e4SLinus Torvalds	copy    %r20,%r1
22411da177e4SLinus Torvalds	bv      %r0(%r25)    /* r21 */
22421da177e4SLinus Torvalds	copy    %r21,%r1
22431da177e4SLinus Torvalds	bv      %r0(%r25)    /* r22 */
22441da177e4SLinus Torvalds	copy    %r22,%r1
22451da177e4SLinus Torvalds	bv      %r0(%r25)    /* r23 */
22461da177e4SLinus Torvalds	copy    %r23,%r1
22471da177e4SLinus Torvalds	bv      %r0(%r25)    /* r24 - shadowed */
22481da177e4SLinus Torvalds	ldi     -1,%r1
22491da177e4SLinus Torvalds	bv      %r0(%r25)    /* r25 - shadowed */
22501da177e4SLinus Torvalds	ldi     -1,%r1
22511da177e4SLinus Torvalds	bv      %r0(%r25)    /* r26 */
22521da177e4SLinus Torvalds	copy    %r26,%r1
22531da177e4SLinus Torvalds	bv      %r0(%r25)    /* r27 */
22541da177e4SLinus Torvalds	copy    %r27,%r1
22551da177e4SLinus Torvalds	bv      %r0(%r25)    /* r28 */
22561da177e4SLinus Torvalds	copy    %r28,%r1
22571da177e4SLinus Torvalds	bv      %r0(%r25)    /* r29 */
22581da177e4SLinus Torvalds	copy    %r29,%r1
22591da177e4SLinus Torvalds	bv      %r0(%r25)    /* r30 */
22601da177e4SLinus Torvalds	copy    %r30,%r1
22611da177e4SLinus Torvalds	bv      %r0(%r25)    /* r31 */
22621da177e4SLinus Torvalds	copy    %r31,%r1
2263f39cce65SHelge DellerENDPROC_CFI(get_register)
22641da177e4SLinus Torvalds
2265c5e76552SHelge Deller
2266f39cce65SHelge DellerENTRY_CFI(set_register)
22671da177e4SLinus Torvalds	/*
22681da177e4SLinus Torvalds	 * set_register is used by the non access tlb miss handlers to
22691da177e4SLinus Torvalds	 * copy the value of r1 into the general register specified in
22701da177e4SLinus Torvalds	 * r8.
22711da177e4SLinus Torvalds	 */
22721da177e4SLinus Torvalds	blr     %r8,%r0
22731da177e4SLinus Torvalds	nop
22741da177e4SLinus Torvalds	bv      %r0(%r25)    /* r0 (silly, but it is a place holder) */
22751da177e4SLinus Torvalds	copy    %r1,%r0
22761da177e4SLinus Torvalds	bv      %r0(%r25)    /* r1 */
22771da177e4SLinus Torvalds	copy    %r1,%r1
22781da177e4SLinus Torvalds	bv      %r0(%r25)    /* r2 */
22791da177e4SLinus Torvalds	copy    %r1,%r2
22801da177e4SLinus Torvalds	bv      %r0(%r25)    /* r3 */
22811da177e4SLinus Torvalds	copy    %r1,%r3
22821da177e4SLinus Torvalds	bv      %r0(%r25)    /* r4 */
22831da177e4SLinus Torvalds	copy    %r1,%r4
22841da177e4SLinus Torvalds	bv      %r0(%r25)    /* r5 */
22851da177e4SLinus Torvalds	copy    %r1,%r5
22861da177e4SLinus Torvalds	bv      %r0(%r25)    /* r6 */
22871da177e4SLinus Torvalds	copy    %r1,%r6
22881da177e4SLinus Torvalds	bv      %r0(%r25)    /* r7 */
22891da177e4SLinus Torvalds	copy    %r1,%r7
22901da177e4SLinus Torvalds	bv      %r0(%r25)    /* r8 */
22911da177e4SLinus Torvalds	copy    %r1,%r8
22921da177e4SLinus Torvalds	bv      %r0(%r25)    /* r9 */
22931da177e4SLinus Torvalds	copy    %r1,%r9
22941da177e4SLinus Torvalds	bv      %r0(%r25)    /* r10 */
22951da177e4SLinus Torvalds	copy    %r1,%r10
22961da177e4SLinus Torvalds	bv      %r0(%r25)    /* r11 */
22971da177e4SLinus Torvalds	copy    %r1,%r11
22981da177e4SLinus Torvalds	bv      %r0(%r25)    /* r12 */
22991da177e4SLinus Torvalds	copy    %r1,%r12
23001da177e4SLinus Torvalds	bv      %r0(%r25)    /* r13 */
23011da177e4SLinus Torvalds	copy    %r1,%r13
23021da177e4SLinus Torvalds	bv      %r0(%r25)    /* r14 */
23031da177e4SLinus Torvalds	copy    %r1,%r14
23041da177e4SLinus Torvalds	bv      %r0(%r25)    /* r15 */
23051da177e4SLinus Torvalds	copy    %r1,%r15
23061da177e4SLinus Torvalds	bv      %r0(%r25)    /* r16 */
23071da177e4SLinus Torvalds	copy    %r1,%r16
23081da177e4SLinus Torvalds	bv      %r0(%r25)    /* r17 */
23091da177e4SLinus Torvalds	copy    %r1,%r17
23101da177e4SLinus Torvalds	bv      %r0(%r25)    /* r18 */
23111da177e4SLinus Torvalds	copy    %r1,%r18
23121da177e4SLinus Torvalds	bv      %r0(%r25)    /* r19 */
23131da177e4SLinus Torvalds	copy    %r1,%r19
23141da177e4SLinus Torvalds	bv      %r0(%r25)    /* r20 */
23151da177e4SLinus Torvalds	copy    %r1,%r20
23161da177e4SLinus Torvalds	bv      %r0(%r25)    /* r21 */
23171da177e4SLinus Torvalds	copy    %r1,%r21
23181da177e4SLinus Torvalds	bv      %r0(%r25)    /* r22 */
23191da177e4SLinus Torvalds	copy    %r1,%r22
23201da177e4SLinus Torvalds	bv      %r0(%r25)    /* r23 */
23211da177e4SLinus Torvalds	copy    %r1,%r23
23221da177e4SLinus Torvalds	bv      %r0(%r25)    /* r24 */
23231da177e4SLinus Torvalds	copy    %r1,%r24
23241da177e4SLinus Torvalds	bv      %r0(%r25)    /* r25 */
23251da177e4SLinus Torvalds	copy    %r1,%r25
23261da177e4SLinus Torvalds	bv      %r0(%r25)    /* r26 */
23271da177e4SLinus Torvalds	copy    %r1,%r26
23281da177e4SLinus Torvalds	bv      %r0(%r25)    /* r27 */
23291da177e4SLinus Torvalds	copy    %r1,%r27
23301da177e4SLinus Torvalds	bv      %r0(%r25)    /* r28 */
23311da177e4SLinus Torvalds	copy    %r1,%r28
23321da177e4SLinus Torvalds	bv      %r0(%r25)    /* r29 */
23331da177e4SLinus Torvalds	copy    %r1,%r29
23341da177e4SLinus Torvalds	bv      %r0(%r25)    /* r30 */
23351da177e4SLinus Torvalds	copy    %r1,%r30
23361da177e4SLinus Torvalds	bv      %r0(%r25)    /* r31 */
23371da177e4SLinus Torvalds	copy    %r1,%r31
2338f39cce65SHelge DellerENDPROC_CFI(set_register)
2339c5e76552SHelge Deller
2340