]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/sparc64/sparc64/mp_exception.S
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.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) \
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, "ipi_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, "ipi_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, "ipi_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 1:      or      %g1, %g3, %g4
239         sethi   %hi(KERNBASE), %g6
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          nop
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, "ipi_tlb_page_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)