blob: 88382200c7b870125e194f2cd25e6e90d17b00a0 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* $Id: trampoline.S,v 1.26 2002/02/09 19:49:30 davem Exp $
2 * trampoline.S: Jump start slave processors on sparc64.
3 *
4 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
5 */
6
7#include <asm/head.h>
8#include <asm/asi.h>
9#include <asm/lsu.h>
10#include <asm/dcr.h>
11#include <asm/dcu.h>
12#include <asm/pstate.h>
13#include <asm/page.h>
14#include <asm/pgtable.h>
15#include <asm/spitfire.h>
16#include <asm/processor.h>
17#include <asm/thread_info.h>
18#include <asm/mmu.h>
David S. Millerd82ace72006-02-09 02:52:44 -080019#include <asm/hypervisor.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020
21 .data
22 .align 8
23call_method:
24 .asciz "call-method"
25 .align 8
26itlb_load:
27 .asciz "SUNW,itlb-load"
28 .align 8
29dtlb_load:
30 .asciz "SUNW,dtlb-load"
31
32 .text
33 .align 8
34 .globl sparc64_cpu_startup, sparc64_cpu_startup_end
35sparc64_cpu_startup:
36 flushw
37
David S. Millerd82ace72006-02-09 02:52:44 -080038 BRANCH_IF_SUN4V(g1, niagara_startup)
39 BRANCH_IF_CHEETAH_BASE(g1, g5, cheetah_startup)
40 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1, g5, cheetah_plus_startup)
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
42 ba,pt %xcc, spitfire_startup
43 nop
44
45cheetah_plus_startup:
46 /* Preserve OBP chosen DCU and DCR register settings. */
47 ba,pt %xcc, cheetah_generic_startup
48 nop
49
50cheetah_startup:
51 mov DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1
52 wr %g1, %asr18
53
54 sethi %uhi(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
55 or %g5, %ulo(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
56 sllx %g5, 32, %g5
57 or %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5
58 stxa %g5, [%g0] ASI_DCU_CONTROL_REG
59 membar #Sync
60
61cheetah_generic_startup:
62 mov TSB_EXTENSION_P, %g3
63 stxa %g0, [%g3] ASI_DMMU
64 stxa %g0, [%g3] ASI_IMMU
65 membar #Sync
66
67 mov TSB_EXTENSION_S, %g3
68 stxa %g0, [%g3] ASI_DMMU
69 membar #Sync
70
71 mov TSB_EXTENSION_N, %g3
72 stxa %g0, [%g3] ASI_DMMU
73 stxa %g0, [%g3] ASI_IMMU
74 membar #Sync
David S. Millerd82ace72006-02-09 02:52:44 -080075 /* fallthru */
Linus Torvalds1da177e2005-04-16 15:20:36 -070076
David S. Millerd82ace72006-02-09 02:52:44 -080077niagara_startup:
Linus Torvalds1da177e2005-04-16 15:20:36 -070078 /* Disable STICK_INT interrupts. */
79 sethi %hi(0x80000000), %g5
80 sllx %g5, 32, %g5
81 wr %g5, %asr25
82
83 ba,pt %xcc, startup_continue
84 nop
85
86spitfire_startup:
87 mov (LSU_CONTROL_IC | LSU_CONTROL_DC | LSU_CONTROL_IM | LSU_CONTROL_DM), %g1
88 stxa %g1, [%g0] ASI_LSU_CONTROL
89 membar #Sync
90
91startup_continue:
92 wrpr %g0, 15, %pil
93
94 sethi %hi(0x80000000), %g2
95 sllx %g2, 32, %g2
96 wr %g2, 0, %tick_cmpr
97
David S. Millerd82ace72006-02-09 02:52:44 -080098 BRANCH_IF_SUN4V(g1, niagara_lock_tlb)
99
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100 /* Call OBP by hand to lock KERNBASE into i/d tlbs.
101 * We lock 2 consequetive entries if we are 'bigkernel'.
102 */
103 mov %o0, %l0
104
105 sethi %hi(prom_entry_lock), %g2
1061: ldstub [%g2 + %lo(prom_entry_lock)], %g1
David S. Millerb445e262005-06-27 15:42:04 -0700107 membar #StoreLoad | #StoreStore
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 brnz,pn %g1, 1b
David S. Millerb445e262005-06-27 15:42:04 -0700109 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110
111 sethi %hi(p1275buf), %g2
112 or %g2, %lo(p1275buf), %g2
113 ldx [%g2 + 0x10], %l2
114 mov %sp, %l1
115 add %l2, -(192 + 128), %sp
116 flushw
117
118 sethi %hi(call_method), %g2
119 or %g2, %lo(call_method), %g2
120 stx %g2, [%sp + 2047 + 128 + 0x00]
121 mov 5, %g2
122 stx %g2, [%sp + 2047 + 128 + 0x08]
123 mov 1, %g2
124 stx %g2, [%sp + 2047 + 128 + 0x10]
125 sethi %hi(itlb_load), %g2
126 or %g2, %lo(itlb_load), %g2
127 stx %g2, [%sp + 2047 + 128 + 0x18]
David S. Millerbff06d52005-09-22 20:11:33 -0700128 sethi %hi(prom_mmu_ihandle_cache), %g2
129 lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 stx %g2, [%sp + 2047 + 128 + 0x20]
131 sethi %hi(KERNBASE), %g2
132 stx %g2, [%sp + 2047 + 128 + 0x28]
133 sethi %hi(kern_locked_tte_data), %g2
134 ldx [%g2 + %lo(kern_locked_tte_data)], %g2
135 stx %g2, [%sp + 2047 + 128 + 0x30]
136
137 mov 15, %g2
138 BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
139
140 mov 63, %g2
1411:
142 stx %g2, [%sp + 2047 + 128 + 0x38]
143 sethi %hi(p1275buf), %g2
144 or %g2, %lo(p1275buf), %g2
145 ldx [%g2 + 0x08], %o1
146 call %o1
147 add %sp, (2047 + 128), %o0
148
149 sethi %hi(bigkernel), %g2
150 lduw [%g2 + %lo(bigkernel)], %g2
David S. Millerd82ace72006-02-09 02:52:44 -0800151 brz,pt %g2, do_dtlb
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152 nop
153
154 sethi %hi(call_method), %g2
155 or %g2, %lo(call_method), %g2
156 stx %g2, [%sp + 2047 + 128 + 0x00]
157 mov 5, %g2
158 stx %g2, [%sp + 2047 + 128 + 0x08]
159 mov 1, %g2
160 stx %g2, [%sp + 2047 + 128 + 0x10]
161 sethi %hi(itlb_load), %g2
162 or %g2, %lo(itlb_load), %g2
163 stx %g2, [%sp + 2047 + 128 + 0x18]
David S. Millerbff06d52005-09-22 20:11:33 -0700164 sethi %hi(prom_mmu_ihandle_cache), %g2
165 lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 stx %g2, [%sp + 2047 + 128 + 0x20]
167 sethi %hi(KERNBASE + 0x400000), %g2
168 stx %g2, [%sp + 2047 + 128 + 0x28]
169 sethi %hi(kern_locked_tte_data), %g2
170 ldx [%g2 + %lo(kern_locked_tte_data)], %g2
171 sethi %hi(0x400000), %g1
172 add %g2, %g1, %g2
173 stx %g2, [%sp + 2047 + 128 + 0x30]
174
175 mov 14, %g2
176 BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
177
178 mov 62, %g2
1791:
180 stx %g2, [%sp + 2047 + 128 + 0x38]
181 sethi %hi(p1275buf), %g2
182 or %g2, %lo(p1275buf), %g2
183 ldx [%g2 + 0x08], %o1
184 call %o1
185 add %sp, (2047 + 128), %o0
186
187do_dtlb:
188 sethi %hi(call_method), %g2
189 or %g2, %lo(call_method), %g2
190 stx %g2, [%sp + 2047 + 128 + 0x00]
191 mov 5, %g2
192 stx %g2, [%sp + 2047 + 128 + 0x08]
193 mov 1, %g2
194 stx %g2, [%sp + 2047 + 128 + 0x10]
195 sethi %hi(dtlb_load), %g2
196 or %g2, %lo(dtlb_load), %g2
197 stx %g2, [%sp + 2047 + 128 + 0x18]
David S. Millerbff06d52005-09-22 20:11:33 -0700198 sethi %hi(prom_mmu_ihandle_cache), %g2
199 lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200 stx %g2, [%sp + 2047 + 128 + 0x20]
201 sethi %hi(KERNBASE), %g2
202 stx %g2, [%sp + 2047 + 128 + 0x28]
203 sethi %hi(kern_locked_tte_data), %g2
204 ldx [%g2 + %lo(kern_locked_tte_data)], %g2
205 stx %g2, [%sp + 2047 + 128 + 0x30]
206
207 mov 15, %g2
208 BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
209
210 mov 63, %g2
2111:
212
213 stx %g2, [%sp + 2047 + 128 + 0x38]
214 sethi %hi(p1275buf), %g2
215 or %g2, %lo(p1275buf), %g2
216 ldx [%g2 + 0x08], %o1
217 call %o1
218 add %sp, (2047 + 128), %o0
219
220 sethi %hi(bigkernel), %g2
221 lduw [%g2 + %lo(bigkernel)], %g2
David S. Millerd82ace72006-02-09 02:52:44 -0800222 brz,pt %g2, do_unlock
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223 nop
224
225 sethi %hi(call_method), %g2
226 or %g2, %lo(call_method), %g2
227 stx %g2, [%sp + 2047 + 128 + 0x00]
228 mov 5, %g2
229 stx %g2, [%sp + 2047 + 128 + 0x08]
230 mov 1, %g2
231 stx %g2, [%sp + 2047 + 128 + 0x10]
232 sethi %hi(dtlb_load), %g2
233 or %g2, %lo(dtlb_load), %g2
234 stx %g2, [%sp + 2047 + 128 + 0x18]
David S. Millerbff06d52005-09-22 20:11:33 -0700235 sethi %hi(prom_mmu_ihandle_cache), %g2
236 lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 stx %g2, [%sp + 2047 + 128 + 0x20]
238 sethi %hi(KERNBASE + 0x400000), %g2
239 stx %g2, [%sp + 2047 + 128 + 0x28]
240 sethi %hi(kern_locked_tte_data), %g2
241 ldx [%g2 + %lo(kern_locked_tte_data)], %g2
242 sethi %hi(0x400000), %g1
243 add %g2, %g1, %g2
244 stx %g2, [%sp + 2047 + 128 + 0x30]
245
246 mov 14, %g2
247 BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
248
249 mov 62, %g2
2501:
251
252 stx %g2, [%sp + 2047 + 128 + 0x38]
253 sethi %hi(p1275buf), %g2
254 or %g2, %lo(p1275buf), %g2
255 ldx [%g2 + 0x08], %o1
256 call %o1
257 add %sp, (2047 + 128), %o0
258
259do_unlock:
260 sethi %hi(prom_entry_lock), %g2
261 stb %g0, [%g2 + %lo(prom_entry_lock)]
262 membar #StoreStore | #StoreLoad
263
David S. Millerd82ace72006-02-09 02:52:44 -0800264 ba,pt %xcc, after_lock_tlb
265 nop
266
267niagara_lock_tlb:
David S. Miller164c2202006-02-09 22:57:21 -0800268 mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
269 sethi %hi(KERNBASE), %o0
270 clr %o1
271 sethi %hi(kern_locked_tte_data), %o2
272 ldx [%o2 + %lo(kern_locked_tte_data)], %o2
273 mov HV_MMU_IMMU, %o3
David S. Millerd82ace72006-02-09 02:52:44 -0800274 ta HV_FAST_TRAP
275
David S. Miller164c2202006-02-09 22:57:21 -0800276 mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
277 sethi %hi(KERNBASE), %o0
278 clr %o1
279 sethi %hi(kern_locked_tte_data), %o2
280 ldx [%o2 + %lo(kern_locked_tte_data)], %o2
281 mov HV_MMU_DMMU, %o3
David S. Millerd82ace72006-02-09 02:52:44 -0800282 ta HV_FAST_TRAP
283
284 sethi %hi(bigkernel), %g2
285 lduw [%g2 + %lo(bigkernel)], %g2
286 brz,pt %g2, after_lock_tlb
287 nop
288
David S. Miller164c2202006-02-09 22:57:21 -0800289 mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
290 sethi %hi(KERNBASE + 0x400000), %o0
291 clr %o1
292 sethi %hi(kern_locked_tte_data), %o2
293 ldx [%o2 + %lo(kern_locked_tte_data)], %o2
294 sethi %hi(0x400000), %o3
295 add %o2, %o3, %o2
296 mov HV_MMU_IMMU, %o3
David S. Millerd82ace72006-02-09 02:52:44 -0800297 ta HV_FAST_TRAP
298
David S. Miller164c2202006-02-09 22:57:21 -0800299 mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
300 sethi %hi(KERNBASE + 0x400000), %o0
301 clr %o1
302 sethi %hi(kern_locked_tte_data), %o2
303 ldx [%o2 + %lo(kern_locked_tte_data)], %o2
304 sethi %hi(0x400000), %o3
305 add %o2, %o3, %o2
306 mov HV_MMU_DMMU, %o3
David S. Millerd82ace72006-02-09 02:52:44 -0800307 ta HV_FAST_TRAP
308
309after_lock_tlb:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310 mov %l1, %sp
311 flushw
312
313 mov %l0, %o0
314
315 wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate
316 wr %g0, 0, %fprs
317
318 /* XXX Buggy PROM... */
319 srl %o0, 0, %o0
320 ldx [%o0], %g6
321
322 wr %g0, ASI_P, %asi
323
324 mov PRIMARY_CONTEXT, %g7
David S. Miller8b11bd12006-02-07 22:13:05 -0800325
326661: stxa %g0, [%g7] ASI_DMMU
327 .section .sun4v_1insn_patch, "ax"
328 .word 661b
329 stxa %g0, [%g7] ASI_MMU
330 .previous
331
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 membar #Sync
333 mov SECONDARY_CONTEXT, %g7
David S. Miller8b11bd12006-02-07 22:13:05 -0800334
335661: stxa %g0, [%g7] ASI_DMMU
336 .section .sun4v_1insn_patch, "ax"
337 .word 661b
338 stxa %g0, [%g7] ASI_MMU
339 .previous
340
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 membar #Sync
342
343 mov 1, %g5
344 sllx %g5, THREAD_SHIFT, %g5
345 sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5
346 add %g6, %g5, %sp
347 mov 0, %fp
348
349 wrpr %g0, 0, %wstate
350 wrpr %g0, 0, %tl
351
David S. Miller56fb4df2006-02-26 23:24:22 -0800352 /* Load TBA, then we can resurface. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353 sethi %hi(sparc64_ttable_tl0), %g5
354 wrpr %g5, %tba
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 ldx [%g6 + TI_TASK], %g4
357
358 wrpr %g0, 0, %wstate
359
360 call init_irqwork_curcpu
361 nop
David S. Millerac29c112006-02-08 00:08:23 -0800362
363 sethi %hi(tlb_type), %g3
364 lduw [%g3 + %lo(tlb_type)], %g2
365 cmp %g2, 3
366 bne,pt %icc, 1f
367 nop
368
369 call sun4v_init_mondo_queues
370 nop
371
3721: call init_cur_cpu_trap
David S. Miller56fb4df2006-02-26 23:24:22 -0800373 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374
David S. Miller0835ae02005-10-04 15:23:20 -0700375 /* Start using proper page size encodings in ctx register. */
David S. Miller8b11bd12006-02-07 22:13:05 -0800376 sethi %hi(sparc64_kern_pri_context), %g3
377 ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2
378 mov PRIMARY_CONTEXT, %g1
379
380661: stxa %g2, [%g1] ASI_DMMU
381 .section .sun4v_1insn_patch, "ax"
382 .word 661b
383 stxa %g2, [%g1] ASI_MMU
384 .previous
385
386 membar #Sync
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 rdpr %pstate, %o1
389 or %o1, PSTATE_IE, %o1
390 wrpr %o1, 0, %pstate
391
David S. Miller12eaa322006-02-10 15:39:51 -0800392 sethi %hi(is_sun4v), %o0
393 lduw [%o0 + %lo(is_sun4v)], %o0
394 brz,pt %o0, 1f
395 nop
396
397 TRAP_LOAD_TRAP_BLOCK(%g2, %g3)
398 add %g2, TRAP_PER_CPU_FAULT_INFO, %g2
399 stxa %g2, [%g0] ASI_SCRATCHPAD
400
401 /* Compute physical address:
402 *
403 * paddr = kern_base + (mmfsa_vaddr - KERNBASE)
404 */
405 sethi %hi(KERNBASE), %g3
406 sub %g2, %g3, %g2
407 sethi %hi(kern_base), %g3
408 ldx [%g3 + %lo(kern_base)], %g3
409 add %g2, %g3, %o1
410
411 call prom_set_trap_table_sun4v
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412 sethi %hi(sparc64_ttable_tl0), %o0
413
David S. Miller12eaa322006-02-10 15:39:51 -0800414 ba,pt %xcc, 2f
415 nop
416
4171: call prom_set_trap_table
418 sethi %hi(sparc64_ttable_tl0), %o0
419
4202: call smp_callin
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 nop
422 call cpu_idle
423 mov 0, %o0
424 call cpu_panic
425 nop
4261: b,a,pt %xcc, 1b
427
428 .align 8
429sparc64_cpu_startup_end: