[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);
 }