mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									eb3436a013
								
							
						
					
					
						commit
						2319f12395
					
				
					 4 changed files with 45 additions and 7 deletions
				
			
		| 
						 | 
					@ -46,6 +46,12 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define MMU_FTR_LOCK_BCAST_INVAL	ASM_CONST(0x00100000)
 | 
					#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__
 | 
					#ifndef __ASSEMBLY__
 | 
				
			||||||
#include <asm/cputable.h>
 | 
					#include <asm/cputable.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,9 +15,14 @@
 | 
				
			||||||
#include <asm/ppc_asm.h>
 | 
					#include <asm/ppc_asm.h>
 | 
				
			||||||
#include <asm/asm-offsets.h>
 | 
					#include <asm/asm-offsets.h>
 | 
				
			||||||
#include <asm/cache.h>
 | 
					#include <asm/cache.h>
 | 
				
			||||||
 | 
					#include <asm/mmu.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_GLOBAL(__setup_cpu_603)
 | 
					_GLOBAL(__setup_cpu_603)
 | 
				
			||||||
	mflr	r4
 | 
						mflr	r4
 | 
				
			||||||
 | 
					BEGIN_MMU_FTR_SECTION
 | 
				
			||||||
 | 
						li	r10,0
 | 
				
			||||||
 | 
						mtspr	SPRN_SPRG4,r10		/* init SW LRU tracking */
 | 
				
			||||||
 | 
					END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
 | 
				
			||||||
BEGIN_FTR_SECTION
 | 
					BEGIN_FTR_SECTION
 | 
				
			||||||
	bl	__init_fpu_registers
 | 
						bl	__init_fpu_registers
 | 
				
			||||||
END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE)
 | 
					END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1090,7 +1090,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
 | 
				
			||||||
		.cpu_name		= "e300c2",
 | 
							.cpu_name		= "e300c2",
 | 
				
			||||||
		.cpu_features		= CPU_FTRS_E300C2,
 | 
							.cpu_features		= CPU_FTRS_E300C2,
 | 
				
			||||||
		.cpu_user_features	= PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
 | 
							.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,
 | 
							.icache_bsize		= 32,
 | 
				
			||||||
		.dcache_bsize		= 32,
 | 
							.dcache_bsize		= 32,
 | 
				
			||||||
		.cpu_setup		= __setup_cpu_603,
 | 
							.cpu_setup		= __setup_cpu_603,
 | 
				
			||||||
| 
						 | 
					@ -1103,7 +1104,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
 | 
				
			||||||
		.cpu_name		= "e300c3",
 | 
							.cpu_name		= "e300c3",
 | 
				
			||||||
		.cpu_features		= CPU_FTRS_E300,
 | 
							.cpu_features		= CPU_FTRS_E300,
 | 
				
			||||||
		.cpu_user_features	= COMMON_USER,
 | 
							.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,
 | 
							.icache_bsize		= 32,
 | 
				
			||||||
		.dcache_bsize		= 32,
 | 
							.dcache_bsize		= 32,
 | 
				
			||||||
		.cpu_setup		= __setup_cpu_603,
 | 
							.cpu_setup		= __setup_cpu_603,
 | 
				
			||||||
| 
						 | 
					@ -1118,7 +1120,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
 | 
				
			||||||
		.cpu_name		= "e300c4",
 | 
							.cpu_name		= "e300c4",
 | 
				
			||||||
		.cpu_features		= CPU_FTRS_E300,
 | 
							.cpu_features		= CPU_FTRS_E300,
 | 
				
			||||||
		.cpu_user_features	= COMMON_USER,
 | 
							.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,
 | 
							.icache_bsize		= 32,
 | 
				
			||||||
		.dcache_bsize		= 32,
 | 
							.dcache_bsize		= 32,
 | 
				
			||||||
		.cpu_setup		= __setup_cpu_603,
 | 
							.cpu_setup		= __setup_cpu_603,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -593,9 +593,21 @@ BEGIN_FTR_SECTION
 | 
				
			||||||
	rlwinm	r1,r1,0,~_PAGE_COHERENT	/* clear M (coherence not required) */
 | 
						rlwinm	r1,r1,0,~_PAGE_COHERENT	/* clear M (coherence not required) */
 | 
				
			||||||
