diff options
Diffstat (limited to 'arch/sparc64/kernel/trampoline.S')
-rw-r--r-- | arch/sparc64/kernel/trampoline.S | 238 |
1 files changed, 163 insertions, 75 deletions
diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S index 9478551cb020..a4dc01a3d238 100644 --- a/arch/sparc64/kernel/trampoline.S +++ b/arch/sparc64/kernel/trampoline.S | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <asm/processor.h> | 16 | #include <asm/processor.h> |
17 | #include <asm/thread_info.h> | 17 | #include <asm/thread_info.h> |
18 | #include <asm/mmu.h> | 18 | #include <asm/mmu.h> |
19 | #include <asm/hypervisor.h> | ||
20 | #include <asm/cpudata.h> | ||
19 | 21 | ||
20 | .data | 22 | .data |
21 | .align 8 | 23 | .align 8 |
@@ -28,14 +30,19 @@ itlb_load: | |||
28 | dtlb_load: | 30 | dtlb_load: |
29 | .asciz "SUNW,dtlb-load" | 31 | .asciz "SUNW,dtlb-load" |
30 | 32 | ||
33 | /* XXX __cpuinit this thing XXX */ | ||
34 | #define TRAMP_STACK_SIZE 1024 | ||
35 | .align 16 | ||
36 | tramp_stack: | ||
37 | .skip TRAMP_STACK_SIZE | ||
38 | |||
31 | .text | 39 | .text |
32 | .align 8 | 40 | .align 8 |
33 | .globl sparc64_cpu_startup, sparc64_cpu_startup_end | 41 | .globl sparc64_cpu_startup, sparc64_cpu_startup_end |
34 | sparc64_cpu_startup: | 42 | sparc64_cpu_startup: |
35 | flushw | 43 | BRANCH_IF_SUN4V(g1, niagara_startup) |
36 | 44 | BRANCH_IF_CHEETAH_BASE(g1, g5, cheetah_startup) | |
37 | BRANCH_IF_CHEETAH_BASE(g1,g5,cheetah_startup) | 45 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1, g5, cheetah_plus_startup) |
38 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g5,cheetah_plus_startup) | ||
39 | 46 | ||
40 | ba,pt %xcc, spitfire_startup | 47 | ba,pt %xcc, spitfire_startup |
41 | nop | 48 | nop |
@@ -55,6 +62,7 @@ cheetah_startup: | |||
55 | or %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5 | 62 | or %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5 |
56 | stxa %g5, [%g0] ASI_DCU_CONTROL_REG | 63 | stxa %g5, [%g0] ASI_DCU_CONTROL_REG |
57 | membar #Sync | 64 | membar #Sync |
65 | /* fallthru */ | ||
58 | 66 | ||
59 | cheetah_generic_startup: | 67 | cheetah_generic_startup: |
60 | mov TSB_EXTENSION_P, %g3 | 68 | mov TSB_EXTENSION_P, %g3 |
@@ -70,7 +78,9 @@ cheetah_generic_startup: | |||
70 | stxa %g0, [%g3] ASI_DMMU | 78 | stxa %g0, [%g3] ASI_DMMU |
71 | stxa %g0, [%g3] ASI_IMMU | 79 | stxa %g0, [%g3] ASI_IMMU |
72 | membar #Sync | 80 | membar #Sync |
81 | /* fallthru */ | ||
73 | 82 | ||
83 | niagara_startup: | ||
74 | /* Disable STICK_INT interrupts. */ | 84 | /* Disable STICK_INT interrupts. */ |
75 | sethi %hi(0x80000000), %g5 | 85 | sethi %hi(0x80000000), %g5 |
76 | sllx %g5, 32, %g5 | 86 | sllx %g5, 32, %g5 |
@@ -85,17 +95,17 @@ spitfire_startup: | |||
85 | membar #Sync | 95 | membar #Sync |
86 | 96 | ||
87 | startup_continue: | 97 | startup_continue: |
88 | wrpr %g0, 15, %pil | ||
89 | |||
90 | sethi %hi(0x80000000), %g2 | 98 | sethi %hi(0x80000000), %g2 |
91 | sllx %g2, 32, %g2 | 99 | sllx %g2, 32, %g2 |
92 | wr %g2, 0, %tick_cmpr | 100 | wr %g2, 0, %tick_cmpr |
93 | 101 | ||
102 | mov %o0, %l0 | ||
103 | |||
104 | BRANCH_IF_SUN4V(g1, niagara_lock_tlb) | ||
105 | |||
94 | /* Call OBP by hand to lock KERNBASE into i/d tlbs. | 106 | /* Call OBP by hand to lock KERNBASE into i/d tlbs. |
95 | * We lock 2 consequetive entries if we are 'bigkernel'. | 107 | * We lock 2 consequetive entries if we are 'bigkernel'. |
96 | */ | 108 | */ |
97 | mov %o0, %l0 | ||
98 | |||
99 | sethi %hi(prom_entry_lock), %g2 | 109 | sethi %hi(prom_entry_lock), %g2 |
100 | 1: ldstub [%g2 + %lo(prom_entry_lock)], %g1 | 110 | 1: ldstub [%g2 + %lo(prom_entry_lock)], %g1 |
101 | membar #StoreLoad | #StoreStore | 111 | membar #StoreLoad | #StoreStore |
@@ -105,7 +115,6 @@ startup_continue: | |||
105 | sethi %hi(p1275buf), %g2 | 115 | sethi %hi(p1275buf), %g2 |
106 | or %g2, %lo(p1275buf), %g2 | 116 | or %g2, %lo(p1275buf), %g2 |
107 | ldx [%g2 + 0x10], %l2 | 117 | ldx [%g2 + 0x10], %l2 |
108 | mov %sp, %l1 | ||
109 | add %l2, -(192 + 128), %sp | 118 | add %l2, -(192 + 128), %sp |
110 | flushw | 119 | flushw |
111 | 120 | ||
@@ -142,8 +151,7 @@ startup_continue: | |||
142 | 151 | ||
143 | sethi %hi(bigkernel), %g2 | 152 | sethi %hi(bigkernel), %g2 |
144 | lduw [%g2 + %lo(bigkernel)], %g2 | 153 | lduw [%g2 + %lo(bigkernel)], %g2 |
145 | cmp %g2, 0 | 154 | brz,pt %g2, do_dtlb |
146 | be,pt %icc, do_dtlb | ||
147 | nop | 155 | nop |
148 | 156 | ||
149 | sethi %hi(call_method), %g2 | 157 | sethi %hi(call_method), %g2 |
@@ -214,8 +222,7 @@ do_dtlb: | |||
214 | 222 | ||
215 | sethi %hi(bigkernel), %g2 | 223 | sethi %hi(bigkernel), %g2 |
216 | lduw [%g2 + %lo(bigkernel)], %g2 | 224 | lduw [%g2 + %lo(bigkernel)], %g2 |
217 | cmp %g2, 0 | 225 | brz,pt %g2, do_unlock |
218 | be,pt %icc, do_unlock | ||
219 | nop | 226 | nop |
220 | 227 | ||
221 | sethi %hi(call_method), %g2 | 228 | sethi %hi(call_method), %g2 |
@@ -257,99 +264,180 @@ do_unlock: | |||
257 | stb %g0, [%g2 + %lo(prom_entry_lock)] | 264 | stb %g0, [%g2 + %lo(prom_entry_lock)] |
258 | membar #StoreStore | #StoreLoad | 265 | membar #StoreStore | #StoreLoad |
259 | 266 | ||
260 | mov %l1, %sp | 267 | ba,pt %xcc, after_lock_tlb |
261 | flushw | 268 | nop |
269 | |||
270 | niagara_lock_tlb: | ||
271 | mov HV_FAST_MMU_MAP_PERM_ADDR, %o5 | ||
272 | sethi %hi(KERNBASE), %o0 | ||
273 | clr %o1 | ||
274 | sethi %hi(kern_locked_tte_data), %o2 | ||
275 | ldx [%o2 + %lo(kern_locked_tte_data)], %o2 | ||
276 | mov HV_MMU_IMMU, %o3 | ||
277 | ta HV_FAST_TRAP | ||
278 | |||
279 | mov HV_FAST_MMU_MAP_PERM_ADDR, %o5 | ||
280 | sethi %hi(KERNBASE), %o0 | ||
281 | clr %o1 | ||
282 | sethi %hi(kern_locked_tte_data), %o2 | ||
283 | ldx [%o2 + %lo(kern_locked_tte_data)], %o2 | ||
284 | mov HV_MMU_DMMU, %o3 | ||
285 | ta HV_FAST_TRAP | ||
262 | 286 | ||
263 | mov %l0, %o0 | 287 | sethi %hi(bigkernel), %g2 |
288 | lduw [%g2 + %lo(bigkernel)], %g2 | ||
289 | brz,pt %g2, after_lock_tlb | ||
290 | nop | ||
264 | 291 | ||
292 | mov HV_FAST_MMU_MAP_PERM_ADDR, %o5 | ||
293 | sethi %hi(KERNBASE + 0x400000), %o0 | ||
294 | clr %o1 | ||
295 | sethi %hi(kern_locked_tte_data), %o2 | ||
296 | ldx [%o2 + %lo(kern_locked_tte_data)], %o2 | ||
297 | sethi %hi(0x400000), %o3 | ||
298 | add %o2, %o3, %o2 | ||
299 | mov HV_MMU_IMMU, %o3 | ||
300 | ta HV_FAST_TRAP | ||
301 | |||
302 | mov HV_FAST_MMU_MAP_PERM_ADDR, %o5 | ||
303 | sethi %hi(KERNBASE + 0x400000), %o0 | ||
304 | clr %o1 | ||
305 | sethi %hi(kern_locked_tte_data), %o2 | ||
306 | ldx [%o2 + %lo(kern_locked_tte_data)], %o2 | ||
307 | sethi %hi(0x400000), %o3 | ||
308 | add %o2, %o3, %o2 | ||
309 | mov HV_MMU_DMMU, %o3 | ||
310 | ta HV_FAST_TRAP | ||
311 | |||
312 | after_lock_tlb: | ||
265 | wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate | 313 | wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate |
266 | wr %g0, 0, %fprs | 314 | wr %g0, 0, %fprs |
267 | 315 | ||
268 | /* XXX Buggy PROM... */ | ||
269 | srl %o0, 0, %o0 | ||
270 | ldx [%o0], %g6 | ||
271 | |||
272 | wr %g0, ASI_P, %asi | 316 | wr %g0, ASI_P, %asi |
273 | 317 | ||
274 | mov PRIMARY_CONTEXT, %g7 | 318 | mov PRIMARY_CONTEXT, %g7 |
275 | stxa %g0, [%g7] ASI_DMMU | 319 | |
320 | 661: stxa %g0, [%g7] ASI_DMMU | ||
321 | .section .sun4v_1insn_patch, "ax" | ||
322 | .word 661b | ||
323 | stxa %g0, [%g7] ASI_MMU | ||
324 | .previous | ||
325 | |||
276 | membar #Sync | 326 | membar #Sync |
277 | mov SECONDARY_CONTEXT, %g7 | 327 | mov SECONDARY_CONTEXT, %g7 |
278 | stxa %g0, [%g7] ASI_DMMU | 328 | |
329 | 661: stxa %g0, [%g7] ASI_DMMU | ||
330 | .section .sun4v_1insn_patch, "ax" | ||
331 | .word 661b | ||
332 | stxa %g0, [%g7] ASI_MMU | ||
333 | .previous | ||
334 | |||
279 | membar #Sync | 335 | membar #Sync |
280 | 336 | ||
281 | mov 1, %g5 | 337 | /* Everything we do here, until we properly take over the |
282 | sllx %g5, THREAD_SHIFT, %g5 | 338 | * trap table, must be done with extreme care. We cannot |
283 | sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5 | 339 | * make any references to %g6 (current thread pointer), |
284 | add %g6, %g5, %sp | 340 | * %g4 (current task pointer), or %g5 (base of current cpu's |
341 | * per-cpu area) until we properly take over the trap table | ||
342 | * from the firmware and hypervisor. | ||
343 | * | ||
344 | * Get onto temporary stack which is in the locked kernel image. | ||
345 | */ | ||
346 | sethi %hi(tramp_stack), %g1 | ||
347 | or %g1, %lo(tramp_stack), %g1 | ||
348 | add %g1, TRAMP_STACK_SIZE, %g1 | ||
349 | sub %g1, STACKFRAME_SZ + STACK_BIAS, %sp | ||
285 | mov 0, %fp | 350 | mov 0, %fp |
286 | 351 | ||
287 | wrpr %g0, 0, %wstate | 352 | /* Put garbage in these registers to trap any access to them. */ |
288 | wrpr %g0, 0, %tl | 353 | set 0xdeadbeef, %g4 |
354 | set 0xdeadbeef, %g5 | ||
355 | set 0xdeadbeef, %g6 | ||
289 | 356 | ||
290 | /* Setup the trap globals, then we can resurface. */ | 357 | call init_irqwork_curcpu |
291 | rdpr %pstate, %o1 | 358 | nop |
292 | mov %g6, %o2 | ||
293 | wrpr %o1, PSTATE_AG, %pstate | ||
294 | sethi %hi(sparc64_ttable_tl0), %g5 | ||
295 | wrpr %g5, %tba | ||
296 | mov %o2, %g6 | ||
297 | |||
298 | wrpr %o1, PSTATE_MG, %pstate | ||
299 | #define KERN_HIGHBITS ((_PAGE_VALID|_PAGE_SZ4MB)^0xfffff80000000000) | ||
300 | #define KERN_LOWBITS (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W) | ||
301 | |||
302 | mov TSB_REG, %g1 | ||
303 | stxa %g0, [%g1] ASI_DMMU | ||
304 | membar #Sync | ||
305 | mov TLB_SFSR, %g1 | ||
306 | sethi %uhi(KERN_HIGHBITS), %g2 | ||
307 | or %g2, %ulo(KERN_HIGHBITS), %g2 | ||
308 | sllx %g2, 32, %g2 | ||
309 | or %g2, KERN_LOWBITS, %g2 | ||
310 | 359 | ||
311 | BRANCH_IF_ANY_CHEETAH(g3,g7,9f) | 360 | sethi %hi(tlb_type), %g3 |
361 | lduw [%g3 + %lo(tlb_type)], %g2 | ||
362 | cmp %g2, 3 | ||
363 | bne,pt %icc, 1f | ||
364 | nop | ||
312 | 365 | ||
313 | ba,pt %xcc, 1f | 366 | call hard_smp_processor_id |
314 | nop | 367 | nop |
368 | |||
369 | mov %o0, %o1 | ||
370 | mov 0, %o0 | ||
371 | mov 0, %o2 | ||
372 | call sun4v_init_mondo_queues | ||
373 | mov 1, %o3 | ||
315 | 374 | ||
316 | 9: | 375 | 1: call init_cur_cpu_trap |
317 | sethi %uhi(VPTE_BASE_CHEETAH), %g3 | 376 | ldx [%l0], %o0 |
318 | or %g3, %ulo(VPTE_BASE_CHEETAH), %g3 | 377 | |
319 | ba,pt %xcc, 2f | 378 | /* Start using proper page size encodings in ctx register. */ |
320 | sllx %g3, 32, %g3 | 379 | sethi %hi(sparc64_kern_pri_context), %g3 |
321 | 1: | 380 | ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2 |
322 | sethi %uhi(VPTE_BASE_SPITFIRE), %g3 | 381 | mov PRIMARY_CONTEXT, %g1 |
323 | or %g3, %ulo(VPTE_BASE_SPITFIRE), %g3 | ||
324 | sllx %g3, 32, %g3 | ||
325 | 382 | ||
326 | 2: | 383 | 661: stxa %g2, [%g1] ASI_DMMU |
327 | clr %g7 | 384 | .section .sun4v_1insn_patch, "ax" |
328 | #undef KERN_HIGHBITS | 385 | .word 661b |
329 | #undef KERN_LOWBITS | 386 | stxa %g2, [%g1] ASI_MMU |
387 | .previous | ||
330 | 388 | ||
331 | wrpr %o1, 0x0, %pstate | 389 | membar #Sync |
332 | ldx [%g6 + TI_TASK], %g4 | ||
333 | 390 | ||
334 | wrpr %g0, 0, %wstate | 391 | wrpr %g0, 0, %wstate |
335 | 392 | ||
336 | call init_irqwork_curcpu | 393 | /* As a hack, put &init_thread_union into %g6. |
394 | * prom_world() loads from here to restore the %asi | ||
395 | * register. | ||
396 | */ | ||
397 | sethi %hi(init_thread_union), %g6 | ||
398 | or %g6, %lo(init_thread_union), %g6 | ||
399 | |||
400 | sethi %hi(is_sun4v), %o0 | ||
401 | lduw [%o0 + %lo(is_sun4v)], %o0 | ||
402 | brz,pt %o0, 1f | ||
337 | nop | 403 | nop |
338 | 404 | ||
339 | /* Start using proper page size encodings in ctx register. */ | 405 | TRAP_LOAD_TRAP_BLOCK(%g2, %g3) |
340 | sethi %hi(sparc64_kern_pri_context), %g3 | 406 | add %g2, TRAP_PER_CPU_FAULT_INFO, %g2 |
341 | ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2 | 407 | stxa %g2, [%g0] ASI_SCRATCHPAD |
342 | mov PRIMARY_CONTEXT, %g1 | 408 | |
343 | stxa %g2, [%g1] ASI_DMMU | 409 | /* Compute physical address: |
344 | membar #Sync | 410 | * |
411 | * paddr = kern_base + (mmfsa_vaddr - KERNBASE) | ||
412 | */ | ||
413 | sethi %hi(KERNBASE), %g3 | ||
414 | sub %g2, %g3, %g2 | ||
415 | sethi %hi(kern_base), %g3 | ||
416 | ldx [%g3 + %lo(kern_base)], %g3 | ||
417 | add %g2, %g3, %o1 | ||
418 | |||
419 | call prom_set_trap_table_sun4v | ||
420 | sethi %hi(sparc64_ttable_tl0), %o0 | ||
421 | |||
422 | ba,pt %xcc, 2f | ||
423 | nop | ||
424 | |||
425 | 1: call prom_set_trap_table | ||
426 | sethi %hi(sparc64_ttable_tl0), %o0 | ||
427 | |||
428 | 2: ldx [%l0], %g6 | ||
429 | ldx [%g6 + TI_TASK], %g4 | ||
430 | |||
431 | mov 1, %g5 | ||
432 | sllx %g5, THREAD_SHIFT, %g5 | ||
433 | sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5 | ||
434 | add %g6, %g5, %sp | ||
435 | mov 0, %fp | ||
345 | 436 | ||
346 | rdpr %pstate, %o1 | 437 | rdpr %pstate, %o1 |
347 | or %o1, PSTATE_IE, %o1 | 438 | or %o1, PSTATE_IE, %o1 |
348 | wrpr %o1, 0, %pstate | 439 | wrpr %o1, 0, %pstate |
349 | 440 | ||
350 | call prom_set_trap_table | ||
351 | sethi %hi(sparc64_ttable_tl0), %o0 | ||
352 | |||
353 | call smp_callin | 441 | call smp_callin |
354 | nop | 442 | nop |
355 | call cpu_idle | 443 | call cpu_idle |