aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2005-05-01 11:58:40 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-01 11:58:40 -0400
commitf1c55dea0bb2df94aa2b01b0871cb02f2e206676 (patch)
tree0bac72de98485c578bd0590daf4c7d9090660c6d
parentb207a290ea7dc83dba02e40b81cc8a29415a9c60 (diff)
[PATCH] ppc32: Fix errata for some G3 CPUs
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. It also makes the code that decides wether HID0_BTIC and HID0_DPM are allowed on a given CPU smarter (it can actually _clear_ them now if they are not allowed instead of just setting them when they are allowed in case the firmware got them wrong) Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/ppc/kernel/cpu_setup_6xx.S42
-rw-r--r--arch/ppc/platforms/pmac_sleep.S4
2 files changed, 40 insertions, 6 deletions
diff --git a/arch/ppc/kernel/cpu_setup_6xx.S b/arch/ppc/kernel/cpu_setup_6xx.S
index 74f781b486a3..468721d9ebd2 100644
--- a/arch/ppc/kernel/cpu_setup_6xx.S
+++ b/arch/ppc/kernel/cpu_setup_6xx.S
@@ -30,12 +30,14 @@ _GLOBAL(__setup_cpu_604)
30 blr 30 blr
31_GLOBAL(__setup_cpu_750) 31_GLOBAL(__setup_cpu_750)
32 mflr r4 32 mflr r4
33 bl __init_fpu_registers
33 bl setup_common_caches 34 bl setup_common_caches
34 bl setup_750_7400_hid0 35 bl setup_750_7400_hid0
35 mtlr r4 36 mtlr r4
36 blr 37 blr
37_GLOBAL(__setup_cpu_750cx) 38_GLOBAL(__setup_cpu_750cx)
38 mflr r4 39 mflr r4
40 bl __init_fpu_registers
39 bl setup_common_caches 41 bl setup_common_caches
40 bl setup_750_7400_hid0 42 bl setup_750_7400_hid0
41 bl setup_750cx 43 bl setup_750cx
@@ -43,6 +45,7 @@ _GLOBAL(__setup_cpu_750cx)
43 blr 45 blr
44_GLOBAL(__setup_cpu_750fx) 46_GLOBAL(__setup_cpu_750fx)
45 mflr r4 47 mflr r4
48 bl __init_fpu_registers
46 bl setup_common_caches 49 bl setup_common_caches
47 bl setup_750_7400_hid0 50 bl setup_750_7400_hid0
48 bl setup_750fx 51 bl setup_750fx
@@ -50,6 +53,7 @@ _GLOBAL(__setup_cpu_750fx)
50 blr 53 blr
51_GLOBAL(__setup_cpu_7400) 54_GLOBAL(__setup_cpu_7400)
52 mflr r4 55 mflr r4
56 bl __init_fpu_registers
53 bl setup_7400_workarounds 57 bl setup_7400_workarounds
54 bl setup_common_caches 58 bl setup_common_caches
55 bl setup_750_7400_hid0 59 bl setup_750_7400_hid0
@@ -57,6 +61,7 @@ _GLOBAL(__setup_cpu_7400)
57 blr 61 blr
58_GLOBAL(__setup_cpu_7410) 62_GLOBAL(__setup_cpu_7410)
59 mflr r4 63 mflr r4
64 bl __init_fpu_registers
60 bl setup_7410_workarounds 65 bl setup_7410_workarounds
61 bl setup_common_caches 66 bl setup_common_caches
62 bl setup_750_7400_hid0 67 bl setup_750_7400_hid0
@@ -80,7 +85,7 @@ setup_common_caches:
80 bne 1f /* don't invalidate the D-cache */ 85 bne 1f /* don't invalidate the D-cache */
81 ori r8,r8,HID0_DCI /* unless it wasn't enabled */ 86 ori r8,r8,HID0_DCI /* unless it wasn't enabled */
821: sync 871: sync
83 mtspr SPRN_HID0,r8 /* enable and invalidate caches */ 88 mtspr SPRN_HID0,r8 /* enable and invalidate caches */
84 sync 89 sync
85 mtspr SPRN_HID0,r11 /* enable caches */ 90 mtspr SPRN_HID0,r11 /* enable caches */
86 sync 91 sync
@@ -152,9 +157,13 @@ setup_7410_workarounds:
152setup_750_7400_hid0: 157setup_750_7400_hid0:
153 mfspr r11,SPRN_HID0 158 mfspr r11,SPRN_HID0
154 ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC 159 ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC
160 oris r11,r11,HID0_DPM@h
155BEGIN_FTR_SECTION 161BEGIN_FTR_SECTION
156 oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ 162 xori r11,r11,HID0_BTIC
157END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) 163END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC)
164BEGIN_FTR_SECTION
165 xoris r11,r11,HID0_DPM@h /* disable dynamic power mgmt */
166END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM)
158 li r3,HID0_SPD 167 li r3,HID0_SPD
159 andc r11,r11,r3 /* clear SPD: enable speculative */ 168 andc r11,r11,r3 /* clear SPD: enable speculative */
160 li r3,0 169 li r3,0
@@ -218,13 +227,15 @@ setup_745x_specifics:
218 227
219 /* All of the bits we have to set..... 228 /* All of the bits we have to set.....
220 */ 229 */
221 ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE | HID0_LRSTK | HID0_BTIC 230 ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE
231 ori r11,r11,HID0_LRSTK | HID0_BTIC
232 oris r11,r11,HID0_DPM@h
222BEGIN_FTR_SECTION 233BEGIN_FTR_SECTION
223 xori r11,r11,HID0_BTIC 234 xori r11,r11,HID0_BTIC
224END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC) 235END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC)
225BEGIN_FTR_SECTION 236BEGIN_FTR_SECTION
226 oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ 237 xoris r11,r11,HID0_DPM@h /* disable dynamic power mgmt */
227END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) 238END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM)
228 239
229 /* All of the bits we have to clear.... 240 /* All of the bits we have to clear....
230 */ 241 */
@@ -248,6 +259,25 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
248 isync 259 isync
249 blr 260 blr
250 261
262/*
263 * Initialize the FPU registers. This is needed to work around an errata
264 * in some 750 cpus where using a not yet initialized FPU register after
265 * power on reset may hang the CPU
266 */
267_GLOBAL(__init_fpu_registers)
268 mfmsr r10
269 ori r11,r10,MSR_FP
270 mtmsr r11
271 isync
272 addis r9,r3,empty_zero_page@ha
273 addi r9,r9,empty_zero_page@l
274 REST_32FPRS(0,r9)
275 sync
276 mtmsr r10
277 isync
278 blr
279
280
251/* Definitions for the table use to save CPU states */ 281/* Definitions for the table use to save CPU states */
252#define CS_HID0 0 282#define CS_HID0 0
253#define CS_HID1 4 283#define CS_HID1 4
diff --git a/arch/ppc/platforms/pmac_sleep.S b/arch/ppc/platforms/pmac_sleep.S
index 3139b6766ad3..f459ade1bd63 100644
--- a/arch/ppc/platforms/pmac_sleep.S
+++ b/arch/ppc/platforms/pmac_sleep.S
@@ -267,6 +267,10 @@ grackle_wake_up:
267 /* Restore various CPU config stuffs */ 267 /* Restore various CPU config stuffs */
268 bl __restore_cpu_setup 268 bl __restore_cpu_setup
269 269
270 /* Make sure all FPRs have been initialized */
271 bl reloc_offset
272 bl __init_fpu_registers
273
270 /* Invalidate & enable L1 cache, we don't care about 274 /* Invalidate & enable L1 cache, we don't care about
271 * whatever the ROM may have tried to write to memory 275 * whatever the ROM may have tried to write to memory
272 */ 276 */