]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/sparc64/sparc64/mp_locore.S
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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/intr_machdep.h>
34 #include <machine/ktr.h>
35 #include <machine/pstate.h>
36 #include <machine/smp.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, normal
48          * globals, windows flushed (cr = 0, cs = nwindows - 1), PIL_TICK and
49          * floating point disabled.
50          * Note that some firmware versions don't implement a clean window
51          * trap handler so we unfortunately can't clear the windows by setting
52          * %cleanwin to zero here.
53          */
54 1:      wrpr    %g0, PSTATE_NORMAL, %pstate
55         wrpr    %g0, PIL_TICK, %pil
56         wr      %g0, 0, %fprs
57
58         rdpr    %ver, %l7
59         srlx    %l7, VER_IMPL_SHIFT, %l7
60         sll     %l7, VER_IMPL_SIZE, %l7
61         srl     %l7, VER_IMPL_SIZE, %l7
62         cmp     %l7, CPU_IMPL_ULTRASPARCIIIp
63         bne     %icc, 3f
64          nop
65
66         /*
67          * Relocate the locked entry in it16 slot 0 (if existent)
68          * as part of working around Cheetah+ erratum 34.
69          */
70
71         setx    TD_V | TD_L, %l1, %l0
72         /*
73          * We read ASI_ITLB_DATA_ACCESS_REG twice in order to work
74          * around errata of USIII and beyond.
75          */
76         ldxa    [%g0] ASI_ITLB_DATA_ACCESS_REG, %g0
77         ldxa    [%g0] ASI_ITLB_DATA_ACCESS_REG, %l6
78         and     %l6, %l0, %l1
79         cmp     %l0, %l1
80         bne     %xcc, 3f
81          nop
82
83         /* Flush the mapping of slot 0. */
84         ldxa    [%g0] ASI_ITLB_TAG_READ_REG, %l5
85         srlx    %l5, TAR_VPN_SHIFT, %l0
86         sllx    %l0, TAR_VPN_SHIFT, %l0
87         or      %l0, TLB_DEMAP_PRIMARY | TLB_DEMAP_PAGE, %l0
88         stxa    %g0, [%l0] ASI_IMMU_DEMAP
89         /* The USIII-family ignores the address. */
90         flush   %g0
91
92         /*
93          * Search a replacement slot != 0 and enter the data and tag
94          * that formerly were in slot 0.
95          */
96         mov     (1 << TLB_DAR_SLOT_SHIFT), %l4
97         setx    TD_V, %l1, %l0
98         /*
99          * We read ASI_ITLB_DATA_ACCESS_REG twice in order to work
100          * around errata of USIII and beyond.
101          */
102 2:      ldxa    [%l4] ASI_ITLB_DATA_ACCESS_REG, %g0
103         ldxa    [%l4] ASI_ITLB_DATA_ACCESS_REG, %l1
104         and     %l1, %l0, %l1
105         cmp     %l0, %l1
106         be,a    %xcc, 2b
107          add    %l4, (1 << TLB_DAR_SLOT_SHIFT), %l4
108         wr      %g0, ASI_IMMU, %asi
109         stxa    %l5, [%g0 + AA_IMMU_TAR] %asi
110         stxa    %l6, [%l4] ASI_ITLB_DATA_ACCESS_REG
111         /* The USIII-family ignores the address. */
112         flush   %g0
113
114 3:      rd      %pc, %l6
115         ldx     [%l6 + (9f-3b)], %l1
116         add     %l6, (11f-3b), %l2
117         clr     %l3
118 4:      cmp     %l3, %l1
119         be      %xcc, 8f
120          nop
121         ldx     [%l2 + TTE_VPN], %l4
122         ldx     [%l2 + TTE_DATA], %l5
123         srlx    %l4, TV_SIZE_BITS, %l4
124         sllx    %l4, PAGE_SHIFT_4M, %l4
125         wr      %g0, ASI_DMMU, %asi
126         stxa    %l4, [%g0 + AA_DMMU_TAR] %asi
127         stxa    %l5, [%g0] ASI_DTLB_DATA_IN_REG
128         membar  #Sync
129
130         cmp     %l7, CPU_IMPL_ULTRASPARCIIIp
131         bne     %icc, 6f
132          wr     %g0, ASI_IMMU, %asi
133
134         /*
135          * Search an unused slot != 0 and explicitly enter the data
136          * and tag there in order to avoid Cheetah+ erratum 34.
137          */
138         mov     (1 << TLB_DAR_SLOT_SHIFT), %l0
139         setx    TD_V, %o1, %o0
140         /*
141          * We read ASI_ITLB_DATA_ACCESS_REG twice in order to work
142          * around errata of USIII and beyond.
143          */
144 5:      ldxa    [%l0] ASI_ITLB_DATA_ACCESS_REG, %g0
145         ldxa    [%l0] ASI_ITLB_DATA_ACCESS_REG, %o1
146         and     %o1, %o0, %o1
147         cmp     %o0, %o1
148         be,a    %xcc, 5b
149          add    %l0, (1 << TLB_DAR_SLOT_SHIFT), %l0
150         sethi   %hi(KERNBASE), %o0
151         stxa    %l4, [%g0 + AA_IMMU_TAR] %asi
152         stxa    %l5, [%l0] ASI_ITLB_DATA_ACCESS_REG
153         flush   %o0
154         ba      %xcc, 7f
155          nop
156
157 6:      sethi   %hi(KERNBASE), %l0
158         stxa    %l4, [%g0 + AA_IMMU_TAR] %asi
159         stxa    %l5, [%g0] ASI_ITLB_DATA_IN_REG
160         flush   %l0
161 7:      add     %l2, 1 << TTE_SHIFT, %l2
162         add     %l3, 1, %l3
163         ba      %xcc, 4b
164          nop
165 8:      ldx     [%l6 + (10f-3b)], %l1
166         jmpl    %l1, %g0
167          nop
168         _ALIGN_DATA
169 9:      .xword  0x0
170 10:     .xword  0x0
171 11:
172
173 DATA(mp_tramp_code)
174         .xword  1b
175 DATA(mp_tramp_code_len)
176         .xword  11b-1b
177 DATA(mp_tramp_tlb_slots)
178         .xword  9b-1b
179 DATA(mp_tramp_func)
180         .xword  10b-1b
181
182 /*
183  * void mp_startup(void)
184  */
185 ENTRY(mp_startup)
186         SET(cpu_start_args, %l1, %l0)
187
188         mov     CPU_TICKSYNC, %l1
189         membar  #StoreLoad
190         stw     %l1, [%l0 + CSA_STATE]
191
192 1:      ldx     [%l0 + CSA_TICK], %l1
193         brz     %l1, 1b
194          nop
195         wrpr    %l1, 0, %tick
196
197         rdpr    %ver, %l1
198         stx     %l1, [%l0 + CSA_VER]
199
200         srlx    %l1, VER_IMPL_SHIFT, %l1
201         sll     %l1, VER_IMPL_SIZE, %l1
202         srl     %l1, VER_IMPL_SIZE, %l1
203         cmp     %l1, CPU_IMPL_SPARC64V
204         bl      %icc, 4f
205          nop
206         cmp     %l1, CPU_IMPL_ULTRASPARCI
207         bl      %icc, 2f
208          nop
209         cmp     %l1, CPU_IMPL_ULTRASPARCIII
210         bl      %icc, 4f
211          nop
212 2:      mov     CPU_STICKSYNC, %l2
213         membar  #StoreLoad
214         stw     %l2, [%l0 + CSA_STATE]
215
216 3:      ldx     [%l0 + CSA_STICK], %l2
217         brz     %l2, 3b
218          nop
219         wr      %l2, 0, %asr24
220
221 4:      call    cpu_get_mid
222          mov    %l1, %o0
223
224         /*
225          * Inform the boot processor we have inited.
226          */
227         mov     CPU_INIT, %l1
228         membar  #LoadStore
229         stw     %l1, [%l0 + CSA_STATE]
230
231         /*
232          * Wait till its our turn to bootstrap.
233          */
234 5:      lduw    [%l0 + CSA_MID], %l1
235         cmp     %l1, %o0
236         bne     %xcc, 5b
237          nop
238
239         add     %l0, CSA_TTES, %l1
240         clr     %l2
241
242         /*
243          * Map the per-CPU pages.
244          */
245 6:      sllx    %l2, TTE_SHIFT, %l3
246         add     %l1, %l3, %l3
247
248         ldx     [%l3 + TTE_VPN], %l4
249         ldx     [%l3 + TTE_DATA], %l5
250
251         wr      %g0, ASI_DMMU, %asi
252         srlx    %l4, TV_SIZE_BITS, %l4
253         sllx    %l4, PAGE_SHIFT_8K, %l4
254         stxa    %l4, [%g0 + AA_DMMU_TAR] %asi
255         stxa    %l5, [%g0] ASI_DTLB_DATA_IN_REG
256         membar  #Sync
257
258         add     %l2, 1, %l2
259         cmp     %l2, PCPU_PAGES
260         bne     %xcc, 6b
261          nop
262
263         /*
264          * Get onto our per-CPU panic stack, which precedes the struct pcpu
265          * in the per-CPU page.
266          */
267         ldx     [%l0 + CSA_PCPU], %l1
268         set     PCPU_PAGES * PAGE_SIZE - PC_SIZEOF, %l2
269         add     %l1, %l2, %l1
270         sub     %l1, SPOFF + CCFSZ, %sp
271
272         /* Initialize global registers. */
273         call    cpu_setregs
274          mov    %l1, %o0
275
276 #if KTR_COMPILE & KTR_SMP
277         CATR(KTR_SMP,
278             "mp_startup: bootstrap cpuid=%d mid=%d pcpu=%#lx data=%#lx sp=%#lx"
279             , %g1, %g2, %g3, 7, 8, 9)
280         lduw    [PCPU(CPUID)], %g2
281         stx     %g2, [%g1 + KTR_PARM1]
282         lduw    [PCPU(MID)], %g2
283         stx     %g2, [%g1 + KTR_PARM2]
284         stx     %l1, [%g1 + KTR_PARM3]
285         stx     %sp, [%g1 + KTR_PARM5]
286 9:
287 #endif
288
289         /*
290          * And away we go.  This doesn't return.
291          */
292         call    cpu_mp_bootstrap
293          mov    %l1, %o0
294         sir
295         ! NOTREACHED
296 END(mp_startup)