mp_exception.S revision 97001
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 * $FreeBSD: head/sys/sparc64/sparc64/mp_exception.S 97001 2002-05-20 16:30:47Z jake $
27 */
28
29#include <machine/asi.h>
30#include <machine/ktr.h>
31#include <machine/asmacros.h>
32#include <machine/pstate.h>
33
34#include "assym.s"
35
36	.register	%g2, #ignore
37	.register	%g3, #ignore
38
39#define	IPI_WAIT(r1, r2, r3, r4) \
40	lduw	[PCPU(CPUMASK)], r4 ;  \
41	ATOMIC_CLEAR_INT(r1, r2, r3, r4) ; \
429:	lduw	[r1], r2 ; \
43	brnz,a,pn r2, 9b ; \
44	 nop
45
46/*
47 * Invalidate a phsyical page in the data cache.
48 */
49ENTRY(tl_ipi_dcache_page_inval)
50#if KTR_COMPILE & KTR_SMP
51	CATR(KTR_SMP, "ipi_dcache_page_inval: pa=%#lx"
52	    , %g1, %g2, %g3, 7, 8, 9)
53	ldx	[%g5 + ICA_PA], %g2
54	stx	%g2, [%g1 + KTR_PARM1]
559:
56#endif
57
58	ldx	[%g5 + ICA_PA], %g6
59	srlx	%g6, PAGE_SHIFT - DC_TAG_SHIFT, %g6
60
61	SET(cache, %g3, %g2)
62	lduw	[%g2 + DC_SIZE], %g3
63	lduw	[%g2 + DC_LINESIZE], %g4
64	sub	%g3, %g4, %g2
65
661:	ldxa	[%g2] ASI_DCACHE_TAG, %g1
67	srlx	%g1, DC_VALID_SHIFT, %g3
68	andcc	%g3, DC_VALID_MASK, %g0
69	bz,pt	%xcc, 2f
70	 set	DC_TAG_MASK, %g3
71	sllx	%g3, DC_TAG_SHIFT, %g3
72	and	%g1, %g3, %g1
73	cmp	%g1, %g6
74	bne,a,pt %xcc, 2f
75	 nop
76	stxa	%g1, [%g2] ASI_DCACHE_TAG
77	membar	#Sync
78
792:	brgz,pt	%g2, 1b
80	 sub	%g2, %g4, %g2
81
82	IPI_WAIT(%g5, %g1, %g2, %g3)
83	retry
84END(tl_ipi_dcache_page_inval)
85
86/*
87 * Invalidate a phsyical page in the instruction cache.
88 */
89ENTRY(tl_ipi_icache_page_inval)
90#if KTR_COMPILE & KTR_SMP
91	CATR(KTR_SMP, "ipi_icache_page_inval: pa=%#lx"
92	    , %g1, %g2, %g3, 7, 8, 9)
93	ldx	[%g5 + ICA_PA], %g2
94	stx	%g2, [%g1 + KTR_PARM1]
959:
96#endif
97
98	ldx	[%g5 + ICA_PA], %g6
99	srlx	%g6, PAGE_SHIFT - IC_TAG_SHIFT, %g6
100
101	SET(cache, %g3, %g2)
102	lduw	[%g2 + IC_SIZE], %g3
103	lduw	[%g2 + IC_LINESIZE], %g4
104	sub	%g3, %g4, %g2
105
1061:	ldda	[%g2] ASI_ICACHE_TAG, %g0 /*, %g1 */
107	srlx	%g1, IC_VALID_SHIFT, %g3
108	andcc	%g3, IC_VALID_MASK, %g0
109	bz,pt	%xcc, 2f
110	 set	IC_TAG_MASK, %g3
111	sllx	%g3, IC_TAG_SHIFT, %g3
112	and	%g1, %g3, %g1
113	cmp	%g1, %g6
114	bne,a,pt %xcc, 2f
115	 nop
116	stxa	%g1, [%g2] ASI_ICACHE_TAG
117	membar	#Sync
118
1192:	brgz,pt	%g2, 1b
120	 sub	%g2, %g4, %g2
121
122	IPI_WAIT(%g5, %g1, %g2, %g3)
123	retry
124END(tl_ipi_icache_page_inval)
125
126/*
127 * Trigger a softint at the desired level.
128 */
129ENTRY(tl_ipi_level)
130#if KTR_COMPILE & KTR_SMP
131	CATR(KTR_SMP, "tl_ipi_level: cpuid=%d mid=%d d1=%#lx d2=%#lx"
132	    , %g1, %g2, %g3, 7, 8, 9)
133	lduw	[PCPU(CPUID)], %g2
134	stx	%g2, [%g1 + KTR_PARM1]
135	lduw	[PCPU(MID)], %g2
136	stx	%g2, [%g1 + KTR_PARM2]
137	stx	%g4, [%g1 + KTR_PARM3]
138	stx	%g5, [%g1 + KTR_PARM4]
1399:
140#endif
141
142	mov	1, %g1
143	sllx	%g1, %g5, %g1
144	wr	%g1, 0, %asr20
145	retry
146END(tl_ipi_level)
147
148ENTRY(tl_ipi_test)
149#if KTR_COMPILE & KTR_SMP
150	CATR(KTR_SMP, "ipi_test: cpuid=%d mid=%d d1=%#lx d2=%#lx"
151	    , %g1, %g2, %g3, 7, 8, 9)
152	lduw	[PCPU(CPUID)], %g2
153	stx	%g2, [%g1 + KTR_PARM1]
154	lduw	[PCPU(MID)], %g2
155	stx	%g2, [%g1 + KTR_PARM2]
156	stx	%g4, [%g1 + KTR_PARM3]
157	stx	%g5, [%g1 + KTR_PARM4]
1589:
159#endif
160	retry
161END(tl_ipi_test)
162
163/*
164 * Demap a page from the dtlb and/or itlb.
165 */
166ENTRY(tl_ipi_tlb_page_demap)
167#if KTR_COMPILE & KTR_SMP
168	CATR(KTR_SMP, "ipi_tlb_page_demap: pm=%p va=%#lx"
169	    , %g1, %g2, %g3, 7, 8, 9)
170	ldx	[%g5 + ITA_PMAP], %g2
171	stx	%g2, [%g1 + KTR_PARM1]
172	ldx	[%g5 + ITA_VA], %g2
173	stx	%g2, [%g1 + KTR_PARM2]
1749:
175#endif
176
177	ldx	[%g5 + ITA_PMAP], %g1
178
179	SET(kernel_pmap_store, %g3, %g2)
180	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
181
182	cmp	%g1, %g2
183	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
184
185	ldx	[%g5 + ITA_TLB], %g1
186	ldx	[%g5 + ITA_VA], %g2
187	or	%g2, %g3, %g2
188
189	andcc	%g1, TLB_DTLB, %g0
190	bz,a,pn	%xcc, 1f
191	 nop
192	stxa	%g0, [%g2] ASI_DMMU_DEMAP
193	membar	#Sync
194
1951:	andcc	%g1, TLB_ITLB, %g0
196	bz,a,pn	%xcc, 2f
197	 nop
198	stxa	%g0, [%g2] ASI_IMMU_DEMAP
199	membar	#Sync
200
2012:	IPI_WAIT(%g5, %g1, %g2, %g3)
202	retry
203END(tl_ipi_tlb_page_demap)
204
205/*
206 * Demap a range of pages from the dtlb and itlb.
207 */
208ENTRY(tl_ipi_tlb_range_demap)
209#if KTR_COMPILE & KTR_SMP
210	CATR(KTR_SMP, "ipi_tlb_range_demap: pm=%p start=%#lx end=%#lx"
211	    , %g1, %g2, %g3, 7, 8, 9)
212	ldx	[%g5 + ITA_PMAP], %g2
213	stx	%g2, [%g1 + KTR_PARM1]
214	ldx	[%g5 + ITA_START], %g2
215	stx	%g2, [%g1 + KTR_PARM2]
216	ldx	[%g5 + ITA_END], %g2
217	stx	%g2, [%g1 + KTR_PARM3]
2189:
219#endif
220
221	ldx	[%g5 + ITA_PMAP], %g1
222
223	SET(kernel_pmap_store, %g3, %g2)
224	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
225
226	cmp	%g1, %g2
227	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
228
229	ldx	[%g5 + ITA_START], %g1
230	ldx	[%g5 + ITA_END], %g2
231
232	set	PAGE_SIZE, %g6
233
2341:	or	%g1, %g3, %g4
235	stxa	%g0, [%g4] ASI_DMMU_DEMAP
236	stxa	%g0, [%g4] ASI_IMMU_DEMAP
237	membar	#Sync
238
239	add	%g1, %g6, %g1
240	cmp	%g1, %g2
241	blt,a,pt %xcc, 1b
242	 nop
243
244	IPI_WAIT(%g5, %g1, %g2, %g3)
245	retry
246END(tl_ipi_tlb_range_demap)
247
248/*
249 * Demap the primary context from the dtlb and itlb.
250 */
251ENTRY(tl_ipi_tlb_context_demap)
252#if KTR_COMPILE & KTR_SMP
253	CATR(KTR_SMP, "ipi_tlb_page_demap: pm=%p va=%#lx"
254	    , %g1, %g2, %g3, 7, 8, 9)
255	ldx	[%g5 + ITA_PMAP], %g2
256	stx	%g2, [%g1 + KTR_PARM1]
257	ldx	[%g5 + ITA_VA], %g2
258	stx	%g2, [%g1 + KTR_PARM2]
2599:
260#endif
261
262	mov	TLB_DEMAP_PRIMARY | TLB_DEMAP_CONTEXT, %g1
263	stxa	%g0, [%g1] ASI_DMMU_DEMAP
264	stxa	%g0, [%g1] ASI_IMMU_DEMAP
265	membar	#Sync
266
267	IPI_WAIT(%g5, %g1, %g2, %g3)
268	retry
269END(tl_ipi_tlb_context_demap)
270