aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-02-07 05:14:48 -0500
committerDavid S. Miller <davem@davemloft.net>2008-02-07 05:58:40 -0500
commitce22e1d39429c7de9f054ce8d03278dd2010b642 (patch)
treeaf47d57927d7b8595d1b252f9bad2535a3c50d5d /arch/sparc64
parent488b5ec871191359b9b79262a3d48456dae7ea5f (diff)
[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>
Diffstat (limited to 'arch/sparc64')
-rw-r--r--arch/sparc64/kernel/head.S25
-rw-r--r--arch/sparc64/prom/init.c3
2 files changed, 28 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
6341: 6341:
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
diff --git a/arch/sparc64/prom/init.c b/arch/sparc64/prom/init.c
index 1c0db842a6f4..87e7c7ea0ee6 100644
--- a/arch/sparc64/prom/init.c
+++ b/arch/sparc64/prom/init.c
@@ -48,7 +48,10 @@ void __init prom_init(void *cif_handler, void *cif_stack)
48 prom_getstring(node, "version", prom_version, sizeof(prom_version)); 48 prom_getstring(node, "version", prom_version, sizeof(prom_version));
49 49
50 prom_printf("\n"); 50 prom_printf("\n");
51}
51 52
53void __init prom_init_report(void)
54{
52 printk("PROMLIB: Sun IEEE Boot Prom '%s'\n", prom_version); 55 printk("PROMLIB: Sun IEEE Boot Prom '%s'\n", prom_version);
53 printk("PROMLIB: Root node compatible: %s\n", prom_root_compatible); 56 printk("PROMLIB: Root node compatible: %s\n", prom_root_compatible);
54} 57}