[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>
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index c4147ad..44b105c 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -632,11 +632,36 @@
/* Not reached... */
1:
+ /* If we boot on a non-zero cpu, all of the per-cpu
+ * variable references we make before setting up the
+ * per-cpu areas will use a bogus offset. Put a
+ * compensating factor into __per_cpu_base to handle
+ * this cleanly.
+ *
+ * What the per-cpu code calculates is:
+ *
+ * __per_cpu_base + (cpu << __per_cpu_shift)
+ *
+ * These two variables are zero initially, so to
+ * make it all cancel out to zero we need to put
+ * "0 - (cpu << 0)" into __per_cpu_base so that the
+ * above formula evaluates to zero.
+ *
+ * We cannot even perform a printk() until this stuff
+ * is setup as that calls cpu_clock() which uses
+ * per-cpu variables.
+ */
+ sub %g0, %o0, %o1
+ sethi %hi(__per_cpu_base), %o2
+ stx %o1, [%o2 + %lo(__per_cpu_base)]
#else
mov 0, %o0
#endif
sth %o0, [%g6 + TI_CPU]
+ call prom_init_report
+ nop
+
/* Off we go.... */
call start_kernel
nop
diff --git a/arch/sparc64/prom/init.c b/arch/sparc64/prom/init.c
index 1c0db84..87e7c7e 100644
--- a/arch/sparc64/prom/init.c
+++ b/arch/sparc64/prom/init.c
@@ -48,7 +48,10 @@
prom_getstring(node, "version", prom_version, sizeof(prom_version));
prom_printf("\n");
+}
+void __init prom_init_report(void)
+{
printk("PROMLIB: Sun IEEE Boot Prom '%s'\n", prom_version);
printk("PROMLIB: Root node compatible: %s\n", prom_root_compatible);
}