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$");
29
30 #include <machine/asi.h>
31 #include <machine/asmacros.h>
32 #include <machine/cache.h>
33 #include <machine/ktr.h>
34 #include <machine/pstate.h>
35
36 #include "assym.s"
37
38 .register %g2, #ignore
39 .register %g3, #ignore
40
41 #define IPI_DONE(r1, r2, r3, r4) \
42 lduw [PCPU(CPUMASK)], r4 ; \
43 ATOMIC_CLEAR_INT(r1, r2, r3, r4)
44
45 /*
46 * Invalidate a physical page in the data cache. For UltraSPARC I and II.
47 */
48 ENTRY(tl_ipi_spitfire_dcache_page_inval)
49 #if KTR_COMPILE & KTR_SMP
50 CATR(KTR_SMP, "tl_ipi_spitfire_dcache_page_inval: pa=%#lx"
51 , %g1, %g2, %g3, 7, 8, 9)
52 ldx [%g5 + ICA_PA], %g2
53 stx %g2, [%g1 + KTR_PARM1]
54 9:
55 #endif
56
57 ldx [%g5 + ICA_PA], %g6
58 srlx %g6, PAGE_SHIFT - DC_TAG_SHIFT, %g6
59
60 lduw [PCPU(CACHE) + DC_SIZE], %g3
61 lduw [PCPU(CACHE) + DC_LINESIZE], %g4
62 sub %g3, %g4, %g2
63
64 1: ldxa [%g2] ASI_DCACHE_TAG, %g1
65 srlx %g1, DC_VALID_SHIFT, %g3
66 andcc %g3, DC_VALID_MASK, %g0
67 bz,pt %xcc, 2f
68 set DC_TAG_MASK, %g3
69 sllx %g3, DC_TAG_SHIFT, %g3
70 and %g1, %g3, %g1
71 cmp %g1, %g6
72 bne,a,pt %xcc, 2f
73 nop
74 stxa %g1, [%g2] ASI_DCACHE_TAG
75 membar #Sync
76
77 2: brgz,pt %g2, 1b
78 sub %g2, %g4, %g2
79
80 IPI_DONE(%g5, %g1, %g2, %g3)
81 retry
82 END(tl_ipi_spitfire_dcache_page_inval)
83
84 /*
85 * Invalidate a physical page in the instruction cache. For UltraSPARC I and
86 * II.
87 */
88 ENTRY(tl_ipi_spitfire_icache_page_inval)
89 #if KTR_COMPILE & KTR_SMP
90 CATR(KTR_SMP, "tl_ipi_spitfire_icache_page_inval: pa=%#lx"
91 , %g1, %g2, %g3, 7, 8, 9)
92 ldx [%g5 + ICA_PA], %g2
93 stx %g2, [%g1 + KTR_PARM1]
94 9:
95 #endif
96
97 ldx [%g5 + ICA_PA], %g6
98 srlx %g6, PAGE_SHIFT - IC_TAG_SHIFT, %g6
99
100 lduw [PCPU(CACHE) + IC_SIZE], %g3
101 lduw [PCPU(CACHE) + IC_LINESIZE], %g4
102 sub %g3, %g4, %g2
103
104 1: ldda [%g2] ASI_ICACHE_TAG, %g0 /*, %g1 */
105 srlx %g1, IC_VALID_SHIFT, %g3
106 andcc %g3, IC_VALID_MASK, %g0
107 bz,pt %xcc, 2f
108 set IC_TAG_MASK, %g3
109 sllx %g3, IC_TAG_SHIFT, %g3
110 and %g1, %g3, %g1
111 cmp %g1, %g6
112 bne,a,pt %xcc, 2f
113 nop
114 stxa %g1, [%g2] ASI_ICACHE_TAG
115 membar #Sync
116
117 2: brgz,pt %g2, 1b
118 sub %g2, %g4, %g2
119
120 IPI_DONE(%g5, %g1, %g2, %g3)
121 retry
122 END(tl_ipi_spitfire_icache_page_inval)
123
124 /*
125 * Invalidate a physical page in the data cache. For UltraSPARC III.
126 */
127 ENTRY(tl_ipi_cheetah_dcache_page_inval)
128 #if KTR_COMPILE & KTR_SMP
129 CATR(KTR_SMP, "tl_ipi_cheetah_dcache_page_inval: pa=%#lx"
130 , %g1, %g2, %g3, 7, 8, 9)
131 ldx [%g5 + ICA_PA], %g2
132 stx %g2, [%g1 + KTR_PARM1]
133 9:
134 #endif
135
136 ldx [%g5 + ICA_PA], %g1
137
138 set PAGE_SIZE, %g2
139 add %g1, %g2, %g3
140
141 lduw [PCPU(CACHE) + DC_LINESIZE], %g2
142
143 1: stxa %g0, [%g1] ASI_DCACHE_INVALIDATE
144 membar #Sync
145
146 add %g1, %g2, %g1
147 cmp %g1, %g3
148 blt,a,pt %xcc, 1b
149 nop
150
151 IPI_DONE(%g5, %g1, %g2, %g3)
152 retry
153 END(tl_ipi_cheetah_dcache_page_inval)
154
155 /*
156 * Trigger a softint at the desired level.
157 */
158 ENTRY(tl_ipi_level)
159 #if KTR_COMPILE & KTR_SMP
160 CATR(KTR_SMP, "tl_ipi_level: cpuid=%d mid=%d d1=%#lx d2=%#lx"
161 , %g1, %g2, %g3, 7, 8, 9)
162 lduw [PCPU(CPUID)], %g2
163 stx %g2, [%g1 + KTR_PARM1]
164 lduw [PCPU(MID)], %g2
165 stx %g2, [%g1 + KTR_PARM2]
166 stx %g4, [%g1 + KTR_PARM3]
167 stx %g5, [%g1 + KTR_PARM4]
168 9:
169 #endif
170
171 mov 1, %g1
172 sllx %g1, %g5, %g1
173 wr %g1, 0, %set_softint
174 retry
175 END(tl_ipi_level)
176
177 /*
178 * Demap a page from the dtlb and/or itlb.
179 */
180 ENTRY(tl_ipi_tlb_page_demap)
181 #if KTR_COMPILE & KTR_SMP
182 CATR(KTR_SMP, "ipi_tlb_page_demap: pm=%p va=%#lx"
183 , %g1, %g2, %g3, 7, 8, 9)
184 ldx [%g5 + ITA_PMAP], %g2
185 stx %g2, [%g1 + KTR_PARM1]
186 ldx [%g5 + ITA_VA], %g2
187 stx %g2, [%g1 + KTR_PARM2]
188 9:
189 #endif
190
191 ldx [%g5 + ITA_PMAP], %g1
192
193 SET(kernel_pmap_store, %g3, %g2)
194 mov TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
195
196 cmp %g1, %g2
197 movne %xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
198
199 ldx [%g5 + ITA_VA], %g2
200 or %g2, %g3, %g2
201
202 sethi %hi(KERNBASE), %g3
203 stxa %g0, [%g2] ASI_DMMU_DEMAP
204 stxa %g0, [%g2] ASI_IMMU_DEMAP
205 flush %g3
206
207 IPI_DONE(%g5, %g1, %g2, %g3)
208 retry
209 END(tl_ipi_tlb_page_demap)
210
211 /*
212 * Demap a range of pages from the dtlb and itlb.
213 */
214 ENTRY(tl_ipi_tlb_range_demap)
215 #if KTR_COMPILE & KTR_SMP
216 CATR(KTR_SMP, "ipi_tlb_range_demap: pm=%p start=%#lx end=%#lx"
217 , %g1, %g2, %g3, 7, 8, 9)
218 ldx [%g5 + ITA_PMAP], %g2
219 stx %g2, [%g1 + KTR_PARM1]
220 ldx [%g5 + ITA_START], %g2
221 stx %g2, [%g1 + KTR_PARM2]
222 ldx [%g5 + ITA_END], %g2
223 stx %g2, [%g1 + KTR_PARM3]
224 9:
225 #endif
226
227 ldx [%g5 + ITA_PMAP], %g1
228
229 SET(kernel_pmap_store, %g3, %g2)
230 mov TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, %g3
231
232 cmp %g1, %g2
233 movne %xcc, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %g3
234
235 ldx [%g5 + ITA_START], %g1
236 ldx [%g5 + ITA_END], %g2
237
238 sethi %hi(KERNBASE), %g6
239 1: or %g1, %g3, %g4
240 stxa %g0, [%g4] ASI_DMMU_DEMAP
241 stxa %g0, [%g4] ASI_IMMU_DEMAP
242 flush %g6
243
244 set PAGE_SIZE, %g6
245 add %g1, %g6, %g1
246 cmp %g1, %g2
247 blt,a,pt %xcc, 1b
248 sethi %hi(KERNBASE), %g6
249
250 IPI_DONE(%g5, %g1, %g2, %g3)
251 retry
252 END(tl_ipi_tlb_range_demap)
253
254 /*
255 * Demap the primary context from the dtlb and itlb.
256 */
257 ENTRY(tl_ipi_tlb_context_demap)
258 #if KTR_COMPILE & KTR_SMP
259 CATR(KTR_SMP, "tl_ipi_tlb_context_demap: pm=%p va=%#lx"
260 , %g1, %g2, %g3, 7, 8, 9)
261 ldx [%g5 + ITA_PMAP], %g2
262 stx %g2, [%g1 + KTR_PARM1]
263 ldx [%g5 + ITA_VA], %g2
264 stx %g2, [%g1 + KTR_PARM2]
265 9:
266 #endif
267
268 mov TLB_DEMAP_PRIMARY | TLB_DEMAP_CONTEXT, %g1
269 sethi %hi(KERNBASE), %g3
270 stxa %g0, [%g1] ASI_DMMU_DEMAP
271 stxa %g0, [%g1] ASI_IMMU_DEMAP
272 flush %g3
273
274 IPI_DONE(%g5, %g1, %g2, %g3)
275 retry
276 END(tl_ipi_tlb_context_demap)
277
278 /*
279 * Read %stick.
280 */
281 ENTRY(tl_ipi_stick_rd)
282 ldx [%g5 + IRA_VAL], %g1
283 rd %asr24, %g2
284 stx %g2, [%g1]
285
286 IPI_DONE(%g5, %g1, %g2, %g3)
287 retry
288 END(tl_ipi_stick_rd)
289
290 /*
291 * Read %tick.
292 */
293 ENTRY(tl_ipi_tick_rd)
294 ldx [%g5 + IRA_VAL], %g1
295 rd %tick, %g2
296 stx %g2, [%g1]
297
298 IPI_DONE(%g5, %g1, %g2, %g3)
299 retry
300 END(tl_ipi_tick_rd)
Cache object: fbf126113b8b62521bdcff18d0dc671b
|