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