END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
 | 
					END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
 | 
				
			||||||
	mtspr	SPRN_RPA,r1
 | 
						mtspr	SPRN_RPA,r1
 | 
				
			||||||
 | 
						mfspr	r2,SPRN_SRR1		/* Need to restore CR0 */
 | 
				
			||||||
 | 
						mtcrf	0x80,r2
 | 
				
			||||||
 | 
					BEGIN_MMU_FTR_SECTION
 | 
				
			||||||
 | 
						li	r0,1
 | 
				
			||||||
 | 
						mfspr	r1,SPRN_SPRG4
 | 
				
			||||||
 | 
						rlwinm	r2,r3,20,27,31		/* Get Address bits 15:19 */
 | 
				
			||||||
 | 
						slw	r0,r0,r2
 | 
				
			||||||
 | 
						xor	r1,r0,r1
 | 
				
			||||||
 | 
						srw	r0,r1,r2
 | 
				
			||||||
 | 
						mtspr   SPRN_SPRG4,r1
 | 
				
			||||||
 | 
						mfspr	r2,SPRN_SRR1
 | 
				
			||||||
 | 
						rlwimi	r2,r0,31-14,14,14
 | 
				
			||||||
 | 
						mtspr   SPRN_SRR1,r2
 | 
				
			||||||
 | 
					END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
 | 
				
			||||||
	tlbld	r3
 | 
						tlbld	r3
 | 
				
			||||||
	mfspr	r3,SPRN_SRR1		/* Need to restore CR0 */
 | 
					 | 
				
			||||||
	mtcrf	0x80,r3
 | 
					 | 
				
			||||||
	rfi
 | 
						rfi
 | 
				
			||||||
DataAddressInvalid:
 | 
					DataAddressInvalid:
 | 
				
			||||||
	mfspr	r3,SPRN_SRR1
 | 
						mfspr	r3,SPRN_SRR1
 | 
				
			||||||
| 
						 | 
					@ -661,9 +673,21 @@ BEGIN_FTR_SECTION
 | 
				
			||||||
	rlwinm	r1,r1,0,~_PAGE_COHERENT	/* clear M (coherence not required) */
 | 
						rlwinm	r1,r1,0,~_PAGE_COHERENT	/* clear M (coherence not required) */
 | 
				
			||||||
END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
 | 
					END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
 | 
				
			||||||
	mtspr	SPRN_RPA,r1
 | 
						mtspr	SPRN_RPA,r1
 | 
				
			||||||
 | 
						mfspr	r2,SPRN_SRR1		/* Need to restore CR0 */
 | 
				
			||||||
 | 
						mtcrf	0x80,r2
 | 
				
			||||||
 | 
					BEGIN_MMU_FTR_SECTION
 | 
				
			||||||
 | 
						li	r0,1
 | 
				
			||||||
 | 
						mfspr	r1,SPRN_SPRG4
 | 
				
			||||||
 | 
						rlwinm	r2,r3,20,27,31		/* Get Address bits 15:19 */
 | 
				
			||||||
 | 
						slw	r0,r0,r2
 | 
				
			||||||
 | 
						xor	r1,r0,r1
 | 
				
			||||||
 | 
						srw	r0,r1,r2
 | 
				
			||||||
 | 
						mtspr   SPRN_SPRG4,r1
 | 
				
			||||||
 | 
						mfspr	r2,SPRN_SRR1
 | 
				
			||||||
 | 
						rlwimi	r2,r0,31-14,14,14
 | 
				
			||||||
 | 
						mtspr   SPRN_SRR1,r2
 | 
				
			||||||
 | 
					END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
 | 
				
			||||||
	tlbld	r3
 | 
						tlbld	r3
 | 
				
			||||||
	mfspr	r3,SPRN_SRR1		/* Need to restore CR0 */
 | 
					 | 
				
			||||||
	mtcrf	0x80,r3
 | 
					 | 
				
			||||||
	rfi
 | 
						rfi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef CONFIG_ALTIVEC
 | 
					#ifndef CONFIG_ALTIVEC
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue