xref: /openbmc/linux/arch/sparc/lib/clear_page.S (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */
2478b8fecSSam Ravnborg/* clear_page.S: UltraSparc optimized clear 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>
965fddcfcSMike Rapoport#include <linux/pgtable.h>
10478b8fecSSam Ravnborg#include <asm/visasm.h>
11478b8fecSSam Ravnborg#include <asm/thread_info.h>
12478b8fecSSam Ravnborg#include <asm/page.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	.text
29478b8fecSSam Ravnborg
30478b8fecSSam Ravnborg	.globl		_clear_page
31d3867f04SAl Viro	EXPORT_SYMBOL(_clear_page)
32478b8fecSSam Ravnborg_clear_page:		/* %o0=dest */
33478b8fecSSam Ravnborg	ba,pt		%xcc, clear_page_common
34478b8fecSSam Ravnborg	 clr		%o4
35478b8fecSSam Ravnborg
36478b8fecSSam Ravnborg	/* This thing is pretty important, it shows up
37478b8fecSSam Ravnborg	 * on the profiles via do_anonymous_page().
38478b8fecSSam Ravnborg	 */
39478b8fecSSam Ravnborg	.align		32
40478b8fecSSam Ravnborg	.globl		clear_user_page
41d3867f04SAl Viro	EXPORT_SYMBOL(clear_user_page)
42478b8fecSSam Ravnborgclear_user_page:	/* %o0=dest, %o1=vaddr */
43478b8fecSSam Ravnborg	lduw		[%g6 + TI_PRE_COUNT], %o2
44b2d43834SDavid S. Miller	sethi		%hi(PAGE_OFFSET), %g2
45478b8fecSSam Ravnborg	sethi		%hi(PAGE_SIZE), %o4
46478b8fecSSam Ravnborg
47b2d43834SDavid S. Miller	ldx		[%g2 + %lo(PAGE_OFFSET)], %g2
48478b8fecSSam Ravnborg	sethi		%hi(PAGE_KERNEL_LOCKED), %g3
49478b8fecSSam Ravnborg
50478b8fecSSam Ravnborg	ldx		[%g3 + %lo(PAGE_KERNEL_LOCKED)], %g3
51478b8fecSSam Ravnborg	sub		%o0, %g2, %g1		! paddr
52478b8fecSSam Ravnborg
53478b8fecSSam Ravnborg	and		%o1, %o4, %o0		! vaddr D-cache alias bit
54478b8fecSSam Ravnborg
55478b8fecSSam Ravnborg	or		%g1, %g3, %g1		! TTE data
56478b8fecSSam Ravnborg	sethi		%hi(TLBTEMP_BASE), %o3
57478b8fecSSam Ravnborg
58478b8fecSSam Ravnborg	add		%o2, 1, %o4
59478b8fecSSam Ravnborg	add		%o0, %o3, %o0		! TTE vaddr
60478b8fecSSam Ravnborg
61478b8fecSSam Ravnborg	/* Disable preemption.  */
62478b8fecSSam Ravnborg	mov		TLB_TAG_ACCESS, %g3
63478b8fecSSam Ravnborg	stw		%o4, [%g6 + TI_PRE_COUNT]
64478b8fecSSam Ravnborg
65478b8fecSSam Ravnborg	/* Load TLB entry.  */
66478b8fecSSam Ravnborg	rdpr		%pstate, %o4
67478b8fecSSam Ravnborg	wrpr		%o4, PSTATE_IE, %pstate
68478b8fecSSam Ravnborg	stxa		%o0, [%g3] ASI_DMMU
69478b8fecSSam Ravnborg	stxa		%g1, [%g0] ASI_DTLB_DATA_IN
70478b8fecSSam Ravnborg	sethi		%hi(KERNBASE), %g1
71478b8fecSSam Ravnborg	flush		%g1
72478b8fecSSam Ravnborg	wrpr		%o4, 0x0, %pstate
73478b8fecSSam Ravnborg
74478b8fecSSam Ravnborg	mov		1, %o4
75478b8fecSSam Ravnborg
76478b8fecSSam Ravnborgclear_page_common:
77478b8fecSSam Ravnborg	VISEntryHalf
78478b8fecSSam Ravnborg	membar		#StoreLoad | #StoreStore | #LoadStore
79478b8fecSSam Ravnborg	fzero		%f0
80478b8fecSSam Ravnborg	sethi		%hi(PAGE_SIZE/64), %o1
81478b8fecSSam Ravnborg	mov		%o0, %g1		! remember vaddr for tlbflush
82478b8fecSSam Ravnborg	fzero		%f2
83478b8fecSSam Ravnborg	or		%o1, %lo(PAGE_SIZE/64), %o1
84478b8fecSSam Ravnborg	faddd		%f0, %f2, %f4
85478b8fecSSam Ravnborg	fmuld		%f0, %f2, %f6
86478b8fecSSam Ravnborg	faddd		%f0, %f2, %f8
87478b8fecSSam Ravnborg	fmuld		%f0, %f2, %f10
88478b8fecSSam Ravnborg
89478b8fecSSam Ravnborg	faddd		%f0, %f2, %f12
90478b8fecSSam Ravnborg	fmuld		%f0, %f2, %f14
91478b8fecSSam Ravnborg1:	stda		%f0, [%o0 + %g0] ASI_BLK_P
92478b8fecSSam Ravnborg	subcc		%o1, 1, %o1
93478b8fecSSam Ravnborg	bne,pt		%icc, 1b
94478b8fecSSam Ravnborg	 add		%o0, 0x40, %o0
95478b8fecSSam Ravnborg	membar		#Sync
96478b8fecSSam Ravnborg	VISExitHalf
97478b8fecSSam Ravnborg
98478b8fecSSam Ravnborg	brz,pn		%o4, out
99478b8fecSSam Ravnborg	 nop
100478b8fecSSam Ravnborg
101478b8fecSSam Ravnborg	stxa		%g0, [%g1] ASI_DMMU_DEMAP
102478b8fecSSam Ravnborg	membar		#Sync
103478b8fecSSam Ravnborg	stw		%o2, [%g6 + TI_PRE_COUNT]
104478b8fecSSam Ravnborg
105478b8fecSSam Ravnborgout:	retl
106478b8fecSSam Ravnborg	 nop
107478b8fecSSam Ravnborg
108