Commit ce22e1d39429c7de9f054ce8d03278dd2010b642
1 parent
488b5ec871
Exists in
master
and in
7 other branches
[SPARC64]: Fix booting on non-zero cpu.
The early per-cpu handling needs a slight tweak to work when booting on a non-zero cpu. We got away with this for a long time, but can't any longer as now even printk() calls functions (cpu_clock() for example) that thus make early references to per-cpu variables. Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 2 changed files with 28 additions and 0 deletions Side-by-side Diff
arch/sparc64/kernel/head.S
... | ... | @@ -632,10 +632,35 @@ |
632 | 632 | /* Not reached... */ |
633 | 633 | |
634 | 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 | 657 | #else |
636 | 658 | mov 0, %o0 |
637 | 659 | #endif |
638 | 660 | sth %o0, [%g6 + TI_CPU] |
661 | + | |
662 | + call prom_init_report | |
663 | + nop | |
639 | 664 | |
640 | 665 | /* Off we go.... */ |
641 | 666 | call start_kernel |
arch/sparc64/prom/init.c
... | ... | @@ -48,7 +48,10 @@ |
48 | 48 | prom_getstring(node, "version", prom_version, sizeof(prom_version)); |
49 | 49 | |
50 | 50 | prom_printf("\n"); |
51 | +} | |
51 | 52 | |
53 | +void __init prom_init_report(void) | |
54 | +{ | |
52 | 55 | printk("PROMLIB: Sun IEEE Boot Prom '%s'\n", prom_version); |
53 | 56 | printk("PROMLIB: Root node compatible: %s\n", prom_root_compatible); |
54 | 57 | } |