]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/sparc64/sparc64/mp_locore.S
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / sparc64 / sparc64 / mp_locore.S
1 /*-
2  * Copyright (c) 2002 Jake Burkholder.
3  * Copyright (c) 2008 Marius Strobl <marius@FreeBSD.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27
28 #include <machine/asm.h>
29 __FBSDID("$FreeBSD$");
30
31 #include <machine/asi.h>
32 #include <machine/asmacros.h>
33 #include <machine/ktr.h>
34 #include <machine/pstate.h>
35 #include <machine/smp.h>
36 #include <machine/upa.h>
37 #include <machine/ver.h>
38
39 #include "assym.s"
40
41         .register       %g2, #ignore
42         .register       %g3, #ignore
43
44         .text
45         _ALIGN_TEXT
46         /*
47          * Initialize misc. state to known values: interrupts disabled,
48          * normal globals, no clean windows, PIL 0, and floating point
49          * disabled.
50          */
51 1:      wrpr    %g0, PSTATE_NORMAL, %pstate
52         wrpr    %g0, 0, %cleanwin
53         wrpr    %g0, 0, %pil
54         wr      %g0, 0, %fprs
55
56         rdpr    %ver, %l7
57         srlx    %l7, VER_IMPL_SHIFT, %l7
58         sll     %l7, VER_IMPL_SIZE, %l7
59         srl     %l7, VER_IMPL_SIZE, %l7
60         cmp     %l7, CPU_IMPL_ULTRASPARCIIIp
61         bne     %icc, 3f
62          nop
63
64         /*
65          * Relocate the locked entry in it16 slot 0 (if existent)
66          * as part of working around Cheetah+ erratum 34.
67          */
68
69         setx    TD_V | TD_L, %l1, %l0
70         /*
71          * We read ASI_DTLB_DATA_ACCESS_REG twice in order to work
72          * around errata of USIII and beyond.
73          */
74         ldxa    [%g0] ASI_ITLB_DATA_ACCESS_REG, %g0
75         ldxa    [%g0] ASI_ITLB_DATA_ACCESS_REG, %l6
76         and     %l6, %l0, %l1
77         cmp     %l0, %l1
78         bne     %xcc, 3f
79          nop
80
81         /* Flush the mapping of slot 0. */
82         ldxa    [%g0] ASI_ITLB_TAG_READ_REG, %l5
83         srlx    %l5, TAR_VPN_SHIFT, %l0
84         sllx    %l0, TAR_VPN_SHIFT, %l0
85         or      %l0, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %l0
86         stxa    %g0, [%l0] ASI_IMMU_DEMAP
87         /* The USIII-family ignores the address. */
88         flush   %g0
89
90         /*
91          * Search a replacement slot != 0 and enter the data and tag
92          * that formerly were in slot 0.
93          */
94         mov     (1 << TLB_DAR_SLOT_SHIFT), %l4
95         setx    TD_V, %l1, %l0
96         /*
97          * We read ASI_DTLB_DATA_ACCESS_REG twice in order to work
98          * around errata of USIII and beyond.
99          */
100 2:      ldxa    [%l4] ASI_ITLB_DATA_ACCESS_REG, %g0
101         ldxa    [%l4] ASI_ITLB_DATA_ACCESS_REG, %l1
102         and     %l1, %l0, %l1
103         cmp     %l0, %l1
104         be,a    %xcc, 2b
105          add    %l4, (1 << TLB_DAR_SLOT_SHIFT), %l4
106         wr      %g0, ASI_IMMU, %asi
107         stxa    %l5, [%g0 + AA_IMMU_TAR] %asi
108         stxa    %l6, [%l4] ASI_ITLB_DATA_ACCESS_REG
109         /* The USIII-family ignores the address. */
110         flush   %g0
111
112 3:      rd      %pc, %l6
113         ldx     [%l6 + (9f-3b)], %l1
114         add     %l6, (11f-3b), %l2
115         clr     %l3
116 4:      cmp     %l3, %l1
117         be      %xcc, 8f
118          nop
119         ldx     [%l2 + TTE_VPN], %l4
120         ldx     [%l2 + TTE_DATA], %l5
121         srlx    %l4, TV_SIZE_BITS, %l4
122         sllx    %l4, PAGE_SHIFT_4M, %l4
123         wr      %g0, ASI_DMMU, %asi
124         stxa    %l4, [%g0 + AA_DMMU_TAR] %asi
125         stxa    %l5, [%g0] ASI_DTLB_DATA_IN_REG
126         membar  #Sync
127
128         cmp     %l7, CPU_IMPL_ULTRASPARCIIIp
129         bne     %icc, 6f
130          wr     %g0, ASI_IMMU, %asi
131
132         /*
133          * Search an unused slot != 0 and explicitly enter the data
134          * and tag there in order to avoid Cheetah+ erratum 34.
135          */
136         mov     (1 << TLB_DAR_SLOT_SHIFT), %l0
137         setx    TD_V, %o1, %o0
138         /*
139          * We read ASI_DTLB_DATA_ACCESS_REG twice in order to work
140          * around errata of USIII and beyond.
141          */
142 5:      ldxa    [%l0] ASI_ITLB_DATA_ACCESS_REG, %g0
143         ldxa    [%l0] ASI_ITLB_DATA_ACCESS_REG, %o1
144         and     %o1, %o0, %o1
145         cmp     %o0, %o1
146         be,a    %xcc, 5b
147          add    %l0, (1 << TLB_DAR_SLOT_SHIFT), %l0
148         sethi   %hi(KERNBASE), %o0
149         stxa    %l4, [%g0 + AA_IMMU_TAR] %asi
150         stxa    %l5, [%l0] ASI_ITLB_DATA_ACCESS_REG
151         flush   %o0
152         ba      %xcc, 7f
153          nop
154
155 6:      sethi   %hi(KERNBASE), %l0
156         stxa    %l4, [%g0 + AA_IMMU_TAR] %asi
157         stxa    %l5, [%g0] ASI_ITLB_DATA_IN_REG
158         flush   %l0
159 7:      add     %l2, 1 << TTE_SHIFT, %l2
160         add     %l3, 1, %l3
161         ba      %xcc, 4b
162          nop
163 8:      ldx     [%l6 + (10f-3b)], %l1
164         jmpl    %l1, %g0
165          nop
166         _ALIGN_DATA
167 9:      .xword  0x0
168 10:     .xword  0x0
169 11:
170
171 DATA(mp_tramp_code)
172         .xword  1b
173 DATA(mp_tramp_code_len)
174         .xword  11b-1b
175 DATA(mp_tramp_tlb_slots)
176         .xword  9b-1b
177 DATA(mp_tramp_func)
178         .xword  10b-1b
179
180 /*
181  * void mp_startup(void)
182  */
183 ENTRY(mp_startup)
184         SET(cpu_start_args, %l1, %l0)
185
186         mov     CPU_TICKSYNC, %l1
187         membar  #StoreLoad
188         stw     %l1, [%l0 + CSA_STATE]
189
190 1:      ldx     [%l0 + CSA_TICK], %l1
191         brz     %l1, 1b
192          nop
193         wrpr    %l1, 0, %tick
194
195         rdpr    %ver, %l1
196         stx     %l1, [%l0 + CSA_VER]
197
198         srlx    %l1, VER_IMPL_SHIFT, %l1
199         sll     %l1, VER_IMPL_SIZE, %l1
200         srl     %l1, VER_IMPL_SIZE, %l1
201         cmp     %l1, CPU_IMPL_ULTRASPARCIII
202         bl      %icc, 3f
203          nop
204         mov     CPU_STICKSYNC, %l1
205         membar  #StoreLoad
206         stw     %l1, [%l0 + CSA_STATE]
207
208 2:      ldx     [%l0 + CSA_STICK], %l1
209         brz     %l1, 2b
210          nop
211         wr      %l1, 0, %asr24
212
213 3:      UPA_GET_MID(%o0)
214
215 #if KTR_COMPILE & KTR_SMP
216         CATR(KTR_SMP, "mp_start: CPU %d entered kernel"
217             , %g1, %g2, %g3, 7, 8, 9)
218         stx     %o0, [%g1 + KTR_PARM1]
219 9:
220 #endif
221
222         /*
223          * Inform the boot processor we have inited.
224          */
225         mov     CPU_INIT, %l1
226         membar  #LoadStore
227         stw     %l1, [%l0 + CSA_STATE]
228
229         /*
230          * Wait till its our turn to bootstrap.
231          */
232 4:      lduw    [%l0 + CSA_MID], %l1
233         cmp     %l1, %o0
234         bne     %xcc, 4b
235          nop
236
237 #if KTR_COMPILE & KTR_SMP
238         CATR(KTR_SMP, "_mp_start: CPU %d got start signal"
239             , %g1, %g2, %g3, 7, 8, 9)
240         stx     %o0, [%g1 + KTR_PARM1]
241 9:
242 #endif
243
244         add     %l0, CSA_TTES, %l1
245         clr     %l2
246
247         /*
248          * Map the per-CPU pages.
249          */
250 5:      sllx    %l2, TTE_SHIFT, %l3
251         add     %l1, %l3, %l3
252
253         ldx     [%l3 + TTE_VPN], %l4
254         ldx     [%l3 + TTE_DATA], %l5
255
256         wr      %g0, ASI_DMMU, %asi
257         srlx    %l4, TV_SIZE_BITS, %l4
258         sllx    %l4, PAGE_SHIFT_8K, %l4
259         stxa    %l4, [%g0 + AA_DMMU_TAR] %asi
260         stxa    %l5, [%g0] ASI_DTLB_DATA_IN_REG
261         membar  #Sync
262
263         add     %l2, 1, %l2
264         cmp     %l2, PCPU_PAGES
265         bne     %xcc, 5b
266          nop
267
268         /*
269          * Get onto our per-CPU panic stack, which precedes the struct pcpu
270          * in the per-CPU page.
271          */
272         ldx     [%l0 + CSA_PCPU], %l1
273         set     PCPU_PAGES * PAGE_SIZE - PC_SIZEOF, %l2
274         add     %l1, %l2, %l1
275         sub     %l1, SPOFF + CCFSZ, %sp
276
277         /*
278          * Enable interrupts.
279          */
280         wrpr    %g0, PSTATE_KERNEL, %pstate
281
282 #if KTR_COMPILE & KTR_SMP
283         CATR(KTR_SMP,
284             "_mp_start: bootstrap cpuid=%d mid=%d pcpu=%#lx data=%#lx sp=%#lx"
285             , %g1, %g2, %g3, 7, 8, 9)
286         lduw    [%l1 + PC_CPUID], %g2
287         stx     %g2, [%g1 + KTR_PARM1]
288         lduw    [%l1 + PC_MID], %g2
289         stx     %g2, [%g1 + KTR_PARM2]
290         stx     %l1, [%g1 + KTR_PARM3]
291         stx     %sp, [%g1 + KTR_PARM5]
292 9:
293 #endif
294
295         /*
296          * And away we go.  This doesn't return.
297          */
298         call    cpu_mp_bootstrap
299          mov    %l1, %o0
300         sir
301         ! NOTREACHED
302 END(mp_startup)