
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Some G3 CPUs can crash in funny way if a store from an FPU register
instruction is executed on a register that has never been initialized since
power on.  This patch fixes it by making sure all FP registers have been
properly initialized at kernel boot and when waking from sleep.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/arch/ppc/kernel/cpu_setup_6xx.S |   24 ++++++++++++++++++++++++
 25-akpm/arch/ppc/platforms/pmac_sleep.S |    4 ++++
 2 files changed, 28 insertions(+)

diff -puN arch/ppc/kernel/cpu_setup_6xx.S~ppc32-fix-errata-for-some-g3-cpus arch/ppc/kernel/cpu_setup_6xx.S
--- 25/arch/ppc/kernel/cpu_setup_6xx.S~ppc32-fix-errata-for-some-g3-cpus	2005-04-04 18:00:55.000000000 -0700
+++ 25-akpm/arch/ppc/kernel/cpu_setup_6xx.S	2005-04-04 18:00:55.000000000 -0700
@@ -30,12 +30,14 @@ _GLOBAL(__setup_cpu_604)
 	blr
 _GLOBAL(__setup_cpu_750)
 	mflr	r4
+	bl	__init_fpu_registers
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
 	mtlr	r4
 	blr
 _GLOBAL(__setup_cpu_750cx)
 	mflr	r4
+	bl	__init_fpu_registers
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
 	bl	setup_750cx
@@ -43,6 +45,7 @@ _GLOBAL(__setup_cpu_750cx)
 	blr
 _GLOBAL(__setup_cpu_750fx)
 	mflr	r4
+	bl	__init_fpu_registers
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
 	bl	setup_750fx
@@ -51,6 +54,7 @@ _GLOBAL(__setup_cpu_750fx)
 _GLOBAL(__setup_cpu_7400)
 	mflr	r4
 	bl	setup_7400_workarounds
+	bl	__init_fpu_registers
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
 	mtlr	r4
@@ -58,6 +62,7 @@ _GLOBAL(__setup_cpu_7400)
 _GLOBAL(__setup_cpu_7410)
 	mflr	r4
 	bl	setup_7410_workarounds
+	bl	__init_fpu_registers
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
 	li	r3,0
@@ -248,6 +253,25 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
 	isync
 	blr
 
+/*
+ * Initialize the FPU registers. This is needed to work around an errata
+ * in some 750 cpus where using a not yet initialized FPU register after
+ * power on reset may hang the CPU
+ */
+_GLOBAL(__init_fpu_registers)
+	mfmsr	r10
+	ori	r11,r10,MSR_FP
+	mtmsr	r11
+	isync
+	addis	r9,r3,empty_zero_page@ha
+	addi	r9,r9,empty_zero_page@l
+	REST_32FPRS(0,r9)
+	sync
+	mtmsr	r10
+	isync
+	blr
+
+
 /* Definitions for the table use to save CPU states */
 #define CS_HID0		0
 #define CS_HID1		4
diff -puN arch/ppc/platforms/pmac_sleep.S~ppc32-fix-errata-for-some-g3-cpus arch/ppc/platforms/pmac_sleep.S
--- 25/arch/ppc/platforms/pmac_sleep.S~ppc32-fix-errata-for-some-g3-cpus	2005-04-04 18:00:55.000000000 -0700
+++ 25-akpm/arch/ppc/platforms/pmac_sleep.S	2005-04-04 18:00:55.000000000 -0700
@@ -267,6 +267,10 @@ grackle_wake_up:
 	/* Restore various CPU config stuffs */
 	bl	__restore_cpu_setup
 
+	/* Make sure all FPRs have been initialized */
+	bl	reloc_offset
+	bl	__init_fpu_registers
+
 	/* Invalidate & enable L1 cache, we don't care about
 	 * whatever the ROM may have tried to write to memory
 	 */
_
