1 /* $Id: trampoline.S,v 1.26 2002/02/09 19:49:30 davem Exp $
2 * trampoline.S: Jump start slave processors on sparc64.
4 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
12 #include <asm/pstate.h>
14 #include <asm/pgtable.h>
15 #include <asm/spitfire.h>
16 #include <asm/processor.h>
17 #include <asm/thread_info.h>
19 #include <asm/hypervisor.h>
27 .asciz "SUNW,itlb-load"
30 .asciz "SUNW,dtlb-load"
34 .globl sparc64_cpu_startup, sparc64_cpu_startup_end
38 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)
42 ba,pt %xcc, spitfire_startup
46 /* Preserve OBP chosen DCU and DCR register settings. */
47 ba,pt %xcc, cheetah_generic_startup
51 mov DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1
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
57 or %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5
58 stxa %g5, [%g0] ASI_DCU_CONTROL_REG
61 cheetah_generic_startup:
62 mov TSB_EXTENSION_P, %g3
63 stxa %g0, [%g3] ASI_DMMU
64 stxa %g0, [%g3] ASI_IMMU
67 mov TSB_EXTENSION_S, %g3
68 stxa %g0, [%g3] ASI_DMMU
71 mov TSB_EXTENSION_N, %g3
72 stxa %g0, [%g3] ASI_DMMU
73 stxa %g0, [%g3] ASI_IMMU
78 /* Disable STICK_INT interrupts. */
79 sethi %hi(0x80000000), %g5
83 ba,pt %xcc, startup_continue
87 mov (LSU_CONTROL_IC | LSU_CONTROL_DC | LSU_CONTROL_IM | LSU_CONTROL_DM), %g1
88 stxa %g1, [%g0] ASI_LSU_CONTROL
94 sethi %hi(0x80000000), %g2
98 BRANCH_IF_SUN4V(g1, niagara_lock_tlb)
100 /* Call OBP by hand to lock KERNBASE into i/d tlbs.
101 * We lock 2 consequetive entries if we are 'bigkernel'.
105 sethi %hi(prom_entry_lock), %g2
106 1: ldstub [%g2 + %lo(prom_entry_lock)], %g1
107 membar #StoreLoad | #StoreStore
111 sethi %hi(p1275buf), %g2
112 or %g2, %lo(p1275buf), %g2
113 ldx [%g2 + 0x10], %l2
115 add %l2, -(192 + 128), %sp
118 sethi %hi(call_method), %g2
119 or %g2, %lo(call_method), %g2
120 stx %g2, [%sp + 2047 + 128 + 0x00]
122 stx %g2, [%sp + 2047 + 128 + 0x08]
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]
128 sethi %hi(prom_mmu_ihandle_cache), %g2
129 lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
130 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]
138 BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
142 stx %g2, [%sp + 2047 + 128 + 0x38]
143 sethi %hi(p1275buf), %g2
144 or %g2, %lo(p1275buf), %g2
145 ldx [%g2 + 0x08], %o1
147 add %sp, (2047 + 128), %o0
149 sethi %hi(bigkernel), %g2
150 lduw [%g2 + %lo(bigkernel)], %g2
154 sethi %hi(call_method), %g2
155 or %g2, %lo(call_method), %g2
156 stx %g2, [%sp + 2047 + 128 + 0x00]
158 stx %g2, [%sp + 2047 + 128 + 0x08]
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]
164 sethi %hi(prom_mmu_ihandle_cache), %g2
165 lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
166 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
173 stx %g2, [%sp + 2047 + 128 + 0x30]
176 BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
180 stx %g2, [%sp + 2047 + 128 + 0x38]
181 sethi %hi(p1275buf), %g2
182 or %g2, %lo(p1275buf), %g2
183 ldx [%g2 + 0x08], %o1
185 add %sp, (2047 + 128), %o0
188 sethi %hi(call_method), %g2
189 or %g2, %lo(call_method), %g2
190 stx %g2, [%sp + 2047 + 128 + 0x00]
192 stx %g2, [%sp + 2047 + 128 + 0x08]
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]
198 sethi %hi(prom_mmu_ihandle_cache), %g2
199 lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
200 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]
208 BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
213 stx %g2, [%sp + 2047 + 128 + 0x38]
214 sethi %hi(p1275buf), %g2
215 or %g2, %lo(p1275buf), %g2
216 ldx [%g2 + 0x08], %o1
218 add %sp, (2047 + 128), %o0
220 sethi %hi(bigkernel), %g2
221 lduw [%g2 + %lo(bigkernel)], %g2
222 brz,pt %g2, do_unlock
225 sethi %hi(call_method), %g2
226 or %g2, %lo(call_method), %g2
227 stx %g2, [%sp + 2047 + 128 + 0x00]
229 stx %g2, [%sp + 2047 + 128 + 0x08]
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]
235 sethi %hi(prom_mmu_ihandle_cache), %g2
236 lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
237 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
244 stx %g2, [%sp + 2047 + 128 + 0x30]
247 BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
252 stx %g2, [%sp + 2047 + 128 + 0x38]
253 sethi %hi(p1275buf), %g2
254 or %g2, %lo(p1275buf), %g2
255 ldx [%g2 + 0x08], %o1
257 add %sp, (2047 + 128), %o0
260 sethi %hi(prom_entry_lock), %g2
261 stb %g0, [%g2 + %lo(prom_entry_lock)]
262 membar #StoreStore | #StoreLoad
264 ba,pt %xcc, after_lock_tlb
268 mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
269 sethi %hi(KERNBASE), %o0
271 sethi %hi(kern_locked_tte_data), %o2
272 ldx [%o2 + %lo(kern_locked_tte_data)], %o2
276 mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
277 sethi %hi(KERNBASE), %o0
279 sethi %hi(kern_locked_tte_data), %o2
280 ldx [%o2 + %lo(kern_locked_tte_data)], %o2
284 sethi %hi(bigkernel), %g2
285 lduw [%g2 + %lo(bigkernel)], %g2
286 brz,pt %g2, after_lock_tlb
289 mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
290 sethi %hi(KERNBASE + 0x400000), %o0
292 sethi %hi(kern_locked_tte_data), %o2
293 ldx [%o2 + %lo(kern_locked_tte_data)], %o2
294 sethi %hi(0x400000), %o3
299 mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
300 sethi %hi(KERNBASE + 0x400000), %o0
302 sethi %hi(kern_locked_tte_data), %o2
303 ldx [%o2 + %lo(kern_locked_tte_data)], %o2
304 sethi %hi(0x400000), %o3
315 wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate
318 /* XXX Buggy PROM... */
324 mov PRIMARY_CONTEXT, %g7
326 661: stxa %g0, [%g7] ASI_DMMU
327 .section .sun4v_1insn_patch, "ax"
329 stxa %g0, [%g7] ASI_MMU
333 mov SECONDARY_CONTEXT, %g7
335 661: stxa %g0, [%g7] ASI_DMMU
336 .section .sun4v_1insn_patch, "ax"
338 stxa %g0, [%g7] ASI_MMU
344 sllx %g5, THREAD_SHIFT, %g5
345 sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5
352 /* Load TBA, then we can resurface. */
353 sethi %hi(sparc64_ttable_tl0), %g5
356 ldx [%g6 + TI_TASK], %g4
360 call init_irqwork_curcpu
363 sethi %hi(tlb_type), %g3
364 lduw [%g3 + %lo(tlb_type)], %g2
369 call sun4v_init_mondo_queues
372 1: call init_cur_cpu_trap
375 /* Start using proper page size encodings in ctx register. */
376 sethi %hi(sparc64_kern_pri_context), %g3
377 ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2
378 mov PRIMARY_CONTEXT, %g1
380 661: stxa %g2, [%g1] ASI_DMMU
381 .section .sun4v_1insn_patch, "ax"
383 stxa %g2, [%g1] ASI_MMU
389 or %o1, PSTATE_IE, %o1
392 sethi %hi(is_sun4v), %o0
393 lduw [%o0 + %lo(is_sun4v)], %o0
397 TRAP_LOAD_TRAP_BLOCK(%g2, %g3)
398 add %g2, TRAP_PER_CPU_FAULT_INFO, %g2
399 stxa %g2, [%g0] ASI_SCRATCHPAD
401 /* Compute physical address:
403 * paddr = kern_base + (mmfsa_vaddr - KERNBASE)
405 sethi %hi(KERNBASE), %g3
407 sethi %hi(kern_base), %g3
408 ldx [%g3 + %lo(kern_base)], %g3
411 call prom_set_trap_table_sun4v
412 sethi %hi(sparc64_ttable_tl0), %o0
417 1: call prom_set_trap_table
418 sethi %hi(sparc64_ttable_tl0), %o0
429 sparc64_cpu_startup_end: