mp_exception.S revision 108379
174131Sjlemon/*-
274131Sjlemon * Copyright (c) 2002 Jake Burkholder.
374131Sjlemon * All rights reserved.
474131Sjlemon *
574131Sjlemon * Redistribution and use in source and binary forms, with or without
674131Sjlemon * modification, are permitted provided that the following conditions
774131Sjlemon * are met:
874131Sjlemon * 1. Redistributions of source code must retain the above copyright
974131Sjlemon *    notice, this list of conditions and the following disclaimer.
1074131Sjlemon * 2. Redistributions in binary form must reproduce the above copyright
1174131Sjlemon *    notice, this list of conditions and the following disclaimer in the
1274131Sjlemon *    documentation and/or other materials provided with the distribution.
1374131Sjlemon *
1474131Sjlemon * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1574131Sjlemon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1674131Sjlemon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1774131Sjlemon * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1874131Sjlemon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1974131Sjlemon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2074131Sjlemon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2174131Sjlemon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2274131Sjlemon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2374131Sjlemon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2474131Sjlemon * SUCH DAMAGE.
2574131Sjlemon *
2674131Sjlemon * $FreeBSD: head/sys/sparc64/sparc64/mp_exception.S 108379 2002-12-29 00:23:48Z jake $
2774131Sjlemon */
2874131Sjlemon
2974131Sjlemon#include <machine/asi.h>
3074131Sjlemon#include <machine/ktr.h>
3174131Sjlemon#include <machine/asmacros.h>
32226154Smarius#include <machine/pstate.h>
33226154Smarius
34226154Smarius#include "assym.s"
35226154Smarius
36226154Smarius	.register	%g2, #ignore
37226154Smarius	.register	%g3, #ignore
38226154Smarius
39226154Smarius#define	IPI_WAIT(r1, r2, r3, r4) \
40226154Smarius	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, %set_softint
145	retry
146END(tl_ipi_level)
147
148/*
149 * Demap a page from the dtlb and/or itlb.
150 */
151ENTRY(tl_ipi_tlb_page_demap)
152#if KTR_COMPILE & KTR_SMP
153	CATR(KTR_SMP, "ipi_tlb_page_demap: pm=%p va=%#lx"
154	    , %g1, %g2, %g3, 7, 8, 9)
155	ldx	[%g5 + ITA_PMAP], %g2
156	stx	%g2, [%g1 + KTR_PARM1]
157	ldx	[%g5 + ITA_VA], %g2
158	stx	%g2, [%g1 + KTR_PARM2]
1599:
160#endif
161
162	ldx	[%g5 + ITA_PMAP], %g1
163
164	SET(kernel_pmap_store, %g3, %g2)
165	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
166
167	cmp	%g1, %g2
168	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
169
170	ldx	[%g5 + ITA_VA], %g2
171	or	%g2, %g3, %g2
172
173	stxa	%g0, [%g2] ASI_DMMU_DEMAP
174	stxa	%g0, [%g2] ASI_IMMU_DEMAP
175	membar	#Sync
176
177	IPI_WAIT(%g5, %g1, %g2, %g3)
178	retry
179END(tl_ipi_tlb_page_demap)
180
181/*
182 * Demap a range of pages from the dtlb and itlb.
183 */
184ENTRY(tl_ipi_tlb_range_demap)
185#if KTR_COMPILE & KTR_SMP
186	CATR(KTR_SMP, "ipi_tlb_range_demap: pm=%p start=%#lx end=%#lx"
187	    , %g1, %g2, %g3, 7, 8, 9)
188	ldx	[%g5 + ITA_PMAP], %g2
189	stx	%g2, [%g1 + KTR_PARM1]
190	ldx	[%g5 + ITA_START], %g2
191	stx	%g2, [%g1 + KTR_PARM2]
192	ldx	[%g5 + ITA_END], %g2
193	stx	%g2, [%g1 + KTR_PARM3]
1949:
195#endif
196
197	ldx	[%g5 + ITA_PMAP], %g1
198
199	SET(kernel_pmap_store, %g3, %g2)
200	mov	TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
201
202	cmp	%g1, %g2
203	movne	%xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
204
205	ldx	[%g5 + ITA_START], %g1
206	ldx	[%g5 + ITA_END], %g2
207
208	set	PAGE_SIZE, %g6
209
2101:	or	%g1, %g3, %g4
211	stxa	%g0, [%g4] ASI_DMMU_DEMAP
212	stxa	%g0, [%g4] ASI_IMMU_DEMAP
213	membar	#Sync
214
215	add	%g1, %g6, %g1
216	cmp	%g1, %g2
217	blt,a,pt %xcc, 1b
218	 nop
219
220	IPI_WAIT(%g5, %g1, %g2, %g3)
221	retry
222END(tl_ipi_tlb_range_demap)
223
224/*
225 * Demap the primary context from the dtlb and itlb.
226 */
227ENTRY(tl_ipi_tlb_context_demap)
228#if KTR_COMPILE & KTR_SMP
229	CATR(KTR_SMP, "ipi_tlb_page_demap: pm=%p va=%#lx"
230	    , %g1, %g2, %g3, 7, 8, 9)
231	ldx	[%g5 + ITA_PMAP], %g2
232	stx	%g2, [%g1 + KTR_PARM1]
233	ldx	[%g5 + ITA_VA], %g2
234	stx	%g2, [%g1 + KTR_PARM2]
2359:
236#endif
237
238	mov	TLB_DEMAP_PRIMARY | TLB_DEMAP_CONTEXT, %g1
239	stxa	%g0, [%g1] ASI_DMMU_DEMAP
240	stxa	%g0, [%g1] ASI_IMMU_DEMAP
241	membar	#Sync
242
243	IPI_WAIT(%g5, %g1, %g2, %g3)
244	retry
245END(tl_ipi_tlb_context_demap)
246