xref: /linux/arch/parisc/kernel/pacache.S (revision f39cce654f9a1df331d7e1ba703f5f06a79f2159)
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>
398e9e9844SHelge Deller#include <linux/linkage.h>
401da177e4SLinus Torvalds
41dfcf753bSKyle McMartin	.text
421da177e4SLinus Torvalds	.align	128
431da177e4SLinus Torvalds
44*f39cce65SHelge DellerENTRY_CFI(flush_tlb_all_local)
451da177e4SLinus Torvalds	.proc
461da177e4SLinus Torvalds	.callinfo NO_CALLS
471da177e4SLinus Torvalds	.entry
481da177e4SLinus Torvalds
491da177e4SLinus Torvalds	/*
501da177e4SLinus Torvalds	 * The pitlbe and pdtlbe instructions should only be used to
511da177e4SLinus Torvalds	 * flush the entire tlb. Also, there needs to be no intervening
521da177e4SLinus Torvalds	 * tlb operations, e.g. tlb misses, so the operation needs
531da177e4SLinus Torvalds	 * to happen in real mode with all interruptions disabled.
541da177e4SLinus Torvalds	 */
551da177e4SLinus Torvalds
56896a3756SGrant Grundler	/* pcxt_ssm_bug	- relied upon translation! PA 2.0 Arch. F-4 and F-5 */
57896a3756SGrant Grundler	rsm		PSW_SM_I, %r19		/* save I-bit state */
58896a3756SGrant Grundler	load32		PA(1f), %r1
591da177e4SLinus Torvalds	nop
601da177e4SLinus Torvalds	nop
611da177e4SLinus Torvalds	nop
621da177e4SLinus Torvalds	nop
631da177e4SLinus Torvalds	nop
641da177e4SLinus Torvalds
65896a3756SGrant Grundler	rsm		PSW_SM_Q, %r0		/* prep to load iia queue */
661da177e4SLinus Torvalds	mtctl		%r0, %cr17		/* Clear IIASQ tail */
671da177e4SLinus Torvalds	mtctl		%r0, %cr17		/* Clear IIASQ head */
681da177e4SLinus Torvalds	mtctl		%r1, %cr18		/* IIAOQ head */
691da177e4SLinus Torvalds	ldo		4(%r1), %r1
701da177e4SLinus Torvalds	mtctl		%r1, %cr18		/* IIAOQ tail */
71896a3756SGrant Grundler	load32		REAL_MODE_PSW, %r1
72896a3756SGrant Grundler	mtctl           %r1, %ipsw
731da177e4SLinus Torvalds	rfi
741da177e4SLinus Torvalds	nop
751da177e4SLinus Torvalds
762fd83038SHelge Deller1:      load32		PA(cache_info), %r1
771da177e4SLinus Torvalds
781da177e4SLinus Torvalds	/* Flush Instruction Tlb */
791da177e4SLinus Torvalds
801da177e4SLinus Torvalds	LDREG		ITLB_SID_BASE(%r1), %r20
811da177e4SLinus Torvalds	LDREG		ITLB_SID_STRIDE(%r1), %r21
821da177e4SLinus Torvalds	LDREG		ITLB_SID_COUNT(%r1), %r22
831da177e4SLinus Torvalds	LDREG		ITLB_OFF_BASE(%r1), %arg0
841da177e4SLinus Torvalds	LDREG		ITLB_OFF_STRIDE(%r1), %arg1
851da177e4SLinus Torvalds	LDREG		ITLB_OFF_COUNT(%r1), %arg2
861da177e4SLinus Torvalds	LDREG		ITLB_LOOP(%r1), %arg3
871da177e4SLinus Torvalds
88872f6debSKyle McMartin	addib,COND(=)		-1, %arg3, fitoneloop	/* Preadjust and test */
891da177e4SLinus Torvalds	movb,<,n	%arg3, %r31, fitdone	/* If loop < 0, skip */
901da177e4SLinus Torvalds	copy		%arg0, %r28		/* Init base addr */
911da177e4SLinus Torvalds
921da177e4SLinus Torvaldsfitmanyloop:					/* Loop if LOOP >= 2 */
931da177e4SLinus Torvalds	mtsp		%r20, %sr1
941da177e4SLinus Torvalds	add		%r21, %r20, %r20	/* increment space */
951da177e4SLinus Torvalds	copy		%arg2, %r29		/* Init middle loop count */
961da177e4SLinus Torvalds
971da177e4SLinus Torvaldsfitmanymiddle:					/* Loop if LOOP >= 2 */
98872f6debSKyle McMartin	addib,COND(>)		-1, %r31, fitmanymiddle	/* Adjusted inner loop decr */
991da177e4SLinus Torvalds	pitlbe		0(%sr1, %r28)
1001da177e4SLinus Torvalds	pitlbe,m	%arg1(%sr1, %r28)	/* Last pitlbe and addr adjust */
101872f6debSKyle McMartin	addib,COND(>)		-1, %r29, fitmanymiddle	/* Middle loop decr */
1021da177e4SLinus Torvalds	copy		%arg3, %r31		/* Re-init inner loop count */
1031da177e4SLinus Torvalds
1041da177e4SLinus Torvalds	movb,tr		%arg0, %r28, fitmanyloop /* Re-init base addr */
105872f6debSKyle McMartin	addib,COND(<=),n	-1, %r22, fitdone	/* Outer loop count decr */
1061da177e4SLinus Torvalds
1071da177e4SLinus Torvaldsfitoneloop:					/* Loop if LOOP = 1 */
1081da177e4SLinus Torvalds	mtsp		%r20, %sr1
1091da177e4SLinus Torvalds	copy		%arg0, %r28		/* init base addr */
1101da177e4SLinus Torvalds	copy		%arg2, %r29		/* init middle loop count */
1111da177e4SLinus Torvalds
1121da177e4SLinus Torvaldsfitonemiddle:					/* Loop if LOOP = 1 */
113872f6debSKyle McMartin	addib,COND(>)		-1, %r29, fitonemiddle	/* Middle loop count decr */
1141da177e4SLinus Torvalds	pitlbe,m	%arg1(%sr1, %r28)	/* pitlbe for one loop */
1151da177e4SLinus Torvalds
116872f6debSKyle McMartin	addib,COND(>)		-1, %r22, fitoneloop	/* Outer loop count decr */
1171da177e4SLinus Torvalds	add		%r21, %r20, %r20		/* increment space */
1181da177e4SLinus Torvalds
1191da177e4SLinus Torvaldsfitdone:
1201da177e4SLinus Torvalds
1211da177e4SLinus Torvalds	/* Flush Data Tlb */
1221da177e4SLinus Torvalds
1231da177e4SLinus Torvalds	LDREG		DTLB_SID_BASE(%r1), %r20
1241da177e4SLinus Torvalds	LDREG		DTLB_SID_STRIDE(%r1), %r21
1251da177e4SLinus Torvalds	LDREG		DTLB_SID_COUNT(%r1), %r22
1261da177e4SLinus Torvalds	LDREG		DTLB_OFF_BASE(%r1), %arg0
1271da177e4SLinus Torvalds	LDREG		DTLB_OFF_STRIDE(%r1), %arg1
1281da177e4SLinus Torvalds	LDREG		DTLB_OFF_COUNT(%r1), %arg2
1291da177e4SLinus Torvalds	LDREG		DTLB_LOOP(%r1), %arg3
1301da177e4SLinus Torvalds
131872f6debSKyle McMartin	addib,COND(=)		-1, %arg3, fdtoneloop	/* Preadjust and test */
1321da177e4SLinus Torvalds	movb,<,n	%arg3, %r31, fdtdone	/* If loop < 0, skip */
1331da177e4SLinus Torvalds	copy		%arg0, %r28		/* Init base addr */
1341da177e4SLinus Torvalds
1351da177e4SLinus Torvaldsfdtmanyloop:					/* Loop if LOOP >= 2 */
1361da177e4SLinus Torvalds	mtsp		%r20, %sr1
1371da177e4SLinus Torvalds	add		%r21, %r20, %r20	/* increment space */
1381da177e4SLinus Torvalds	copy		%arg2, %r29		/* Init middle loop count */
1391da177e4SLinus Torvalds
1401da177e4SLinus Torvaldsfdtmanymiddle:					/* Loop if LOOP >= 2 */
141872f6debSKyle McMartin	addib,COND(>)		-1, %r31, fdtmanymiddle	/* Adjusted inner loop decr */
1421da177e4SLinus Torvalds	pdtlbe		0(%sr1, %r28)
1431da177e4SLinus Torvalds	pdtlbe,m	%arg1(%sr1, %r28)	/* Last pdtlbe and addr adjust */
144872f6debSKyle McMartin	addib,COND(>)		-1, %r29, fdtmanymiddle	/* Middle loop decr */
1451da177e4SLinus Torvalds	copy		%arg3, %r31		/* Re-init inner loop count */
1461da177e4SLinus Torvalds
1471da177e4SLinus Torvalds	movb,tr		%arg0, %r28, fdtmanyloop /* Re-init base addr */
148872f6debSKyle McMartin	addib,COND(<=),n	-1, %r22,fdtdone	/* Outer loop count decr */
1491da177e4SLinus Torvalds
1501da177e4SLinus Torvaldsfdtoneloop:					/* Loop if LOOP = 1 */
1511da177e4SLinus Torvalds	mtsp		%r20, %sr1
1521da177e4SLinus Torvalds	copy		%arg0, %r28		/* init base addr */
1531da177e4SLinus Torvalds	copy		%arg2, %r29		/* init middle loop count */
1541da177e4SLinus Torvalds
1551da177e4SLinus Torvaldsfdtonemiddle:					/* Loop if LOOP = 1 */
156872f6debSKyle McMartin	addib,COND(>)		-1, %r29, fdtonemiddle	/* Middle loop count decr */
1571da177e4SLinus Torvalds	pdtlbe,m	%arg1(%sr1, %r28)	/* pdtlbe for one loop */
1581da177e4SLinus Torvalds
159872f6debSKyle McMartin	addib,COND(>)		-1, %r22, fdtoneloop	/* Outer loop count decr */
1601da177e4SLinus Torvalds	add		%r21, %r20, %r20	/* increment space */
1611da177e4SLinus Torvalds
162896a3756SGrant Grundler
1631da177e4SLinus Torvaldsfdtdone:
164896a3756SGrant Grundler	/*
165896a3756SGrant Grundler	 * Switch back to virtual mode
166896a3756SGrant Grundler	 */
167896a3756SGrant Grundler	/* pcxt_ssm_bug */
168896a3756SGrant Grundler	rsm		PSW_SM_I, %r0
169896a3756SGrant Grundler	load32		2f, %r1
170896a3756SGrant Grundler	nop
171896a3756SGrant Grundler	nop
172896a3756SGrant Grundler	nop
173896a3756SGrant Grundler	nop
174896a3756SGrant Grundler	nop
1751da177e4SLinus Torvalds
176896a3756SGrant Grundler	rsm		PSW_SM_Q, %r0		/* prep to load iia queue */
1771da177e4SLinus Torvalds	mtctl		%r0, %cr17		/* Clear IIASQ tail */
1781da177e4SLinus Torvalds	mtctl		%r0, %cr17		/* Clear IIASQ head */
1791da177e4SLinus Torvalds	mtctl		%r1, %cr18		/* IIAOQ head */
1801da177e4SLinus Torvalds	ldo		4(%r1), %r1
1811da177e4SLinus Torvalds	mtctl		%r1, %cr18		/* IIAOQ tail */
182896a3756SGrant Grundler	load32		KERNEL_PSW, %r1
183896a3756SGrant Grundler	or		%r1, %r19, %r1	/* I-bit to state on entry */
184896a3756SGrant Grundler	mtctl		%r1, %ipsw	/* restore I-bit (entire PSW) */
1851da177e4SLinus Torvalds	rfi
1861da177e4SLinus Torvalds	nop
1871da177e4SLinus Torvalds
1881da177e4SLinus Torvalds2:      bv		%r0(%r2)
1891da177e4SLinus Torvalds	nop
1901da177e4SLinus Torvalds
191896a3756SGrant Grundler	.exit
1921da177e4SLinus Torvalds	.procend
193*f39cce65SHelge DellerENDPROC_CFI(flush_tlb_all_local)
1941da177e4SLinus Torvalds
1951da177e4SLinus Torvalds	.import cache_info,data
1961da177e4SLinus Torvalds
197*f39cce65SHelge DellerENTRY_CFI(flush_instruction_cache_local)
1981da177e4SLinus Torvalds	.proc
1991da177e4SLinus Torvalds	.callinfo NO_CALLS
2001da177e4SLinus Torvalds	.entry
2011da177e4SLinus Torvalds
2022fd83038SHelge Deller	load32		cache_info, %r1
2031da177e4SLinus Torvalds
2041da177e4SLinus Torvalds	/* Flush Instruction Cache */
2051da177e4SLinus Torvalds
2061da177e4SLinus Torvalds	LDREG		ICACHE_BASE(%r1), %arg0
2071da177e4SLinus Torvalds	LDREG		ICACHE_STRIDE(%r1), %arg1
2081da177e4SLinus Torvalds	LDREG		ICACHE_COUNT(%r1), %arg2
2091da177e4SLinus Torvalds	LDREG		ICACHE_LOOP(%r1), %arg3
2101da177e4SLinus Torvalds	rsm		PSW_SM_I, %r22		/* No mmgt ops during loop*/
2116d2ddc2fSJohn David Anglin	mtsp		%r0, %sr1
212872f6debSKyle McMartin	addib,COND(=)		-1, %arg3, fioneloop	/* Preadjust and test */
2131da177e4SLinus Torvalds	movb,<,n	%arg3, %r31, fisync	/* If loop < 0, do sync */
2141da177e4SLinus Torvalds
2151da177e4SLinus Torvaldsfimanyloop:					/* Loop if LOOP >= 2 */
216872f6debSKyle McMartin	addib,COND(>)		-1, %r31, fimanyloop	/* Adjusted inner loop decr */
2179b3b331dSGrant Grundler	fice            %r0(%sr1, %arg0)
2181da177e4SLinus Torvalds	fice,m		%arg1(%sr1, %arg0)	/* Last fice and addr adjust */
2191da177e4SLinus Torvalds	movb,tr		%arg3, %r31, fimanyloop	/* Re-init inner loop count */
220872f6debSKyle McMartin	addib,COND(<=),n	-1, %arg2, fisync	/* Outer loop decr */
2211da177e4SLinus Torvalds
2221da177e4SLinus Torvaldsfioneloop:					/* Loop if LOOP = 1 */
2236d2ddc2fSJohn David Anglin	/* Some implementations may flush with a single fice instruction */
2246d2ddc2fSJohn David Anglin	cmpib,COND(>>=),n	15, %arg2, fioneloop2
2256d2ddc2fSJohn David Anglin
2266d2ddc2fSJohn David Anglinfioneloop1:
2276d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2286d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
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	addib,COND(>)	-16, %arg2, fioneloop1
2436d2ddc2fSJohn David Anglin	fice,m		%arg1(%sr1, %arg0)
2446d2ddc2fSJohn David Anglin
2456d2ddc2fSJohn David Anglin	/* Check if done */
2466d2ddc2fSJohn David Anglin	cmpb,COND(=),n	%arg2, %r0, fisync	/* Predict branch taken */
2476d2ddc2fSJohn David Anglin
2486d2ddc2fSJohn David Anglinfioneloop2:
2496d2ddc2fSJohn David Anglin	addib,COND(>)	-1, %arg2, fioneloop2	/* Outer loop count decr */
2501da177e4SLinus Torvalds	fice,m		%arg1(%sr1, %arg0)	/* Fice for one loop */
2511da177e4SLinus Torvalds
2521da177e4SLinus Torvaldsfisync:
2531da177e4SLinus Torvalds	sync
254896a3756SGrant Grundler	mtsm		%r22			/* restore I-bit */
2551da177e4SLinus Torvalds	bv		%r0(%r2)
2561da177e4SLinus Torvalds	nop
2571da177e4SLinus Torvalds	.exit
2581da177e4SLinus Torvalds
2591da177e4SLinus Torvalds	.procend
260*f39cce65SHelge DellerENDPROC_CFI(flush_instruction_cache_local)
2611da177e4SLinus Torvalds
2628e9e9844SHelge Deller
2631da177e4SLinus Torvalds	.import cache_info, data
264*f39cce65SHelge DellerENTRY_CFI(flush_data_cache_local)
2651da177e4SLinus Torvalds	.proc
2661da177e4SLinus Torvalds	.callinfo NO_CALLS
2671da177e4SLinus Torvalds	.entry
2681da177e4SLinus Torvalds
2692fd83038SHelge Deller	load32		cache_info, %r1
2701da177e4SLinus Torvalds
2711da177e4SLinus Torvalds	/* Flush Data Cache */
2721da177e4SLinus Torvalds
2731da177e4SLinus Torvalds	LDREG		DCACHE_BASE(%r1), %arg0
2741da177e4SLinus Torvalds	LDREG		DCACHE_STRIDE(%r1), %arg1
2751da177e4SLinus Torvalds	LDREG		DCACHE_COUNT(%r1), %arg2
2761da177e4SLinus Torvalds	LDREG		DCACHE_LOOP(%r1), %arg3
2776d2ddc2fSJohn David Anglin	rsm		PSW_SM_I, %r22		/* No mmgt ops during loop*/
2786d2ddc2fSJohn David Anglin	mtsp		%r0, %sr1
279872f6debSKyle McMartin	addib,COND(=)		-1, %arg3, fdoneloop	/* Preadjust and test */
2801da177e4SLinus Torvalds	movb,<,n	%arg3, %r31, fdsync	/* If loop < 0, do sync */
2811da177e4SLinus Torvalds
2821da177e4SLinus Torvaldsfdmanyloop:					/* Loop if LOOP >= 2 */
283872f6debSKyle McMartin	addib,COND(>)		-1, %r31, fdmanyloop	/* Adjusted inner loop decr */
2849b3b331dSGrant Grundler	fdce		%r0(%sr1, %arg0)
2851da177e4SLinus Torvalds	fdce,m		%arg1(%sr1, %arg0)	/* Last fdce and addr adjust */
2861da177e4SLinus Torvalds	movb,tr		%arg3, %r31, fdmanyloop	/* Re-init inner loop count */
287872f6debSKyle McMartin	addib,COND(<=),n	-1, %arg2, fdsync	/* Outer loop decr */
2881da177e4SLinus Torvalds
2891da177e4SLinus Torvaldsfdoneloop:					/* Loop if LOOP = 1 */
2906d2ddc2fSJohn David Anglin	/* Some implementations may flush with a single fdce instruction */
2916d2ddc2fSJohn David Anglin	cmpib,COND(>>=),n	15, %arg2, fdoneloop2
2926d2ddc2fSJohn David Anglin
2936d2ddc2fSJohn David Anglinfdoneloop1:
2946d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
2956d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
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	addib,COND(>)	-16, %arg2, fdoneloop1
3106d2ddc2fSJohn David Anglin	fdce,m		%arg1(%sr1, %arg0)
3116d2ddc2fSJohn David Anglin
3126d2ddc2fSJohn David Anglin	/* Check if done */
3136d2ddc2fSJohn David Anglin	cmpb,COND(=),n	%arg2, %r0, fdsync	/* Predict branch taken */
3146d2ddc2fSJohn David Anglin
3156d2ddc2fSJohn David Anglinfdoneloop2:
3166d2ddc2fSJohn David Anglin	addib,COND(>)	-1, %arg2, fdoneloop2	/* Outer loop count decr */
3171da177e4SLinus Torvalds	fdce,m		%arg1(%sr1, %arg0)	/* Fdce for one loop */
3181da177e4SLinus Torvalds
3191da177e4SLinus Torvaldsfdsync:
3201da177e4SLinus Torvalds	syncdma
3211da177e4SLinus Torvalds	sync
322896a3756SGrant Grundler	mtsm		%r22			/* restore I-bit */
3231da177e4SLinus Torvalds	bv		%r0(%r2)
3241da177e4SLinus Torvalds	nop
3251da177e4SLinus Torvalds	.exit
3261da177e4SLinus Torvalds
3271da177e4SLinus Torvalds	.procend
328*f39cce65SHelge DellerENDPROC_CFI(flush_data_cache_local)
3291da177e4SLinus Torvalds
3301da177e4SLinus Torvalds	.align	16
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
3366d2ddc2fSJohn David Anglin	ldil		L%pa_tlb_lock,%r1
3376d2ddc2fSJohn David Anglin	ldo		R%pa_tlb_lock(%r1),\la
3386d2ddc2fSJohn David Anglin	rsm		PSW_SM_I,\flags
3396d2ddc2fSJohn David Anglin1:	LDCW		0(\la),\tmp
3406d2ddc2fSJohn David Anglin	cmpib,<>,n	0,\tmp,3f
3416d2ddc2fSJohn David Anglin2:	ldw		0(\la),\tmp
3426d2ddc2fSJohn David Anglin	cmpb,<>		%r0,\tmp,1b
3436d2ddc2fSJohn David Anglin	nop
3446d2ddc2fSJohn David Anglin	b,n		2b
3456d2ddc2fSJohn David Anglin3:
3466d2ddc2fSJohn David Anglin#endif
3476d2ddc2fSJohn David Anglin	.endm
3486d2ddc2fSJohn David Anglin
3496d2ddc2fSJohn David Anglin	.macro	tlb_unlock	la,flags,tmp
3506d2ddc2fSJohn David Anglin#ifdef CONFIG_SMP
3516d2ddc2fSJohn David Anglin	ldi		1,\tmp
3526d2ddc2fSJohn David Anglin	stw		\tmp,0(\la)
3536d2ddc2fSJohn David Anglin	mtsm		\flags
3546d2ddc2fSJohn David Anglin#endif
3556d2ddc2fSJohn David Anglin	.endm
3566d2ddc2fSJohn David Anglin
3576d2ddc2fSJohn David Anglin/* Clear page using kernel mapping.  */
3586d2ddc2fSJohn David Anglin
359*f39cce65SHelge DellerENTRY_CFI(clear_page_asm)
3606d2ddc2fSJohn David Anglin	.proc
3616d2ddc2fSJohn David Anglin	.callinfo NO_CALLS
3626d2ddc2fSJohn David Anglin	.entry
3636d2ddc2fSJohn David Anglin
3646d2ddc2fSJohn David Anglin#ifdef CONFIG_64BIT
3656d2ddc2fSJohn David Anglin
3666d2ddc2fSJohn David Anglin	/* Unroll the loop.  */
3676d2ddc2fSJohn David Anglin	ldi		(PAGE_SIZE / 128), %r1
3686d2ddc2fSJohn David Anglin
3696d2ddc2fSJohn David Anglin1:
3706d2ddc2fSJohn David Anglin	std		%r0, 0(%r26)
3716d2ddc2fSJohn David Anglin	std		%r0, 8(%r26)
3726d2ddc2fSJohn David Anglin	std		%r0, 16(%r26)
3736d2ddc2fSJohn David Anglin	std		%r0, 24(%r26)
3746d2ddc2fSJohn David Anglin	std		%r0, 32(%r26)
3756d2ddc2fSJohn David Anglin	std		%r0, 40(%r26)
3766d2ddc2fSJohn David Anglin	std		%r0, 48(%r26)
3776d2ddc2fSJohn David Anglin	std		%r0, 56(%r26)
3786d2ddc2fSJohn David Anglin	std		%r0, 64(%r26)
3796d2ddc2fSJohn David Anglin	std		%r0, 72(%r26)
3806d2ddc2fSJohn David Anglin	std		%r0, 80(%r26)
3816d2ddc2fSJohn David Anglin	std		%r0, 88(%r26)
3826d2ddc2fSJohn David Anglin	std		%r0, 96(%r26)
3836d2ddc2fSJohn David Anglin	std		%r0, 104(%r26)
3846d2ddc2fSJohn David Anglin	std		%r0, 112(%r26)
3856d2ddc2fSJohn David Anglin	std		%r0, 120(%r26)
3866d2ddc2fSJohn David Anglin
3876d2ddc2fSJohn David Anglin	/* Note reverse branch hint for addib is taken.  */
3886d2ddc2fSJohn David Anglin	addib,COND(>),n	-1, %r1, 1b
3896d2ddc2fSJohn David Anglin	ldo		128(%r26), %r26
3906d2ddc2fSJohn David Anglin
3916d2ddc2fSJohn David Anglin#else
3926d2ddc2fSJohn David Anglin
3936d2ddc2fSJohn David Anglin	/*
3946d2ddc2fSJohn David Anglin	 * Note that until (if) we start saving the full 64-bit register
3956d2ddc2fSJohn David Anglin	 * values on interrupt, we can't use std on a 32 bit kernel.
3966d2ddc2fSJohn David Anglin	 */
3976d2ddc2fSJohn David Anglin	ldi		(PAGE_SIZE / 64), %r1
3986d2ddc2fSJohn David Anglin
3996d2ddc2fSJohn David Anglin1:
4006d2ddc2fSJohn David Anglin	stw		%r0, 0(%r26)
4016d2ddc2fSJohn David Anglin	stw		%r0, 4(%r26)
4026d2ddc2fSJohn David Anglin	stw		%r0, 8(%r26)
4036d2ddc2fSJohn David Anglin	stw		%r0, 12(%r26)
4046d2ddc2fSJohn David Anglin	stw		%r0, 16(%r26)
4056d2ddc2fSJohn David Anglin	stw		%r0, 20(%r26)
4066d2ddc2fSJohn David Anglin	stw		%r0, 24(%r26)
4076d2ddc2fSJohn David Anglin	stw		%r0, 28(%r26)
4086d2ddc2fSJohn David Anglin	stw		%r0, 32(%r26)
4096d2ddc2fSJohn David Anglin	stw		%r0, 36(%r26)
4106d2ddc2fSJohn David Anglin	stw		%r0, 40(%r26)
4116d2ddc2fSJohn David Anglin	stw		%r0, 44(%r26)
4126d2ddc2fSJohn David Anglin	stw		%r0, 48(%r26)
4136d2ddc2fSJohn David Anglin	stw		%r0, 52(%r26)
4146d2ddc2fSJohn David Anglin	stw		%r0, 56(%r26)
4156d2ddc2fSJohn David Anglin	stw		%r0, 60(%r26)
4166d2ddc2fSJohn David Anglin
4176d2ddc2fSJohn David Anglin	addib,COND(>),n	-1, %r1, 1b
4186d2ddc2fSJohn David Anglin	ldo		64(%r26), %r26
4196d2ddc2fSJohn David Anglin#endif
4206d2ddc2fSJohn David Anglin	bv		%r0(%r2)
4216d2ddc2fSJohn David Anglin	nop
4226d2ddc2fSJohn David Anglin	.exit
4236d2ddc2fSJohn David Anglin
4246d2ddc2fSJohn David Anglin	.procend
425*f39cce65SHelge DellerENDPROC_CFI(clear_page_asm)
4266d2ddc2fSJohn David Anglin
4276d2ddc2fSJohn David Anglin/* Copy page using kernel mapping.  */
4286d2ddc2fSJohn David Anglin
429*f39cce65SHelge DellerENTRY_CFI(copy_page_asm)
4301da177e4SLinus Torvalds	.proc
4311da177e4SLinus Torvalds	.callinfo NO_CALLS
4321da177e4SLinus Torvalds	.entry
4331da177e4SLinus Torvalds
434413059f2SGrant Grundler#ifdef CONFIG_64BIT
4351da177e4SLinus Torvalds	/* PA8x00 CPUs can consume 2 loads or 1 store per cycle.
4361da177e4SLinus Torvalds	 * Unroll the loop by hand and arrange insn appropriately.
4376d2ddc2fSJohn David Anglin	 * Prefetch doesn't improve performance on rp3440.
4386d2ddc2fSJohn David Anglin	 * GCC probably can do this just as well...
4391da177e4SLinus Torvalds	 */
4401da177e4SLinus Torvalds
4416ebeafffSKyle McMartin	ldi		(PAGE_SIZE / 128), %r1
4422fd83038SHelge Deller
4436d2ddc2fSJohn David Anglin1:	ldd		0(%r25), %r19
4446d2ddc2fSJohn David Anglin	ldd		8(%r25), %r20
4451da177e4SLinus Torvalds
4461da177e4SLinus Torvalds	ldd		16(%r25), %r21
4471da177e4SLinus Torvalds	ldd		24(%r25), %r22
4481da177e4SLinus Torvalds	std		%r19, 0(%r26)
4491da177e4SLinus Torvalds	std		%r20, 8(%r26)
4501da177e4SLinus Torvalds
4511da177e4SLinus Torvalds	ldd		32(%r25), %r19
4521da177e4SLinus Torvalds	ldd		40(%r25), %r20
4531da177e4SLinus Torvalds	std		%r21, 16(%r26)
4541da177e4SLinus Torvalds	std		%r22, 24(%r26)
4551da177e4SLinus Torvalds
4561da177e4SLinus Torvalds	ldd		48(%r25), %r21
4571da177e4SLinus Torvalds	ldd		56(%r25), %r22
4581da177e4SLinus Torvalds	std		%r19, 32(%r26)
4591da177e4SLinus Torvalds	std		%r20, 40(%r26)
4601da177e4SLinus Torvalds
4611da177e4SLinus Torvalds	ldd		64(%r25), %r19
4621da177e4SLinus Torvalds	ldd		72(%r25), %r20
4631da177e4SLinus Torvalds	std		%r21, 48(%r26)
4641da177e4SLinus Torvalds	std		%r22, 56(%r26)
4651da177e4SLinus Torvalds
4661da177e4SLinus Torvalds	ldd		80(%r25), %r21
4671da177e4SLinus Torvalds	ldd		88(%r25), %r22
4681da177e4SLinus Torvalds	std		%r19, 64(%r26)
4691da177e4SLinus Torvalds	std		%r20, 72(%r26)
4701da177e4SLinus Torvalds
4711da177e4SLinus Torvalds	ldd		 96(%r25), %r19
4721da177e4SLinus Torvalds	ldd		104(%r25), %r20
4731da177e4SLinus Torvalds	std		%r21, 80(%r26)
4741da177e4SLinus Torvalds	std		%r22, 88(%r26)
4751da177e4SLinus Torvalds
4761da177e4SLinus Torvalds	ldd		112(%r25), %r21
4771da177e4SLinus Torvalds	ldd		120(%r25), %r22
4786d2ddc2fSJohn David Anglin	ldo		128(%r25), %r25
4791da177e4SLinus Torvalds	std		%r19, 96(%r26)
4801da177e4SLinus Torvalds	std		%r20, 104(%r26)
4811da177e4SLinus Torvalds
4821da177e4SLinus Torvalds	std		%r21, 112(%r26)
4831da177e4SLinus Torvalds	std		%r22, 120(%r26)
4841da177e4SLinus Torvalds
4856d2ddc2fSJohn David Anglin	/* Note reverse branch hint for addib is taken.  */
4866d2ddc2fSJohn David Anglin	addib,COND(>),n	-1, %r1, 1b
4876d2ddc2fSJohn David Anglin	ldo		128(%r26), %r26
4881da177e4SLinus Torvalds
4891da177e4SLinus Torvalds#else
4901da177e4SLinus Torvalds
4911da177e4SLinus Torvalds	/*
4921da177e4SLinus Torvalds	 * This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
4931da177e4SLinus Torvalds	 * bundles (very restricted rules for bundling).
4941da177e4SLinus Torvalds	 * Note that until (if) we start saving
4951da177e4SLinus Torvalds	 * the full 64 bit register values on interrupt, we can't
4961da177e4SLinus Torvalds	 * use ldd/std on a 32 bit kernel.
4971da177e4SLinus Torvalds	 */
49837318a3cSGrant Grundler	ldw		0(%r25), %r19
4996ebeafffSKyle McMartin	ldi		(PAGE_SIZE / 64), %r1
5001da177e4SLinus Torvalds
5011da177e4SLinus Torvalds1:
5021da177e4SLinus Torvalds	ldw		4(%r25), %r20
5031da177e4SLinus Torvalds	ldw		8(%r25), %r21
5041da177e4SLinus Torvalds	ldw		12(%r25), %r22
5051da177e4SLinus Torvalds	stw		%r19, 0(%r26)
5061da177e4SLinus Torvalds	stw		%r20, 4(%r26)
5071da177e4SLinus Torvalds	stw		%r21, 8(%r26)
5081da177e4SLinus Torvalds	stw		%r22, 12(%r26)
5091da177e4SLinus Torvalds	ldw		16(%r25), %r19
5101da177e4SLinus Torvalds	ldw		20(%r25), %r20
5111da177e4SLinus Torvalds	ldw		24(%r25), %r21
5121da177e4SLinus Torvalds	ldw		28(%r25), %r22
5131da177e4SLinus Torvalds	stw		%r19, 16(%r26)
5141da177e4SLinus Torvalds	stw		%r20, 20(%r26)
5151da177e4SLinus Torvalds	stw		%r21, 24(%r26)
5161da177e4SLinus Torvalds	stw		%r22, 28(%r26)
5171da177e4SLinus Torvalds	ldw		32(%r25), %r19
5181da177e4SLinus Torvalds	ldw		36(%r25), %r20
5191da177e4SLinus Torvalds	ldw		40(%r25), %r21
5201da177e4SLinus Torvalds	ldw		44(%r25), %r22
5211da177e4SLinus Torvalds	stw		%r19, 32(%r26)
5221da177e4SLinus Torvalds	stw		%r20, 36(%r26)
5231da177e4SLinus Torvalds	stw		%r21, 40(%r26)
5241da177e4SLinus Torvalds	stw		%r22, 44(%r26)
5251da177e4SLinus Torvalds	ldw		48(%r25), %r19
5261da177e4SLinus Torvalds	ldw		52(%r25), %r20
5271da177e4SLinus Torvalds	ldw		56(%r25), %r21
5281da177e4SLinus Torvalds	ldw		60(%r25), %r22
5291da177e4SLinus Torvalds	stw		%r19, 48(%r26)
5301da177e4SLinus Torvalds	stw		%r20, 52(%r26)
53137318a3cSGrant Grundler	ldo		64(%r25), %r25
5321da177e4SLinus Torvalds	stw		%r21, 56(%r26)
5331da177e4SLinus Torvalds	stw		%r22, 60(%r26)
5341da177e4SLinus Torvalds	ldo		64(%r26), %r26
535872f6debSKyle McMartin	addib,COND(>),n	-1, %r1, 1b
53637318a3cSGrant Grundler	ldw		0(%r25), %r19
5371da177e4SLinus Torvalds#endif
5381da177e4SLinus Torvalds	bv		%r0(%r2)
5391da177e4SLinus Torvalds	nop
5401da177e4SLinus Torvalds	.exit
5411da177e4SLinus Torvalds
5421da177e4SLinus Torvalds	.procend
543*f39cce65SHelge DellerENDPROC_CFI(copy_page_asm)
5441da177e4SLinus Torvalds
5451da177e4SLinus Torvalds/*
5461da177e4SLinus Torvalds * NOTE: Code in clear_user_page has a hard coded dependency on the
5471da177e4SLinus Torvalds *       maximum alias boundary being 4 Mb. We've been assured by the
5481da177e4SLinus Torvalds *       parisc chip designers that there will not ever be a parisc
5491da177e4SLinus Torvalds *       chip with a larger alias boundary (Never say never :-) ).
5501da177e4SLinus Torvalds *
5511da177e4SLinus Torvalds *       Subtle: the dtlb miss handlers support the temp alias region by
5521da177e4SLinus Torvalds *       "knowing" that if a dtlb miss happens within the temp alias
5531da177e4SLinus Torvalds *       region it must have occurred while in clear_user_page. Since
5541da177e4SLinus Torvalds *       this routine makes use of processor local translations, we
5551da177e4SLinus Torvalds *       don't want to insert them into the kernel page table. Instead,
5561da177e4SLinus Torvalds *       we load up some general registers (they need to be registers
5571da177e4SLinus Torvalds *       which aren't shadowed) with the physical page numbers (preshifted
5581da177e4SLinus Torvalds *       for tlb insertion) needed to insert the translations. When we
5591da177e4SLinus Torvalds *       miss on the translation, the dtlb miss handler inserts the
5601da177e4SLinus Torvalds *       translation into the tlb using these values:
5611da177e4SLinus Torvalds *
5621da177e4SLinus Torvalds *          %r26 physical page (shifted for tlb insert) of "to" translation
5631da177e4SLinus Torvalds *          %r23 physical page (shifted for tlb insert) of "from" translation
5641da177e4SLinus Torvalds */
5651da177e4SLinus Torvalds
5666a45716aSHelge Deller        /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
5676a45716aSHelge Deller        #define PAGE_ADD_SHIFT  (PAGE_SHIFT-12)
5686a45716aSHelge Deller        .macro          convert_phys_for_tlb_insert20  phys
5696a45716aSHelge Deller        extrd,u         \phys, 56-PAGE_ADD_SHIFT, 32-PAGE_ADD_SHIFT, \phys
5706a45716aSHelge Deller#if _PAGE_SIZE_ENCODING_DEFAULT
5716a45716aSHelge Deller        depdi           _PAGE_SIZE_ENCODING_DEFAULT, 63, (63-58), \phys
5726a45716aSHelge Deller#endif
5736a45716aSHelge Deller	.endm
5746a45716aSHelge Deller
5751da177e4SLinus Torvalds	/*
576910a8643SJohn David Anglin	 * copy_user_page_asm() performs a page copy using mappings
577910a8643SJohn David Anglin	 * equivalent to the user page mappings.  It can be used to
578910a8643SJohn David Anglin	 * implement copy_user_page() but unfortunately both the `from'
579910a8643SJohn David Anglin	 * and `to' pages need to be flushed through mappings equivalent
580910a8643SJohn David Anglin	 * to the user mappings after the copy because the kernel accesses
581910a8643SJohn David Anglin	 * the `from' page through the kmap kernel mapping and the `to'
582910a8643SJohn David Anglin	 * page needs to be flushed since code can be copied.  As a
583910a8643SJohn David Anglin	 * result, this implementation is less efficient than the simpler
584910a8643SJohn David Anglin	 * copy using the kernel mapping.  It only needs the `from' page
585910a8643SJohn David Anglin	 * to flushed via the user mapping.  The kunmap routines handle
586910a8643SJohn David Anglin	 * the flushes needed for the kernel mapping.
5871da177e4SLinus Torvalds	 *
5881da177e4SLinus Torvalds	 * I'm still keeping this around because it may be possible to
5891da177e4SLinus Torvalds	 * use it if more information is passed into copy_user_page().
5901da177e4SLinus Torvalds	 * Have to do some measurements to see if it is worthwhile to
5911da177e4SLinus Torvalds	 * lobby for such a change.
5926d2ddc2fSJohn David Anglin	 *
5931da177e4SLinus Torvalds	 */
5941da177e4SLinus Torvalds
595*f39cce65SHelge DellerENTRY_CFI(copy_user_page_asm)
5961da177e4SLinus Torvalds	.proc
5971da177e4SLinus Torvalds	.callinfo NO_CALLS
5981da177e4SLinus Torvalds	.entry
5991da177e4SLinus Torvalds
6006d2ddc2fSJohn David Anglin	/* Convert virtual `to' and `from' addresses to physical addresses.
6016d2ddc2fSJohn David Anglin	   Move `from' physical address to non shadowed register.  */
6021da177e4SLinus Torvalds	ldil		L%(__PAGE_OFFSET), %r1
6031da177e4SLinus Torvalds	sub		%r26, %r1, %r26
6046d2ddc2fSJohn David Anglin	sub		%r25, %r1, %r23
6051da177e4SLinus Torvalds
6061da177e4SLinus Torvalds	ldil		L%(TMPALIAS_MAP_START), %r28
607413059f2SGrant Grundler#ifdef CONFIG_64BIT
6086d2ddc2fSJohn David Anglin#if (TMPALIAS_MAP_START >= 0x80000000)
6096d2ddc2fSJohn David Anglin	depdi		0, 31,32, %r28		/* clear any sign extension */
6106d2ddc2fSJohn David Anglin#endif
6116a45716aSHelge Deller	convert_phys_for_tlb_insert20 %r26	/* convert phys addr to tlb insert format */
6126a45716aSHelge Deller	convert_phys_for_tlb_insert20 %r23	/* convert phys addr to tlb insert format */
6131da177e4SLinus Torvalds	depd		%r24,63,22, %r28	/* Form aliased virtual address 'to' */
6146a45716aSHelge Deller	depdi		0, 63,PAGE_SHIFT, %r28	/* Clear any offset bits */
6151da177e4SLinus Torvalds	copy		%r28, %r29
6161da177e4SLinus Torvalds	depdi		1, 41,1, %r29		/* Form aliased virtual address 'from' */
6171da177e4SLinus Torvalds#else
6181da177e4SLinus Torvalds	extrw,u		%r26, 24,25, %r26	/* convert phys addr to tlb insert format */
6191da177e4SLinus Torvalds	extrw,u		%r23, 24,25, %r23	/* convert phys addr to tlb insert format */
6201da177e4SLinus Torvalds	depw		%r24, 31,22, %r28	/* Form aliased virtual address 'to' */
621d845b5fbSHelge Deller	depwi		0, 31,PAGE_SHIFT, %r28	/* Clear any offset bits */
6221da177e4SLinus Torvalds	copy		%r28, %r29
6231da177e4SLinus Torvalds	depwi		1, 9,1, %r29		/* Form aliased virtual address 'from' */
6241da177e4SLinus Torvalds#endif
6251da177e4SLinus Torvalds
6261da177e4SLinus Torvalds	/* Purge any old translations */
6271da177e4SLinus Torvalds
6286d2ddc2fSJohn David Anglin#ifdef CONFIG_PA20
6296d2ddc2fSJohn David Anglin	pdtlb,l		0(%r28)
6306d2ddc2fSJohn David Anglin	pdtlb,l		0(%r29)
6316d2ddc2fSJohn David Anglin#else
6326d2ddc2fSJohn David Anglin	tlb_lock	%r20,%r21,%r22
6331da177e4SLinus Torvalds	pdtlb		0(%r28)
6341da177e4SLinus Torvalds	pdtlb		0(%r29)
6356d2ddc2fSJohn David Anglin	tlb_unlock	%r20,%r21,%r22
6366d2ddc2fSJohn David Anglin#endif
6371da177e4SLinus Torvalds
6386d2ddc2fSJohn David Anglin#ifdef CONFIG_64BIT
6396d2ddc2fSJohn David Anglin	/* PA8x00 CPUs can consume 2 loads or 1 store per cycle.
6406d2ddc2fSJohn David Anglin	 * Unroll the loop by hand and arrange insn appropriately.
6416d2ddc2fSJohn David Anglin	 * GCC probably can do this just as well.
6426d2ddc2fSJohn David Anglin	 */
6436d2ddc2fSJohn David Anglin
6446d2ddc2fSJohn David Anglin	ldd		0(%r29), %r19
6456d2ddc2fSJohn David Anglin	ldi		(PAGE_SIZE / 128), %r1
6466d2ddc2fSJohn David Anglin
6476d2ddc2fSJohn David Anglin1:	ldd		8(%r29), %r20
6486d2ddc2fSJohn David Anglin
6496d2ddc2fSJohn David Anglin	ldd		16(%r29), %r21
6506d2ddc2fSJohn David Anglin	ldd		24(%r29), %r22
6516d2ddc2fSJohn David Anglin	std		%r19, 0(%r28)
6526d2ddc2fSJohn David Anglin	std		%r20, 8(%r28)
6536d2ddc2fSJohn David Anglin
6546d2ddc2fSJohn David Anglin	ldd		32(%r29), %r19
6556d2ddc2fSJohn David Anglin	ldd		40(%r29), %r20
6566d2ddc2fSJohn David Anglin	std		%r21, 16(%r28)
6576d2ddc2fSJohn David Anglin	std		%r22, 24(%r28)
6586d2ddc2fSJohn David Anglin
6596d2ddc2fSJohn David Anglin	ldd		48(%r29), %r21
6606d2ddc2fSJohn David Anglin	ldd		56(%r29), %r22
6616d2ddc2fSJohn David Anglin	std		%r19, 32(%r28)
6626d2ddc2fSJohn David Anglin	std		%r20, 40(%r28)
6636d2ddc2fSJohn David Anglin
6646d2ddc2fSJohn David Anglin	ldd		64(%r29), %r19
6656d2ddc2fSJohn David Anglin	ldd		72(%r29), %r20
6666d2ddc2fSJohn David Anglin	std		%r21, 48(%r28)
6676d2ddc2fSJohn David Anglin	std		%r22, 56(%r28)
6686d2ddc2fSJohn David Anglin
6696d2ddc2fSJohn David Anglin	ldd		80(%r29), %r21
6706d2ddc2fSJohn David Anglin	ldd		88(%r29), %r22
6716d2ddc2fSJohn David Anglin	std		%r19, 64(%r28)
6726d2ddc2fSJohn David Anglin	std		%r20, 72(%r28)
6736d2ddc2fSJohn David Anglin
6746d2ddc2fSJohn David Anglin	ldd		 96(%r29), %r19
6756d2ddc2fSJohn David Anglin	ldd		104(%r29), %r20
6766d2ddc2fSJohn David Anglin	std		%r21, 80(%r28)
6776d2ddc2fSJohn David Anglin	std		%r22, 88(%r28)
6786d2ddc2fSJohn David Anglin
6796d2ddc2fSJohn David Anglin	ldd		112(%r29), %r21
6806d2ddc2fSJohn David Anglin	ldd		120(%r29), %r22
6816d2ddc2fSJohn David Anglin	std		%r19, 96(%r28)
6826d2ddc2fSJohn David Anglin	std		%r20, 104(%r28)
6836d2ddc2fSJohn David Anglin
6846d2ddc2fSJohn David Anglin	ldo		128(%r29), %r29
6856d2ddc2fSJohn David Anglin	std		%r21, 112(%r28)
6866d2ddc2fSJohn David Anglin	std		%r22, 120(%r28)
6876d2ddc2fSJohn David Anglin	ldo		128(%r28), %r28
6886d2ddc2fSJohn David Anglin
6896d2ddc2fSJohn David Anglin	/* conditional branches nullify on forward taken branch, and on
6906d2ddc2fSJohn David Anglin	 * non-taken backward branch. Note that .+4 is a backwards branch.
6916d2ddc2fSJohn David Anglin	 * The ldd should only get executed if the branch is taken.
6926d2ddc2fSJohn David Anglin	 */
6936d2ddc2fSJohn David Anglin	addib,COND(>),n	-1, %r1, 1b		/* bundle 10 */
6946d2ddc2fSJohn David Anglin	ldd		0(%r29), %r19		/* start next loads */
6956d2ddc2fSJohn David Anglin
6966d2ddc2fSJohn David Anglin#else
6976d2ddc2fSJohn David Anglin	ldi		(PAGE_SIZE / 64), %r1
6981da177e4SLinus Torvalds
6991da177e4SLinus Torvalds	/*
7001da177e4SLinus Torvalds	 * This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
7011da177e4SLinus Torvalds	 * bundles (very restricted rules for bundling). It probably
7021da177e4SLinus Torvalds	 * does OK on PCXU and better, but we could do better with
7031da177e4SLinus Torvalds	 * ldd/std instructions. Note that until (if) we start saving
7041da177e4SLinus Torvalds	 * the full 64 bit register values on interrupt, we can't
7051da177e4SLinus Torvalds	 * use ldd/std on a 32 bit kernel.
7061da177e4SLinus Torvalds	 */
7071da177e4SLinus Torvalds
7086d2ddc2fSJohn David Anglin1:	ldw		0(%r29), %r19
7091da177e4SLinus Torvalds	ldw		4(%r29), %r20
7101da177e4SLinus Torvalds	ldw		8(%r29), %r21
7111da177e4SLinus Torvalds	ldw		12(%r29), %r22
7121da177e4SLinus Torvalds	stw		%r19, 0(%r28)
7131da177e4SLinus Torvalds	stw		%r20, 4(%r28)
7141da177e4SLinus Torvalds	stw		%r21, 8(%r28)
7151da177e4SLinus Torvalds	stw		%r22, 12(%r28)
7161da177e4SLinus Torvalds	ldw		16(%r29), %r19
7171da177e4SLinus Torvalds	ldw		20(%r29), %r20
7181da177e4SLinus Torvalds	ldw		24(%r29), %r21
7191da177e4SLinus Torvalds	ldw		28(%r29), %r22
7201da177e4SLinus Torvalds	stw		%r19, 16(%r28)
7211da177e4SLinus Torvalds	stw		%r20, 20(%r28)
7221da177e4SLinus Torvalds	stw		%r21, 24(%r28)
7231da177e4SLinus Torvalds	stw		%r22, 28(%r28)
7241da177e4SLinus Torvalds	ldw		32(%r29), %r19
7251da177e4SLinus Torvalds	ldw		36(%r29), %r20
7261da177e4SLinus Torvalds	ldw		40(%r29), %r21
7271da177e4SLinus Torvalds	ldw		44(%r29), %r22
7281da177e4SLinus Torvalds	stw		%r19, 32(%r28)
7291da177e4SLinus Torvalds	stw		%r20, 36(%r28)
7301da177e4SLinus Torvalds	stw		%r21, 40(%r28)
7311da177e4SLinus Torvalds	stw		%r22, 44(%r28)
7321da177e4SLinus Torvalds	ldw		48(%r29), %r19
7331da177e4SLinus Torvalds	ldw		52(%r29), %r20
7341da177e4SLinus Torvalds	ldw		56(%r29), %r21
7351da177e4SLinus Torvalds	ldw		60(%r29), %r22
7361da177e4SLinus Torvalds	stw		%r19, 48(%r28)
7371da177e4SLinus Torvalds	stw		%r20, 52(%r28)
7381da177e4SLinus Torvalds	stw		%r21, 56(%r28)
7391da177e4SLinus Torvalds	stw		%r22, 60(%r28)
7401da177e4SLinus Torvalds	ldo		64(%r28), %r28
7416d2ddc2fSJohn David Anglin
742872f6debSKyle McMartin	addib,COND(>)		-1, %r1,1b
7431da177e4SLinus Torvalds	ldo		64(%r29), %r29
7446d2ddc2fSJohn David Anglin#endif
7451da177e4SLinus Torvalds
7461da177e4SLinus Torvalds	bv		%r0(%r2)
7471da177e4SLinus Torvalds	nop
7481da177e4SLinus Torvalds	.exit
7491da177e4SLinus Torvalds
7501da177e4SLinus Torvalds	.procend
751*f39cce65SHelge DellerENDPROC_CFI(copy_user_page_asm)
7521da177e4SLinus Torvalds
753*f39cce65SHelge DellerENTRY_CFI(clear_user_page_asm)
7541da177e4SLinus Torvalds	.proc
7551da177e4SLinus Torvalds	.callinfo NO_CALLS
7561da177e4SLinus Torvalds	.entry
7571da177e4SLinus Torvalds
7581da177e4SLinus Torvalds	tophys_r1	%r26
7591da177e4SLinus Torvalds
7601da177e4SLinus Torvalds	ldil		L%(TMPALIAS_MAP_START), %r28
761413059f2SGrant Grundler#ifdef CONFIG_64BIT
7621da177e4SLinus Torvalds#if (TMPALIAS_MAP_START >= 0x80000000)
7631da177e4SLinus Torvalds	depdi		0, 31,32, %r28		/* clear any sign extension */
7641da177e4SLinus Torvalds#endif
7656a45716aSHelge Deller	convert_phys_for_tlb_insert20 %r26	/* convert phys addr to tlb insert format */
7661da177e4SLinus Torvalds	depd		%r25, 63,22, %r28	/* Form aliased virtual address 'to' */
7676a45716aSHelge Deller	depdi		0, 63,PAGE_SHIFT, %r28	/* Clear any offset bits */
7681da177e4SLinus Torvalds#else
7691da177e4SLinus Torvalds	extrw,u		%r26, 24,25, %r26	/* convert phys addr to tlb insert format */
7701da177e4SLinus Torvalds	depw		%r25, 31,22, %r28	/* Form aliased virtual address 'to' */
771d845b5fbSHelge Deller	depwi		0, 31,PAGE_SHIFT, %r28	/* Clear any offset bits */
7721da177e4SLinus Torvalds#endif
7731da177e4SLinus Torvalds
7741da177e4SLinus Torvalds	/* Purge any old translation */
7751da177e4SLinus Torvalds
7766d2ddc2fSJohn David Anglin#ifdef CONFIG_PA20
7776d2ddc2fSJohn David Anglin	pdtlb,l		0(%r28)
7786d2ddc2fSJohn David Anglin#else
7796d2ddc2fSJohn David Anglin	tlb_lock	%r20,%r21,%r22
7801da177e4SLinus Torvalds	pdtlb		0(%r28)
7816d2ddc2fSJohn David Anglin	tlb_unlock	%r20,%r21,%r22
7826d2ddc2fSJohn David Anglin#endif
7831da177e4SLinus Torvalds
784413059f2SGrant Grundler#ifdef CONFIG_64BIT
7856ebeafffSKyle McMartin	ldi		(PAGE_SIZE / 128), %r1
7861da177e4SLinus Torvalds
7871da177e4SLinus Torvalds	/* PREFETCH (Write) has not (yet) been proven to help here */
7881da177e4SLinus Torvalds	/* #define	PREFETCHW_OP	ldd		256(%0), %r0 */
7891da177e4SLinus Torvalds
7901da177e4SLinus Torvalds1:	std		%r0, 0(%r28)
7911da177e4SLinus Torvalds	std		%r0, 8(%r28)
7921da177e4SLinus Torvalds	std		%r0, 16(%r28)
7931da177e4SLinus Torvalds	std		%r0, 24(%r28)
7941da177e4SLinus Torvalds	std		%r0, 32(%r28)
7951da177e4SLinus Torvalds	std		%r0, 40(%r28)
7961da177e4SLinus Torvalds	std		%r0, 48(%r28)
7971da177e4SLinus Torvalds	std		%r0, 56(%r28)
7981da177e4SLinus Torvalds	std		%r0, 64(%r28)
7991da177e4SLinus Torvalds	std		%r0, 72(%r28)
8001da177e4SLinus Torvalds	std		%r0, 80(%r28)
8011da177e4SLinus Torvalds	std		%r0, 88(%r28)
8021da177e4SLinus Torvalds	std		%r0, 96(%r28)
8031da177e4SLinus Torvalds	std		%r0, 104(%r28)
8041da177e4SLinus Torvalds	std		%r0, 112(%r28)
8051da177e4SLinus Torvalds	std		%r0, 120(%r28)
806872f6debSKyle McMartin	addib,COND(>)		-1, %r1, 1b
8071da177e4SLinus Torvalds	ldo		128(%r28), %r28
8081da177e4SLinus Torvalds
809413059f2SGrant Grundler#else	/* ! CONFIG_64BIT */
8106ebeafffSKyle McMartin	ldi		(PAGE_SIZE / 64), %r1
8111da177e4SLinus Torvalds
8126d2ddc2fSJohn David Anglin1:	stw		%r0, 0(%r28)
8131da177e4SLinus Torvalds	stw		%r0, 4(%r28)
8141da177e4SLinus Torvalds	stw		%r0, 8(%r28)
8151da177e4SLinus Torvalds	stw		%r0, 12(%r28)
8161da177e4SLinus Torvalds	stw		%r0, 16(%r28)
8171da177e4SLinus Torvalds	stw		%r0, 20(%r28)
8181da177e4SLinus Torvalds	stw		%r0, 24(%r28)
8191da177e4SLinus Torvalds	stw		%r0, 28(%r28)
8201da177e4SLinus Torvalds	stw		%r0, 32(%r28)
8211da177e4SLinus Torvalds	stw		%r0, 36(%r28)
8221da177e4SLinus Torvalds	stw		%r0, 40(%r28)
8231da177e4SLinus Torvalds	stw		%r0, 44(%r28)
8241da177e4SLinus Torvalds	stw		%r0, 48(%r28)
8251da177e4SLinus Torvalds	stw		%r0, 52(%r28)
8261da177e4SLinus Torvalds	stw		%r0, 56(%r28)
8271da177e4SLinus Torvalds	stw		%r0, 60(%r28)
828872f6debSKyle McMartin	addib,COND(>)		-1, %r1, 1b
8291da177e4SLinus Torvalds	ldo		64(%r28), %r28
830413059f2SGrant Grundler#endif	/* CONFIG_64BIT */
8311da177e4SLinus Torvalds
8321da177e4SLinus Torvalds	bv		%r0(%r2)
8331da177e4SLinus Torvalds	nop
8341da177e4SLinus Torvalds	.exit
8351da177e4SLinus Torvalds
8361da177e4SLinus Torvalds	.procend
837*f39cce65SHelge DellerENDPROC_CFI(clear_user_page_asm)
8381da177e4SLinus Torvalds
839*f39cce65SHelge DellerENTRY_CFI(flush_dcache_page_asm)
840f311847cSJames Bottomley	.proc
841f311847cSJames Bottomley	.callinfo NO_CALLS
842f311847cSJames Bottomley	.entry
843f311847cSJames Bottomley
844f311847cSJames Bottomley	ldil		L%(TMPALIAS_MAP_START), %r28
845f311847cSJames Bottomley#ifdef CONFIG_64BIT
846f311847cSJames Bottomley#if (TMPALIAS_MAP_START >= 0x80000000)
847f311847cSJames Bottomley	depdi		0, 31,32, %r28		/* clear any sign extension */
848f311847cSJames Bottomley#endif
8496a45716aSHelge Deller	convert_phys_for_tlb_insert20 %r26	/* convert phys addr to tlb insert format */
850f311847cSJames Bottomley	depd		%r25, 63,22, %r28	/* Form aliased virtual address 'to' */
8516a45716aSHelge Deller	depdi		0, 63,PAGE_SHIFT, %r28	/* Clear any offset bits */
852f311847cSJames Bottomley#else
853f311847cSJames Bottomley	extrw,u		%r26, 24,25, %r26	/* convert phys addr to tlb insert format */
854f311847cSJames Bottomley	depw		%r25, 31,22, %r28	/* Form aliased virtual address 'to' */
855d845b5fbSHelge Deller	depwi		0, 31,PAGE_SHIFT, %r28	/* Clear any offset bits */
856f311847cSJames Bottomley#endif
857f311847cSJames Bottomley
858f311847cSJames Bottomley	/* Purge any old translation */
859f311847cSJames Bottomley
8606d2ddc2fSJohn David Anglin#ifdef CONFIG_PA20
8616d2ddc2fSJohn David Anglin	pdtlb,l		0(%r28)
8626d2ddc2fSJohn David Anglin#else
8636d2ddc2fSJohn David Anglin	tlb_lock	%r20,%r21,%r22
864f311847cSJames Bottomley	pdtlb		0(%r28)
8656d2ddc2fSJohn David Anglin	tlb_unlock	%r20,%r21,%r22
8666d2ddc2fSJohn David Anglin#endif
867f311847cSJames Bottomley
868f311847cSJames Bottomley	ldil		L%dcache_stride, %r1
869d65ea48dSJohn David Anglin	ldw		R%dcache_stride(%r1), r31
870f311847cSJames Bottomley
871f311847cSJames Bottomley#ifdef CONFIG_64BIT
872f311847cSJames Bottomley	depdi,z		1, 63-PAGE_SHIFT,1, %r25
873f311847cSJames Bottomley#else
874f311847cSJames Bottomley	depwi,z		1, 31-PAGE_SHIFT,1, %r25
875f311847cSJames Bottomley#endif
876f311847cSJames Bottomley	add		%r28, %r25, %r25
877d65ea48dSJohn David Anglin	sub		%r25, r31, %r25
878f311847cSJames Bottomley
879f311847cSJames Bottomley
880d65ea48dSJohn David Anglin1:      fdc,m		r31(%r28)
881d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
882d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
883d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
884d65ea48dSJohn David Anglin	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)
895f311847cSJames Bottomley	cmpb,COND(<<)		%r28, %r25,1b
896d65ea48dSJohn David Anglin	fdc,m		r31(%r28)
897f311847cSJames Bottomley
898f311847cSJames Bottomley	sync
8996d2ddc2fSJohn David Anglin
9006d2ddc2fSJohn David Anglin#ifdef CONFIG_PA20
9016d2ddc2fSJohn David Anglin	pdtlb,l		0(%r25)
9026d2ddc2fSJohn David Anglin#else
9036d2ddc2fSJohn David Anglin	tlb_lock	%r20,%r21,%r22
9046d2ddc2fSJohn David Anglin	pdtlb		0(%r25)
9056d2ddc2fSJohn David Anglin	tlb_unlock	%r20,%r21,%r22
9066d2ddc2fSJohn David Anglin#endif
9076d2ddc2fSJohn David Anglin
908f311847cSJames Bottomley	bv		%r0(%r2)
9096d2ddc2fSJohn David Anglin	nop
910f311847cSJames Bottomley	.exit
911f311847cSJames Bottomley
912f311847cSJames Bottomley	.procend
913*f39cce65SHelge DellerENDPROC_CFI(flush_dcache_page_asm)
914f311847cSJames Bottomley
915*f39cce65SHelge DellerENTRY_CFI(flush_icache_page_asm)
916f311847cSJames Bottomley	.proc
917f311847cSJames Bottomley	.callinfo NO_CALLS
918f311847cSJames Bottomley	.entry
919f311847cSJames Bottomley
920f311847cSJames Bottomley	ldil		L%(TMPALIAS_MAP_START), %r28
921f311847cSJames Bottomley#ifdef CONFIG_64BIT
922f311847cSJames Bottomley#if (TMPALIAS_MAP_START >= 0x80000000)
923f311847cSJames Bottomley	depdi		0, 31,32, %r28		/* clear any sign extension */
924f311847cSJames Bottomley#endif
9256a45716aSHelge Deller	convert_phys_for_tlb_insert20 %r26	/* convert phys addr to tlb insert format */
926f311847cSJames Bottomley	depd		%r25, 63,22, %r28	/* Form aliased virtual address 'to' */
9276a45716aSHelge Deller	depdi		0, 63,PAGE_SHIFT, %r28	/* Clear any offset bits */
928f311847cSJames Bottomley#else
929f311847cSJames Bottomley	extrw,u		%r26, 24,25, %r26	/* convert phys addr to tlb insert format */
930f311847cSJames Bottomley	depw		%r25, 31,22, %r28	/* Form aliased virtual address 'to' */
931d845b5fbSHelge Deller	depwi		0, 31,PAGE_SHIFT, %r28	/* Clear any offset bits */
932f311847cSJames Bottomley#endif
933f311847cSJames Bottomley
934f311847cSJames Bottomley	/* Purge any old translation */
935f311847cSJames Bottomley
9366d2ddc2fSJohn David Anglin#ifdef CONFIG_PA20
9376d2ddc2fSJohn David Anglin	pitlb,l         %r0(%sr4,%r28)
9386d2ddc2fSJohn David Anglin#else
9396d2ddc2fSJohn David Anglin	tlb_lock        %r20,%r21,%r22
940207f583dSJohn David Anglin	pitlb           (%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
9786d2ddc2fSJohn David Anglin#ifdef CONFIG_PA20
9796d2ddc2fSJohn David Anglin	pitlb,l         %r0(%sr4,%r25)
9806d2ddc2fSJohn David Anglin#else
9816d2ddc2fSJohn David Anglin	tlb_lock        %r20,%r21,%r22
982207f583dSJohn David Anglin	pitlb           (%sr4,%r25)
9836d2ddc2fSJohn David Anglin	tlb_unlock      %r20,%r21,%r22
9846d2ddc2fSJohn David Anglin#endif
9856d2ddc2fSJohn David Anglin
9866d2ddc2fSJohn David Anglin	bv		%r0(%r2)
9876d2ddc2fSJohn David Anglin	nop
988f311847cSJames Bottomley	.exit
989f311847cSJames Bottomley
990f311847cSJames Bottomley	.procend
991*f39cce65SHelge DellerENDPROC_CFI(flush_icache_page_asm)
992f311847cSJames Bottomley
993*f39cce65SHelge DellerENTRY_CFI(flush_kernel_dcache_page_asm)
9941da177e4SLinus Torvalds	.proc
9951da177e4SLinus Torvalds	.callinfo NO_CALLS
9961da177e4SLinus Torvalds	.entry
9971da177e4SLinus Torvalds
9981da177e4SLinus Torvalds	ldil		L%dcache_stride, %r1
9991da177e4SLinus Torvalds	ldw		R%dcache_stride(%r1), %r23
10001da177e4SLinus Torvalds
1001413059f2SGrant Grundler#ifdef CONFIG_64BIT
10021da177e4SLinus Torvalds	depdi,z		1, 63-PAGE_SHIFT,1, %r25
10031da177e4SLinus Torvalds#else
10041da177e4SLinus Torvalds	depwi,z		1, 31-PAGE_SHIFT,1, %r25
10051da177e4SLinus Torvalds#endif
10061da177e4SLinus Torvalds	add		%r26, %r25, %r25
10071da177e4SLinus Torvalds	sub		%r25, %r23, %r25
10081da177e4SLinus Torvalds
10091da177e4SLinus Torvalds
10101da177e4SLinus Torvalds1:      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)
10161da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10171da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10181da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10191da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10201da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10211da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10221da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10231da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10241da177e4SLinus Torvalds	fdc,m		%r23(%r26)
1025872f6debSKyle McMartin	cmpb,COND(<<)		%r26, %r25,1b
10261da177e4SLinus Torvalds	fdc,m		%r23(%r26)
10271da177e4SLinus Torvalds
10281da177e4SLinus Torvalds	sync
10291da177e4SLinus Torvalds	bv		%r0(%r2)
10301da177e4SLinus Torvalds	nop
10311da177e4SLinus Torvalds	.exit
10321da177e4SLinus Torvalds
10331da177e4SLinus Torvalds	.procend
1034*f39cce65SHelge DellerENDPROC_CFI(flush_kernel_dcache_page_asm)
10351da177e4SLinus Torvalds
1036*f39cce65SHelge DellerENTRY_CFI(purge_kernel_dcache_page_asm)
10371da177e4SLinus Torvalds	.proc
10381da177e4SLinus Torvalds	.callinfo NO_CALLS
10391da177e4SLinus Torvalds	.entry
10401da177e4SLinus Torvalds
10411da177e4SLinus Torvalds	ldil		L%dcache_stride, %r1
10421da177e4SLinus Torvalds	ldw		R%dcache_stride(%r1), %r23
10431da177e4SLinus Torvalds
1044413059f2SGrant Grundler#ifdef CONFIG_64BIT
10451da177e4SLinus Torvalds	depdi,z		1, 63-PAGE_SHIFT,1, %r25
10461da177e4SLinus Torvalds#else
10471da177e4SLinus Torvalds	depwi,z		1, 31-PAGE_SHIFT,1, %r25
10481da177e4SLinus Torvalds#endif
10491da177e4SLinus Torvalds	add		%r26, %r25, %r25
10501da177e4SLinus Torvalds	sub		%r25, %r23, %r25
10511da177e4SLinus Torvalds
10521da177e4SLinus Torvalds1:      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)
10581da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10591da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10601da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10611da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10621da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10631da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10641da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10651da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10661da177e4SLinus Torvalds	pdc,m		%r23(%r26)
1067872f6debSKyle McMartin	cmpb,COND(<<)		%r26, %r25, 1b
10681da177e4SLinus Torvalds	pdc,m		%r23(%r26)
10691da177e4SLinus Torvalds
10701da177e4SLinus Torvalds	sync
10711da177e4SLinus Torvalds	bv		%r0(%r2)
10721da177e4SLinus Torvalds	nop
10731da177e4SLinus Torvalds	.exit
10741da177e4SLinus Torvalds
10751da177e4SLinus Torvalds	.procend
1076*f39cce65SHelge DellerENDPROC_CFI(purge_kernel_dcache_page_asm)
10771da177e4SLinus Torvalds
1078*f39cce65SHelge DellerENTRY_CFI(flush_user_dcache_range_asm)
10791da177e4SLinus Torvalds	.proc
10801da177e4SLinus Torvalds	.callinfo NO_CALLS
10811da177e4SLinus Torvalds	.entry
10821da177e4SLinus Torvalds
10831da177e4SLinus Torvalds	ldil		L%dcache_stride, %r1
10841da177e4SLinus Torvalds	ldw		R%dcache_stride(%r1), %r23
10851da177e4SLinus Torvalds	ldo		-1(%r23), %r21
10861da177e4SLinus Torvalds	ANDCM		%r26, %r21, %r26
10871da177e4SLinus Torvalds
1088872f6debSKyle McMartin1:      cmpb,COND(<<),n	%r26, %r25, 1b
10891da177e4SLinus Torvalds	fdc,m		%r23(%sr3, %r26)
10901da177e4SLinus Torvalds
10911da177e4SLinus Torvalds	sync
10921da177e4SLinus Torvalds	bv		%r0(%r2)
10931da177e4SLinus Torvalds	nop
10941da177e4SLinus Torvalds	.exit
10951da177e4SLinus Torvalds
10961da177e4SLinus Torvalds	.procend
1097*f39cce65SHelge DellerENDPROC_CFI(flush_user_dcache_range_asm)
10981da177e4SLinus Torvalds
1099*f39cce65SHelge DellerENTRY_CFI(flush_kernel_dcache_range_asm)
11001da177e4SLinus Torvalds	.proc
11011da177e4SLinus Torvalds	.callinfo NO_CALLS
11021da177e4SLinus Torvalds	.entry
11031da177e4SLinus Torvalds
11041da177e4SLinus Torvalds	ldil		L%dcache_stride, %r1
11051da177e4SLinus Torvalds	ldw		R%dcache_stride(%r1), %r23
11061da177e4SLinus Torvalds	ldo		-1(%r23), %r21
11071da177e4SLinus Torvalds	ANDCM		%r26, %r21, %r26
11081da177e4SLinus Torvalds
1109872f6debSKyle McMartin1:      cmpb,COND(<<),n	%r26, %r25,1b
11101da177e4SLinus Torvalds	fdc,m		%r23(%r26)
11111da177e4SLinus Torvalds
11121da177e4SLinus Torvalds	sync
11131da177e4SLinus Torvalds	syncdma
11141da177e4SLinus Torvalds	bv		%r0(%r2)
11151da177e4SLinus Torvalds	nop
11161da177e4SLinus Torvalds	.exit
11171da177e4SLinus Torvalds
11181da177e4SLinus Torvalds	.procend
1119*f39cce65SHelge DellerENDPROC_CFI(flush_kernel_dcache_range_asm)
11201da177e4SLinus Torvalds
1121*f39cce65SHelge DellerENTRY_CFI(flush_user_icache_range_asm)
11221da177e4SLinus Torvalds	.proc
11231da177e4SLinus Torvalds	.callinfo NO_CALLS
11241da177e4SLinus Torvalds	.entry
11251da177e4SLinus Torvalds
11261da177e4SLinus Torvalds	ldil		L%icache_stride, %r1
11271da177e4SLinus Torvalds	ldw		R%icache_stride(%r1), %r23
11281da177e4SLinus Torvalds	ldo		-1(%r23), %r21
11291da177e4SLinus Torvalds	ANDCM		%r26, %r21, %r26
11301da177e4SLinus Torvalds
1131872f6debSKyle McMartin1:      cmpb,COND(<<),n	%r26, %r25,1b
11321da177e4SLinus Torvalds	fic,m		%r23(%sr3, %r26)
11331da177e4SLinus Torvalds
11341da177e4SLinus Torvalds	sync
11351da177e4SLinus Torvalds	bv		%r0(%r2)
11361da177e4SLinus Torvalds	nop
11371da177e4SLinus Torvalds	.exit
11381da177e4SLinus Torvalds
11391da177e4SLinus Torvalds	.procend
1140*f39cce65SHelge DellerENDPROC_CFI(flush_user_icache_range_asm)
11411da177e4SLinus Torvalds
1142*f39cce65SHelge DellerENTRY_CFI(flush_kernel_icache_page)
11431da177e4SLinus Torvalds	.proc
11441da177e4SLinus Torvalds	.callinfo NO_CALLS
11451da177e4SLinus Torvalds	.entry
11461da177e4SLinus Torvalds
11471da177e4SLinus Torvalds	ldil		L%icache_stride, %r1
11481da177e4SLinus Torvalds	ldw		R%icache_stride(%r1), %r23
11491da177e4SLinus Torvalds
1150413059f2SGrant Grundler#ifdef CONFIG_64BIT
11511da177e4SLinus Torvalds	depdi,z		1, 63-PAGE_SHIFT,1, %r25
11521da177e4SLinus Torvalds#else
11531da177e4SLinus Torvalds	depwi,z		1, 31-PAGE_SHIFT,1, %r25
11541da177e4SLinus Torvalds#endif
11551da177e4SLinus Torvalds	add		%r26, %r25, %r25
11561da177e4SLinus Torvalds	sub		%r25, %r23, %r25
11571da177e4SLinus Torvalds
11581da177e4SLinus Torvalds
1159e635c96eSMatthew Wilcox1:      fic,m		%r23(%sr4, %r26)
1160e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1161e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1162e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1163e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1164e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1165e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1166e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1167e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1168e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1169e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1170e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1171e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1172e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1173e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
1174872f6debSKyle McMartin	cmpb,COND(<<)		%r26, %r25, 1b
1175e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
11761da177e4SLinus Torvalds
11771da177e4SLinus Torvalds	sync
11781da177e4SLinus Torvalds	bv		%r0(%r2)
11791da177e4SLinus Torvalds	nop
11801da177e4SLinus Torvalds	.exit
11811da177e4SLinus Torvalds
11821da177e4SLinus Torvalds	.procend
1183*f39cce65SHelge DellerENDPROC_CFI(flush_kernel_icache_page)
11841da177e4SLinus Torvalds
1185*f39cce65SHelge DellerENTRY_CFI(flush_kernel_icache_range_asm)
11861da177e4SLinus Torvalds	.proc
11871da177e4SLinus Torvalds	.callinfo NO_CALLS
11881da177e4SLinus Torvalds	.entry
11891da177e4SLinus Torvalds
11901da177e4SLinus Torvalds	ldil		L%icache_stride, %r1
11911da177e4SLinus Torvalds	ldw		R%icache_stride(%r1), %r23
11921da177e4SLinus Torvalds	ldo		-1(%r23), %r21
11931da177e4SLinus Torvalds	ANDCM		%r26, %r21, %r26
11941da177e4SLinus Torvalds
1195872f6debSKyle McMartin1:      cmpb,COND(<<),n	%r26, %r25, 1b
1196e635c96eSMatthew Wilcox	fic,m		%r23(%sr4, %r26)
11971da177e4SLinus Torvalds
11981da177e4SLinus Torvalds	sync
11991da177e4SLinus Torvalds	bv		%r0(%r2)
12001da177e4SLinus Torvalds	nop
12011da177e4SLinus Torvalds	.exit
12021da177e4SLinus Torvalds	.procend
1203*f39cce65SHelge DellerENDPROC_CFI(flush_kernel_icache_range_asm)
12041da177e4SLinus Torvalds
1205896a3756SGrant Grundler	/* align should cover use of rfi in disable_sr_hashing_asm and
1206896a3756SGrant Grundler	 * srdis_done.
1207896a3756SGrant Grundler	 */
1208896a3756SGrant Grundler	.align	256
1209*f39cce65SHelge DellerENTRY_CFI(disable_sr_hashing_asm)
12101da177e4SLinus Torvalds	.proc
12111da177e4SLinus Torvalds	.callinfo NO_CALLS
12121da177e4SLinus Torvalds	.entry
12131da177e4SLinus Torvalds
1214896a3756SGrant Grundler	/*
1215896a3756SGrant Grundler	 * Switch to real mode
1216896a3756SGrant Grundler	 */
1217896a3756SGrant Grundler	/* pcxt_ssm_bug */
1218896a3756SGrant Grundler	rsm		PSW_SM_I, %r0
1219896a3756SGrant Grundler	load32		PA(1f), %r1
12201da177e4SLinus Torvalds	nop
12211da177e4SLinus Torvalds	nop
12221da177e4SLinus Torvalds	nop
12231da177e4SLinus Torvalds	nop
12241da177e4SLinus Torvalds	nop
12251da177e4SLinus Torvalds
1226896a3756SGrant Grundler	rsm		PSW_SM_Q, %r0		/* prep to load iia queue */
12271da177e4SLinus Torvalds	mtctl		%r0, %cr17		/* Clear IIASQ tail */
12281da177e4SLinus Torvalds	mtctl		%r0, %cr17		/* Clear IIASQ head */
12291da177e4SLinus Torvalds	mtctl		%r1, %cr18		/* IIAOQ head */
12301da177e4SLinus Torvalds	ldo		4(%r1), %r1
12311da177e4SLinus Torvalds	mtctl		%r1, %cr18		/* IIAOQ tail */
1232896a3756SGrant Grundler	load32		REAL_MODE_PSW, %r1
1233896a3756SGrant Grundler	mtctl		%r1, %ipsw
12341da177e4SLinus Torvalds	rfi
12351da177e4SLinus Torvalds	nop
12361da177e4SLinus Torvalds
12371da177e4SLinus Torvalds1:      cmpib,=,n	SRHASH_PCXST, %r26,srdis_pcxs
12381da177e4SLinus Torvalds	cmpib,=,n	SRHASH_PCXL, %r26,srdis_pcxl
12391da177e4SLinus Torvalds	cmpib,=,n	SRHASH_PA20, %r26,srdis_pa20
12401da177e4SLinus Torvalds	b,n		srdis_done
12411da177e4SLinus Torvalds
12421da177e4SLinus Torvaldssrdis_pcxs:
12431da177e4SLinus Torvalds
12441da177e4SLinus Torvalds	/* Disable Space Register Hashing for PCXS,PCXT,PCXT' */
12451da177e4SLinus Torvalds
12461da177e4SLinus Torvalds	.word		0x141c1a00		/* mfdiag %dr0, %r28 */
12471da177e4SLinus Torvalds	.word		0x141c1a00		/* must issue twice */
12481da177e4SLinus Torvalds	depwi		0,18,1, %r28		/* Clear DHE (dcache hash enable) */
12491da177e4SLinus Torvalds	depwi		0,20,1, %r28		/* Clear IHE (icache hash enable) */
12501da177e4SLinus Torvalds	.word		0x141c1600		/* mtdiag %r28, %dr0 */
12511da177e4SLinus Torvalds	.word		0x141c1600		/* must issue twice */
12521da177e4SLinus Torvalds	b,n		srdis_done
12531da177e4SLinus Torvalds
12541da177e4SLinus Torvaldssrdis_pcxl:
12551da177e4SLinus Torvalds
12561da177e4SLinus Torvalds	/* Disable Space Register Hashing for PCXL */
12571da177e4SLinus Torvalds
12581da177e4SLinus Torvalds	.word		0x141c0600		/* mfdiag %dr0, %r28 */
12591da177e4SLinus Torvalds	depwi           0,28,2, %r28		/* Clear DHASH_EN & IHASH_EN */
12601da177e4SLinus Torvalds	.word		0x141c0240		/* mtdiag %r28, %dr0 */
12611da177e4SLinus Torvalds	b,n		srdis_done
12621da177e4SLinus Torvalds
12631da177e4SLinus Torvaldssrdis_pa20:
12641da177e4SLinus Torvalds
1265896a3756SGrant Grundler	/* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+,PCXW2 */
12661da177e4SLinus Torvalds
12671da177e4SLinus Torvalds	.word		0x144008bc		/* mfdiag %dr2, %r28 */
12681da177e4SLinus Torvalds	depdi		0, 54,1, %r28		/* clear DIAG_SPHASH_ENAB (bit 54) */
12691da177e4SLinus Torvalds	.word		0x145c1840		/* mtdiag %r28, %dr2 */
12701da177e4SLinus Torvalds
1271896a3756SGrant Grundler
12721da177e4SLinus Torvaldssrdis_done:
12731da177e4SLinus Torvalds	/* Switch back to virtual mode */
1274896a3756SGrant Grundler	rsm		PSW_SM_I, %r0		/* prep to load iia queue */
1275896a3756SGrant Grundler	load32 	   	2f, %r1
1276896a3756SGrant Grundler	nop
1277896a3756SGrant Grundler	nop
1278896a3756SGrant Grundler	nop
1279896a3756SGrant Grundler	nop
1280896a3756SGrant Grundler	nop
12811da177e4SLinus Torvalds
1282896a3756SGrant Grundler	rsm		PSW_SM_Q, %r0		/* prep to load iia queue */
12831da177e4SLinus Torvalds	mtctl		%r0, %cr17		/* Clear IIASQ tail */
12841da177e4SLinus Torvalds	mtctl		%r0, %cr17		/* Clear IIASQ head */
12851da177e4SLinus Torvalds	mtctl		%r1, %cr18		/* IIAOQ head */
12861da177e4SLinus Torvalds	ldo		4(%r1), %r1
12871da177e4SLinus Torvalds	mtctl		%r1, %cr18		/* IIAOQ tail */
1288896a3756SGrant Grundler	load32		KERNEL_PSW, %r1
1289896a3756SGrant Grundler	mtctl		%r1, %ipsw
12901da177e4SLinus Torvalds	rfi
12911da177e4SLinus Torvalds	nop
12921da177e4SLinus Torvalds
12931da177e4SLinus Torvalds2:      bv		%r0(%r2)
12941da177e4SLinus Torvalds	nop
12951da177e4SLinus Torvalds	.exit
12961da177e4SLinus Torvalds
12971da177e4SLinus Torvalds	.procend
1298*f39cce65SHelge DellerENDPROC_CFI(disable_sr_hashing_asm)
12991da177e4SLinus Torvalds
13001da177e4SLinus Torvalds	.end
1301