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