aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2009-03-18 23:55:41 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-03-23 22:47:32 -0400
commit2319f1239592d0de80414ad2338c2bd7384a2a41 (patch)
tree805de041dfc84ae9ca767c9767d833977654dbe0 /arch/powerpc/kernel
parenteb3436a0139a651a39dbb37a75b10a2cccd00ad5 (diff)
powerpc/mm: e300c2/c3/c4 TLB errata workaround
Complete workaround for DTLB errata in e300c2/c3/c4 processors. Due to the bug, the hardware-implemented LRU algorythm always goes to way 1 of the TLB. This fix implements the proposed software workaround in form of a LRW table for chosing the TLB-way. Based on patch from David Jander <david@protonic.nl> Signed-off-by: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/cpu_setup_6xx.S5
-rw-r--r--arch/powerpc/kernel/cputable.c9
-rw-r--r--arch/powerpc/kernel/head_32.S32
3 files changed, 39 insertions, 7 deletions
diff --git a/arch/powerpc/kernel/cpu_setup_6xx.S b/arch/powerpc/kernel/cpu_setup_6xx.S
index 72d1d739525..54f767e31a1 100644
--- a/arch/powerpc/kernel/cpu_setup_6xx.S
+++ b/arch/powerpc/kernel/cpu_setup_6xx.S
@@ -15,9 +15,14 @@
15#include <asm/ppc_asm.h> 15#include <asm/ppc_asm.h>
16#include <asm/asm-offsets.h> 16#include <asm/asm-offsets.h>
17#include <asm/cache.h> 17#include <asm/cache.h>
18#include <asm/mmu.h>
18 19
19_GLOBAL(__setup_cpu_603) 20_GLOBAL(__setup_cpu_603)
20 mflr r4 21 mflr r4
22BEGIN_MMU_FTR_SECTION
23 li r10,0
24 mtspr SPRN_SPRG4,r10 /* init SW LRU tracking */
25END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
21BEGIN_FTR_SECTION 26BEGIN_FTR_SECTION
22 bl __init_fpu_registers 27 bl __init_fpu_registers
23END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE) 28END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE)
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index ccea2431ddf..cd1b687544f 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -1090,7 +1090,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
1090 .cpu_name = "e300c2", 1090 .cpu_name = "e300c2",
1091 .cpu_features = CPU_FTRS_E300C2, 1091 .cpu_features = CPU_FTRS_E300C2,
1092 .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, 1092 .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
1093 .mmu_features = MMU_FTR_USE_HIGH_BATS, 1093 .mmu_features = MMU_FTR_USE_HIGH_BATS |
1094 MMU_FTR_NEED_DTLB_SW_LRU,
1094 .icache_bsize = 32, 1095 .icache_bsize = 32,
1095 .dcache_bsize = 32, 1096 .dcache_bsize = 32,
1096 .cpu_setup = __setup_cpu_603, 1097 .cpu_setup = __setup_cpu_603,
@@ -1103,7 +1104,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
1103 .cpu_name = "e300c3", 1104 .cpu_name = "e300c3",
1104 .cpu_features = CPU_FTRS_E300, 1105 .cpu_features = CPU_FTRS_E300,
1105 .cpu_user_features = COMMON_USER, 1106 .cpu_user_features = COMMON_USER,
1106 .mmu_features = MMU_FTR_USE_HIGH_BATS, 1107 .mmu_features = MMU_FTR_USE_HIGH_BATS |
1108 MMU_FTR_NEED_DTLB_SW_LRU,
1107 .icache_bsize = 32, 1109 .icache_bsize = 32,
1108 .dcache_bsize = 32, 1110 .dcache_bsize = 32,
1109 .cpu_setup = __setup_cpu_603, 1111 .cpu_setup = __setup_cpu_603,
@@ -1118,7 +1120,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
1118 .cpu_name = "e300c4", 1120 .cpu_name = "e300c4",
1119 .cpu_features = CPU_FTRS_E300, 1121 .cpu_features = CPU_FTRS_E300,
1120 .cpu_user_features = COMMON_USER, 1122 .cpu_user_features = COMMON_USER,
1121 .mmu_features = MMU_FTR_USE_HIGH_BATS, 1123 .mmu_features = MMU_FTR_USE_HIGH_BATS |
1124 MMU_FTR_NEED_DTLB_SW_LRU,
1122 .icache_bsize = 32, 1125 .icache_bsize = 32,
1123 .dcache_bsize = 32, 1126 .dcache_bsize = 32,
1124 .cpu_setup = __setup_cpu_603, 1127 .cpu_setup = __setup_cpu_603,
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index 58dcc7c0310..54e68c11ae1 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -593,9 +593,21 @@ BEGIN_FTR_SECTION
593 rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */ 593 rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */
594END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) 594END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
595 mtspr SPRN_RPA,r1 595 mtspr SPRN_RPA,r1
596 mfspr r2,SPRN_SRR1 /* Need to restore CR0 */
597 mtcrf 0x80,r2
598BEGIN_MMU_FTR_SECTION
599 li r0,1
600 mfspr r1,SPRN_SPRG4
601 rlwinm r2,r3,20,27,31 /* Get Address bits 15:19 */
602 slw r0,r0,r2
603 xor r1,r0,r1
604 srw r0,r1,r2
605 mtspr SPRN_SPRG4,r1
606 mfspr r2,SPRN_SRR1
607 rlwimi r2,r0,31-14,14,14
608 mtspr SPRN_SRR1,r2
609END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
596 tlbld r3 610 tlbld r3
597 mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
598 mtcrf 0x80,r3
599 rfi 611 rfi
600DataAddressInvalid: 612DataAddressInvalid:
601 mfspr r3,SPRN_SRR1 613 mfspr r3,SPRN_SRR1
@@ -661,9 +673,21 @@ BEGIN_FTR_SECTION
661 rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */ 673 rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */
662END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) 674END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
663 mtspr SPRN_RPA,r1 675 mtspr SPRN_RPA,r1
676 mfspr r2,SPRN_SRR1 /* Need to restore CR0 */
677 mtcrf 0x80,r2
678BEGIN_MMU_FTR_SECTION
679 li r0,1
680 mfspr r1,SPRN_SPRG4
681 rlwinm r2,r3,20,27,31 /* Get Address bits 15:19 */
682 slw r0,r0,r2
683 xor r1,r0,r1
684 srw r0,r1,r2
685 mtspr SPRN_SPRG4,r1
686 mfspr r2,SPRN_SRR1
687 rlwimi r2,r0,31-14,14,14
688 mtspr SPRN_SRR1,r2
689END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
664 tlbld r3 690 tlbld r3
665 mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
666 mtcrf 0x80,r3
667 rfi 691 rfi
668 692
669#ifndef CONFIG_ALTIVEC 693#ifndef CONFIG_ALTIVEC