Commit f1c55dea authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Linus Torvalds

[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: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent b207a290
...@@ -30,12 +30,14 @@ _GLOBAL(__setup_cpu_604) ...@@ -30,12 +30,14 @@ _GLOBAL(__setup_cpu_604)
blr blr
_GLOBAL(__setup_cpu_750) _GLOBAL(__setup_cpu_750)
mflr r4 mflr r4
bl __init_fpu_registers
bl setup_common_caches bl setup_common_caches
bl setup_750_7400_hid0 bl setup_750_7400_hid0
mtlr r4 mtlr r4
blr blr
_GLOBAL(__setup_cpu_750cx) _GLOBAL(__setup_cpu_750cx)
mflr r4 mflr r4
bl __init_fpu_registers
bl setup_common_caches bl setup_common_caches
bl setup_750_7400_hid0 bl setup_750_7400_hid0
bl setup_750cx bl setup_750cx
...@@ -43,6 +45,7 @@ _GLOBAL(__setup_cpu_750cx) ...@@ -43,6 +45,7 @@ _GLOBAL(__setup_cpu_750cx)
blr blr
_GLOBAL(__setup_cpu_750fx) _GLOBAL(__setup_cpu_750fx)
mflr r4 mflr r4
bl __init_fpu_registers
bl setup_common_caches bl setup_common_caches
bl setup_750_7400_hid0 bl setup_750_7400_hid0
bl setup_750fx bl setup_750fx
...@@ -50,6 +53,7 @@ _GLOBAL(__setup_cpu_750fx) ...@@ -50,6 +53,7 @@ _GLOBAL(__setup_cpu_750fx)
blr blr
_GLOBAL(__setup_cpu_7400) _GLOBAL(__setup_cpu_7400)
mflr r4 mflr r4
bl __init_fpu_registers
bl setup_7400_workarounds bl setup_7400_workarounds
bl setup_common_caches bl setup_common_caches
bl setup_750_7400_hid0 bl setup_750_7400_hid0
...@@ -57,6 +61,7 @@ _GLOBAL(__setup_cpu_7400) ...@@ -57,6 +61,7 @@ _GLOBAL(__setup_cpu_7400)
blr blr
_GLOBAL(__setup_cpu_7410) _GLOBAL(__setup_cpu_7410)
mflr r4 mflr r4
bl __init_fpu_registers
bl setup_7410_workarounds bl setup_7410_workarounds
bl setup_common_caches bl setup_common_caches
bl setup_750_7400_hid0 bl setup_750_7400_hid0
...@@ -80,7 +85,7 @@ setup_common_caches: ...@@ -80,7 +85,7 @@ setup_common_caches:
bne 1f /* don't invalidate the D-cache */ bne 1f /* don't invalidate the D-cache */
ori r8,r8,HID0_DCI /* unless it wasn't enabled */ ori r8,r8,HID0_DCI /* unless it wasn't enabled */
1: sync 1: sync
mtspr SPRN_HID0,r8 /* enable and invalidate caches */ mtspr SPRN_HID0,r8 /* enable and invalidate caches */
sync sync
mtspr SPRN_HID0,r11 /* enable caches */ mtspr SPRN_HID0,r11 /* enable caches */
sync sync
...@@ -152,9 +157,13 @@ setup_7410_workarounds: ...@@ -152,9 +157,13 @@ setup_7410_workarounds:
setup_750_7400_hid0: setup_750_7400_hid0:
mfspr r11,SPRN_HID0 mfspr r11,SPRN_HID0
ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC
oris r11,r11,HID0_DPM@h
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ xori r11,r11,HID0_BTIC
END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC)
BEGIN_FTR_SECTION
xoris r11,r11,HID0_DPM@h /* disable dynamic power mgmt */
END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM)
li r3,HID0_SPD li r3,HID0_SPD
andc r11,r11,r3 /* clear SPD: enable speculative */ andc r11,r11,r3 /* clear SPD: enable speculative */
li r3,0 li r3,0
...@@ -218,13 +227,15 @@ setup_745x_specifics: ...@@ -218,13 +227,15 @@ setup_745x_specifics:
/* All of the bits we have to set..... /* All of the bits we have to set.....
*/ */
ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE | HID0_LRSTK | HID0_BTIC ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE
ori r11,r11,HID0_LRSTK | HID0_BTIC
oris r11,r11,HID0_DPM@h
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
xori r11,r11,HID0_BTIC xori r11,r11,HID0_BTIC
END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC) END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ xoris r11,r11,HID0_DPM@h /* disable dynamic power mgmt */
END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM)
/* All of the bits we have to clear.... /* All of the bits we have to clear....
*/ */
...@@ -248,6 +259,25 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) ...@@ -248,6 +259,25 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
isync isync
blr 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 */ /* Definitions for the table use to save CPU states */
#define CS_HID0 0 #define CS_HID0 0
#define CS_HID1 4 #define CS_HID1 4
......
...@@ -267,6 +267,10 @@ grackle_wake_up: ...@@ -267,6 +267,10 @@ grackle_wake_up:
/* Restore various CPU config stuffs */ /* Restore various CPU config stuffs */
bl __restore_cpu_setup 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 /* Invalidate & enable L1 cache, we don't care about
* whatever the ROM may have tried to write to memory * whatever the ROM may have tried to write to memory
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment