xref: /OK3568_Linux_fs/kernel/arch/sparc/mm/viking.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun/* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun/*
3*4882a593Smuzhiyun * viking.S: High speed Viking cache/mmu operations
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
6*4882a593Smuzhiyun * Copyright (C) 1997,1998,1999  Jakub Jelinek  (jj@ultra.linux.cz)
7*4882a593Smuzhiyun * Copyright (C) 1999  Pavel Semerad  (semerad@ss1000.ms.mff.cuni.cz)
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun#include <asm/ptrace.h>
11*4882a593Smuzhiyun#include <asm/psr.h>
12*4882a593Smuzhiyun#include <asm/asm-offsets.h>
13*4882a593Smuzhiyun#include <asm/asi.h>
14*4882a593Smuzhiyun#include <asm/mxcc.h>
15*4882a593Smuzhiyun#include <asm/page.h>
16*4882a593Smuzhiyun#include <asm/pgtable.h>
17*4882a593Smuzhiyun#include <asm/pgtsrmmu.h>
18*4882a593Smuzhiyun#include <asm/viking.h>
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun#ifdef CONFIG_SMP
21*4882a593Smuzhiyun	.data
22*4882a593Smuzhiyun	.align	4
23*4882a593Smuzhiyunsun4dsmp_flush_tlb_spin:
24*4882a593Smuzhiyun	.word	0
25*4882a593Smuzhiyun#endif
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun	.text
28*4882a593Smuzhiyun	.align	4
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun	.globl	viking_flush_cache_all, viking_flush_cache_mm
31*4882a593Smuzhiyun	.globl	viking_flush_cache_range, viking_flush_cache_page
32*4882a593Smuzhiyun	.globl	viking_flush_page, viking_mxcc_flush_page
33*4882a593Smuzhiyun	.globl	viking_flush_page_for_dma, viking_flush_page_to_ram
34*4882a593Smuzhiyun	.globl	viking_flush_sig_insns
35*4882a593Smuzhiyun	.globl	viking_flush_tlb_all, viking_flush_tlb_mm
36*4882a593Smuzhiyun	.globl	viking_flush_tlb_range, viking_flush_tlb_page
37*4882a593Smuzhiyun
38*4882a593Smuzhiyunviking_flush_page:
39*4882a593Smuzhiyun	sethi	%hi(PAGE_OFFSET), %g2
40*4882a593Smuzhiyun	sub	%o0, %g2, %g3
41*4882a593Smuzhiyun	srl	%g3, 12, %g1		! ppage >> 12
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun	clr	%o1			! set counter, 0 - 127
44*4882a593Smuzhiyun	sethi	%hi(PAGE_OFFSET + PAGE_SIZE - 0x80000000), %o3
45*4882a593Smuzhiyun	sethi	%hi(0x80000000), %o4
46*4882a593Smuzhiyun	sethi	%hi(VIKING_PTAG_VALID), %o5
47*4882a593Smuzhiyun	sethi	%hi(2*PAGE_SIZE), %o0
48*4882a593Smuzhiyun	sethi	%hi(PAGE_SIZE), %g7
49*4882a593Smuzhiyun	clr	%o2			! block counter, 0 - 3
50*4882a593Smuzhiyun5:
51*4882a593Smuzhiyun	sll	%o1, 5, %g4
52*4882a593Smuzhiyun	or	%g4, %o4, %g4		! 0x80000000 | (set << 5)
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun	sll	%o2, 26, %g5		! block << 26
55*4882a593Smuzhiyun6:
56*4882a593Smuzhiyun	or	%g5, %g4, %g5
57*4882a593Smuzhiyun	ldda	[%g5] ASI_M_DATAC_TAG, %g2
58*4882a593Smuzhiyun	cmp	%g3, %g1		! ptag == ppage?
59*4882a593Smuzhiyun	bne	7f
60*4882a593Smuzhiyun	 inc	%o2
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun	andcc	%g2, %o5, %g0		! ptag VALID?
63*4882a593Smuzhiyun	be	7f
64*4882a593Smuzhiyun	 add	%g4, %o3, %g2		! (PAGE_OFFSET + PAGE_SIZE) | (set << 5)
65*4882a593Smuzhiyun	ld	[%g2], %g3
66*4882a593Smuzhiyun	ld	[%g2 + %g7], %g3
67*4882a593Smuzhiyun	add	%g2, %o0, %g2
68*4882a593Smuzhiyun	ld	[%g2], %g3
69*4882a593Smuzhiyun	ld	[%g2 + %g7], %g3
70*4882a593Smuzhiyun	add	%g2, %o0, %g2
71*4882a593Smuzhiyun	ld	[%g2], %g3
72*4882a593Smuzhiyun	ld	[%g2 + %g7], %g3
73*4882a593Smuzhiyun	add	%g2, %o0, %g2
74*4882a593Smuzhiyun	ld	[%g2], %g3
75*4882a593Smuzhiyun	b	8f
76*4882a593Smuzhiyun	 ld	[%g2 + %g7], %g3
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun7:
79*4882a593Smuzhiyun	cmp	%o2, 3
80*4882a593Smuzhiyun	ble	6b
81*4882a593Smuzhiyun	 sll	%o2, 26, %g5			! block << 26
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun8:	inc	%o1
84*4882a593Smuzhiyun	cmp	%o1, 0x7f
85*4882a593Smuzhiyun	ble	5b
86*4882a593Smuzhiyun	 clr	%o2
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun9:	retl
89*4882a593Smuzhiyun	 nop
90*4882a593Smuzhiyun
91*4882a593Smuzhiyunviking_mxcc_flush_page:
92*4882a593Smuzhiyun	sethi	%hi(PAGE_OFFSET), %g2
93*4882a593Smuzhiyun	sub	%o0, %g2, %g3
94*4882a593Smuzhiyun	sub	%g3, -PAGE_SIZE, %g3		! ppage + PAGE_SIZE
95*4882a593Smuzhiyun	sethi	%hi(MXCC_SRCSTREAM), %o3	! assume %hi(MXCC_SRCSTREAM) == %hi(MXCC_DESTSTREAM)
96*4882a593Smuzhiyun	mov	0x10, %g2			! set cacheable bit
97*4882a593Smuzhiyun	or	%o3, %lo(MXCC_SRCSTREAM), %o2
98*4882a593Smuzhiyun	or	%o3, %lo(MXCC_DESSTREAM), %o3
99*4882a593Smuzhiyun	sub	%g3, MXCC_STREAM_SIZE, %g3
100*4882a593Smuzhiyun6:
101*4882a593Smuzhiyun	stda	%g2, [%o2] ASI_M_MXCC
102*4882a593Smuzhiyun	stda	%g2, [%o3] ASI_M_MXCC
103*4882a593Smuzhiyun	andncc	%g3, PAGE_MASK, %g0
104*4882a593Smuzhiyun	bne	6b
105*4882a593Smuzhiyun	 sub	%g3, MXCC_STREAM_SIZE, %g3
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun9:	retl
108*4882a593Smuzhiyun	 nop
109*4882a593Smuzhiyun
110*4882a593Smuzhiyunviking_flush_cache_page:
111*4882a593Smuzhiyunviking_flush_cache_range:
112*4882a593Smuzhiyun#ifndef CONFIG_SMP
113*4882a593Smuzhiyun	ld	[%o0 + VMA_VM_MM], %o0
114*4882a593Smuzhiyun#endif
115*4882a593Smuzhiyunviking_flush_cache_mm:
116*4882a593Smuzhiyun#ifndef CONFIG_SMP
117*4882a593Smuzhiyun	ld	[%o0 + AOFF_mm_context], %g1
118*4882a593Smuzhiyun	cmp	%g1, -1
119*4882a593Smuzhiyun	bne	viking_flush_cache_all
120*4882a593Smuzhiyun	 nop
121*4882a593Smuzhiyun	b,a	viking_flush_cache_out
122*4882a593Smuzhiyun#endif
123*4882a593Smuzhiyunviking_flush_cache_all:
124*4882a593Smuzhiyun	WINDOW_FLUSH(%g4, %g5)
125*4882a593Smuzhiyunviking_flush_cache_out:
126*4882a593Smuzhiyun	retl
127*4882a593Smuzhiyun	 nop
128*4882a593Smuzhiyun
129*4882a593Smuzhiyunviking_flush_tlb_all:
130*4882a593Smuzhiyun	mov	0x400, %g1
131*4882a593Smuzhiyun	retl
132*4882a593Smuzhiyun	 sta	%g0, [%g1] ASI_M_FLUSH_PROBE
133*4882a593Smuzhiyun
134*4882a593Smuzhiyunviking_flush_tlb_mm:
135*4882a593Smuzhiyun	mov	SRMMU_CTX_REG, %g1
136*4882a593Smuzhiyun	ld	[%o0 + AOFF_mm_context], %o1
137*4882a593Smuzhiyun	lda	[%g1] ASI_M_MMUREGS, %g5
138*4882a593Smuzhiyun#ifndef CONFIG_SMP
139*4882a593Smuzhiyun	cmp	%o1, -1
140*4882a593Smuzhiyun	be	1f
141*4882a593Smuzhiyun#endif
142*4882a593Smuzhiyun	mov	0x300, %g2
143*4882a593Smuzhiyun	sta	%o1, [%g1] ASI_M_MMUREGS
144*4882a593Smuzhiyun	sta	%g0, [%g2] ASI_M_FLUSH_PROBE
145*4882a593Smuzhiyun	retl
146*4882a593Smuzhiyun	 sta	%g5, [%g1] ASI_M_MMUREGS
147*4882a593Smuzhiyun#ifndef CONFIG_SMP
148*4882a593Smuzhiyun1:	retl
149*4882a593Smuzhiyun	 nop
150*4882a593Smuzhiyun#endif
151*4882a593Smuzhiyun
152*4882a593Smuzhiyunviking_flush_tlb_range:
153*4882a593Smuzhiyun	ld	[%o0 + VMA_VM_MM], %o0
154*4882a593Smuzhiyun	mov	SRMMU_CTX_REG, %g1
155*4882a593Smuzhiyun	ld	[%o0 + AOFF_mm_context], %o3
156*4882a593Smuzhiyun	lda	[%g1] ASI_M_MMUREGS, %g5
157*4882a593Smuzhiyun#ifndef CONFIG_SMP
158*4882a593Smuzhiyun	cmp	%o3, -1
159*4882a593Smuzhiyun	be	2f
160*4882a593Smuzhiyun#endif
161*4882a593Smuzhiyun	sethi	%hi(~((1 << PGDIR_SHIFT) - 1)), %o4
162*4882a593Smuzhiyun	sta	%o3, [%g1] ASI_M_MMUREGS
163*4882a593Smuzhiyun	and	%o1, %o4, %o1
164*4882a593Smuzhiyun	add	%o1, 0x200, %o1
165*4882a593Smuzhiyun	sta	%g0, [%o1] ASI_M_FLUSH_PROBE
166*4882a593Smuzhiyun1:	sub	%o1, %o4, %o1
167*4882a593Smuzhiyun	cmp	%o1, %o2
168*4882a593Smuzhiyun	blu,a	1b
169*4882a593Smuzhiyun	 sta	%g0, [%o1] ASI_M_FLUSH_PROBE
170*4882a593Smuzhiyun	retl
171*4882a593Smuzhiyun	 sta	%g5, [%g1] ASI_M_MMUREGS
172*4882a593Smuzhiyun#ifndef CONFIG_SMP
173*4882a593Smuzhiyun2:	retl
174*4882a593Smuzhiyun	 nop
175*4882a593Smuzhiyun#endif
176*4882a593Smuzhiyun
177*4882a593Smuzhiyunviking_flush_tlb_page:
178*4882a593Smuzhiyun	ld	[%o0 + VMA_VM_MM], %o0
179*4882a593Smuzhiyun	mov	SRMMU_CTX_REG, %g1
180*4882a593Smuzhiyun	ld	[%o0 + AOFF_mm_context], %o3
181*4882a593Smuzhiyun	lda	[%g1] ASI_M_MMUREGS, %g5
182*4882a593Smuzhiyun#ifndef CONFIG_SMP
183*4882a593Smuzhiyun	cmp	%o3, -1
184*4882a593Smuzhiyun	be	1f
185*4882a593Smuzhiyun#endif
186*4882a593Smuzhiyun	and	%o1, PAGE_MASK, %o1
187*4882a593Smuzhiyun	sta	%o3, [%g1] ASI_M_MMUREGS
188*4882a593Smuzhiyun	sta	%g0, [%o1] ASI_M_FLUSH_PROBE
189*4882a593Smuzhiyun	retl
190*4882a593Smuzhiyun	 sta	%g5, [%g1] ASI_M_MMUREGS
191*4882a593Smuzhiyun#ifndef CONFIG_SMP
192*4882a593Smuzhiyun1:	retl
193*4882a593Smuzhiyun	 nop
194*4882a593Smuzhiyun#endif
195*4882a593Smuzhiyun
196*4882a593Smuzhiyunviking_flush_page_to_ram:
197*4882a593Smuzhiyunviking_flush_page_for_dma:
198*4882a593Smuzhiyunviking_flush_sig_insns:
199*4882a593Smuzhiyun	retl
200*4882a593Smuzhiyun	 nop
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun#ifdef CONFIG_SMP
203*4882a593Smuzhiyun	.globl	sun4dsmp_flush_tlb_all, sun4dsmp_flush_tlb_mm
204*4882a593Smuzhiyun	.globl	sun4dsmp_flush_tlb_range, sun4dsmp_flush_tlb_page
205*4882a593Smuzhiyunsun4dsmp_flush_tlb_all:
206*4882a593Smuzhiyun	sethi	%hi(sun4dsmp_flush_tlb_spin), %g3
207*4882a593Smuzhiyun1:	ldstub	[%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
208*4882a593Smuzhiyun	tst	%g5
209*4882a593Smuzhiyun	bne	2f
210*4882a593Smuzhiyun	 mov	0x400, %g1
211*4882a593Smuzhiyun	sta	%g0, [%g1] ASI_M_FLUSH_PROBE
212*4882a593Smuzhiyun	retl
213*4882a593Smuzhiyun	 stb	%g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)]
214*4882a593Smuzhiyun2:	tst	%g5
215*4882a593Smuzhiyun	bne,a	2b
216*4882a593Smuzhiyun	 ldub	[%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
217*4882a593Smuzhiyun	b,a	1b
218*4882a593Smuzhiyun
219*4882a593Smuzhiyunsun4dsmp_flush_tlb_mm:
220*4882a593Smuzhiyun	sethi	%hi(sun4dsmp_flush_tlb_spin), %g3
221*4882a593Smuzhiyun1:	ldstub	[%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
222*4882a593Smuzhiyun	tst	%g5
223*4882a593Smuzhiyun	bne	2f
224*4882a593Smuzhiyun	 mov	SRMMU_CTX_REG, %g1
225*4882a593Smuzhiyun	ld	[%o0 + AOFF_mm_context], %o1
226*4882a593Smuzhiyun	lda	[%g1] ASI_M_MMUREGS, %g5
227*4882a593Smuzhiyun	mov	0x300, %g2
228*4882a593Smuzhiyun	sta	%o1, [%g1] ASI_M_MMUREGS
229*4882a593Smuzhiyun	sta	%g0, [%g2] ASI_M_FLUSH_PROBE
230*4882a593Smuzhiyun	sta	%g5, [%g1] ASI_M_MMUREGS
231*4882a593Smuzhiyun	retl
232*4882a593Smuzhiyun	 stb	%g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)]
233*4882a593Smuzhiyun2:	tst	%g5
234*4882a593Smuzhiyun	bne,a	2b
235*4882a593Smuzhiyun	 ldub	[%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
236*4882a593Smuzhiyun	b,a	1b
237*4882a593Smuzhiyun
238*4882a593Smuzhiyunsun4dsmp_flush_tlb_range:
239*4882a593Smuzhiyun	sethi	%hi(sun4dsmp_flush_tlb_spin), %g3
240*4882a593Smuzhiyun1:	ldstub	[%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
241*4882a593Smuzhiyun	tst	%g5
242*4882a593Smuzhiyun	bne	3f
243*4882a593Smuzhiyun	 mov	SRMMU_CTX_REG, %g1
244*4882a593Smuzhiyun	ld	[%o0 + VMA_VM_MM], %o0
245*4882a593Smuzhiyun	ld	[%o0 + AOFF_mm_context], %o3
246*4882a593Smuzhiyun	lda	[%g1] ASI_M_MMUREGS, %g5
247*4882a593Smuzhiyun	sethi	%hi(~((1 << PGDIR_SHIFT) - 1)), %o4
248*4882a593Smuzhiyun	sta	%o3, [%g1] ASI_M_MMUREGS
249*4882a593Smuzhiyun	and	%o1, %o4, %o1
250*4882a593Smuzhiyun	add	%o1, 0x200, %o1
251*4882a593Smuzhiyun	sta	%g0, [%o1] ASI_M_FLUSH_PROBE
252*4882a593Smuzhiyun2:	sub	%o1, %o4, %o1
253*4882a593Smuzhiyun	cmp	%o1, %o2
254*4882a593Smuzhiyun	blu,a	2b
255*4882a593Smuzhiyun	 sta	%g0, [%o1] ASI_M_FLUSH_PROBE
256*4882a593Smuzhiyun	sta	%g5, [%g1] ASI_M_MMUREGS
257*4882a593Smuzhiyun	retl
258*4882a593Smuzhiyun	 stb	%g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)]
259*4882a593Smuzhiyun3:	tst	%g5
260*4882a593Smuzhiyun	bne,a	3b
261*4882a593Smuzhiyun	 ldub	[%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
262*4882a593Smuzhiyun	b,a	1b
263*4882a593Smuzhiyun
264*4882a593Smuzhiyunsun4dsmp_flush_tlb_page:
265*4882a593Smuzhiyun	sethi	%hi(sun4dsmp_flush_tlb_spin), %g3
266*4882a593Smuzhiyun1:	ldstub	[%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
267*4882a593Smuzhiyun	tst	%g5
268*4882a593Smuzhiyun	bne	2f
269*4882a593Smuzhiyun	 mov	SRMMU_CTX_REG, %g1
270*4882a593Smuzhiyun	ld	[%o0 + VMA_VM_MM], %o0
271*4882a593Smuzhiyun	ld	[%o0 + AOFF_mm_context], %o3
272*4882a593Smuzhiyun	lda	[%g1] ASI_M_MMUREGS, %g5
273*4882a593Smuzhiyun	and	%o1, PAGE_MASK, %o1
274*4882a593Smuzhiyun	sta	%o3, [%g1] ASI_M_MMUREGS
275*4882a593Smuzhiyun	sta	%g0, [%o1] ASI_M_FLUSH_PROBE
276*4882a593Smuzhiyun	sta	%g5, [%g1] ASI_M_MMUREGS
277*4882a593Smuzhiyun	retl
278*4882a593Smuzhiyun	 stb	%g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)]
279*4882a593Smuzhiyun2:	tst	%g5
280*4882a593Smuzhiyun	bne,a	2b
281*4882a593Smuzhiyun	 ldub	[%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
282*4882a593Smuzhiyun	b,a	1b
283*4882a593Smuzhiyun	 nop
284*4882a593Smuzhiyun#endif
285