Commit | Line | Data |
---|---|---|
b00dc837 | 1 | /* |
1da177e4 LT |
2 | * trampoline.S: Jump start slave processors on sparc64. |
3 | * | |
4 | * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) | |
5 | */ | |
6 | ||
0f7f22d9 SR |
7 | #include <linux/init.h> |
8 | ||
1da177e4 LT |
9 | #include <asm/head.h> |
10 | #include <asm/asi.h> | |
11 | #include <asm/lsu.h> | |
12 | #include <asm/dcr.h> | |
13 | #include <asm/dcu.h> | |
14 | #include <asm/pstate.h> | |
15 | #include <asm/page.h> | |
16 | #include <asm/pgtable.h> | |
17 | #include <asm/spitfire.h> | |
18 | #include <asm/processor.h> | |
19 | #include <asm/thread_info.h> | |
20 | #include <asm/mmu.h> | |
d82ace7d | 21 | #include <asm/hypervisor.h> |
3af6e01e | 22 | #include <asm/cpudata.h> |
1da177e4 LT |
23 | |
24 | .data | |
25 | .align 8 | |
26 | call_method: | |
27 | .asciz "call-method" | |
28 | .align 8 | |
29 | itlb_load: | |
30 | .asciz "SUNW,itlb-load" | |
31 | .align 8 | |
32 | dtlb_load: | |
33 | .asciz "SUNW,dtlb-load" | |
34 | ||
72aff53f DM |
35 | /* XXX __cpuinit this thing XXX */ |
36 | #define TRAMP_STACK_SIZE 1024 | |
37 | .align 16 | |
38 | tramp_stack: | |
39 | .skip TRAMP_STACK_SIZE | |
40 | ||
0f7f22d9 | 41 | __CPUINIT |
1da177e4 LT |
42 | .align 8 |
43 | .globl sparc64_cpu_startup, sparc64_cpu_startup_end | |
44 | sparc64_cpu_startup: | |
d82ace7d DM |
45 | BRANCH_IF_SUN4V(g1, niagara_startup) |
46 | BRANCH_IF_CHEETAH_BASE(g1, g5, cheetah_startup) | |
47 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1, g5, cheetah_plus_startup) | |
1da177e4 LT |
48 | |
49 | ba,pt %xcc, spitfire_startup | |
50 | nop | |
51 | ||
52 | cheetah_plus_startup: | |
53 | /* Preserve OBP chosen DCU and DCR register settings. */ | |
54 | ba,pt %xcc, cheetah_generic_startup | |
55 | nop | |
56 | ||
57 | cheetah_startup: | |
58 | mov DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1 | |
59 | wr %g1, %asr18 | |
60 | ||
61 | sethi %uhi(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5 | |
62 | or %g5, %ulo(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5 | |
63 | sllx %g5, 32, %g5 | |
64 | or %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5 | |
65 | stxa %g5, [%g0] ASI_DCU_CONTROL_REG | |
66 | membar #Sync | |
72aff53f | 67 | /* fallthru */ |
1da177e4 LT |
68 | |
69 | cheetah_generic_startup: | |
70 | mov TSB_EXTENSION_P, %g3 | |
71 | stxa %g0, [%g3] ASI_DMMU | |
72 | stxa %g0, [%g3] ASI_IMMU | |
73 | membar #Sync | |
74 | ||
75 | mov TSB_EXTENSION_S, %g3 | |
76 | stxa %g0, [%g3] ASI_DMMU | |
77 | membar #Sync | |
78 | ||
79 | mov TSB_EXTENSION_N, %g3 | |
80 | stxa %g0, [%g3] ASI_DMMU | |
81 | stxa %g0, [%g3] ASI_IMMU | |
82 | membar #Sync | |
d82ace7d | 83 | /* fallthru */ |
1da177e4 | 84 | |
d82ace7d | 85 | niagara_startup: |
1da177e4 LT |
86 | /* Disable STICK_INT interrupts. */ |
87 | sethi %hi(0x80000000), %g5 | |
88 | sllx %g5, 32, %g5 | |
89 | wr %g5, %asr25 | |
90 | ||
91 | ba,pt %xcc, startup_continue | |
92 | nop | |
93 | ||
94 | spitfire_startup: | |
95 | mov (LSU_CONTROL_IC | LSU_CONTROL_DC | LSU_CONTROL_IM | LSU_CONTROL_DM), %g1 | |
96 | stxa %g1, [%g0] ASI_LSU_CONTROL | |
97 | membar #Sync | |
98 | ||
99 | startup_continue: | |
7dc40880 DM |
100 | mov %o0, %l0 |
101 | BRANCH_IF_SUN4V(g1, niagara_lock_tlb) | |
102 | ||
1da177e4 LT |
103 | sethi %hi(0x80000000), %g2 |
104 | sllx %g2, 32, %g2 | |
105 | wr %g2, 0, %tick_cmpr | |
106 | ||
107 | /* Call OBP by hand to lock KERNBASE into i/d tlbs. | |
64658743 | 108 | * We lock 'num_kernel_image_mappings' consequetive entries. |
1da177e4 | 109 | */ |
1da177e4 LT |
110 | sethi %hi(prom_entry_lock), %g2 |
111 | 1: ldstub [%g2 + %lo(prom_entry_lock)], %g1 | |
b445e26c | 112 | membar #StoreLoad | #StoreStore |
1da177e4 | 113 | brnz,pn %g1, 1b |
b445e26c | 114 | nop |
1da177e4 LT |
115 | |
116 | sethi %hi(p1275buf), %g2 | |
117 | or %g2, %lo(p1275buf), %g2 | |
118 | ldx [%g2 + 0x10], %l2 | |
1da177e4 LT |
119 | add %l2, -(192 + 128), %sp |
120 | flushw | |
121 | ||
64658743 DM |
122 | /* Setup the loop variables: |
123 | * %l3: VADDR base | |
124 | * %l4: TTE base | |
125 | * %l5: Loop iterator, iterates from 0 to 'num_kernel_image_mappings' | |
126 | * %l6: Number of TTE entries to map | |
127 | * %l7: Highest TTE entry number, we count down | |
128 | */ | |
129 | sethi %hi(KERNBASE), %l3 | |
130 | sethi %hi(kern_locked_tte_data), %l4 | |
131 | ldx [%l4 + %lo(kern_locked_tte_data)], %l4 | |
132 | clr %l5 | |
133 | sethi %hi(num_kernel_image_mappings), %l6 | |
134 | lduw [%l6 + %lo(num_kernel_image_mappings)], %l6 | |
135 | add %l6, 1, %l6 | |
136 | ||
137 | mov 15, %l7 | |
138 | BRANCH_IF_ANY_CHEETAH(g1,g5,2f) | |
139 | ||
140 | mov 63, %l7 | |
141 | 2: | |
142 | ||
143 | 3: | |
144 | /* Lock into I-MMU */ | |
1da177e4 LT |
145 | sethi %hi(call_method), %g2 |
146 | or %g2, %lo(call_method), %g2 | |
147 | stx %g2, [%sp + 2047 + 128 + 0x00] | |
148 | mov 5, %g2 | |
149 | stx %g2, [%sp + 2047 + 128 + 0x08] | |
150 | mov 1, %g2 | |
151 | stx %g2, [%sp + 2047 + 128 + 0x10] | |
152 | sethi %hi(itlb_load), %g2 | |
153 | or %g2, %lo(itlb_load), %g2 | |
154 | stx %g2, [%sp + 2047 + 128 + 0x18] | |
bff06d55 DM |
155 | sethi %hi(prom_mmu_ihandle_cache), %g2 |
156 | lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2 | |
1da177e4 | 157 | stx %g2, [%sp + 2047 + 128 + 0x20] |
1da177e4 | 158 | |
64658743 DM |
159 | /* Each TTE maps 4MB, convert index to offset. */ |
160 | sllx %l5, 22, %g1 | |
1da177e4 | 161 | |
64658743 DM |
162 | add %l3, %g1, %g2 |
163 | stx %g2, [%sp + 2047 + 128 + 0x28] ! VADDR | |
164 | add %l4, %g1, %g2 | |
165 | stx %g2, [%sp + 2047 + 128 + 0x30] ! TTE | |
1da177e4 | 166 | |
64658743 DM |
167 | /* TTE index is highest minus loop index. */ |
168 | sub %l7, %l5, %g2 | |
1da177e4 | 169 | stx %g2, [%sp + 2047 + 128 + 0x38] |
64658743 | 170 | |
1da177e4 LT |
171 | sethi %hi(p1275buf), %g2 |
172 | or %g2, %lo(p1275buf), %g2 | |
173 | ldx [%g2 + 0x08], %o1 | |
174 | call %o1 | |
175 | add %sp, (2047 + 128), %o0 | |
176 | ||
64658743 | 177 | /* Lock into D-MMU */ |
1da177e4 LT |
178 | sethi %hi(call_method), %g2 |
179 | or %g2, %lo(call_method), %g2 | |
180 | stx %g2, [%sp + 2047 + 128 + 0x00] | |
181 | mov 5, %g2 | |
182 | stx %g2, [%sp + 2047 + 128 + 0x08] | |
183 | mov 1, %g2 | |
184 | stx %g2, [%sp + 2047 + 128 + 0x10] | |
185 | sethi %hi(dtlb_load), %g2 | |
186 | or %g2, %lo(dtlb_load), %g2 | |
187 | stx %g2, [%sp + 2047 + 128 + 0x18] | |
bff06d55 DM |
188 | sethi %hi(prom_mmu_ihandle_cache), %g2 |
189 | lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2 | |
1da177e4 | 190 | stx %g2, [%sp + 2047 + 128 + 0x20] |
1da177e4 | 191 | |
64658743 DM |
192 | /* Each TTE maps 4MB, convert index to offset. */ |
193 | sllx %l5, 22, %g1 | |
1da177e4 | 194 | |
64658743 DM |
195 | add %l3, %g1, %g2 |
196 | stx %g2, [%sp + 2047 + 128 + 0x28] ! VADDR | |
197 | add %l4, %g1, %g2 | |
198 | stx %g2, [%sp + 2047 + 128 + 0x30] ! TTE | |
1da177e4 | 199 | |
64658743 DM |
200 | /* TTE index is highest minus loop index. */ |
201 | sub %l7, %l5, %g2 | |
1da177e4 | 202 | stx %g2, [%sp + 2047 + 128 + 0x38] |
64658743 | 203 | |
1da177e4 LT |
204 | sethi %hi(p1275buf), %g2 |
205 | or %g2, %lo(p1275buf), %g2 | |
206 | ldx [%g2 + 0x08], %o1 | |
207 | call %o1 | |
208 | add %sp, (2047 + 128), %o0 | |
209 | ||
64658743 DM |
210 | add %l5, 1, %l5 |
211 | cmp %l5, %l6 | |
212 | bne,pt %xcc, 3b | |
1da177e4 LT |
213 | nop |
214 | ||
1da177e4 LT |
215 | sethi %hi(prom_entry_lock), %g2 |
216 | stb %g0, [%g2 + %lo(prom_entry_lock)] | |
217 | membar #StoreStore | #StoreLoad | |
218 | ||
d82ace7d DM |
219 | ba,pt %xcc, after_lock_tlb |
220 | nop | |
221 | ||
222 | niagara_lock_tlb: | |
64658743 DM |
223 | sethi %hi(KERNBASE), %l3 |
224 | sethi %hi(kern_locked_tte_data), %l4 | |
225 | ldx [%l4 + %lo(kern_locked_tte_data)], %l4 | |
226 | clr %l5 | |
227 | sethi %hi(num_kernel_image_mappings), %l6 | |
228 | lduw [%l6 + %lo(num_kernel_image_mappings)], %l6 | |
229 | add %l6, 1, %l6 | |
230 | ||
231 | 1: | |
164c220f | 232 | mov HV_FAST_MMU_MAP_PERM_ADDR, %o5 |
64658743 DM |
233 | sllx %l5, 22, %g2 |
234 | add %l3, %g2, %o0 | |
164c220f | 235 | clr %o1 |
64658743 | 236 | add %l4, %g2, %o2 |
164c220f | 237 | mov HV_MMU_IMMU, %o3 |
d82ace7d DM |
238 | ta HV_FAST_TRAP |
239 | ||
164c220f | 240 | mov HV_FAST_MMU_MAP_PERM_ADDR, %o5 |
64658743 DM |
241 | sllx %l5, 22, %g2 |
242 | add %l3, %g2, %o0 | |
164c220f | 243 | clr %o1 |
64658743 | 244 | add %l4, %g2, %o2 |
164c220f | 245 | mov HV_MMU_DMMU, %o3 |
d82ace7d DM |
246 | ta HV_FAST_TRAP |
247 | ||
64658743 DM |
248 | add %l5, 1, %l5 |
249 | cmp %l5, %l6 | |
250 | bne,pt %xcc, 1b | |
d82ace7d DM |
251 | nop |
252 | ||
d82ace7d | 253 | after_lock_tlb: |
1da177e4 LT |
254 | wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate |
255 | wr %g0, 0, %fprs | |
256 | ||
1da177e4 LT |
257 | wr %g0, ASI_P, %asi |
258 | ||
259 | mov PRIMARY_CONTEXT, %g7 | |
8b11bd12 DM |
260 | |
261 | 661: stxa %g0, [%g7] ASI_DMMU | |
262 | .section .sun4v_1insn_patch, "ax" | |
263 | .word 661b | |
264 | stxa %g0, [%g7] ASI_MMU | |
265 | .previous | |
266 | ||
1da177e4 LT |
267 | membar #Sync |
268 | mov SECONDARY_CONTEXT, %g7 | |
8b11bd12 DM |
269 | |
270 | 661: stxa %g0, [%g7] ASI_DMMU | |
271 | .section .sun4v_1insn_patch, "ax" | |
272 | .word 661b | |
273 | stxa %g0, [%g7] ASI_MMU | |
274 | .previous | |
275 | ||
1da177e4 LT |
276 | membar #Sync |
277 | ||
72aff53f DM |
278 | /* Everything we do here, until we properly take over the |
279 | * trap table, must be done with extreme care. We cannot | |
280 | * make any references to %g6 (current thread pointer), | |
281 | * %g4 (current task pointer), or %g5 (base of current cpu's | |
282 | * per-cpu area) until we properly take over the trap table | |
283 | * from the firmware and hypervisor. | |
284 | * | |
285 | * Get onto temporary stack which is in the locked kernel image. | |
286 | */ | |
287 | sethi %hi(tramp_stack), %g1 | |
288 | or %g1, %lo(tramp_stack), %g1 | |
289 | add %g1, TRAMP_STACK_SIZE, %g1 | |
301feb65 | 290 | sub %g1, STACKFRAME_SZ + STACK_BIAS + 256, %sp |
1da177e4 LT |
291 | mov 0, %fp |
292 | ||
72aff53f DM |
293 | /* Put garbage in these registers to trap any access to them. */ |
294 | set 0xdeadbeef, %g4 | |
295 | set 0xdeadbeef, %g5 | |
296 | set 0xdeadbeef, %g6 | |
1da177e4 LT |
297 | |
298 | call init_irqwork_curcpu | |
299 | nop | |
ac29c11d DM |
300 | |
301 | sethi %hi(tlb_type), %g3 | |
302 | lduw [%g3 + %lo(tlb_type)], %g2 | |
303 | cmp %g2, 3 | |
304 | bne,pt %icc, 1f | |
305 | nop | |
306 | ||
72aff53f DM |
307 | call hard_smp_processor_id |
308 | nop | |
309 | ||
b434e719 DM |
310 | call sun4v_register_mondo_queues |
311 | nop | |
ac29c11d DM |
312 | |
313 | 1: call init_cur_cpu_trap | |
72aff53f | 314 | ldx [%l0], %o0 |
1da177e4 | 315 | |
0835ae0f | 316 | /* Start using proper page size encodings in ctx register. */ |
8b11bd12 DM |
317 | sethi %hi(sparc64_kern_pri_context), %g3 |
318 | ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2 | |
319 | mov PRIMARY_CONTEXT, %g1 | |
320 | ||
321 | 661: stxa %g2, [%g1] ASI_DMMU | |
322 | .section .sun4v_1insn_patch, "ax" | |
323 | .word 661b | |
324 | stxa %g2, [%g1] ASI_MMU | |
325 | .previous | |
326 | ||
327 | membar #Sync | |
1da177e4 | 328 | |
72aff53f DM |
329 | wrpr %g0, 0, %wstate |
330 | ||
e0037df3 AS |
331 | sethi %hi(prom_entry_lock), %g2 |
332 | 1: ldstub [%g2 + %lo(prom_entry_lock)], %g1 | |
333 | membar #StoreLoad | #StoreStore | |
334 | brnz,pn %g1, 1b | |
335 | nop | |
336 | ||
72aff53f DM |
337 | /* As a hack, put &init_thread_union into %g6. |
338 | * prom_world() loads from here to restore the %asi | |
339 | * register. | |
340 | */ | |
341 | sethi %hi(init_thread_union), %g6 | |
342 | or %g6, %lo(init_thread_union), %g6 | |
1da177e4 | 343 | |
12eaa328 DM |
344 | sethi %hi(is_sun4v), %o0 |
345 | lduw [%o0 + %lo(is_sun4v)], %o0 | |
e0037df3 | 346 | brz,pt %o0, 2f |
12eaa328 DM |
347 | nop |
348 | ||
349 | TRAP_LOAD_TRAP_BLOCK(%g2, %g3) | |
350 | add %g2, TRAP_PER_CPU_FAULT_INFO, %g2 | |
351 | stxa %g2, [%g0] ASI_SCRATCHPAD | |
352 | ||
353 | /* Compute physical address: | |
354 | * | |
355 | * paddr = kern_base + (mmfsa_vaddr - KERNBASE) | |
356 | */ | |
357 | sethi %hi(KERNBASE), %g3 | |
358 | sub %g2, %g3, %g2 | |
359 | sethi %hi(kern_base), %g3 | |
360 | ldx [%g3 + %lo(kern_base)], %g3 | |
361 | add %g2, %g3, %o1 | |
301feb65 | 362 | sethi %hi(sparc64_ttable_tl0), %o0 |
12eaa328 | 363 | |
301feb65 DM |
364 | set prom_set_trap_table_name, %g2 |
365 | stx %g2, [%sp + 2047 + 128 + 0x00] | |
366 | mov 2, %g2 | |
367 | stx %g2, [%sp + 2047 + 128 + 0x08] | |
368 | mov 0, %g2 | |
369 | stx %g2, [%sp + 2047 + 128 + 0x10] | |
370 | stx %o0, [%sp + 2047 + 128 + 0x18] | |
371 | stx %o1, [%sp + 2047 + 128 + 0x20] | |
372 | sethi %hi(p1275buf), %g2 | |
373 | or %g2, %lo(p1275buf), %g2 | |
374 | ldx [%g2 + 0x08], %o1 | |
375 | call %o1 | |
376 | add %sp, (2047 + 128), %o0 | |
12eaa328 | 377 | |
e0037df3 | 378 | ba,pt %xcc, 3f |
12eaa328 DM |
379 | nop |
380 | ||
e0037df3 | 381 | 2: sethi %hi(sparc64_ttable_tl0), %o0 |
301feb65 DM |
382 | set prom_set_trap_table_name, %g2 |
383 | stx %g2, [%sp + 2047 + 128 + 0x00] | |
384 | mov 1, %g2 | |
385 | stx %g2, [%sp + 2047 + 128 + 0x08] | |
386 | mov 0, %g2 | |
387 | stx %g2, [%sp + 2047 + 128 + 0x10] | |
388 | stx %o0, [%sp + 2047 + 128 + 0x18] | |
389 | sethi %hi(p1275buf), %g2 | |
390 | or %g2, %lo(p1275buf), %g2 | |
391 | ldx [%g2 + 0x08], %o1 | |
392 | call %o1 | |
393 | add %sp, (2047 + 128), %o0 | |
1da177e4 | 394 | |
e0037df3 AS |
395 | 3: sethi %hi(prom_entry_lock), %g2 |
396 | stb %g0, [%g2 + %lo(prom_entry_lock)] | |
397 | membar #StoreStore | #StoreLoad | |
398 | ||
399 | ldx [%l0], %g6 | |
72aff53f DM |
400 | ldx [%g6 + TI_TASK], %g4 |
401 | ||
402 | mov 1, %g5 | |
403 | sllx %g5, THREAD_SHIFT, %g5 | |
404 | sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5 | |
405 | add %g6, %g5, %sp | |
406 | mov 0, %fp | |
407 | ||
408 | rdpr %pstate, %o1 | |
409 | or %o1, PSTATE_IE, %o1 | |
410 | wrpr %o1, 0, %pstate | |
411 | ||
412 | call smp_callin | |
1da177e4 LT |
413 | nop |
414 | call cpu_idle | |
415 | mov 0, %o0 | |
416 | call cpu_panic | |
417 | nop | |
418 | 1: b,a,pt %xcc, 1b | |
419 | ||
420 | .align 8 | |
421 | sparc64_cpu_startup_end: |