xref: /linux/arch/parisc/kernel/pacache.S (revision 2a03bb9e7af2052ad6990bf417a3ba9ff7e8900e)
11da177e4SLinus Torvalds/*
21da177e4SLinus Torvalds *  PARISC TLB and cache flushing support
31da177e4SLinus Torvalds *  Copyright (C) 2000-2001 Hewlett-Packard (John Marvin)
41da177e4SLinus Torvalds *  Copyright (C) 2001 Matthew Wilcox (willy at parisc-linux.org)
51da177e4SLinus Torvalds *  Copyright (C) 2002 Richard Hirst (rhirst with parisc-linux.org)
61da177e4SLinus Torvalds *
71da177e4SLinus Torvalds *    This program is free software; you can redistribute it and/or modify
81da177e4SLinus Torvalds *    it under the terms of the GNU General Public License as published by
91da177e4SLinus Torvalds *    the Free Software Foundation; either version 2, or (at your option)
101da177e4SLinus Torvalds *    any later version.
111da177e4SLinus Torvalds *
121da177e4SLinus Torvalds *    This program is distributed in the hope that it will be useful,
131da177e4SLinus Torvalds *    but WITHOUT ANY WARRANTY; without even the implied warranty of
141da177e4SLinus Torvalds *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
151da177e4SLinus Torvalds *    GNU General Public License for more details.
161da177e4SLinus Torvalds *
171da177e4SLinus Torvalds *    You should have received a copy of the GNU General Public License
181da177e4SLinus Torvalds *    along with this program; if not, write to the Free Software
191da177e4SLinus Torvalds *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
201da177e4SLinus Torvalds */
211da177e4SLinus Torvalds
221da177e4SLinus Torvalds/*
231da177e4SLinus Torvalds * NOTE: fdc,fic, and pdc instructions that use base register modification
241da177e4SLinus Torvalds *       should only use index and base registers that are not shadowed,
251da177e4SLinus Torvalds *       so that the fast path emulation in the non access miss handler
261da177e4SLinus Torvalds *       can be used.
271da177e4SLinus Torvalds */
281da177e4SLinus Torvalds
29413059f2SGrant Grundler#ifdef CONFIG_64BIT
301da177e4SLinus Torvalds	.level	2.0w
311da177e4SLinus Torvalds#else
321da177e4SLinus Torvalds	.level	2.0
331da177e4SLinus Torvalds#endif
341da177e4SLinus Torvalds
351da177e4SLinus Torvalds#include <asm/psw.h>
36896a3756SGrant Grundler#include <asm/assembly.h>
371da177e4SLinus Torvalds#include <asm/pgtable.h>
381da177e4SLinus Torvalds#include <asm/cache.h>
3988776c0eSHelge Deller#include <asm/ldcw.h>
408e9e9844SHelge Deller#include <linux/linkage.h>
41*2a03bb9eSHelge Deller#include <linux/init.h>
421da177e4SLinus Torvalds
43*2a03bb9eSHelge Deller	.section .text.hot
44*2a03bb9eSHelge Deller	.align	16
451da177e4SLinus Torvalds
46f39cce65SHelge DellerENTRY_CFI(flush_tlb_all_local)
471da177e4SLinus Torvalds	.proc
481da177e4SLinus Torvalds	.callinfo NO_CALLS
491da177e4SLinus Torvalds	.entry
501da177e4SLinus Torvalds
511da177e4SLinus Torvalds	/*
521da177e4SLinus Torvalds	 * The pitlbe and pdtlbe instructions should only be used to
531da177e4SLinus Torvalds	 * flush the entire tlb. Also, there needs to be no intervening
541da177e4SLinus Torvalds	 * tlb operations, e.g. tlb misses, so the operation needs
551da177e4SLinus Torvalds	 * to happen in real mode with all interruptions disabled.
561da177e4SLinus Torvalds	 */
571da177e4SLinus Torvalds
58896a3756SGrant Grundler	/* pcxt_ssm_bug	- relied upon translation! PA 2.0 Arch. F-4 and F-5 */
59896a3756SGrant Grundler	rsm		PSW_SM_I, %r19		/* save I-bit state */
60896a3756SGrant Grundler	load32		PA(1f), %r1
611da177e4SLinus Torvalds	nop
621da177e4SLinus Torvalds	nop
631da177e4SLinus Torvalds	nop
641da177e4SLinus Torvalds	nop
651da177e4SLinus Torvalds	nop
661da177e4SLinus Torvalds
67896a3756SGrant Grundler	rsm		PSW_SM_Q, %r0		/* prep to load iia queue */
681da177e4SLinus Torvalds	mtctl		%r0, %cr17		/* Clear IIASQ tail */
691da177e4SLinus Torvalds	mtctl		%r0, %cr17		/* Clear IIASQ head */
701da177e4SLinus Torvalds	mtctl		%r1, %cr18		/* IIAOQ head */
711da177e4SLinus Torvalds	ldo		4(%r1), %r1
721da177e4SLinus Torvalds	mtctl		%r1, %cr18		/* IIAOQ tail */
73896a3756SGrant Grundler	load32		REAL_MODE_PSW, %r1
74896a3756SGrant Grundler	mtctl           %r1, %ipsw
751da177e4SLinus Torvalds	rfi
761da177e4SLinus Torvalds	nop
771da177e4SLinus Torvalds
782fd83038SHelge Deller1:      load32		PA(cache_info), %r1
791da177e4SLinus Torvalds
801da177e4SLinus Torvalds	/* Flush Instruction Tlb */
811da177e4SLinus Torvalds
821da177e4SLinus Torvalds	LDREG		ITLB_SID_BASE(%r1), %r20
831da177e4SLinus Torvalds	LDREG		ITLB_SID_STRIDE(%r1), %r21
841da177e4SLinus Torvalds	LDREG		ITLB_SID_COUNT(%r1), %r22
851da177e4SLinus Torvalds	LDREG		ITLB_OFF_BASE(%r1), %arg0
861da177e4SLinus Torvalds	LDREG		ITLB_OFF_STRIDE(%r1), %arg1
871da177e4SLinus Torvalds	LDREG		ITLB_OFF_COUNT(%r1), %arg2
881da177e4SLinus Torvalds	LDREG		ITLB_LOOP(%r1), %arg3
891da177e4SLinus Torvalds
90872f6debSKyle McMartin	addib,COND(=)		-1, %arg3, fitoneloop	/* Preadjust and test */
911da177e4SLinus Torvalds	movb,<,n	%arg3, %r31, fitdone	/* If loop < 0, skip */
921da177e4SLinus Torvalds	copy		%arg0, %r28		/* Init base addr */
931da177e4SLinus Torvalds
941da177e4SLinus Torvaldsfitmanyloop:					/* Loop if LOOP >= 2 */
951da177e4SLinus Torvalds	mtsp		%r20, %sr1
961da177e4SLinus Torvalds	add		%r21, %r20, %r20	/* increment space */
971da177e4SLinus Torvalds	copy		%arg2, %r29		/* Init middle loop count */
981da177e4SLinus Torvalds
991da177e4SLinus Torvaldsfitmanymiddle:					/* Loop if LOOP >= 2 */
100872f6debSKyle McMartin	addib,COND(>)		-1, %r31, fitmanymiddle	/* Adjusted inner loop decr */
1015035b230SJohn David Anglin	pitlbe		%r0(%sr1, %r28)
1021da177e4SLinus Torvalds	pitlbe,m	%arg1(%sr1, %r28)	/* Last pitlbe and addr adjust */
103872f6debSKyle McMartin	addib,COND(>)		-1, %r29, fitmanymiddle	/* Middle loop decr */
1041da177e4SLinus Torvalds	copy		%arg3, %r31		/* Re-init inner loop count */
1051da177e4SLinus Torvalds
1061da177e4SLinus Torvalds	movb,tr		%arg0, %r28, fitmanyloop /* Re-init base addr */
107872f6debSKyle McMartin	addib,COND(<=),n	-1, %r22, fitdone	/* Outer loop count decr */
1081da177e4SLinus Torvalds
1091da177e4SLinus Torvaldsfitoneloop:					/* Loop if LOOP = 1 */
1101da177e4SLinus Torvalds	mtsp		%r20, %sr1
1111da177e4SLinus Torvalds	copy		%arg0, %r28		/* init base addr */
1121da177e4SLinus Torvalds	copy		%arg2, %r29		/* init middle loop count */
1131da177e4SLinus Torvalds
1141da177e4SLinus Torvaldsfitonemiddle:					/* Loop if LOOP = 1 */
115872f6debSKyle McMartin	addib,COND(>)		-1, %r29, fitonemiddle	/* Middle loop count decr */
1161da177e4SLinus Torvalds	pitlbe,m	%arg1(%sr1, %r28)	/* pitlbe for one loop */
1171da177e4SLinus Torvalds
118872f6debSKyle McMartin	addib,COND(>)		-1, %r22, fitoneloop	/* Outer loop count decr */
1191da177e4SLinus Torvalds	add		%r21, %r20, %r20		/* increment space */
1201da177e4SLinus Torvalds
1211da177e4SLinus Torvaldsfitdone:
1221da177e4SLinus Torvalds
1231da177e4SLinus Torvalds	/* Flush Data Tlb */
1241da177e4SLinus Torvalds
1251da177e4SLinus Torvalds	LDREG		DTLB_SID_BASE(%r1), %r20
1261da177e4SLinus Torvalds	LDREG		DTLB_SID_STRIDE(%r1), %r21
1271da177e4SLinus Torvalds	LDREG		DTLB_SID_COUNT(%r1), %r22
1281da177e4SLinus Torvalds	LDREG		DTLB_OFF_BASE(%r1), %arg0
1291da177e4SLinus Torvalds	LDREG		DTLB_OFF_STRIDE(%r1), %arg1
1301da177e4SLinus Torvalds	LDREG		DTLB_OFF_COUNT(%r1), %arg2
1311da177e4SLinus Torvalds	LDREG		DTLB_LOOP(%r1), %arg3
1321da177e4SLinus Torvalds
133872f6debSKyle McMartin	addib,COND(=)		-1, %arg3, fdtoneloop	/* Preadjust and test */
1341da177e4SLinus Torvalds	movb,<,n	%arg3, %r31, fdtdone	/* If loop < 0, skip */
1351da177e4SLinus Torvalds	copy		%arg0, %r28		/* Init base addr */
1361da177e4SLinus Torvalds
1371da177e4SLinus Torvaldsfdtmanyloop:					/* Loop if LOOP >= 2 */
1381da177e4SLinus Torvalds	mtsp		%r20, %sr1
1391da177e4SLinus Torvalds	add		%r21, %r20, %r20	/* increment space */
1401da177e4SLinus Torvalds	copy		%arg2, %r29		/* Init middle loop count */
1411da177e4SLinus Torvalds
1421da177e4SLinus Torvaldsfdtmanymiddle:					/* Loop if LOOP >= 2 */
143872f6debSKyle McMartin	addib,COND(>)		-1, %r31, fdtmanymiddle	/* Adjusted inner loop decr */
1445035b230SJohn David Anglin	pdtlbe		%r0(%sr1, %r28)
1451da177e4SLinus Torvalds	pdtlbe,m	%arg1(%sr1, %r28)	/* Last pdtlbe and addr adjust */
146872f6debSKyle McMartin	addib,COND(>)		-1, %r29, fdtmanymiddle	/* Middle loop decr */
1471da177e4SLinus Torvalds	copy		%arg3, %r31		/* Re-init inner loop count */
1481da177e4SLinus Torvalds
1491da177e4SLinus Torvalds	movb,tr		%arg0, %r28, fdtmanyloop /* Re-init base addr */
150872f6debSKyle McMartin	addib,COND(<=),n	-1, %r22,fdtdone	/* Outer loop count decr */
1511da177e4SLinus Torvalds
1521da177e4SLinus Torvaldsfdtoneloop:					/* Loop if LOOP = 1 */
1531da177e4SLinus Torvalds	mtsp		%r20, %sr1
1541da177e4SLinus Torvalds	copy		%arg0, %r28		/* init base addr */
1551da177e4SLinus Torvalds	copy		%arg2, %r29		/* init middle loop count */
1561da177e4SLinus Torvalds
1571da177e4SLinus Torvaldsfdtonemiddle:					/* Loop if LOOP = 1 */
158872f6debSKyle McMartin	addib,COND(>)		-1, %r29, fdtonemiddle	/* Middle loop count decr */
1591da177e4SLinus Torvalds	pdtlbe,m	%arg1(%sr1, %r28)	/* pdtlbe for one loop */
1601da177e4SLinus Torvalds
161872f6debSKyle McMartin	addib,COND(>)		-1, %r22, fdtoneloop	/* Outer loop count decr */
1621da177e4SLinus Torvalds	add		%r21, %r20, %r20	/* increment space */
1631da177e4SLinus Torvalds
164896a3756SGrant Grundler
1651da177e4SLinus Torvaldsfdtdone:
166896a3756SGrant Grundler	/*
167896a3756SGrant Grundler	 * Switch back to virtual mode
168896a3756SGrant Grundler	 */
169896a3756SGrant Grundler	/* pcxt_ssm_bug */
170896a3756SGrant Grundler	rsm		PSW_SM_I, %r0
171896a3756SGrant Grundler	load32		2f, %r1
172896a3756SGrant Grundler	nop
173896a3756SGrant Grundler	nop
174896a3756SGrant Grundler	nop
175896a3756SGrant Grundler	nop
176896a3756SGrant Grundler	nop
1771da177e4SLinus Torvalds
178896a3756SGrant Grundler	rsm		PSW_SM_Q, %r0		/* prep to load iia queue */
1791da177e4SLinus Torvalds	mtctl		%r0, %cr17		/* Clear IIASQ tail */
1801da177e4SLinus Torvalds	mtctl		%r0, %cr17		/* Clear IIASQ head */
1811da177e4SLinus Torvalds	mtctl		%r1, %cr18		/* IIAOQ head */
1821da177e4SLinus Torvalds	ldo		4(%r1), %r1
1831da177e4SLinus Torvalds	mtctl		%r1, %cr18		/* IIAOQ tail */
184896a3756SGrant Grundler	load32		KERNEL_PSW, %r1
185896a3756SGrant Grundler	or		%r1, %r19, %r1	/* I-bit to state on entry */
186896a3756SGrant Grundler	mtctl		%r1, %ipsw	/* restore I-bit (entire PSW) */
1871da177e4SLinus Torvalds	rfi
1881da177e4SLinus Torvalds	nop
1891da177e4SLinus Torvalds
1901da177e4SLinus Torvalds2:      bv		%r0(%r2)
1911da177e4SLinus Torvalds	nop
1921da177e4SLinus Torvalds
193896a3756SGrant Grundler	.exit
1941da177e4SLinus Torvalds	.procend
195f39cce65SHelge DellerENDPROC_CFI(flush_tlb_all_local)
1961da177e4SLinus Torvalds
1971da177e4SLinus Torvalds	.import cache_info,data
1981da177e4SLinus Torvalds
199f39cce65SHelge DellerENTRY_CFI(flush_instruction_cache_local)
2001da177e4SLinus Torvalds	.proc
2011da177e4SLinus Torvalds	.callinfo NO_CALLS
2021da177e4SLinus Torvalds	.entry
2031da177e4SLinus Torvalds
2042fd83038SHelge Deller	load32		cache_info, %r1
2051da177e4SLinus Torvalds
2061da177e4SLinus Torvalds	/* Flush Instruction Cache */
2071da177e4SLinus Torvalds
2081da177e4SLinus Torvalds	LDREG		ICACHE_BASE(%r1), %arg0
2091da177e4SLinus Torvalds	LDREG		ICACHE_STRIDE(%r1), %arg1
2101da177e4SLinus Torvalds	LDREG		ICACHE_COUNT(%r1), %arg2
2111da177e4SLinus Torvalds	LDREG		ICACHE_LOOP(%r1), %arg3
2121da177e4SLinus Torvalds	rsm		PSW_SM_I, %r22		/* No mmgt ops during loop*/
2136d2ddc2fSJohn David Anglin	mtsp		%r0, %sr1
214872f6debSKyle McMartin	addib,COND(=)		-1, %arg3, fioneloop	/* Preadjust and test */
2151da177e4SLinus Torvalds	movb,<,n	%arg3, %r31, fisync	/* If loop < 0, do sync */
2161da177e4SLinus Torvalds
2171da177e4SLinus Torvaldsfimanyloop:					/* Loop if LOOP >= 2 */
218872f6debSKyle McMartin	addib,COND(>)		-1, %r31, fimanyloop	/* Adjusted inner loop decr */
2199b3b331dSGrant Grundler	fice            %r0(%sr1, %arg0)
2201da177e4SLinus Torvalds	fice,m		%arg1(%sr1, %arg0)	/* Last fice and addr adjust */
2211da177e4SLinus Torvalds	movb,tr		%arg3, %r31, fimanyloop	/* Re-init inner loop count */
222872f6debSKyle McMartin	addib,COND(<=),n	-1, %arg2, fisync	/* Outer loop decr */
2231da177e4SLinus Torvalds
2241da177e4SLinus Torvaldsfioneloop:					/* Loop if LOOP = 1 */
2256d2ddc2fSJohn David Anglin	/* Some implementations may flush with a single fice instruction */
2266d2ddc2fSJohn David Anglin	cmpib,COND(>>=),n	15, %arg2, fioneloop2
2276d2ddc2fSJohn David Anglin
2286d2ddc2fSJohn David Anglinfioneloop1:
2296d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2306d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2316d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2326d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2336d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2346d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2356d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2366d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2376d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2386d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2396d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2406d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2416d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2426d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2436d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2446d2ddc2fSJohn David Anglin	addib,COND(>)	-16, %arg2, fioneloop1
2456d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2466d2ddc2fSJohn David Anglin
2476d2ddc2fSJohn David Anglin	/* Check if done */
2486d2ddc2fSJohn David Anglin	cmpb,COND(=),n	%arg2, %r0, fisync	/* Predict branch taken */
2496d2ddc2fSJohn David Anglin
2506d2ddc2fSJohn David Anglinfioneloop2:
2516d2ddc2fSJohn David Anglin	addib,COND(>)	-1, %arg2, fioneloop2	/* Outer loop count decr */
2521da177e4SLinus Torvalds	fice,m		%arg1(%sr1, %arg0)	/* Fice for one loop */
2531da177e4SLinus Torvalds
2541da177e4SLinus Torvaldsfisync:
2551da177e4SLinus Torvalds	sync
256896a3756SGrant Grundler	mtsm		%r22			/* restore I-bit */
2571da177e4SLinus Torvalds	bv		%r0(%r2)
2581da177e4SLinus Torvalds	nop
2591da177e4SLinus Torvalds	.exit
2601da177e4SLinus Torvalds
2611da177e4SLinus Torvalds	.procend
262f39cce65SHelge DellerENDPROC_CFI(flush_instruction_cache_local)
2631da177e4SLinus Torvalds
2648e9e9844SHelge Deller
2651da177e4SLinus Torvalds	.import cache_info, data
266f39cce65SHelge DellerENTRY_CFI(flush_data_cache_local)
2671da177e4SLinus Torvalds	.proc
2681da177e4SLinus Torvalds	.callinfo NO_CALLS
2691da177e4SLinus Torvalds	.entry
2701da177e4SLinus Torvalds
2712fd83038SHelge Deller	load32		cache_info, %r1
2721da177e4SLinus Torvalds
2731da177e4SLinus Torvalds	/* Flush Data Cache */
2741da177e4SLinus Torvalds
2751da177e4SLinus Torvalds	LDREG		DCACHE_BASE(%r1), %arg0
2761da177e4SLinus Torvalds	LDREG		DCACHE_STRIDE(%r1), %arg1
2771da177e4SLinus Torvalds	LDREG		DCACHE_COUNT(%r1), %arg2
2781da177e4SLinus Torvalds	LDREG		DCACHE_LOOP(%r1), %arg3
2796d2ddc2fSJohn David Anglin	rsm		PSW_SM_I, %r22		/* No mmgt ops during loop*/
2806d2ddc2fSJohn David Anglin	mtsp		%r0, %sr1
281872f6debSKyle McMartin	addib,COND(=)		-1, %arg3, fdoneloop	/* Preadjust and test */
2821da177e4SLinus Torvalds	movb,<,n	%arg3, %r31, fdsync	/* If loop < 0, do sync */
2831da177e4SLinus Torvalds
2841da177e4SLinus Torvaldsfdmanyloop:					/* Loop if LOOP >= 2 */
285872f6debSKyle McMartin	addib,COND(>)		-1, %r31, fdmanyloop	/* Adjusted inner loop decr */
2869b3b331dSGrant Grundler	fdce		%r0(%sr1, %arg0)
2871da177e4SLinus Torvalds	fdce,m		%arg1(%sr1, %arg0)	/* Last fdce and addr adjust */
2881da177e4SLinus Torvalds	movb,tr		%arg3, %r31, fdmanyloop	/* Re-init inner loop count */
289872f6debSKyle McMartin	addib,COND(<=),n	-1, %arg2, fdsync	/* Outer loop decr */
2901da177e4SLinus Torvalds
2911da177e4SLinus Torvaldsfdoneloop:					/* Loop if LOOP = 1 */
2926d2ddc2fSJohn David Anglin	/* Some implementations may flush with a single fdce instruction */
2936d2ddc2fSJohn David Anglin	cmpib,COND(>>=),n	15, %arg2, fdoneloop2
2946d2ddc2fSJohn David Anglin
2956d2ddc2fSJohn David Anglinfdoneloop1:
2966d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
2976d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
2986d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
2996d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
3006d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
3016d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
3026d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
3036d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
3046d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
3056d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
3066d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
3076d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
3086d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
3096d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
3106d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
3116d2ddc2fSJohn David Anglin	addib,COND(>)	-16, %arg2, fdoneloop1
3126d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
3136d2ddc2fSJohn David Anglin
3146d2ddc2fSJohn David Anglin	/* Check if done */
3156d2ddc2fSJohn David Anglin	cmpb,COND(=),n	%arg2, %r0, fdsync	/* Predict branch taken */
3166d2ddc2fSJohn David Anglin
3176d2ddc2fSJohn David Anglinfdoneloop2:
3186d2ddc2fSJohn David Anglin	addib,COND(>)	-1, %arg2, fdoneloop2	/* Outer loop count decr */
3191da177e4SLinus Torvalds	fdce,m		%arg1(%sr1, %arg0)	/* Fdce for one loop */
3201da177e4SLinus Torvalds
3211da177e4SLinus Torvaldsfdsync:
3221da177e4SLinus Torvalds	syncdma
3231da177e4SLinus Torvalds	sync
324896a3756SGrant Grundler	mtsm		%r22			/* restore I-bit */
3251da177e4SLinus Torvalds	bv		%r0(%r2)
3261da177e4SLinus Torvalds	nop
3271da177e4SLinus Torvalds	.exit
3281da177e4SLinus Torvalds
3291da177e4SLinus Torvalds	.procend
330f39cce65SHelge DellerENDPROC_CFI(flush_data_cache_local)
3311da177e4SLinus Torvalds
3326d2ddc2fSJohn David Anglin/* Macros to serialize TLB purge operations on SMP.  */
3336d2ddc2fSJohn David Anglin
3346d2ddc2fSJohn David Anglin	.macro	tlb_lock	la,flags,tmp
3356d2ddc2fSJohn David Anglin#ifdef CONFIG_SMP
33688776c0eSHelge Deller#if __PA_LDCW_ALIGNMENT > 4
33788776c0eSHelge Deller	load32		pa_tlb_lock + __PA_LDCW_ALIGNMENT-1, \la
33888776c0eSHelge Deller	depi		0,31,__PA_LDCW_ALIGN_ORDER, \la
33988776c0eSHelge Deller#else
34088776c0eSHelge Deller	load32		pa_tlb_lock, \la
34188776c0eSHelge Deller#endif
3426d2ddc2fSJohn David Anglin	rsm		PSW_SM_I,\flags
3436d2ddc2fSJohn David Anglin1:	LDCW		0(\la),\tmp
3446d2ddc2fSJohn David Anglin	cmpib,<>,n	0,\tmp,3f
3456d2ddc2fSJohn David Anglin2:	ldw		0(\la),\tmp
3466d2ddc2fSJohn David Anglin	cmpb,<>		%r0,\tmp,1b
3476d2ddc2fSJohn David Anglin	nop
3486d2ddc2fSJohn David Anglin	b,n		2b
3496d2ddc2fSJohn David Anglin3:
3506d2ddc2fSJohn David Anglin#endif
3516d2ddc2fSJohn David Anglin	.endm
3526d2ddc2fSJohn David Anglin
3536d2ddc2fSJohn David Anglin	.macro	tlb_unlock	la,flags,tmp
3546d2ddc2fSJohn David Anglin#ifdef CONFIG_SMP
3556d2ddc2fSJohn David Anglin	ldi		1,\tmp
3566d2ddc2fSJohn David Anglin	stw		\tmp,0(\la)
3576d2ddc2fSJohn David Anglin	mtsm		\flags
3586d2ddc2fSJohn David Anglin#endif
3596d2ddc2fSJohn David Anglin	.endm
3606d2ddc2fSJohn David Anglin
3616d2ddc2fSJohn David Anglin/* Clear page using kernel mapping.  */
3626d2ddc2fSJohn David Anglin
363f39cce65SHelge DellerENTRY_CFI(clear_page_asm)
3646d2ddc2fSJohn David Anglin	.proc
3656d2ddc2fSJohn David Anglin	.callinfo NO_CALLS
3666d2ddc2fSJohn David Anglin	.entry
3676d2ddc2fSJohn David Anglin
3686d2ddc2fSJohn David Anglin#ifdef CONFIG_64BIT
3696d2ddc2fSJohn David Anglin
3706d2ddc2fSJohn David Anglin	/* Unroll the loop.  */
3716d2ddc2fSJohn David Anglin	ldi		(PAGE_SIZE / 128), %r1
3726d2ddc2fSJohn David Anglin
3736d2ddc2fSJohn David Anglin1:
3746d2ddc2fSJohn David Anglin	std		%r0, 0(%r26)
3756d2ddc2fSJohn David Anglin	std		%r0, 8(%r26)
3766d2ddc2fSJohn David Anglin	std		%r0, 16(%r26)
3776d2ddc2fSJohn David Anglin	std		%r0, 24(%r26)
3786d2ddc2fSJohn David Anglin	std		%r0, 32(%r26)
3796d2ddc2fSJohn David Anglin	std		%r0, 40(%r26)
3806d2ddc2fSJohn David Anglin	std		%r0, 48(%r26)
3816d2ddc2fSJohn David Anglin	std		%r0, 56(%r26)
3826d2ddc2fSJohn David Anglin	std		%r0, 64(%r26)
3836d2ddc2fSJohn David Anglin	std		%r0, 72(%r26)
3846d2ddc2fSJohn David Anglin	std		%r0, 80(%r26)
3856d2ddc2fSJohn David Anglin	std		%r0, 88(%r26)
3866d2ddc2fSJohn David Anglin	std		%r0, 96(%r26)
3876d2ddc2fSJohn David Anglin	std		%r0, 104(%r26)
3886d2ddc2fSJohn David Anglin	std		%r0, 112(%r26)
3896d2ddc2fSJohn David Anglin	std		%r0, 120(%r26)
3906d2ddc2fSJohn David Anglin
3916d2ddc2fSJohn David Anglin	/* Note reverse branch hint for addib is taken.  */
3926d2ddc2fSJohn David Anglin	addib,COND(>),n	-1, %r1, 1b
3936d2ddc2fSJohn David Anglin	ldo		128(%r26), %r26
3946d2ddc2fSJohn David Anglin
3956d2ddc2fSJohn David Anglin#else
3966d2ddc2fSJohn David Anglin
3976d2ddc2fSJohn David Anglin	/*
3986d2ddc2fSJohn David Anglin	 * Note that until (if) we start saving the full 64-bit register
3996d2ddc2fSJohn David Anglin	 * values on interrupt, we can't use std on a 32 bit kernel.
4006d2ddc2fSJohn David Anglin	 */
4016d2ddc2fSJohn David Anglin	ldi		(PAGE_SIZE / 64), %r1
4026d2ddc2fSJohn David Anglin
4036d2ddc2fSJohn David Anglin1:
4046d2ddc2fSJohn David Anglin	stw		%r0, 0(%r26)
4056d2ddc2fSJohn David Anglin	stw		%r0, 4(%r26)
4066d2ddc2fSJohn David Anglin	stw		%r0, 8(%r26)
4076d2ddc2fSJohn David Anglin	stw		%r0, 12(%r26)
4086d2ddc2fSJohn David Anglin	stw		%r0, 16(%r26)
4096d2ddc2fSJohn David Anglin	stw		%r0, 20(%r26)
4106d2ddc2fSJohn David Anglin	stw		%r0, 24(%r26)
4116d2ddc2fSJohn David Anglin	stw		%r0, 28(%r26)
4126d2ddc2fSJohn David Anglin	stw		%r0, 32(%r26)
4136d2ddc2fSJohn David Anglin	stw		%r0, 36(%r26)
4146d2ddc2fSJohn David Anglin	stw		%r0, 40(%r26)
4156d2ddc2fSJohn David Anglin	stw		%r0, 44(%r26)
4166d2ddc2fSJohn David Anglin	stw		%r0, 48(%r26)
4176d2ddc2fSJohn David Anglin	stw		%r0, 52(%r26)
4186d2ddc2fSJohn David Anglin	stw		%r0, 56(%r26)
4196d2ddc2fSJohn David Anglin	stw		%r0, 60(%r26)
4206d2ddc2fSJohn David Anglin
4216d2ddc2fSJohn David Anglin	addib,COND(>),n	-1, %r1, 1b
4226d2ddc2fSJohn David Anglin	ldo		64(%r26), %r26
4236d2ddc2fSJohn David Anglin#endif
4246d2ddc2fSJohn David Anglin	bv		%r0(%r2)
4256d2ddc2fSJohn David Anglin	nop
4266d2ddc2fSJohn David Anglin	.exit
4276d2ddc2fSJohn David Anglin
4286d2ddc2fSJohn David Anglin	.procend
429f39cce65SHelge DellerENDPROC_CFI(clear_page_asm)
4306d2ddc2fSJohn David Anglin
4316d2ddc2fSJohn David Anglin/* Copy page using kernel mapping.  */
4326d2ddc2fSJohn David Anglin
433f39cce65SHelge DellerENTRY_CFI(copy_page_asm)
4341da177e4SLinus Torvalds	.proc
4351da177e4SLinus Torvalds	.callinfo NO_CALLS
4361da177e4SLinus Torvalds	.entry
4371da177e4SLinus Torvalds
438413059f2SGrant Grundler#ifdef CONFIG_64BIT
4391da177e4SLinus Torvalds	/* PA8x00 CPUs can consume 2 loads or 1 store per cycle.
4401da177e4SLinus Torvalds	 * Unroll the loop by hand and arrange insn appropriately.
4416d2ddc2fSJohn David Anglin	 * Prefetch doesn't improve performance on rp3440.
4426d2ddc2fSJohn David Anglin	 * GCC probably can do this just as well...
4431da177e4SLinus Torvalds	 */
4441da177e4SLinus Torvalds
4456ebeafffSKyle McMartin	ldi		(PAGE_SIZE / 128), %r1
4462fd83038SHelge Deller
4476d2ddc2fSJohn David Anglin1:	ldd		0(%r25), %r19
4486d2ddc2fSJohn David Anglin	ldd		8(%r25), %r20
4491da177e4SLinus Torvalds
4501da177e4SLinus Torvalds	ldd		16(%r25), %r21
4511da177e4SLinus Torvalds	ldd		24(%r25), %r22
4521da177e4SLinus Torvalds	std		%r19, 0(%r26)
4531da177e4SLinus Torvalds	std		%r20, 8(%r26)
4541da177e4SLinus Torvalds
4551da177e4SLinus Torvalds	ldd		32(%r25), %r19
4561da177e4SLinus Torvalds	ldd		40(%r25), %r20
4571da177e4SLinus Torvalds	std		%r21, 16(%r26)
4581da177e4SLinus Torvalds	std		%r22, 24(%r26)
4591da177e4SLinus Torvalds
4601da177e4SLinus Torvalds	ldd		48(%r25), %r21
4611da177e4SLinus Torvalds	ldd		56(%r25), %r22
4621da177e4SLinus Torvalds	std		%r19, 32(%r26)
4631da177e4SLinus Torvalds	std		%r20, 40(%r26)
4641da177e4SLinus Torvalds
4651da177e4SLinus Torvalds	ldd		64(%r25), %r19
4661da177e4SLinus Torvalds	ldd		72(%r25), %r20
4671da177e4SLinus Torvalds	std		%r21, 48(%r26)
4681da177e4SLinus Torvalds	std		%r22, 56(%r26)
4691da177e4SLinus Torvalds
4701da177e4SLinus Torvalds	ldd		80(%r25), %r21
4711da177e4SLinus Torvalds	ldd		88(%r25), %r22
4721da177e4SLinus Torvalds	std		%r19, 64(%r26)
4731da177e4SLinus Torvalds	std		%r20, 72(%r26)
4741da177e4SLinus Torvalds
4751da177e4SLinus Torvalds	ldd		 96(%r25), %r19
4761da177e4SLinus Torvalds	ldd		104(%r25), %r20
4771da177e4SLinus Torvalds	std		%r21, 80(%r26)
4781da177e4SLinus Torvalds	std		%r22, 88(%r26)
4791da177e4SLinus Torvalds
4801da177e4SLinus Torvalds	ldd		112(%r25), %r21
4811da177e4SLinus Torvalds	ldd		120(%r25), %r22
4826d2ddc2fSJohn David Anglin	ldo		128(%r25), %r25
4831da177e4SLinus Torvalds	std		%r19, 96(%r26)
4841da177e4SLinus Torvalds	std		%r20, 104(%r26)
4851da177e4SLinus Torvalds
4861da177e4SLinus Torvalds	std		%r21, 112(%r26)
4871da177e4SLinus Torvalds	std		%r22, 120(%r26)
4881da177e4SLinus Torvalds
4896d2ddc2fSJohn David Anglin	/* Note reverse branch hint for addib is taken.  */
4906d2ddc2fSJohn David Anglin	addib,COND(>),n	-1, %r1, 1b
4916d2ddc2fSJohn David Anglin	ldo		128(%r26), %r26
4921da177e4SLinus Torvalds
4931da177e4SLinus Torvalds#else
4941da177e4SLinus Torvalds
4951da177e4SLinus Torvalds	/*
4961da177e4SLinus Torvalds	 * This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
4971da177e4SLinus Torvalds	 * bundles (very restricted rules for bundling).
4981da177e4SLinus Torvalds	 * Note that until (if) we start saving
4991da177e4SLinus Torvalds	 * the full 64 bit register values on interrupt, we can't
5001da177e4SLinus Torvalds	 * use ldd/std on a 32 bit kernel.
5011da177e4SLinus Torvalds	 */
50237318a3cSGrant Grundler	ldw		0(%r25), %r19
5036ebeafffSKyle McMartin	ldi		(PAGE_SIZE / 64), %r1
5041da177e4SLinus Torvalds
5051da177e4SLinus Torvalds1:
5061da177e4SLinus Torvalds	ldw		4(%r25), %r20
5071da177e4SLinus Torvalds	ldw		8(%r25), %r21
5081da177e4SLinus Torvalds	ldw		12(%r25), %r22
5091da177e4SLinus Torvalds	stw		%r19, 0(%r26)
5101da177e4SLinus Torvalds	stw		%r20, 4(%r26)
5111da177e4SLinus Torvalds	stw		%r21, 8(%r26)
5121da177e4SLinus Torvalds	stw		%r22, 12(%r26)
5131da177e4SLinus Torvalds	ldw		16(%r25), %r19
5141da177e4SLinus Torvalds	ldw		20(%r25), %r20
5151da177e4SLinus Torvalds	ldw		24(%r25), %r21
5161da177e4SLinus Torvalds	ldw		28(%r25), %r22
5171da177e4SLinus Torvalds	stw		%r19, 16(%r26)
5181da177e4SLinus Torvalds	stw		%r20, 20(%r26)
5191da177e4SLinus Torvalds	stw		%r21, 24(%r26)
5201da177e4SLinus Torvalds	stw		%r22, 28(%r26)
5211da177e4SLinus Torvalds	ldw		32(%r25), %r19
5221da177e4SLinus Torvalds	ldw		36(%r25), %r20
5231da177e4SLinus Torvalds	ldw		40(%r25), %r21
5241da177e4SLinus Torvalds	ldw		44(%r25), %r22
5251da177e4SLinus Torvalds	stw		%r19, 32(%r26)
5261da177e4SLinus Torvalds	stw		%r20, 36(%r26)
5271da177e4SLinus Torvalds	stw		%r21, 40(%r26)
5281da177e4SLinus Torvalds	stw		%r22, 44(%r26)
5291da177e4SLinus Torvalds	ldw		48(%r25), %r19
5301da177e4SLinus Torvalds	ldw		52(%r25), %r20
5311da177e4SLinus Torvalds	ldw		56(%r25), %r21
5321da177e4SLinus Torvalds	ldw		60(%r25), %r22
5331da177e4SLinus Torvalds	stw		%r19, 48(%r26)
5341da177e4SLinus Torvalds	stw		%r20, 52(%r26)
53537318a3cSGrant Grundler	ldo		64(%r25), %r25
5361da177e4SLinus Torvalds	stw		%r21, 56(%r26)
5371da177e4SLinus Torvalds	stw		%r22, 60(%r26)
5381da177e4SLinus Torvalds	ldo		64(%r26), %r26
539872f6debSKyle McMartin	addib,COND(>),n	-1, %r1, 1b
54037318a3cSGrant Grundler	ldw		0(%r25), %r19
5411da177e4SLinus Torvalds#endif
5421da177e4SLinus Torvalds	bv		%r0(%r2)
5431da177e4SLinus Torvalds	nop
5441da177e4SLinus Torvalds	.exit
5451da177e4SLinus Torvalds
5461da177e4SLinus Torvalds	.procend
547f39cce65SHelge DellerENDPROC_CFI(copy_page_asm)
5481da177e4SLinus Torvalds
5491da177e4SLinus Torvalds/*
5501da177e4SLinus Torvalds * NOTE: Code in clear_user_page has a hard coded dependency on the
5511da177e4SLinus Torvalds *       maximum alias boundary being 4 Mb. We've been assured by the
5521da177e4SLinus Torvalds *       parisc chip designers that there will not ever be a parisc
5531da177e4SLinus Torvalds *       chip with a larger alias boundary (Never say never :-) ).
5541da177e4SLinus Torvalds *
5551da177e4SLinus Torvalds *       Subtle: the dtlb miss handlers support the temp alias region by
5561da177e4SLinus Torvalds *       "knowing" that if a dtlb miss happens within the temp alias
5571da177e4SLinus Torvalds *       region it must have occurred while in clear_user_page. Since
5581da177e4SLinus Torvalds *       this routine makes use of processor local translations, we
5591da177e4SLinus Torvalds *       don't want to insert them into the kernel page table. Instead,
5601da177e4SLinus Torvalds *       we load up some general registers (they need to be registers
5611da177e4SLinus Torvalds *       which aren't shadowed) with the physical page numbers (preshifted
5621da177e4SLinus Torvalds *       for tlb insertion) needed to insert the translations. When we
5631da177e4SLinus Torvalds *       miss on the translation, the dtlb miss handler inserts the
5641da177e4SLinus Torvalds *       translation into the tlb using these values:
5651da177e4SLinus Torvalds *
5661da177e4SLinus Torvalds *          %r26 physical page (shifted for tlb insert) of "to" translation
5671da177e4SLinus Torvalds *          %r23 physical page (shifted for tlb insert) of "from" translation
5681da177e4SLinus Torvalds */
5691da177e4SLinus Torvalds
5706a45716aSHelge Deller        /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
5716a45716aSHelge Deller        #define PAGE_ADD_SHIFT  (PAGE_SHIFT-12)
5726a45716aSHelge Deller        .macro          convert_phys_for_tlb_insert20  phys
5736a45716aSHelge Deller        extrd,u         \phys, 56-PAGE_ADD_SHIFT, 32-PAGE_ADD_SHIFT, \phys
5746a45716aSHelge Deller#if _PAGE_SIZE_ENCODING_DEFAULT
5756a45716aSHelge Deller        depdi           _PAGE_SIZE_ENCODING_DEFAULT, 63, (63-58), \phys
5766a45716aSHelge Deller#endif
5776a45716aSHelge Deller	.endm
5786a45716aSHelge Deller
5791da177e4SLinus Torvalds	/*
580910a8643SJohn David Anglin	 * copy_user_page_asm() performs a page copy using mappings
581910a8643SJohn David Anglin	 * equivalent to the user page mappings.  It can be used to
582910a8643SJohn David Anglin	 * implement copy_user_page() but unfortunately both the `from'
583910a8643SJohn David Anglin	 * and `to' pages need to be flushed through mappings equivalent
584910a8643SJohn David Anglin	 * to the user mappings after the copy because the kernel accesses
585910a8643SJohn David Anglin	 * the `from' page through the kmap kernel mapping and the `to'
586910a8643SJohn David Anglin	 * page needs to be flushed since code can be copied.  As a
587910a8643SJohn David Anglin	 * result, this implementation is less efficient than the simpler
588910a8643SJohn David Anglin	 * copy using the kernel mapping.  It only needs the `from' page
589910a8643SJohn David Anglin	 * to flushed via the user mapping.  The kunmap routines handle
590910a8643SJohn David Anglin	 * the flushes needed for the kernel mapping.
5911da177e4SLinus Torvalds	 *
5921da177e4SLinus Torvalds	 * I'm still keeping this around because it may be possible to
5931da177e4SLinus Torvalds	 * use it if more information is passed into copy_user_page().
5941da177e4SLinus Torvalds	 * Have to do some measurements to see if it is worthwhile to
5951da177e4SLinus Torvalds	 * lobby for such a change.
5966d2ddc2fSJohn David Anglin	 *
5971da177e4SLinus Torvalds	 */
5981da177e4SLinus Torvalds
599f39cce65SHelge DellerENTRY_CFI(copy_user_page_asm)
6001da177e4SLinus Torvalds	.proc
6011da177e4SLinus Torvalds	.callinfo NO_CALLS
6021da177e4SLinus Torvalds	.entry
6031da177e4SLinus Torvalds
6046d2ddc2fSJohn David Anglin	/* Convert virtual `to' and `from' addresses to physical addresses.
6056d2ddc2fSJohn David Anglin	   Move `from' physical address to non shadowed register.  */
6061da177e4SLinus Torvalds	ldil		L%(__PAGE_OFFSET), %r1
6071da177e4SLinus Torvalds	sub		%r26, %r1, %r26
6086d2ddc2fSJohn David Anglin	sub		%r25, %r1, %r23
6091da177e4SLinus Torvalds
6101da177e4SLinus Torvalds	ldil		L%(TMPALIAS_MAP_START), %r28
611413059f2SGrant Grundler#ifdef CONFIG_64BIT
6126d2ddc2fSJohn David Anglin#if (TMPALIAS_MAP_START >= 0x80000000)
6136d2ddc2fSJohn David Anglin	depdi		0, 31,32, %r28		/* clear any sign extension */
6146d2ddc2fSJohn David Anglin#endif
6156a45716aSHelge Deller	convert_phys_for_tlb_insert20 %r26	/* convert phys addr to tlb insert format */
6166a45716aSHelge Deller	convert_phys_for_tlb_insert20 %r23	/* convert phys addr to tlb insert format */
6171da177e4SLinus Torvalds	depd		%r24,63,22, %r28	/* Form aliased virtual address 'to' */
6186a45716aSHelge Deller	depdi		0, 63,PAGE_SHIFT, %r28	/* Clear any offset bits */
6191da177e4SLinus Torvalds	copy		%r28, %r29
6201da177e4SLinus Torvalds	depdi		1, 41,1, %r29		/* Form aliased virtual address 'from' */
6211da177e4SLinus Torvalds#else
6221da177e4SLinus Torvalds	extrw,u		%r26, 24,25, %r26	/* convert phys addr to tlb insert format */
6231da177e4SLinus Torvalds	extrw,u		%r23, 24,25, %r23	/* convert phys addr to tlb insert format */
6241da177e4SLinus Torvalds	depw		%r24, 31,22, %r28	/* Form aliased virtual address 'to' */
625d845b5fbSHelge Deller	depwi		0, 31,PAGE_SHIFT, %r28	/* Clear any offset bits */
6261da177e4SLinus Torvalds	copy		%r28, %r29
6271da177e4SLinus Torvalds	depwi		1, 9,1, %r29		/* Form aliased virtual address 'from' */
6281da177e4SLinus Torvalds#endif
6291da177e4SLinus Torvalds
6301da177e4SLinus Torvalds	/* Purge any old translations */
6311da177e4SLinus Torvalds
6326d2ddc2fSJohn David Anglin#ifdef CONFIG_PA20
6335035b230SJohn David Anglin	pdtlb,l		%r0(%r28)
6345035b230SJohn David Anglin	pdtlb,l		%r0(%r29)
6356d2ddc2fSJohn David Anglin#else
6366d2ddc2fSJohn David Anglin	tlb_lock	%r20,%r21,%r22
6375035b230SJohn David Anglin	pdtlb		%r0(%r28)
6385035b230SJohn David Anglin	pdtlb		%r0(%r29)
6396d2ddc2fSJohn David Anglin	tlb_unlock	%r20,%r21,%r22
6406d2ddc2fSJohn David Anglin#endif
6411da177e4SLinus Torvalds
6426d2ddc2fSJohn David Anglin#ifdef CONFIG_64BIT
6436d2ddc2fSJohn David Anglin	/* PA8x00 CPUs can consume 2 loads or 1 store per cycle.
6446d2ddc2fSJohn David Anglin	 * Unroll the loop by hand and arrange insn appropriately.
6456d2ddc2fSJohn David Anglin	 * GCC probably can do this just as well.
6466d2ddc2fSJohn David Anglin	 */
6476d2ddc2fSJohn David Anglin
6486d2ddc2fSJohn David Anglin	ldd		0(%r29), %r19
6496d2ddc2fSJohn David Anglin	ldi		(PAGE_SIZE / 128), %r1
6506d2ddc2fSJohn David Anglin
6516d2ddc2fSJohn David Anglin1:	ldd		8(%r29), %r20
6526d2ddc2fSJohn David Anglin
6536d2ddc2fSJohn David Anglin	ldd		16(%r29), %r21
6546d2ddc2fSJohn David Anglin	ldd		24(%r29), %r22
6556d2ddc2fSJohn David Anglin	std		%r19, 0(%r28)
6566d2ddc2fSJohn David Anglin	std		%r20, 8(%r28)
6576d2ddc2fSJohn David Anglin
6586d2ddc2fSJohn David Anglin	ldd		32(%r29), %r19
6596d2ddc2fSJohn David Anglin	ldd		40(%r29), %r20
6606d2ddc2fSJohn David Anglin	std		%r21, 16(%r28)
6616d2ddc2fSJohn David Anglin	std		%r22, 24(%r28)
6626d2ddc2fSJohn David Anglin
6636d2ddc2fSJohn David Anglin	ldd		48(%r29), %r21
6646d2ddc2fSJohn David Anglin	ldd		56(%r29), %r22
6656d2ddc2fSJohn David Anglin	std		%r19, 32(%r28)
6666d2ddc2fSJohn David Anglin	std		%r20, 40(%r28)
6676d2ddc2fSJohn David Anglin
6686d2ddc2fSJohn David Anglin	ldd		64(%r29), %r19
6696d2ddc2fSJohn David Anglin	ldd		72(%r29), %r20
6706d2ddc2fSJohn David Anglin	std		%r21, 48(%r28)
6716d2ddc2fSJohn David Anglin	std		%r22, 56(%r28)
6726d2ddc2fSJohn David Anglin
6736d2ddc2fSJohn David Anglin	ldd		80(%r29), %r21
6746d2ddc2fSJohn David Anglin	ldd		88(%r29), %r22
6756d2ddc2fSJohn David Anglin	std		%r19, 64(%r28)
6766d2ddc2fSJohn David Anglin	std		%r20, 72(%r28)
6776d2ddc2fSJohn David Anglin
6786d2ddc2fSJohn David Anglin	ldd		 96(%r29), %r19
6796d2ddc2fSJohn David Anglin	ldd		104(%r29), %r20
6806d2ddc2fSJohn David Anglin	std		%r21, 80(%r28)
6816d2ddc2fSJohn David Anglin	std		%r22, 88(%r28)
6826d2ddc2fSJohn David Anglin
6836d2ddc2fSJohn David Anglin	ldd		112(%r29), %r21
6846d2ddc2fSJohn David Anglin	ldd		120(%r29), %r22
6856d2ddc2fSJohn David Anglin	std		%r19, 96(%r28)
6866d2ddc2fSJohn David Anglin	std		%r20, 104(%r28)
6876d2ddc2fSJohn David Anglin
6886d2ddc2fSJohn David Anglin	ldo		128(%r29), %r29
6896d2ddc2fSJohn David Anglin	std		%r21, 112(%r28)
6906d2ddc2fSJohn David Anglin	std		%r22, 120(%r28)
6916d2ddc2fSJohn David Anglin	ldo		128(%r28), %r28
6926d2ddc2fSJohn David Anglin
6936d2ddc2fSJohn David Anglin	/* conditional branches nullify on forward taken branch, and on
6946d2ddc2fSJohn David Anglin	 * non-taken backward branch. Note that .+4 is a backwards branch.
6956d2ddc2fSJohn David Anglin	 * The ldd should only get executed if the branch is taken.
6966d2ddc2fSJohn David Anglin	 */
6976d2ddc2fSJohn David Anglin	addib,COND(>),n	-1, %r1, 1b		/* bundle 10 */
6986d2ddc2fSJohn David Anglin	ldd		0(%r29), %r19		/* start next loads */
6996d2ddc2fSJohn David Anglin
7006d2ddc2fSJohn David Anglin#else
7016d2ddc2fSJohn David Anglin	ldi		(PAGE_SIZE / 64), %r1
7021da177e4SLinus Torvalds
7031da177e4SLinus Torvalds	/*
7041da177e4SLinus Torvalds	 * This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
7051da177e4SLinus Torvalds	 * bundles (very restricted rules for bundling). It probably
7061da177e4SLinus Torvalds	 * does OK on PCXU and better, but we could do better with
7071da177e4SLinus Torvalds	 * ldd/std instructions. Note that until (if) we start saving
7081da177e4SLinus Torvalds	 * the full 64 bit register values on interrupt, we can't
7091da177e4SLinus Torvalds	 * use ldd/std on a 32 bit kernel.
7101da177e4SLinus Torvalds	 */
7111da177e4SLinus Torvalds
7126d2ddc2fSJohn David Anglin1:	ldw		0(%r29), %r19
7131da177e4SLinus Torvalds	ldw		4(%r29), %r20
7141da177e4SLinus Torvalds	ldw		8(%r29), %r21
7151da177e4SLinus Torvalds	ldw		12(%r29), %r22
7161da177e4SLinus Torvalds	stw		%r19, 0(%r28)
7171da177e4SLinus Torvalds	stw		%r20, 4(%r28)
7181da177e4SLinus Torvalds	stw		%r21, 8(%r28)
7191da177e4SLinus Torvalds	stw		%r22, 12(%r28)
7201da177e4SLinus Torvalds	ldw		16(%r29), %r19
7211da177e4SLinus Torvalds	ldw		20(%r29), %r20
7221da177e4SLinus Torvalds	ldw		24(%r29), %r21
7231da177e4SLinus Torvalds	ldw		28(%r29), %r22
7241da177e4SLinus Torvalds	stw		%r19, 16(%r28)
7251da177e4SLinus Torvalds	stw		%r20, 20(%r28)
7261da177e4SLinus Torvalds	stw		%r21, 24(%r28)
7271da177e4SLinus Torvalds	stw		%r22, 28(%r28)
7281da177e4SLinus Torvalds	ldw		32(%r29), %r19
7291da177e4SLinus Torvalds	ldw		36(%r29), %r20
7301da177e4SLinus Torvalds	ldw		40(%r29), %r21
7311da177e4SLinus Torvalds	ldw		44(%r29), %r22
7321da177e4SLinus Torvalds	stw		%r19, 32(%r28)
7331da177e4SLinus Torvalds	stw		%r20, 36(%r28)
7341da177e4SLinus Torvalds	stw		%r21, 40(%r28)
7351da177e4SLinus Torvalds	stw		%r22, 44(%r28)
7361da177e4SLinus Torvalds	ldw		48(%r29), %r19
7371da177e4SLinus Torvalds	ldw		52(%r29), %r20
7381da177e4SLinus Torvalds	ldw		56(%r29), %r21
7391da177e4SLinus Torvalds	ldw		60(%r29), %r22
7401da177e4SLinus Torvalds	stw		%r19, 48(%r28)
7411da177e4SLinus Torvalds	stw		%r20, 52(%r28)
7421da177e4SLinus Torvalds	stw		%r21, 56(%r28)
7431da177e4SLinus Torvalds	stw		%r22, 60(%r28)
7441da177e4SLinus Torvalds	ldo		64(%r28), %r28
7456d2ddc2fSJohn David Anglin
746872f6debSKyle McMartin	addib,COND(>)		-1, %r1,1b
7471da177e4SLinus Torvalds	ldo		64(%r29), %r29
7486d2ddc2fSJohn David Anglin#endif
7491da177e4SLinus Torvalds
7501da177e4SLinus Torvalds	bv		%r0(%r2)
7511da177e4SLinus Torvalds	nop
7521da177e4SLinus Torvalds	.exit
7531da177e4SLinus Torvalds
7541da177e4SLinus Torvalds	.procend
755f39cce65SHelge DellerENDPROC_CFI(copy_user_page_asm)
7561da177e4SLinus Torvalds
757f39cce65SHelge DellerENTRY_CFI(clear_user_page_asm)
7581da177e4SLinus Torvalds	.proc
7591da177e4SLinus Torvalds	.callinfo NO_CALLS
7601da177e4SLinus Torvalds	.entry
7611da177e4SLinus Torvalds
7621da177e4SLinus Torvalds	tophys_r1	%r26
7631da177e4SLinus Torvalds
7641da177e4SLinus Torvalds	ldil		L%(TMPALIAS_MAP_START), %r28
765413059f2SGrant Grundler#ifdef CONFIG_64BIT
7661da177e4SLinus Torvalds#if (TMPALIAS_MAP_START >= 0x80000000)
7671da177e4SLinus Torvalds	depdi		0, 31,32, %r28		/* clear any sign extension */
7681da177e4SLinus Torvalds#endif
7696a45716aSHelge Deller	convert_phys_for_tlb_insert20 %r26	/* convert phys addr to tlb insert format */
7701da177e4SLinus Torvalds	depd		%r25, 63,22, %r28	/* Form aliased virtual address 'to' */
7716a45716aSHelge Deller	depdi		0, 63,PAGE_SHIFT, %r28	/* Clear any offset bits */
7721da177e4SLinus Torvalds#else
7731da177e4SLinus Torvalds	extrw,u		%r26, 24,25, %r26	/* convert phys addr to tlb insert format */
7741da177e4SLinus Torvalds	depw		%r25, 31,22, %r28	/* Form aliased virtual address 'to' */
775d845b5fbSHelge Deller	depwi		0, 31,PAGE_SHIFT, %r28	/* Clear any offset bits */
7761da177e4SLinus Torvalds#endif
7771da177e4SLinus Torvalds
7781da177e4SLinus Torvalds	/* Purge any old translation */
7791da177e4SLinus Torvalds
7806d2ddc2fSJohn David Anglin#ifdef CONFIG_PA20
7815035b230SJohn David Anglin	pdtlb,l		%r0(%r28)
7826d2ddc2fSJohn David Anglin#else
7836d2ddc2fSJohn David Anglin	tlb_lock	%r20,%r21,%r22
7845035b230SJohn David Anglin	pdtlb		%r0(%r28)
7856d2ddc2fSJohn David Anglin	tlb_unlock	%r20,%r21,%r22
7866d2ddc2fSJohn David Anglin#endif
7871da177e4SLinus Torvalds
788413059f2SGrant Grundler#ifdef CONFIG_64BIT
7896ebeafffSKyle McMartin	ldi		(PAGE_SIZE / 128), %r1
7901da177e4SLinus Torvalds
7911da177e4SLinus Torvalds	/* PREFETCH (Write) has not (yet) been proven to help here */
7921da177e4SLinus Torvalds	/* #define	PREFETCHW_OP	ldd		256(%0), %r0 */
7931da177e4SLinus Torvalds
7941da177e4SLinus Torvalds1:	std		%r0, 0(%r28)
7951da177e4SLinus Torvalds	std		%r0, 8(%r28)
7961da177e4SLinus Torvalds	std		%r0, 16(%r28)
7971da177e4SLinus Torvalds	std		%r0, 24(%r28)
7981da177e4SLinus Torvalds	std		%r0, 32(%r28)
7991da177e4SLinus Torvalds	std		%r0, 40(%r28)
8001da177e4SLinus Torvalds	std		%r0, 48(%r28)
8011da177e4SLinus Torvalds	std		%r0, 56(%r28)
8021da177e4SLinus Torvalds	std		%r0, 64(%r28)
8031da177e4SLinus Torvalds	std		%r0, 72(%r28)
8041da177e4SLinus Torvalds	std		%r0, 80(%r28)
8051da177e4SLinus Torvalds	std		%r0, 88(%r28)
8061da177e4SLinus Torvalds	std		%r0, 96(%r28)
8071da177e4SLinus Torvalds	std		%r0, 104(%r28)
8081da177e4SLinus Torvalds	std		%r0, 112(%r28)
8091da177e4SLinus Torvalds	std		%r0, 120(%r28)
810872f6debSKyle McMartin	addib,COND(>)		-1, %r1, 1b
8111da177e4SLinus Torvalds	ldo		128(%r28), %r28
8121da177e4SLinus Torvalds
813413059f2SGrant Grundler#else	/* ! CONFIG_64BIT */
8146ebeafffSKyle McMartin	ldi		(PAGE_SIZE / 64), %r1
8151da177e4SLinus Torvalds
8166d2ddc2fSJohn David Anglin1:	stw		%r0, 0(%r28)
8171da177e4SLinus Torvalds	stw		%r0, 4(%r28)
8181da177e4SLinus Torvalds	stw		%r0, 8(%r28)
8191da177e4SLinus Torvalds	stw		%r0, 12(%r28)
8201da177e4SLinus Torvalds	stw		%r0, 16(%r28)
8211da177e4SLinus Torvalds	stw		%r0, 20(%r28)
8221da177e4SLinus Torvalds	stw		%r0, 24(%r28)
8231da177e4SLinus Torvalds	stw		%r0, 28(%r28)
8241da177e4SLinus Torvalds	stw		%r0, 32(%r28)
8251da177e4SLinus Torvalds	stw		%r0, 36(%r28)
8261da177e4SLinus Torvalds	stw		%r0, 40(%r28)
8271da177e4SLinus Torvalds	stw		%r0, 44(%r28)
8281da177e4SLinus Torvalds	stw		%r0, 48(%r28)
8291da177e4SLinus Torvalds	stw		%r0, 52(%r28)
8301da177e4SLinus Torvalds	stw		%r0, 56(%r28)
8311da177e4SLinus Torvalds	stw		%r0, 60(%r28)
832872f6debSKyle McMartin	addib,COND(>)		-1, %r1, 1b
8331da177e4SLinus Torvalds	ldo		64(%r28), %r28
834413059f2SGrant Grundler#endif	/* CONFIG_64BIT */
8351da177e4SLinus Torvalds
8361da177e4SLinus Torvalds	bv		%r0(%r2)
8371da177e4SLinus Torvalds	nop
8381da177e4SLinus Torvalds	.exit
8391da177e4SLinus Torvalds
8401da177e4SLinus Torvalds	.procend
841f39cce65SHelge DellerENDPROC_CFI(clear_user_page_asm)
8421da177e4SLinus Torvalds
843f39cce65SHelge DellerENTRY_CFI(flush_dcache_page_asm)
844f311847cSJames Bottomley	.proc
845f311847cSJames Bottomley	.callinfo NO_CALLS
846f311847cSJames Bottomley	.entry
847f311847cSJames Bottomley
848f311847cSJames Bottomley	ldil		L%(TMPALIAS_MAP_START), %r28
849f311847cSJames Bottomley#ifdef CONFIG_64BIT
850f311847cSJames Bottomley#if (TMPALIAS_MAP_START >= 0x80000000)
851f311847cSJames Bottomley	depdi		0, 31,32, %r28		/* clear any sign extension */
852f311847cSJames Bottomley#endif
8536a45716aSHelge Deller	convert_phys_for_tlb_insert20 %r26	/* convert phys addr to tlb insert format */
854f311847cSJames Bottomley	depd		%r25, 63,22, %r28	/* Form aliased virtual address 'to' */
8556a45716aSHelge Deller	depdi		0, 63,PAGE_SHIFT, %r28	/* Clear any offset bits */
856f311847cSJames Bottomley#else
857f311847cSJames Bottomley	extrw,u		%r26, 24,25, %r26	/* convert phys addr to tlb insert format */
858f311847cSJames Bottomley	depw		%r25, 31,22, %r28	/* Form aliased virtual address 'to' */
859d845b5fbSHelge Deller	depwi		0, 31,PAGE_SHIFT, %r28	/* Clear any offset bits */
860f311847cSJames Bottomley#endif
861f311847cSJames Bottomley
862f311847cSJames Bottomley	/* Purge any old translation */
863f311847cSJames Bottomley
8646d2ddc2fSJohn David Anglin#ifdef CONFIG_PA20
8655035b230SJohn David Anglin	pdtlb,l		%r0(%r28)
8666d2ddc2fSJohn David Anglin#else
8676d2ddc2fSJohn David Anglin	tlb_lock	%r20,%r21,%r22
8685035b230SJohn David Anglin	pdtlb		%r0(%r28)
8696d2ddc2fSJohn David Anglin	tlb_unlock	%r20,%r21,%r22
8706d2ddc2fSJohn David Anglin#endif
871f311847cSJames Bottomley
872f311847cSJames Bottomley	ldil		L%dcache_stride, %r1
873d65ea48dSJohn David Anglin	ldw		R%dcache_stride(%r1), r31
874f311847cSJames Bottomley
875f311847cSJames Bottomley#ifdef CONFIG_64BIT
876f311847cSJames Bottomley	depdi,z		1, 63-PAGE_SHIFT,1, %r25
877f311847cSJames Bottomley#else
878f311847cSJames Bottomley	depwi,z		1, 31-PAGE_SHIFT,1, %r25
879f311847cSJames Bottomley#endif
880f311847cSJames Bottomley	add		%r28, %r25, %r25
881d65ea48dSJohn David Anglin	sub		%r25, r31, %r25
882f311847cSJames Bottomley
883f311847cSJames Bottomley
884d65ea48dSJohn David Anglin1:      fdc,m		r31(%r28)
885d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
886d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
887d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
888d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
889d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
890d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
891d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
892d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
893d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
894d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
895d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
896d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
897d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
898d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
899f311847cSJames Bottomley	cmpb,COND(<<)	%r28, %r25,1b
900d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
901f311847cSJames Bottomley
902f311847cSJames Bottomley	sync
903f311847cSJames Bottomley	bv		%r0(%r2)
9046d2ddc2fSJohn David Anglin	nop
905f311847cSJames Bottomley	.exit
906f311847cSJames Bottomley
907f311847cSJames Bottomley	.procend
908f39cce65SHelge DellerENDPROC_CFI(flush_dcache_page_asm)
909f311847cSJames Bottomley
910f39cce65SHelge DellerENTRY_CFI(flush_icache_page_asm)
911f311847cSJames Bottomley	.proc
912f311847cSJames Bottomley	.callinfo NO_CALLS
913f311847cSJames Bottomley	.entry
914f311847cSJames Bottomley
915f311847cSJames Bottomley	ldil		L%(TMPALIAS_MAP_START), %r28
916f311847cSJames Bottomley#ifdef CONFIG_64BIT
917f311847cSJames Bottomley#if (TMPALIAS_MAP_START >= 0x80000000)
918f311847cSJames Bottomley	depdi		0, 31,32, %r28		/* clear any sign extension */
919f311847cSJames Bottomley#endif
9206a45716aSHelge Deller	convert_phys_for_tlb_insert20 %r26	/* convert phys addr to tlb insert format */
921f311847cSJames Bottomley	depd		%r25, 63,22, %r28	/* Form aliased virtual address 'to' */
9226a45716aSHelge Deller	depdi		0, 63,PAGE_SHIFT, %r28	/* Clear any offset bits */
923f311847cSJames Bottomley#else
924f311847cSJames Bottomley	extrw,u		%r26, 24,25, %r26	/* convert phys addr to tlb insert format */
925f311847cSJames Bottomley	depw		%r25, 31,22, %r28	/* Form aliased virtual address 'to' */
926d845b5fbSHelge Deller	depwi		0, 31,PAGE_SHIFT, %r28	/* Clear any offset bits */
927f311847cSJames Bottomley#endif
928f311847cSJames Bottomley
9295035b230SJohn David Anglin	/* Purge any old translation.  Note that the FIC instruction
9305035b230SJohn David Anglin	 * may use either the instruction or data TLB.  Given that we
9315035b230SJohn David Anglin	 * have a flat address space, it's not clear which TLB will be
9325035b230SJohn David Anglin	 * used.  So, we purge both entries.  */
933f311847cSJames Bottomley
9346d2ddc2fSJohn David Anglin#ifdef CONFIG_PA20
9355035b230SJohn David Anglin	pdtlb,l		%r0(%r28)
9366d2ddc2fSJohn David Anglin	pitlb,l         %r0(%sr4,%r28)
9376d2ddc2fSJohn David Anglin#else
9386d2ddc2fSJohn David Anglin	tlb_lock        %r20,%r21,%r22
9395035b230SJohn David Anglin	pdtlb		%r0(%r28)
9405035b230SJohn David Anglin	pitlb           %r0(%sr4,%r28)
9416d2ddc2fSJohn David Anglin	tlb_unlock      %r20,%r21,%r22
9426d2ddc2fSJohn David Anglin#endif
943f311847cSJames Bottomley
944f311847cSJames Bottomley	ldil		L%icache_stride, %r1
945d65ea48dSJohn David Anglin	ldw		R%icache_stride(%r1), %r31
946f311847cSJames Bottomley
947f311847cSJames Bottomley#ifdef CONFIG_64BIT
948f311847cSJames Bottomley	depdi,z		1, 63-PAGE_SHIFT,1, %r25
949f311847cSJames Bottomley#else
950f311847cSJames Bottomley	depwi,z		1, 31-PAGE_SHIFT,1, %r25
951f311847cSJames Bottomley#endif
952f311847cSJames Bottomley	add		%r28, %r25, %r25
953d65ea48dSJohn David Anglin	sub		%r25, %r31, %r25
954f311847cSJames Bottomley
955f311847cSJames Bottomley
956207f583dSJohn David Anglin	/* fic only has the type 26 form on PA1.1, requiring an
957207f583dSJohn David Anglin	 * explicit space specification, so use %sr4 */
958d65ea48dSJohn David Anglin1:      fic,m		%r31(%sr4,%r28)
959d65ea48dSJohn David Anglin	fic,m		%r31(%sr4,%r28)
960d65ea48dSJohn David Anglin	fic,m		%r31(%sr4,%r28)
961d65ea48dSJohn David Anglin	fic,m		%r31(%sr4,%r28)
962d65ea48dSJohn David Anglin	fic,m		%r31(%sr4,%r28)
963d65ea48dSJohn David Anglin	fic,m		%r31(%sr4,%r28)
964d65ea48dSJohn David Anglin	fic,m		%r31(%sr4,%r28)
965d65ea48dSJohn David Anglin	fic,m		%r31(%sr4,%r28)
966d65ea48dSJohn David Anglin	fic,m		%r31(%sr4,%r28)
967d65ea48dSJohn David Anglin	fic,m		%r31(%sr4,%r28)
968d65ea48dSJohn David Anglin	fic,m		%r31(%sr4,%r28)
969d65ea48dSJohn David Anglin	fic,m		%r31(%sr4,%r28)
970d65ea48dSJohn David Anglin	fic,m		%r31(%sr4,%r28)
971d65ea48dSJohn David Anglin	fic,m		%r31(%sr4,%r28)
972d65ea48dSJohn David Anglin	fic,m		%r31(%sr4,%r28)
973f311847cSJames Bottomley	cmpb,COND(<<)	%r28, %r25,1b
974d65ea48dSJohn David Anglin	fic,m		%r31(%sr4,%r28)
975f311847cSJames Bottomley
976f311847cSJames Bottomley	sync
9776d2ddc2fSJohn David Anglin	bv		%r0(%r2)
9786d2ddc2fSJohn David Anglin	nop
979f311847cSJames Bottomley	.exit
980f311847cSJames Bottomley
981f311847cSJames Bottomley	.procend
982f39cce65SHelge DellerENDPROC_CFI(flush_icache_page_asm)
983f311847cSJames Bottomley
984f39cce65SHelge DellerENTRY_CFI(flush_kernel_dcache_page_asm)
9851da177e4SLinus Torvalds	.proc
9861da177e4SLinus Torvalds	.callinfo NO_CALLS
9871da177e4SLinus Torvalds	.entry
9881da177e4SLinus Torvalds
9891da177e4SLinus Torvalds	ldil		L%dcache_stride, %r1
9901da177e4SLinus Torvalds	ldw		R%dcache_stride(%r1), %r23
9911da177e4SLinus Torvalds
992413059f2SGrant Grundler#ifdef CONFIG_64BIT
9931da177e4SLinus Torvalds	depdi,z		1, 63-PAGE_SHIFT,1, %r25
9941da177e4SLinus Torvalds#else
9951da177e4SLinus Torvalds	depwi,z		1, 31-PAGE_SHIFT,1, %r25
9961da177e4SLinus Torvalds#endif
9971da177e4SLinus Torvalds	add		%r26, %r25, %r25
9981da177e4SLinus Torvalds	sub		%r25, %r23, %r25
9991da177e4SLinus Torvalds
10001da177e4SLinus Torvalds
10011da177e4SLinus Torvalds1:      fdc,m		%r23(%r26)
10021da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10031da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10041da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10051da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10061da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10071da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10081da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10091da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10101da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10111da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10121da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10131da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10141da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10151da177e4SLinus Torvalds	fdc,m		%r23(%r26)
1016872f6debSKyle McMartin	cmpb,COND(<<)		%r26, %r25,1b
10171da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10181da177e4SLinus Torvalds
10191da177e4SLinus Torvalds	sync
10201da177e4SLinus Torvalds	bv		%r0(%r2)
10211da177e4SLinus Torvalds	nop
10221da177e4SLinus Torvalds	.exit
10231da177e4SLinus Torvalds
10241da177e4SLinus Torvalds	.procend
1025f39cce65SHelge DellerENDPROC_CFI(flush_kernel_dcache_page_asm)
10261da177e4SLinus Torvalds
1027f39cce65SHelge DellerENTRY_CFI(purge_kernel_dcache_page_asm)
10281da177e4SLinus Torvalds	.proc
10291da177e4SLinus Torvalds	.callinfo NO_CALLS
10301da177e4SLinus Torvalds	.entry
10311da177e4SLinus Torvalds
10321da177e4SLinus Torvalds	ldil		L%dcache_stride, %r1
10331da177e4SLinus Torvalds	ldw		R%dcache_stride(%r1), %r23
10341da177e4SLinus Torvalds
1035413059f2SGrant Grundler#ifdef CONFIG_64BIT
10361da177e4SLinus Torvalds	depdi,z		1, 63-PAGE_SHIFT,1, %r25
10371da177e4SLinus Torvalds#else
10381da177e4SLinus Torvalds	depwi,z		1, 31-PAGE_SHIFT,1, %r25
10391da177e4SLinus Torvalds#endif
10401da177e4SLinus Torvalds	add		%r26, %r25, %r25
10411da177e4SLinus Torvalds	sub		%r25, %r23, %r25
10421da177e4SLinus Torvalds
10431da177e4SLinus Torvalds1:      pdc,m		%r23(%r26)
10441da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10451da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10461da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10471da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10481da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10491da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10501da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10511da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10521da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10531da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10541da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10551da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10561da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10571da177e4SLinus Torvalds	pdc,m		%r23(%r26)
1058872f6debSKyle McMartin	cmpb,COND(<<)		%r26, %r25, 1b
10591da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10601da177e4SLinus Torvalds
10611da177e4SLinus Torvalds	sync
10621da177e4SLinus Torvalds	bv		%r0(%r2)
10631da177e4SLinus Torvalds	nop
10641da177e4SLinus Torvalds	.exit
10651da177e4SLinus Torvalds
10661da177e4SLinus Torvalds	.procend
1067f39cce65SHelge DellerENDPROC_CFI(purge_kernel_dcache_page_asm)
10681da177e4SLinus Torvalds
1069f39cce65SHelge DellerENTRY_CFI(flush_user_dcache_range_asm)
10701da177e4SLinus Torvalds	.proc
10711da177e4SLinus Torvalds	.callinfo NO_CALLS
10721da177e4SLinus Torvalds	.entry
10731da177e4SLinus Torvalds
10741da177e4SLinus Torvalds	ldil		L%dcache_stride, %r1
10751da177e4SLinus Torvalds	ldw		R%dcache_stride(%r1), %r23
10761da177e4SLinus Torvalds	ldo		-1(%r23), %r21
10771da177e4SLinus Torvalds	ANDCM		%r26, %r21, %r26
10781da177e4SLinus Torvalds
1079872f6debSKyle McMartin1:      cmpb,COND(<<),n	%r26, %r25, 1b
10801da177e4SLinus Torvalds	fdc,m		%r23(%sr3, %r26)
10811da177e4SLinus Torvalds
10821da177e4SLinus Torvalds	sync
10831da177e4SLinus Torvalds	bv		%r0(%r2)
10841da177e4SLinus Torvalds	nop
10851da177e4SLinus Torvalds	.exit
10861da177e4SLinus Torvalds
10871da177e4SLinus Torvalds	.procend
1088f39cce65SHelge DellerENDPROC_CFI(flush_user_dcache_range_asm)
10891da177e4SLinus Torvalds
1090f39cce65SHelge DellerENTRY_CFI(flush_kernel_dcache_range_asm)
10911da177e4SLinus Torvalds	.proc
10921da177e4SLinus Torvalds	.callinfo NO_CALLS
10931da177e4SLinus Torvalds	.entry
10941da177e4SLinus Torvalds
10951da177e4SLinus Torvalds	ldil		L%dcache_stride, %r1
10961da177e4SLinus Torvalds	ldw		R%dcache_stride(%r1), %r23
10971da177e4SLinus Torvalds	ldo		-1(%r23), %r21
10981da177e4SLinus Torvalds	ANDCM		%r26, %r21, %r26
10991da177e4SLinus Torvalds
1100872f6debSKyle McMartin1:      cmpb,COND(<<),n	%r26, %r25,1b
11011da177e4SLinus Torvalds	fdc,m		%r23(%r26)
11021da177e4SLinus Torvalds
11031da177e4SLinus Torvalds	sync
11041da177e4SLinus Torvalds	syncdma
11051da177e4SLinus Torvalds	bv		%r0(%r2)
11061da177e4SLinus Torvalds	nop
11071da177e4SLinus Torvalds	.exit
11081da177e4SLinus Torvalds
11091da177e4SLinus Torvalds	.procend
1110f39cce65SHelge DellerENDPROC_CFI(flush_kernel_dcache_range_asm)
11111da177e4SLinus Torvalds
11120adb24e0SJohn David AnglinENTRY_CFI(purge_kernel_dcache_range_asm)
11130adb24e0SJohn David Anglin	.proc
11140adb24e0SJohn David Anglin	.callinfo NO_CALLS
11150adb24e0SJohn David Anglin	.entry
11160adb24e0SJohn David Anglin
11170adb24e0SJohn David Anglin	ldil		L%dcache_stride, %r1
11180adb24e0SJohn David Anglin	ldw		R%dcache_stride(%r1), %r23
11190adb24e0SJohn David Anglin	ldo		-1(%r23), %r21
11200adb24e0SJohn David Anglin	ANDCM		%r26, %r21, %r26
11210adb24e0SJohn David Anglin
11220adb24e0SJohn David Anglin1:      cmpb,COND(<<),n	%r26, %r25,1b
11230adb24e0SJohn David Anglin	pdc,m		%r23(%r26)
11240adb24e0SJohn David Anglin
11250adb24e0SJohn David Anglin	sync
11260adb24e0SJohn David Anglin	syncdma
11270adb24e0SJohn David Anglin	bv		%r0(%r2)
11280adb24e0SJohn David Anglin	nop
11290adb24e0SJohn David Anglin	.exit
11300adb24e0SJohn David Anglin
11310adb24e0SJohn David Anglin	.procend
11320adb24e0SJohn David AnglinENDPROC_CFI(purge_kernel_dcache_range_asm)
11330adb24e0SJohn David Anglin
1134f39cce65SHelge DellerENTRY_CFI(flush_user_icache_range_asm)
11351da177e4SLinus Torvalds	.proc
11361da177e4SLinus Torvalds	.callinfo NO_CALLS
11371da177e4SLinus Torvalds	.entry
11381da177e4SLinus Torvalds
11391da177e4SLinus Torvalds	ldil		L%icache_stride, %r1
11401da177e4SLinus Torvalds	ldw		R%icache_stride(%r1), %r23
11411da177e4SLinus Torvalds	ldo		-1(%r23), %r21
11421da177e4SLinus Torvalds	ANDCM		%r26, %r21, %r26
11431da177e4SLinus Torvalds
1144872f6debSKyle McMartin1:      cmpb,COND(<<),n	%r26, %r25,1b
11451da177e4SLinus Torvalds	fic,m		%r23(%sr3, %r26)
11461da177e4SLinus Torvalds
11471da177e4SLinus Torvalds	sync
11481da177e4SLinus Torvalds	bv		%r0(%r2)
11491da177e4SLinus Torvalds	nop
11501da177e4SLinus Torvalds	.exit
11511da177e4SLinus Torvalds
11521da177e4SLinus Torvalds	.procend
1153f39cce65SHelge DellerENDPROC_CFI(flush_user_icache_range_asm)
11541da177e4SLinus Torvalds
1155f39cce65SHelge DellerENTRY_CFI(flush_kernel_icache_page)
11561da177e4SLinus Torvalds	.proc
11571da177e4SLinus Torvalds	.callinfo NO_CALLS
11581da177e4SLinus Torvalds	.entry
11591da177e4SLinus Torvalds
11601da177e4SLinus Torvalds	ldil		L%icache_stride, %r1
11611da177e4SLinus Torvalds	ldw		R%icache_stride(%r1), %r23
11621da177e4SLinus Torvalds
1163413059f2SGrant Grundler#ifdef CONFIG_64BIT
11641da177e4SLinus Torvalds	depdi,z		1, 63-PAGE_SHIFT,1, %r25
11651da177e4SLinus Torvalds#else
11661da177e4SLinus Torvalds	depwi,z		1, 31-PAGE_SHIFT,1, %r25
11671da177e4SLinus Torvalds#endif
11681da177e4SLinus Torvalds	add		%r26, %r25, %r25
11691da177e4SLinus Torvalds	sub		%r25, %r23, %r25
11701da177e4SLinus Torvalds
11711da177e4SLinus Torvalds
1172e635c96eSMatthew Wilcox1:      fic,m		%r23(%sr4, %r26)
1173e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1174e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1175e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1176e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1177e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1178e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1179e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1180e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1181e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1182e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1183e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1184e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1185e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1186e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1187872f6debSKyle McMartin	cmpb,COND(<<)		%r26, %r25, 1b
1188e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
11891da177e4SLinus Torvalds
11901da177e4SLinus Torvalds	sync
11911da177e4SLinus Torvalds	bv		%r0(%r2)
11921da177e4SLinus Torvalds	nop
11931da177e4SLinus Torvalds	.exit
11941da177e4SLinus Torvalds
11951da177e4SLinus Torvalds	.procend
1196f39cce65SHelge DellerENDPROC_CFI(flush_kernel_icache_page)
11971da177e4SLinus Torvalds
1198f39cce65SHelge DellerENTRY_CFI(flush_kernel_icache_range_asm)
11991da177e4SLinus Torvalds	.proc
12001da177e4SLinus Torvalds	.callinfo NO_CALLS
12011da177e4SLinus Torvalds	.entry
12021da177e4SLinus Torvalds
12031da177e4SLinus Torvalds	ldil		L%icache_stride, %r1
12041da177e4SLinus Torvalds	ldw		R%icache_stride(%r1), %r23
12051da177e4SLinus Torvalds	ldo		-1(%r23), %r21
12061da177e4SLinus Torvalds	ANDCM		%r26, %r21, %r26
12071da177e4SLinus Torvalds
1208872f6debSKyle McMartin1:      cmpb,COND(<<),n	%r26, %r25, 1b
1209e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
12101da177e4SLinus Torvalds
12111da177e4SLinus Torvalds	sync
12121da177e4SLinus Torvalds	bv		%r0(%r2)
12131da177e4SLinus Torvalds	nop
12141da177e4SLinus Torvalds	.exit
12151da177e4SLinus Torvalds	.procend
1216f39cce65SHelge DellerENDPROC_CFI(flush_kernel_icache_range_asm)
12171da177e4SLinus Torvalds
1218*2a03bb9eSHelge Deller	__INIT
1219*2a03bb9eSHelge Deller
1220896a3756SGrant Grundler	/* align should cover use of rfi in disable_sr_hashing_asm and
1221896a3756SGrant Grundler	 * srdis_done.
1222896a3756SGrant Grundler	 */
1223896a3756SGrant Grundler	.align	256
1224f39cce65SHelge DellerENTRY_CFI(disable_sr_hashing_asm)
12251da177e4SLinus Torvalds	.proc
12261da177e4SLinus Torvalds	.callinfo NO_CALLS
12271da177e4SLinus Torvalds	.entry
12281da177e4SLinus Torvalds
1229896a3756SGrant Grundler	/*
1230896a3756SGrant Grundler	 * Switch to real mode
1231896a3756SGrant Grundler	 */
1232896a3756SGrant Grundler	/* pcxt_ssm_bug */
1233896a3756SGrant Grundler	rsm		PSW_SM_I, %r0
1234896a3756SGrant Grundler	load32		PA(1f), %r1
12351da177e4SLinus Torvalds	nop
12361da177e4SLinus Torvalds	nop
12371da177e4SLinus Torvalds	nop
12381da177e4SLinus Torvalds	nop
12391da177e4SLinus Torvalds	nop
12401da177e4SLinus Torvalds
1241896a3756SGrant Grundler	rsm		PSW_SM_Q, %r0		/* prep to load iia queue */
12421da177e4SLinus Torvalds	mtctl		%r0, %cr17		/* Clear IIASQ tail */
12431da177e4SLinus Torvalds	mtctl		%r0, %cr17		/* Clear IIASQ head */
12441da177e4SLinus Torvalds	mtctl		%r1, %cr18		/* IIAOQ head */
12451da177e4SLinus Torvalds	ldo		4(%r1), %r1
12461da177e4SLinus Torvalds	mtctl		%r1, %cr18		/* IIAOQ tail */
1247896a3756SGrant Grundler	load32		REAL_MODE_PSW, %r1
1248896a3756SGrant Grundler	mtctl		%r1, %ipsw
12491da177e4SLinus Torvalds	rfi
12501da177e4SLinus Torvalds	nop
12511da177e4SLinus Torvalds
12521da177e4SLinus Torvalds1:      cmpib,=,n	SRHASH_PCXST, %r26,srdis_pcxs
12531da177e4SLinus Torvalds	cmpib,=,n	SRHASH_PCXL, %r26,srdis_pcxl
12541da177e4SLinus Torvalds	cmpib,=,n	SRHASH_PA20, %r26,srdis_pa20
12551da177e4SLinus Torvalds	b,n		srdis_done
12561da177e4SLinus Torvalds
12571da177e4SLinus Torvaldssrdis_pcxs:
12581da177e4SLinus Torvalds
12591da177e4SLinus Torvalds	/* Disable Space Register Hashing for PCXS,PCXT,PCXT' */
12601da177e4SLinus Torvalds
12611da177e4SLinus Torvalds	.word		0x141c1a00		/* mfdiag %dr0, %r28 */
12621da177e4SLinus Torvalds	.word		0x141c1a00		/* must issue twice */
12631da177e4SLinus Torvalds	depwi		0,18,1, %r28		/* Clear DHE (dcache hash enable) */
12641da177e4SLinus Torvalds	depwi		0,20,1, %r28		/* Clear IHE (icache hash enable) */
12651da177e4SLinus Torvalds	.word		0x141c1600		/* mtdiag %r28, %dr0 */
12661da177e4SLinus Torvalds	.word		0x141c1600		/* must issue twice */
12671da177e4SLinus Torvalds	b,n		srdis_done
12681da177e4SLinus Torvalds
12691da177e4SLinus Torvaldssrdis_pcxl:
12701da177e4SLinus Torvalds
12711da177e4SLinus Torvalds	/* Disable Space Register Hashing for PCXL */
12721da177e4SLinus Torvalds
12731da177e4SLinus Torvalds	.word		0x141c0600		/* mfdiag %dr0, %r28 */
12741da177e4SLinus Torvalds	depwi           0,28,2, %r28		/* Clear DHASH_EN & IHASH_EN */
12751da177e4SLinus Torvalds	.word		0x141c0240		/* mtdiag %r28, %dr0 */
12761da177e4SLinus Torvalds	b,n		srdis_done
12771da177e4SLinus Torvalds
12781da177e4SLinus Torvaldssrdis_pa20:
12791da177e4SLinus Torvalds
1280896a3756SGrant Grundler	/* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+,PCXW2 */
12811da177e4SLinus Torvalds
12821da177e4SLinus Torvalds	.word		0x144008bc		/* mfdiag %dr2, %r28 */
12831da177e4SLinus Torvalds	depdi		0, 54,1, %r28		/* clear DIAG_SPHASH_ENAB (bit 54) */
12841da177e4SLinus Torvalds	.word		0x145c1840		/* mtdiag %r28, %dr2 */
12851da177e4SLinus Torvalds
1286896a3756SGrant Grundler
12871da177e4SLinus Torvaldssrdis_done:
12881da177e4SLinus Torvalds	/* Switch back to virtual mode */
1289896a3756SGrant Grundler	rsm		PSW_SM_I, %r0		/* prep to load iia queue */
1290896a3756SGrant Grundler	load32 	   	2f, %r1
1291896a3756SGrant Grundler	nop
1292896a3756SGrant Grundler	nop
1293896a3756SGrant Grundler	nop
1294896a3756SGrant Grundler	nop
1295896a3756SGrant Grundler	nop
12961da177e4SLinus Torvalds
1297896a3756SGrant Grundler	rsm		PSW_SM_Q, %r0		/* prep to load iia queue */
12981da177e4SLinus Torvalds	mtctl		%r0, %cr17		/* Clear IIASQ tail */
12991da177e4SLinus Torvalds	mtctl		%r0, %cr17		/* Clear IIASQ head */
13001da177e4SLinus Torvalds	mtctl		%r1, %cr18		/* IIAOQ head */
13011da177e4SLinus Torvalds	ldo		4(%r1), %r1
13021da177e4SLinus Torvalds	mtctl		%r1, %cr18		/* IIAOQ tail */
1303896a3756SGrant Grundler	load32		KERNEL_PSW, %r1
1304896a3756SGrant Grundler	mtctl		%r1, %ipsw
13051da177e4SLinus Torvalds	rfi
13061da177e4SLinus Torvalds	nop
13071da177e4SLinus Torvalds
13081da177e4SLinus Torvalds2:      bv		%r0(%r2)
13091da177e4SLinus Torvalds	nop
13101da177e4SLinus Torvalds	.exit
13111da177e4SLinus Torvalds
13121da177e4SLinus Torvalds	.procend
1313f39cce65SHelge DellerENDPROC_CFI(disable_sr_hashing_asm)
13141da177e4SLinus Torvalds
13151da177e4SLinus Torvalds	.end
1316