xref: /openbmc/linux/arch/sparc/lib/copy_page.S (revision d3867f04)
1478b8fecSSam Ravnborg/* clear_page.S: UltraSparc optimized copy page.
2478b8fecSSam Ravnborg *
3478b8fecSSam Ravnborg * Copyright (C) 1996, 1998, 1999, 2000, 2004 David S. Miller (davem@redhat.com)
4478b8fecSSam Ravnborg * Copyright (C) 1997 Jakub Jelinek (jakub@redhat.com)
5478b8fecSSam Ravnborg */
6478b8fecSSam Ravnborg
7478b8fecSSam Ravnborg#include <asm/visasm.h>
8478b8fecSSam Ravnborg#include <asm/thread_info.h>
9478b8fecSSam Ravnborg#include <asm/page.h>
10478b8fecSSam Ravnborg#include <asm/pgtable.h>
11478b8fecSSam Ravnborg#include <asm/spitfire.h>
12478b8fecSSam Ravnborg#include <asm/head.h>
13d3867f04SAl Viro#include <asm/export.h>
14478b8fecSSam Ravnborg
15478b8fecSSam Ravnborg	/* What we used to do was lock a TLB entry into a specific
16478b8fecSSam Ravnborg	 * TLB slot, clear the page with interrupts disabled, then
17478b8fecSSam Ravnborg	 * restore the original TLB entry.  This was great for
18478b8fecSSam Ravnborg	 * disturbing the TLB as little as possible, but it meant
19478b8fecSSam Ravnborg	 * we had to keep interrupts disabled for a long time.
20478b8fecSSam Ravnborg	 *
21478b8fecSSam Ravnborg	 * Now, we simply use the normal TLB loading mechanism,
22478b8fecSSam Ravnborg	 * and this makes the cpu choose a slot all by itself.
23478b8fecSSam Ravnborg	 * Then we do a normal TLB flush on exit.  We need only
24478b8fecSSam Ravnborg	 * disable preemption during the clear.
25478b8fecSSam Ravnborg	 */
26478b8fecSSam Ravnborg
27478b8fecSSam Ravnborg#define	DCACHE_SIZE	(PAGE_SIZE * 2)
28478b8fecSSam Ravnborg
29478b8fecSSam Ravnborg#if (PAGE_SHIFT == 13)
30478b8fecSSam Ravnborg#define PAGE_SIZE_REM	0x80
31478b8fecSSam Ravnborg#elif (PAGE_SHIFT == 16)
32478b8fecSSam Ravnborg#define PAGE_SIZE_REM	0x100
33478b8fecSSam Ravnborg#else
34478b8fecSSam Ravnborg#error Wrong PAGE_SHIFT specified
35478b8fecSSam Ravnborg#endif
36478b8fecSSam Ravnborg
37478b8fecSSam Ravnborg#define TOUCH(reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7)	\
386f1d827fSDavid S. Miller	fsrc2	%reg0, %f48; 	fsrc2	%reg1, %f50;		\
396f1d827fSDavid S. Miller	fsrc2	%reg2, %f52; 	fsrc2	%reg3, %f54;		\
406f1d827fSDavid S. Miller	fsrc2	%reg4, %f56; 	fsrc2	%reg5, %f58;		\
416f1d827fSDavid S. Miller	fsrc2	%reg6, %f60; 	fsrc2	%reg7, %f62;
42478b8fecSSam Ravnborg
43478b8fecSSam Ravnborg	.text
44478b8fecSSam Ravnborg
45478b8fecSSam Ravnborg	.align		32
46478b8fecSSam Ravnborg	.globl		copy_user_page
47478b8fecSSam Ravnborg	.type		copy_user_page,#function
48d3867f04SAl Viro	EXPORT_SYMBOL(copy_user_page)
49478b8fecSSam Ravnborgcopy_user_page:		/* %o0=dest, %o1=src, %o2=vaddr */
50478b8fecSSam Ravnborg	lduw		[%g6 + TI_PRE_COUNT], %o4
51b2d43834SDavid S. Miller	sethi		%hi(PAGE_OFFSET), %g2
52478b8fecSSam Ravnborg	sethi		%hi(PAGE_SIZE), %o3
53478b8fecSSam Ravnborg
54b2d43834SDavid S. Miller	ldx		[%g2 + %lo(PAGE_OFFSET)], %g2
55478b8fecSSam Ravnborg	sethi		%hi(PAGE_KERNEL_LOCKED), %g3
56478b8fecSSam Ravnborg
57478b8fecSSam Ravnborg	ldx		[%g3 + %lo(PAGE_KERNEL_LOCKED)], %g3
58478b8fecSSam Ravnborg	sub		%o0, %g2, %g1		! dest paddr
59478b8fecSSam Ravnborg
60478b8fecSSam Ravnborg	sub		%o1, %g2, %g2		! src paddr
61478b8fecSSam Ravnborg
62478b8fecSSam Ravnborg	and		%o2, %o3, %o0		! vaddr D-cache alias bit
63478b8fecSSam Ravnborg	or		%g1, %g3, %g1		! dest TTE data
64478b8fecSSam Ravnborg
65478b8fecSSam Ravnborg	or		%g2, %g3, %g2		! src TTE data
66478b8fecSSam Ravnborg	sethi		%hi(TLBTEMP_BASE), %o3
67478b8fecSSam Ravnborg
68478b8fecSSam Ravnborg	sethi		%hi(DCACHE_SIZE), %o1
69478b8fecSSam Ravnborg	add		%o0, %o3, %o0		! dest TTE vaddr
70478b8fecSSam Ravnborg
71478b8fecSSam Ravnborg	add		%o4, 1, %o2
72478b8fecSSam Ravnborg	add		%o0, %o1, %o1		! src TTE vaddr
73478b8fecSSam Ravnborg
74478b8fecSSam Ravnborg	/* Disable preemption.  */
75478b8fecSSam Ravnborg	mov		TLB_TAG_ACCESS, %g3
76478b8fecSSam Ravnborg	stw		%o2, [%g6 + TI_PRE_COUNT]
77478b8fecSSam Ravnborg
78478b8fecSSam Ravnborg	/* Load TLB entries.  */
79478b8fecSSam Ravnborg	rdpr		%pstate, %o2
80478b8fecSSam Ravnborg	wrpr		%o2, PSTATE_IE, %pstate
81478b8fecSSam Ravnborg	stxa		%o0, [%g3] ASI_DMMU
82478b8fecSSam Ravnborg	stxa		%g1, [%g0] ASI_DTLB_DATA_IN
83478b8fecSSam Ravnborg	membar		#Sync
84478b8fecSSam Ravnborg	stxa		%o1, [%g3] ASI_DMMU
85478b8fecSSam Ravnborg	stxa		%g2, [%g0] ASI_DTLB_DATA_IN
86478b8fecSSam Ravnborg	membar		#Sync
87478b8fecSSam Ravnborg	wrpr		%o2, 0x0, %pstate
88478b8fecSSam Ravnborg
89478b8fecSSam Ravnborgcheetah_copy_page_insn:
90478b8fecSSam Ravnborg	ba,pt		%xcc, 9f
91478b8fecSSam Ravnborg	 nop
92478b8fecSSam Ravnborg
93478b8fecSSam Ravnborg1:
94478b8fecSSam Ravnborg	VISEntryHalf
95478b8fecSSam Ravnborg	membar		#StoreLoad | #StoreStore | #LoadStore
96478b8fecSSam Ravnborg	sethi		%hi((PAGE_SIZE/64)-2), %o2
97478b8fecSSam Ravnborg	mov		%o0, %g1
98478b8fecSSam Ravnborg	prefetch	[%o1 + 0x000], #one_read
99478b8fecSSam Ravnborg	or		%o2, %lo((PAGE_SIZE/64)-2), %o2
100478b8fecSSam Ravnborg	prefetch	[%o1 + 0x040], #one_read
101478b8fecSSam Ravnborg	prefetch	[%o1 + 0x080], #one_read
102478b8fecSSam Ravnborg	prefetch	[%o1 + 0x0c0], #one_read
103478b8fecSSam Ravnborg	ldd		[%o1 + 0x000], %f0
104478b8fecSSam Ravnborg	prefetch	[%o1 + 0x100], #one_read
105478b8fecSSam Ravnborg	ldd		[%o1 + 0x008], %f2
106478b8fecSSam Ravnborg	prefetch	[%o1 + 0x140], #one_read
107478b8fecSSam Ravnborg	ldd		[%o1 + 0x010], %f4
108478b8fecSSam Ravnborg	prefetch	[%o1 + 0x180], #one_read
1096f1d827fSDavid S. Miller	fsrc2		%f0, %f16
110478b8fecSSam Ravnborg	ldd		[%o1 + 0x018], %f6
1116f1d827fSDavid S. Miller	fsrc2		%f2, %f18
112478b8fecSSam Ravnborg	ldd		[%o1 + 0x020], %f8
1136f1d827fSDavid S. Miller	fsrc2		%f4, %f20
114478b8fecSSam Ravnborg	ldd		[%o1 + 0x028], %f10
1156f1d827fSDavid S. Miller	fsrc2		%f6, %f22
116478b8fecSSam Ravnborg	ldd		[%o1 + 0x030], %f12
1176f1d827fSDavid S. Miller	fsrc2		%f8, %f24
118478b8fecSSam Ravnborg	ldd		[%o1 + 0x038], %f14
1196f1d827fSDavid S. Miller	fsrc2		%f10, %f26
120478b8fecSSam Ravnborg	ldd		[%o1 + 0x040], %f0
121478b8fecSSam Ravnborg1:	ldd		[%o1 + 0x048], %f2
1226f1d827fSDavid S. Miller	fsrc2		%f12, %f28
123478b8fecSSam Ravnborg	ldd		[%o1 + 0x050], %f4
1246f1d827fSDavid S. Miller	fsrc2		%f14, %f30
125478b8fecSSam Ravnborg	stda		%f16, [%o0] ASI_BLK_P
126478b8fecSSam Ravnborg	ldd		[%o1 + 0x058], %f6
1276f1d827fSDavid S. Miller	fsrc2		%f0, %f16
128478b8fecSSam Ravnborg	ldd		[%o1 + 0x060], %f8
1296f1d827fSDavid S. Miller	fsrc2		%f2, %f18
130478b8fecSSam Ravnborg	ldd		[%o1 + 0x068], %f10
1316f1d827fSDavid S. Miller	fsrc2		%f4, %f20
132478b8fecSSam Ravnborg	ldd		[%o1 + 0x070], %f12
1336f1d827fSDavid S. Miller	fsrc2		%f6, %f22
134478b8fecSSam Ravnborg	ldd		[%o1 + 0x078], %f14
1356f1d827fSDavid S. Miller	fsrc2		%f8, %f24
136478b8fecSSam Ravnborg	ldd		[%o1 + 0x080], %f0
137478b8fecSSam Ravnborg	prefetch	[%o1 + 0x180], #one_read
1386f1d827fSDavid S. Miller	fsrc2		%f10, %f26
139478b8fecSSam Ravnborg	subcc		%o2, 1, %o2
140478b8fecSSam Ravnborg	add		%o0, 0x40, %o0
141478b8fecSSam Ravnborg	bne,pt		%xcc, 1b
142478b8fecSSam Ravnborg	 add		%o1, 0x40, %o1
143478b8fecSSam Ravnborg
144478b8fecSSam Ravnborg	ldd		[%o1 + 0x048], %f2
1456f1d827fSDavid S. Miller	fsrc2		%f12, %f28
146478b8fecSSam Ravnborg	ldd		[%o1 + 0x050], %f4
1476f1d827fSDavid S. Miller	fsrc2		%f14, %f30
148478b8fecSSam Ravnborg	stda		%f16, [%o0] ASI_BLK_P
149478b8fecSSam Ravnborg	ldd		[%o1 + 0x058], %f6
1506f1d827fSDavid S. Miller	fsrc2		%f0, %f16
151478b8fecSSam Ravnborg	ldd		[%o1 + 0x060], %f8
1526f1d827fSDavid S. Miller	fsrc2		%f2, %f18
153478b8fecSSam Ravnborg	ldd		[%o1 + 0x068], %f10
1546f1d827fSDavid S. Miller	fsrc2		%f4, %f20
155478b8fecSSam Ravnborg	ldd		[%o1 + 0x070], %f12
1566f1d827fSDavid S. Miller	fsrc2		%f6, %f22
157478b8fecSSam Ravnborg	add		%o0, 0x40, %o0
158478b8fecSSam Ravnborg	ldd		[%o1 + 0x078], %f14
1596f1d827fSDavid S. Miller	fsrc2		%f8, %f24
1606f1d827fSDavid S. Miller	fsrc2		%f10, %f26
1616f1d827fSDavid S. Miller	fsrc2		%f12, %f28
1626f1d827fSDavid S. Miller	fsrc2		%f14, %f30
163478b8fecSSam Ravnborg	stda		%f16, [%o0] ASI_BLK_P
164478b8fecSSam Ravnborg	membar		#Sync
165478b8fecSSam Ravnborg	VISExitHalf
166478b8fecSSam Ravnborg	ba,pt		%xcc, 5f
167478b8fecSSam Ravnborg	 nop
168478b8fecSSam Ravnborg
169478b8fecSSam Ravnborg9:
170478b8fecSSam Ravnborg	VISEntry
171478b8fecSSam Ravnborg	ldub		[%g6 + TI_FAULT_CODE], %g3
172478b8fecSSam Ravnborg	mov		%o0, %g1
173478b8fecSSam Ravnborg	cmp		%g3, 0
174478b8fecSSam Ravnborg	rd		%asi, %g3
175478b8fecSSam Ravnborg	be,a,pt		%icc, 1f
176478b8fecSSam Ravnborg	 wr		%g0, ASI_BLK_P, %asi
177478b8fecSSam Ravnborg	wr		%g0, ASI_BLK_COMMIT_P, %asi
178478b8fecSSam Ravnborg1:	ldda		[%o1] ASI_BLK_P, %f0
179478b8fecSSam Ravnborg	add		%o1, 0x40, %o1
180478b8fecSSam Ravnborg	ldda		[%o1] ASI_BLK_P, %f16
181478b8fecSSam Ravnborg	add		%o1, 0x40, %o1
182478b8fecSSam Ravnborg	sethi		%hi(PAGE_SIZE), %o2
183478b8fecSSam Ravnborg1:	TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
184478b8fecSSam Ravnborg	ldda		[%o1] ASI_BLK_P, %f32
185478b8fecSSam Ravnborg	stda		%f48, [%o0] %asi
186478b8fecSSam Ravnborg	add		%o1, 0x40, %o1
187478b8fecSSam Ravnborg	sub		%o2, 0x40, %o2
188478b8fecSSam Ravnborg	add		%o0, 0x40, %o0
189478b8fecSSam Ravnborg	TOUCH(f16, f18, f20, f22, f24, f26, f28, f30)
190478b8fecSSam Ravnborg	ldda		[%o1] ASI_BLK_P, %f0
191478b8fecSSam Ravnborg	stda		%f48, [%o0] %asi
192478b8fecSSam Ravnborg	add		%o1, 0x40, %o1
193478b8fecSSam Ravnborg	sub		%o2, 0x40, %o2
194478b8fecSSam Ravnborg	add		%o0, 0x40, %o0
195478b8fecSSam Ravnborg	TOUCH(f32, f34, f36, f38, f40, f42, f44, f46)
196478b8fecSSam Ravnborg	ldda		[%o1] ASI_BLK_P, %f16
197478b8fecSSam Ravnborg	stda		%f48, [%o0] %asi
198478b8fecSSam Ravnborg	sub		%o2, 0x40, %o2
199478b8fecSSam Ravnborg	add		%o1, 0x40, %o1
200478b8fecSSam Ravnborg	cmp		%o2, PAGE_SIZE_REM
201478b8fecSSam Ravnborg	bne,pt		%xcc, 1b
202478b8fecSSam Ravnborg	 add		%o0, 0x40, %o0
203478b8fecSSam Ravnborg#if (PAGE_SHIFT == 16)
204478b8fecSSam Ravnborg	TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
205478b8fecSSam Ravnborg	ldda		[%o1] ASI_BLK_P, %f32
206478b8fecSSam Ravnborg	stda		%f48, [%o0] %asi
207478b8fecSSam Ravnborg	add		%o1, 0x40, %o1
208478b8fecSSam Ravnborg	sub		%o2, 0x40, %o2
209478b8fecSSam Ravnborg	add		%o0, 0x40, %o0
210478b8fecSSam Ravnborg	TOUCH(f16, f18, f20, f22, f24, f26, f28, f30)
211478b8fecSSam Ravnborg	ldda		[%o1] ASI_BLK_P, %f0
212478b8fecSSam Ravnborg	stda		%f48, [%o0] %asi
213478b8fecSSam Ravnborg	add		%o1, 0x40, %o1
214478b8fecSSam Ravnborg	sub		%o2, 0x40, %o2
215478b8fecSSam Ravnborg	add		%o0, 0x40, %o0
216478b8fecSSam Ravnborg	membar		#Sync
217478b8fecSSam Ravnborg	stda		%f32, [%o0] %asi
218478b8fecSSam Ravnborg	add		%o0, 0x40, %o0
219478b8fecSSam Ravnborg	stda		%f0, [%o0] %asi
220478b8fecSSam Ravnborg#else
221478b8fecSSam Ravnborg	membar		#Sync
222478b8fecSSam Ravnborg	stda		%f0, [%o0] %asi
223478b8fecSSam Ravnborg	add		%o0, 0x40, %o0
224478b8fecSSam Ravnborg	stda		%f16, [%o0] %asi
225478b8fecSSam Ravnborg#endif
226478b8fecSSam Ravnborg	membar		#Sync
227478b8fecSSam Ravnborg	wr		%g3, 0x0, %asi
228478b8fecSSam Ravnborg	VISExit
229478b8fecSSam Ravnborg
230478b8fecSSam Ravnborg5:
231478b8fecSSam Ravnborg	stxa		%g0, [%g1] ASI_DMMU_DEMAP
232478b8fecSSam Ravnborg	membar		#Sync
233478b8fecSSam Ravnborg
234478b8fecSSam Ravnborg	sethi		%hi(DCACHE_SIZE), %g2
235478b8fecSSam Ravnborg	stxa		%g0, [%g1 + %g2] ASI_DMMU_DEMAP
236478b8fecSSam Ravnborg	membar		#Sync
237478b8fecSSam Ravnborg
238478b8fecSSam Ravnborg	retl
239478b8fecSSam Ravnborg	 stw		%o4, [%g6 + TI_PRE_COUNT]
240478b8fecSSam Ravnborg
241478b8fecSSam Ravnborg	.size		copy_user_page, .-copy_user_page
242478b8fecSSam Ravnborg
243478b8fecSSam Ravnborg	.globl		cheetah_patch_copy_page
244478b8fecSSam Ravnborgcheetah_patch_copy_page:
245478b8fecSSam Ravnborg	sethi		%hi(0x01000000), %o1	! NOP
246478b8fecSSam Ravnborg	sethi		%hi(cheetah_copy_page_insn), %o0
247478b8fecSSam Ravnborg	or		%o0, %lo(cheetah_copy_page_insn), %o0
248478b8fecSSam Ravnborg	stw		%o1, [%o0]
249478b8fecSSam Ravnborg	membar		#StoreStore
250478b8fecSSam Ravnborg	flush		%o0
251478b8fecSSam Ravnborg	retl
252478b8fecSSam Ravnborg	 nop
253