Message ID | 1237208538-32597-1-git-send-email-galak@kernel.crashing.org (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Ok, I was analysing your code (which seems much more compact than mine): On Monday 16 March 2009 14:02:18 Kumar Gala wrote: >[...] > --- a/arch/powerpc/kernel/head_32.S > +++ b/arch/powerpc/kernel/head_32.S > @@ -587,9 +587,19 @@ DataLoadTLBMiss: > ori r1,r1,0xe04 /* clear out reserved bits */ > andc r1,r0,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ > mtspr SPRN_RPA,r1 > + mfspr r2,SPRN_SRR1 /* Need to restore CR0 */ > + mtcrf 0x80,r2 > +BEGIN_MMU_FTR_SECTION > + li r0,1 > + lwz r1,sw_way_lru@l(0) > + rlwinm r3,r3,19,25,29 /* Get Address bits 19:15 */ This should be 'rlwinm r3,r3,17,27,31' now, since you address bits, not ints. Note that you are trashing r3 (SPRN_DMISS) here! > + slw r0,r0,r3 > + xor r1,r0,r1 > + srw r0,r1,r3 > + stw r1,sw_way_lru@l(0) > + rlwimi r2,r0,31-14,14,14 > +END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU) > tlbld r3 And now you load r3 into the tlb, is this right? It doesn't seem right to me.... > - mfspr r3,SPRN_SRR1 /* Need to restore CR0 */ > - mtcrf 0x80,r3 > rfi > DataAddressInvalid: > mfspr r3,SPRN_SRR1 > @@ -652,11 +662,25 @@ DataStoreTLBMiss: > li r1,0xe05 /* clear out reserved bits & PP lsb */ > andc r1,r0,r1 /* PP = user? 2: 0 */ > mtspr SPRN_RPA,r1 > + mfspr r2,SPRN_SRR1 /* Need to restore CR0 */ > + mtcrf 0x80,r2 > +BEGIN_MMU_FTR_SECTION > + li r0,1 > + lwz r1,sw_way_lru@l(0) > + rlwinm r3,r3,19,25,29 /* Get Address bits 19:15 */ > + slw r0,r0,r3 > + xor r1,r0,r1 > + srw r0,r1,r3 > + stw r1,sw_way_lru@l(0) > + rlwimi r2,r0,31-14,14,14 > +END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU) > tlbld r3 Same thing here, r3 is trashed. > - mfspr r3,SPRN_SRR1 /* Need to restore CR0 */ > - mtcrf 0x80,r3 > rfi > > + .balign L1_CACHE_BYTES > +sw_way_lru: > + .long 0 > + Ok, I'll try to do it like this, but with lru stored in SPRG6 Best regards,
On Mar 16, 2009, at 10:02 AM, David Jander wrote: > > Ok, I was analysing your code (which seems much more compact than > mine): > > On Monday 16 March 2009 14:02:18 Kumar Gala wrote: >> [...] >> --- a/arch/powerpc/kernel/head_32.S >> +++ b/arch/powerpc/kernel/head_32.S >> @@ -587,9 +587,19 @@ DataLoadTLBMiss: >> ori r1,r1,0xe04 /* clear out reserved bits */ >> andc r1,r0,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ >> mtspr SPRN_RPA,r1 >> + mfspr r2,SPRN_SRR1 /* Need to restore CR0 */ >> + mtcrf 0x80,r2 >> +BEGIN_MMU_FTR_SECTION >> + li r0,1 >> + lwz r1,sw_way_lru@l(0) >> + rlwinm r3,r3,19,25,29 /* Get Address bits 19:15 */ > > This should be 'rlwinm r3,r3,17,27,31' now, since you address bits, > not ints. was just copying/pasting what you had :) > Note that you are trashing r3 (SPRN_DMISS) here! good catch.. >> + slw r0,r0,r3 >> + xor r1,r0,r1 >> + srw r0,r1,r3 >> + stw r1,sw_way_lru@l(0) >> + rlwimi r2,r0,31-14,14,14 >> +END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU) >> tlbld r3 > > And now you load r3 into the tlb, is this right? It doesn't seem > right to > me.... correct.. I wasn't thinking about the fact that tlbld was using r3. - k
On Mar 16, 2009, at 10:06 AM, Kumar Gala wrote: > > On Mar 16, 2009, at 10:02 AM, David Jander wrote: > >> >> Ok, I was analysing your code (which seems much more compact than >> mine): >> >> On Monday 16 March 2009 14:02:18 Kumar Gala wrote: >>> [...] >>> --- a/arch/powerpc/kernel/head_32.S >>> +++ b/arch/powerpc/kernel/head_32.S >>> @@ -587,9 +587,19 @@ DataLoadTLBMiss: >>> ori r1,r1,0xe04 /* clear out reserved bits */ >>> andc r1,r0,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ >>> mtspr SPRN_RPA,r1 >>> + mfspr r2,SPRN_SRR1 /* Need to restore CR0 */ >>> + mtcrf 0x80,r2 >>> +BEGIN_MMU_FTR_SECTION >>> + li r0,1 >>> + lwz r1,sw_way_lru@l(0) >>> + rlwinm r3,r3,19,25,29 /* Get Address bits 19:15 */ >> >> This should be 'rlwinm r3,r3,17,27,31' now, since you address bits, >> not ints. > > was just copying/pasting what you had :) > >> Note that you are trashing r3 (SPRN_DMISS) here! > > good catch.. > >>> + slw r0,r0,r3 >>> + xor r1,r0,r1 >>> + srw r0,r1,r3 >>> + stw r1,sw_way_lru@l(0) >>> + rlwimi r2,r0,31-14,14,14 I'm also missing a: mtspr SPRN_SRR1,r2 - k
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h index 10476a8..cbf1543 100644 --- a/arch/powerpc/include/asm/mmu.h +++ b/arch/powerpc/include/asm/mmu.h @@ -46,6 +46,12 @@ */ #define MMU_FTR_LOCK_BCAST_INVAL ASM_CONST(0x00100000) +/* This indicates that the processor doesn't handle way selection + * properly and needs SW to track and update the LRU state. This + * is specific to an errata on e300c2/c3/c4 class parts + */ +#define MMU_FTR_NEED_DTLB_SW_LRU ASM_CONST(0x00200000) + #ifndef __ASSEMBLY__ #include <asm/cputable.h> diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index ccea243..cd1b687 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1090,7 +1090,8 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_name = "e300c2", .cpu_features = CPU_FTRS_E300C2, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, - .mmu_features = MMU_FTR_USE_HIGH_BATS, + .mmu_features = MMU_FTR_USE_HIGH_BATS | + MMU_FTR_NEED_DTLB_SW_LRU, .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603, @@ -1103,7 +1104,8 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_name = "e300c3", .cpu_features = CPU_FTRS_E300, .cpu_user_features = COMMON_USER, - .mmu_features = MMU_FTR_USE_HIGH_BATS, + .mmu_features = MMU_FTR_USE_HIGH_BATS | + MMU_FTR_NEED_DTLB_SW_LRU, .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603, @@ -1118,7 +1120,8 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_name = "e300c4", .cpu_features = CPU_FTRS_E300, .cpu_user_features = COMMON_USER, - .mmu_features = MMU_FTR_USE_HIGH_BATS, + .mmu_features = MMU_FTR_USE_HIGH_BATS | + MMU_FTR_NEED_DTLB_SW_LRU, .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603, diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index b6c5955..d59771d 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -587,9 +587,19 @@ DataLoadTLBMiss: ori r1,r1,0xe04 /* clear out reserved bits */ andc r1,r0,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ mtspr SPRN_RPA,r1 + mfspr r2,SPRN_SRR1 /* Need to restore CR0 */ + mtcrf 0x80,r2 +BEGIN_MMU_FTR_SECTION + li r0,1 + lwz r1,sw_way_lru@l(0) + rlwinm r3,r3,19,25,29 /* Get Address bits 19:15 */ + slw r0,r0,r3 + xor r1,r0,r1 + srw r0,r1,r3 + stw r1,sw_way_lru@l(0) + rlwimi r2,r0,31-14,14,14 +END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU) tlbld r3 - mfspr r3,SPRN_SRR1 /* Need to restore CR0 */ - mtcrf 0x80,r3 rfi DataAddressInvalid: mfspr r3,SPRN_SRR1 @@ -652,11 +662,25 @@ DataStoreTLBMiss: li r1,0xe05 /* clear out reserved bits & PP lsb */ andc r1,r0,r1 /* PP = user? 2: 0 */ mtspr SPRN_RPA,r1 + mfspr r2,SPRN_SRR1 /* Need to restore CR0 */ + mtcrf 0x80,r2 +BEGIN_MMU_FTR_SECTION + li r0,1 + lwz r1,sw_way_lru@l(0) + rlwinm r3,r3,19,25,29 /* Get Address bits 19:15 */ + slw r0,r0,r3 + xor r1,r0,r1 + srw r0,r1,r3 + stw r1,sw_way_lru@l(0) + rlwimi r2,r0,31-14,14,14 +END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU) tlbld r3 - mfspr r3,SPRN_SRR1 /* Need to restore CR0 */ - mtcrf 0x80,r3 rfi + .balign L1_CACHE_BYTES +sw_way_lru: + .long 0 + #ifndef CONFIG_ALTIVEC #define altivec_assist_exception unknown_exception #endif
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> --- arch/powerpc/include/asm/mmu.h | 6 ++++++ arch/powerpc/kernel/cputable.c | 9 ++++++--- arch/powerpc/kernel/head_32.S | 32 ++++++++++++++++++++++++++++---- 3 files changed, 40 insertions(+), 7 deletions(-)