diff options
Diffstat (limited to 'arch/sparc64/kernel/trampoline.S')
-rw-r--r-- | arch/sparc64/kernel/trampoline.S | 92 |
1 files changed, 56 insertions, 36 deletions
diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S index b9c9f54b0a00..a4dc01a3d238 100644 --- a/arch/sparc64/kernel/trampoline.S +++ b/arch/sparc64/kernel/trampoline.S | |||
@@ -30,12 +30,16 @@ itlb_load: | |||
30 | dtlb_load: | 30 | dtlb_load: |
31 | .asciz "SUNW,dtlb-load" | 31 | .asciz "SUNW,dtlb-load" |
32 | 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 | |||
33 | .text | 39 | .text |
34 | .align 8 | 40 | .align 8 |
35 | .globl sparc64_cpu_startup, sparc64_cpu_startup_end | 41 | .globl sparc64_cpu_startup, sparc64_cpu_startup_end |
36 | sparc64_cpu_startup: | 42 | sparc64_cpu_startup: |
37 | flushw | ||
38 | |||
39 | BRANCH_IF_SUN4V(g1, niagara_startup) | 43 | BRANCH_IF_SUN4V(g1, niagara_startup) |
40 | BRANCH_IF_CHEETAH_BASE(g1, g5, cheetah_startup) | 44 | BRANCH_IF_CHEETAH_BASE(g1, g5, cheetah_startup) |
41 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1, g5, cheetah_plus_startup) | 45 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1, g5, cheetah_plus_startup) |
@@ -58,6 +62,7 @@ cheetah_startup: | |||
58 | or %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5 | 62 | or %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5 |
59 | stxa %g5, [%g0] ASI_DCU_CONTROL_REG | 63 | stxa %g5, [%g0] ASI_DCU_CONTROL_REG |
60 | membar #Sync | 64 | membar #Sync |
65 | /* fallthru */ | ||
61 | 66 | ||
62 | cheetah_generic_startup: | 67 | cheetah_generic_startup: |
63 | mov TSB_EXTENSION_P, %g3 | 68 | mov TSB_EXTENSION_P, %g3 |
@@ -90,19 +95,17 @@ spitfire_startup: | |||
90 | membar #Sync | 95 | membar #Sync |
91 | 96 | ||
92 | startup_continue: | 97 | startup_continue: |
93 | wrpr %g0, 15, %pil | ||
94 | |||
95 | sethi %hi(0x80000000), %g2 | 98 | sethi %hi(0x80000000), %g2 |
96 | sllx %g2, 32, %g2 | 99 | sllx %g2, 32, %g2 |
97 | wr %g2, 0, %tick_cmpr | 100 | wr %g2, 0, %tick_cmpr |
98 | 101 | ||
102 | mov %o0, %l0 | ||
103 | |||
99 | BRANCH_IF_SUN4V(g1, niagara_lock_tlb) | 104 | BRANCH_IF_SUN4V(g1, niagara_lock_tlb) |
100 | 105 | ||
101 | /* Call OBP by hand to lock KERNBASE into i/d tlbs. | 106 | /* Call OBP by hand to lock KERNBASE into i/d tlbs. |
102 | * We lock 2 consequetive entries if we are 'bigkernel'. | 107 | * We lock 2 consequetive entries if we are 'bigkernel'. |
103 | */ | 108 | */ |
104 | mov %o0, %l0 | ||
105 | |||
106 | sethi %hi(prom_entry_lock), %g2 | 109 | sethi %hi(prom_entry_lock), %g2 |
107 | 1: ldstub [%g2 + %lo(prom_entry_lock)], %g1 | 110 | 1: ldstub [%g2 + %lo(prom_entry_lock)], %g1 |
108 | membar #StoreLoad | #StoreStore | 111 | membar #StoreLoad | #StoreStore |
@@ -112,7 +115,6 @@ startup_continue: | |||
112 | sethi %hi(p1275buf), %g2 | 115 | sethi %hi(p1275buf), %g2 |
113 | or %g2, %lo(p1275buf), %g2 | 116 | or %g2, %lo(p1275buf), %g2 |
114 | ldx [%g2 + 0x10], %l2 | 117 | ldx [%g2 + 0x10], %l2 |
115 | mov %sp, %l1 | ||
116 | add %l2, -(192 + 128), %sp | 118 | add %l2, -(192 + 128), %sp |
117 | flushw | 119 | flushw |
118 | 120 | ||
@@ -308,18 +310,9 @@ niagara_lock_tlb: | |||
308 | ta HV_FAST_TRAP | 310 | ta HV_FAST_TRAP |
309 | 311 | ||
310 | after_lock_tlb: | 312 | after_lock_tlb: |
311 | mov %l1, %sp | ||
312 | flushw | ||
313 | |||
314 | mov %l0, %o0 | ||
315 | |||
316 | wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate | 313 | wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate |
317 | wr %g0, 0, %fprs | 314 | wr %g0, 0, %fprs |
318 | 315 | ||
319 | /* XXX Buggy PROM... */ | ||
320 | srl %o0, 0, %o0 | ||
321 | ldx [%o0], %g6 | ||
322 | |||
323 | wr %g0, ASI_P, %asi | 316 | wr %g0, ASI_P, %asi |
324 | 317 | ||
325 | mov PRIMARY_CONTEXT, %g7 | 318 | mov PRIMARY_CONTEXT, %g7 |
@@ -341,22 +334,25 @@ after_lock_tlb: | |||
341 | 334 | ||
342 | membar #Sync | 335 | membar #Sync |
343 | 336 | ||
344 | mov 1, %g5 | 337 | /* Everything we do here, until we properly take over the |
345 | sllx %g5, THREAD_SHIFT, %g5 | 338 | * trap table, must be done with extreme care. We cannot |
346 | sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5 | 339 | * make any references to %g6 (current thread pointer), |
347 | 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 | ||
348 | mov 0, %fp | 350 | mov 0, %fp |
349 | 351 | ||
350 | wrpr %g0, 0, %wstate | 352 | /* Put garbage in these registers to trap any access to them. */ |
351 | wrpr %g0, 0, %tl | 353 | set 0xdeadbeef, %g4 |
352 | 354 | set 0xdeadbeef, %g5 | |
353 | /* Load TBA, then we can resurface. */ | 355 | set 0xdeadbeef, %g6 |
354 | sethi %hi(sparc64_ttable_tl0), %g5 | ||
355 | wrpr %g5, %tba | ||
356 | |||
357 | ldx [%g6 + TI_TASK], %g4 | ||
358 | |||
359 | wrpr %g0, 0, %wstate | ||
360 | 356 | ||
361 | call init_irqwork_curcpu | 357 | call init_irqwork_curcpu |
362 | nop | 358 | nop |
@@ -367,11 +363,17 @@ after_lock_tlb: | |||
367 | bne,pt %icc, 1f | 363 | bne,pt %icc, 1f |
368 | nop | 364 | nop |
369 | 365 | ||
366 | call hard_smp_processor_id | ||
367 | nop | ||
368 | |||
369 | mov %o0, %o1 | ||
370 | mov 0, %o0 | ||
371 | mov 0, %o2 | ||
370 | call sun4v_init_mondo_queues | 372 | call sun4v_init_mondo_queues |
371 | mov 0, %o0 | 373 | mov 1, %o3 |
372 | 374 | ||
373 | 1: call init_cur_cpu_trap | 375 | 1: call init_cur_cpu_trap |
374 | nop | 376 | ldx [%l0], %o0 |
375 | 377 | ||
376 | /* Start using proper page size encodings in ctx register. */ | 378 | /* Start using proper page size encodings in ctx register. */ |
377 | sethi %hi(sparc64_kern_pri_context), %g3 | 379 | sethi %hi(sparc64_kern_pri_context), %g3 |
@@ -386,9 +388,14 @@ after_lock_tlb: | |||
386 | 388 | ||
387 | membar #Sync | 389 | membar #Sync |
388 | 390 | ||
389 | rdpr %pstate, %o1 | 391 | wrpr %g0, 0, %wstate |
390 | or %o1, PSTATE_IE, %o1 | 392 | |
391 | wrpr %o1, 0, %pstate | 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 | ||
392 | 399 | ||
393 | sethi %hi(is_sun4v), %o0 | 400 | sethi %hi(is_sun4v), %o0 |
394 | lduw [%o0 + %lo(is_sun4v)], %o0 | 401 | lduw [%o0 + %lo(is_sun4v)], %o0 |
@@ -418,7 +425,20 @@ after_lock_tlb: | |||
418 | 1: call prom_set_trap_table | 425 | 1: call prom_set_trap_table |
419 | sethi %hi(sparc64_ttable_tl0), %o0 | 426 | sethi %hi(sparc64_ttable_tl0), %o0 |
420 | 427 | ||
421 | 2: call smp_callin | 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 | ||
436 | |||
437 | rdpr %pstate, %o1 | ||
438 | or %o1, PSTATE_IE, %o1 | ||
439 | wrpr %o1, 0, %pstate | ||
440 | |||
441 | call smp_callin | ||
422 | nop | 442 | nop |
423 | call cpu_idle | 443 | call cpu_idle |
424 | mov 0, %o0 | 444 | mov 0, %o0 |