diff options
Diffstat (limited to 'arch/sparc64/kernel/head.S')
-rw-r--r-- | arch/sparc64/kernel/head.S | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index c4147ad8677b..44b105c04dd3 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S | |||
@@ -632,11 +632,36 @@ tlb_fixup_done: | |||
632 | /* Not reached... */ | 632 | /* Not reached... */ |
633 | 633 | ||
634 | 1: | 634 | 1: |
635 | /* If we boot on a non-zero cpu, all of the per-cpu | ||
636 | * variable references we make before setting up the | ||
637 | * per-cpu areas will use a bogus offset. Put a | ||
638 | * compensating factor into __per_cpu_base to handle | ||
639 | * this cleanly. | ||
640 | * | ||
641 | * What the per-cpu code calculates is: | ||
642 | * | ||
643 | * __per_cpu_base + (cpu << __per_cpu_shift) | ||
644 | * | ||
645 | * These two variables are zero initially, so to | ||
646 | * make it all cancel out to zero we need to put | ||
647 | * "0 - (cpu << 0)" into __per_cpu_base so that the | ||
648 | * above formula evaluates to zero. | ||
649 | * | ||
650 | * We cannot even perform a printk() until this stuff | ||
651 | * is setup as that calls cpu_clock() which uses | ||
652 | * per-cpu variables. | ||
653 | */ | ||
654 | sub %g0, %o0, %o1 | ||
655 | sethi %hi(__per_cpu_base), %o2 | ||
656 | stx %o1, [%o2 + %lo(__per_cpu_base)] | ||
635 | #else | 657 | #else |
636 | mov 0, %o0 | 658 | mov 0, %o0 |
637 | #endif | 659 | #endif |
638 | sth %o0, [%g6 + TI_CPU] | 660 | sth %o0, [%g6 + TI_CPU] |
639 | 661 | ||
662 | call prom_init_report | ||
663 | nop | ||
664 | |||
640 | /* Off we go.... */ | 665 | /* Off we go.... */ |
641 | call start_kernel | 666 | call start_kernel |
642 | nop | 667 | nop |