diff options
author | Kumar Gala <galak@kernel.crashing.org> | 2009-03-18 23:55:41 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-03-23 22:47:32 -0400 |
commit | 2319f1239592d0de80414ad2338c2bd7384a2a41 (patch) | |
tree | 805de041dfc84ae9ca767c9767d833977654dbe0 /arch/powerpc/kernel/head_32.S | |
parent | eb3436a0139a651a39dbb37a75b10a2cccd00ad5 (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/head_32.S')
-rw-r--r-- | arch/powerpc/kernel/head_32.S | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index 58dcc7c03109..54e68c11ae15 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) */ |
594 | END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) | 594 | END_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 | ||
598 | BEGIN_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 | ||
609 | END_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 |
600 | DataAddressInvalid: | 612 | DataAddressInvalid: |
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) */ |
662 | END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) | 674 | END_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 | ||
678 | BEGIN_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 | ||
689 | END_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 |