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