mp_exception.S revision 114188
1/*-
2 * Copyright (c) 2002 Jake Burkholder.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <machine/asm.h>
28__FBSDID("$FreeBSD: head/sys/sparc64/sparc64/mp_exception.S 114188 2003-04-29 00:37:41Z jake $");
29
30#include <machine/asi.h>
31#include <machine/ktr.h>
32#include <machine/asmacros.h>
33#include <machine/pstate.h>
34
35#include "assym.s"
36
37	.register	%g2, #ignore
38	.register	%g3, #ignore
39
40#define	IPI_WAIT(r1, r2, r3, r4) \
41	lduw	[PCPU(CPUMASK)], r4 ;  \
42	ATOMIC_CLEAR_INT(r1, r2, r3, r4) ; \
439:	lduw	[r1], r2 ; \
44	brnz,a,pn r2, 9b ; \
45	 nop
46
47/*
48 * Invalidate a physical page in the data cache.  For UltraSPARC I and II.
49 */
50ENTRY(tl_ipi_spitfire_dcache_page_inval)
51#if KTR_COMPILE & KTR_SMP
52	CATR(KTR_SMP, "ipi_dcache_page_inval: pa=%#lx"
53	    , %g1, %g2, %g3, 7, 8, 9)
54	ldx	[%g5 + ICA_PA], %g2
55	stx	%g2, [%g1 + KTR_PARM1]
569:
57#endif
58
59	ldx	[%g5 + ICA_PA], %g6
60	srlx	%g6, PAGE_SHIFT - DC_TAG_SHIFT, %g6
61
62	SET(cache, %g3, %g2)
63	lduw	[%g2 + DC_SIZE], %g3
64	lduw	[%g2 + DC_LINESIZE], %g4
65	sub	%g3, %g4, %g2
66
671:	ldxa	[%g2] ASI_DCACHE_TAG, %g1
68	srlx	%g1, DC_VALID_SHIFT, %g3
69	andcc	%g3, DC_VALID_MASK, %g0
70	bz,pt	%xcc, 2f
71	 set	DC_TAG_MASK, %g3
72	sllx	%g3, DC_TAG_SHIFT, %g3
73	and	%g1, %g3, %g1
74	cmp	%g1, %g6
75	bne,a,pt %xcc, 2f
76	 nop
77	stxa	%g1, [%g2] ASI_DCACHE_TAG
78	membar	#Sync
79
802:	brgz,pt	%g2, 1b
81	 sub	%g2, %g4, %g2
82
83	IPI_WAIT(%g5, %g1, %g2, %g3)
84	retry
85END(tl_ipi_spitfire_dcache_page_inval)
86
87/*
88 * Invalidate a physical page in the instruction cache.  For UltraSPARC I and
89 * II.
90 */
91ENTRY(tl_ipi_spitfire_icache_page_inval)
92#if KTR_COMPILE & KTR_SMP
93	CATR(KTR_SMP, "ipi_icache_page_inval: pa=%#lx"
94	    , %g1, %g2, %g3, 7, 8, 9)
95	ldx	[%g5 + ICA_PA], %g2
96	stx	%g2, [%g1 + KTR_PARM1]
979:
98#endif
99
100	ldx	[%g5 + ICA_PA], %g6
101	srlx	%g6, PAGE_SHIFT - IC_TAG_SHIFT, %g6
102
103	SET(cache, %g3, %g2)
104	lduw	[%g2 + IC_SIZE], %g3
105	lduw	[%g2 + IC_LINESIZE], %g4
106	sub	%g3, %g4, %g2
107
1081:	ldda	[%g2] ASI_ICACHE_TAG, %g0 /*, %g1 */
109	srlx	%g1, IC_VALID_SHIFT, %g3
110	andcc	%g3, IC_VALID_MASK, %g0
111	bz,pt	%xcc, 2f
112	 set	IC_TAG_MASK, %g3
113	sllx	%g3, IC_TAG_SHIFT, %g3
114	and	%g1, %g3, %g1
115	cmp	%g1, %g6
116	bne,a,pt %xcc, 2f
117	 nop
118	stxa	%g1, [%g2] ASI_ICACHE_TAG
119	membar	#Sync
120
1212:	brgz,pt	%g2, 1b
122	 sub	%g2, %g4, %g2
123
124	IPI_WAIT(%g5, %g1, %g2, %g3)
125	retry
126END(tl_ipi_spitfire_icache_page_inval)
127
128/*
129 * Invalidate a physical page in the data cache.  For UltraSPARC III.
130 */
131ENTRY(tl_ipi_cheetah_dcache_page_inval)
132#if KTR_COMPILE & KTR_SMP
133	CATR(KTR_SMP, "ipi_dcache_page_inval: pa=%#lx"
134	    , %g1, %g2, %g3, 7, 8, 9)
135	ldx	[%g5 + ICA_PA], %g2
136	stx	%g2, [%g1 + KTR_PARM1]
1379:
138#endif
139
140	ldx	[%g5 + ICA_PA], %g1
141
142	set	PAGE_SIZE, %g2
143	add	%g1, %g2, %g3
144
145	SET(cache, %g4, %g2)
146	lduw	[%g2 + DC_LINESIZE], %g2
147
1481:	stxa	%g0, [%g1] ASI_DCACHE_INVALIDATE
149	membar	#Sync
150
151	add	%g1, %g2, %g1
152	cmp	%g1, %g3
153	blt,a,pt %xcc, 1b
154	 nop
155
156	IPI_WAIT(%g5, %g1, %g2, %g3)
157	retry
158END(tl_ipi_cheetah_dcache_page_inval)
159
160/*
161 * Trigger a softint at the desired level.
162 */
163ENTRY(tl_ipi_level)
164#if KTR_COMPILE & KTR_SMP
165	CATR(KTR_SMP, "tl_ipi_level: cpuid=%d mid=%d d1=%#lx d2=%#lx"
166	    , %g1, %g2, %g3, 7, 8, 9)
167	lduw	[PCPU(CPUID)], %g2
168	stx	%g2, [%g1 + KTR_PARM1]
169	lduw	[PCPU(MID)], %g2
170	stx	%g2, [%g1 + KTR_PARM2]
171	stx	%g4, [%g1 + KTR_PARM3]
172	stx	%g5, [%g1 + KTR_PARM4]
1739:
174#endif
175
176	mov	1, %g1
177	sllx	%g1, %g5, %g1
178	wr	%g1, 0, %set_softint
179	retry
180END(tl_ipi_level)
181
182/*
183 * Demap a page from the dtlb and/or itlb.
184 */
185ENTRY(tl_ipi_tlb_page_demap)
186#if KTR_COMPILE & KTR_SMP
187	CATR(KTR_SMP, "ipi_tlb_page_demap: pm=%p va=%#lx"
188	    , %g1, %g2, %g3, 7, 8, 9)
189	ldx	[%g5 + ITA_PMAP], %g2
190	stx	%g2, [%g1 + KTR_PARM1]
191	ldx	[%g5 + ITA_VA], %g2
192	stx	%g2, [%g1 + KTR_PARM2]
1939:
194#endif
195
196	ldx	[%g5 + ITA_PMAP], %g1
197
198	SET(kernel_pmap_store, %g3, %g2)
199	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
200
201	cmp	%g1, %g2
202	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
203
204	ldx	[%g5 + ITA_VA], %g2
205	or	%g2, %g3, %g2
206
207	stxa	%g0, [%g2] ASI_DMMU_DEMAP
208	stxa	%g0, [%g2] ASI_IMMU_DEMAP
209	membar	#Sync
210
211	IPI_WAIT(%g5, %g1, %g2, %g3)
212	retry
213END(tl_ipi_tlb_page_demap)
214
215/*
216 * Demap a range of pages from the dtlb and itlb.
217 */
218ENTRY(tl_ipi_tlb_range_demap)
219#if KTR_COMPILE & KTR_SMP
220	CATR(KTR_SMP, "ipi_tlb_range_demap: pm=%p start=%#lx end=%#lx"
221	    , %g1, %g2, %g3, 7, 8, 9)
222	ldx	[%g5 + ITA_PMAP], %g2
223	stx	%g2, [%g1 + KTR_PARM1]
224	ldx	[%g5 + ITA_START], %g2
225	stx	%g2, [%g1 + KTR_PARM2]
226	ldx	[%g5 + ITA_END], %g2
227	stx	%g2, [%g1 + KTR_PARM3]
2289:
229#endif
230
231	ldx	[%g5 + ITA_PMAP], %g1
232
233	SET(kernel_pmap_store, %g3, %g2)
234	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
235
236	cmp	%g1, %g2
237	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
238
239	ldx	[%g5 + ITA_START], %g1
240	ldx	[%g5 + ITA_END], %g2
241
242	set	PAGE_SIZE, %g6
243
2441:	or	%g1, %g3, %g4
245	stxa	%g0, [%g4] ASI_DMMU_DEMAP
246	stxa	%g0, [%g4] ASI_IMMU_DEMAP
247	membar	#Sync
248
249	add	%g1, %g6, %g1
250	cmp	%g1, %g2
251	blt,a,pt %xcc, 1b
252	 nop
253
254	IPI_WAIT(%g5, %g1, %g2, %g3)
255	retry
256END(tl_ipi_tlb_range_demap)
257
258/*
259 * Demap the primary context from the dtlb and itlb.
260 */
261ENTRY(tl_ipi_tlb_context_demap)
262#if KTR_COMPILE & KTR_SMP
263	CATR(KTR_SMP, "ipi_tlb_page_demap: pm=%p va=%#lx"
264	    , %g1, %g2, %g3, 7, 8, 9)
265	ldx	[%g5 + ITA_PMAP], %g2
266	stx	%g2, [%g1 + KTR_PARM1]
267	ldx	[%g5 + ITA_VA], %g2
268	stx	%g2, [%g1 + KTR_PARM2]
2699:
270#endif
271
272	mov	TLB_DEMAP_PRIMARY | TLB_DEMAP_CONTEXT, %g1
273	stxa	%g0, [%g1] ASI_DMMU_DEMAP
274	stxa	%g0, [%g1] ASI_IMMU_DEMAP
275	membar	#Sync
276
277	IPI_WAIT(%g5, %g1, %g2, %g3)
278	retry
279END(tl_ipi_tlb_context_demap)
280