diff options
Diffstat (limited to 'arch/mips/kernel/cpu-probe.c')
| -rw-r--r-- | arch/mips/kernel/cpu-probe.c | 146 | 
1 files changed, 94 insertions, 52 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index cce3782c96c..4bbffdb9024 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -4,7 +4,7 @@   * Copyright (C) xxxx  the Anonymous   * Copyright (C) 1994 - 2006 Ralf Baechle   * Copyright (C) 2003, 2004  Maciej W. Rozycki - * Copyright (C) 2001, 2004, 2011, 2012  MIPS Technologies, Inc. + * Copyright (C) 2001, 2004, 2011, 2012	 MIPS Technologies, Inc.   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License @@ -69,12 +69,12 @@ void r4k_wait_irqoff(void)  			"	wait			\n"  			"	.set	pop		\n");  	local_irq_enable(); -	__asm__(" 	.globl __pastwait	\n" +	__asm__("	.globl __pastwait	\n"  		"__pastwait:			\n");  }  /* - * The RM7000 variant has to handle erratum 38.  The workaround is to not + * The RM7000 variant has to handle erratum 38.	 The workaround is to not   * have any pending stores when the WAIT instruction is executed.   */  static void rm7k_wait_irqoff(void) @@ -201,6 +201,7 @@ void __init check_wait(void)  		break;  	case CPU_M14KC: +	case CPU_M14KEC:  	case CPU_24K:  	case CPU_34K:  	case CPU_1004K: @@ -331,6 +332,34 @@ static inline void cpu_probe_vmbits(struct cpuinfo_mips *c)  #endif  } +static void __cpuinit set_isa(struct cpuinfo_mips *c, unsigned int isa) +{ +	switch (isa) { +	case MIPS_CPU_ISA_M64R2: +		c->isa_level |= MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2; +	case MIPS_CPU_ISA_M64R1: +		c->isa_level |= MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1; +	case MIPS_CPU_ISA_V: +		c->isa_level |= MIPS_CPU_ISA_V; +	case MIPS_CPU_ISA_IV: +		c->isa_level |= MIPS_CPU_ISA_IV; +	case MIPS_CPU_ISA_III: +		c->isa_level |= MIPS_CPU_ISA_I | MIPS_CPU_ISA_II | +				MIPS_CPU_ISA_III; +		break; + +	case MIPS_CPU_ISA_M32R2: +		c->isa_level |= MIPS_CPU_ISA_M32R2; +	case MIPS_CPU_ISA_M32R1: +		c->isa_level |= MIPS_CPU_ISA_M32R1; +	case MIPS_CPU_ISA_II: +		c->isa_level |= MIPS_CPU_ISA_II; +	case MIPS_CPU_ISA_I: +		c->isa_level |= MIPS_CPU_ISA_I; +		break; +	} +} +  static char unknown_isa[] __cpuinitdata = KERN_ERR \  	"Unsupported ISA type, c0.config0: %d."; @@ -348,10 +377,10 @@ static inline unsigned int decode_config0(struct cpuinfo_mips *c)  	case 0:  		switch ((config0 & MIPS_CONF_AR) >> 10) {  		case 0: -			c->isa_level = MIPS_CPU_ISA_M32R1; +			set_isa(c, MIPS_CPU_ISA_M32R1);  			break;  		case 1: -			c->isa_level = MIPS_CPU_ISA_M32R2; +			set_isa(c, MIPS_CPU_ISA_M32R2);  			break;  		default:  			goto unknown; @@ -360,10 +389,10 @@ static inline unsigned int decode_config0(struct cpuinfo_mips *c)  	case 2:  		switch ((config0 & MIPS_CONF_AR) >> 10) {  		case 0: -			c->isa_level = MIPS_CPU_ISA_M64R1; +			set_isa(c, MIPS_CPU_ISA_M64R1);  			break;  		case 1: -			c->isa_level = MIPS_CPU_ISA_M64R2; +			set_isa(c, MIPS_CPU_ISA_M64R2);  			break;  		default:  			goto unknown; @@ -439,6 +468,13 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)  		c->ases |= MIPS_ASE_MIPSMT;  	if (config3 & MIPS_CONF3_ULRI)  		c->options |= MIPS_CPU_ULRI; +	if (config3 & MIPS_CONF3_ISA) +		c->options |= MIPS_CPU_MICROMIPS; +#ifdef CONFIG_CPU_MICROMIPS +	write_c0_config3(read_c0_config3() | MIPS_CONF3_ISA_OE); +#endif +	if (config3 & MIPS_CONF3_VZ) +		c->ases |= MIPS_ASE_VZ;  	return config3 & MIPS_CONF_M;  } @@ -469,7 +505,7 @@ static void __cpuinit decode_configs(struct cpuinfo_mips *c)  	c->scache.flags = MIPS_CACHE_NOT_PRESENT;  	ok = decode_config0(c);			/* Read Config registers.  */ -	BUG_ON(!ok);				/* Arch spec violation!  */ +	BUG_ON(!ok);				/* Arch spec violation!	 */  	if (ok)  		ok = decode_config1(c);  	if (ok) @@ -494,7 +530,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  	case PRID_IMP_R2000:  		c->cputype = CPU_R2000;  		__cpu_name[cpu] = "R2000"; -		c->isa_level = MIPS_CPU_ISA_I; +		set_isa(c, MIPS_CPU_ISA_I);  		c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |  			     MIPS_CPU_NOFPUEX;  		if (__cpu_has_fpu()) @@ -514,7 +550,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  			c->cputype = CPU_R3000;  			__cpu_name[cpu] = "R3000";  		} -		c->isa_level = MIPS_CPU_ISA_I; +		set_isa(c, MIPS_CPU_ISA_I);  		c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |  			     MIPS_CPU_NOFPUEX;  		if (__cpu_has_fpu()) @@ -540,13 +576,16 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  			}  		} -		c->isa_level = MIPS_CPU_ISA_III; +		set_isa(c, MIPS_CPU_ISA_III);  		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |  			     MIPS_CPU_WATCH | MIPS_CPU_VCE |  			     MIPS_CPU_LLSC;  		c->tlbsize = 48;  		break;  	case PRID_IMP_VR41XX: +		set_isa(c, MIPS_CPU_ISA_III); +		c->options = R4K_OPTS; +		c->tlbsize = 32;  		switch (c->processor_id & 0xf0) {  		case PRID_REV_VR4111:  			c->cputype = CPU_VR4111; @@ -571,6 +610,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  				__cpu_name[cpu] = "NEC VR4131";  			} else {  				c->cputype = CPU_VR4133; +				c->options |= MIPS_CPU_LLSC;  				__cpu_name[cpu] = "NEC VR4133";  			}  			break; @@ -580,14 +620,11 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  			__cpu_name[cpu] = "NEC Vr41xx";  			break;  		} -		c->isa_level = MIPS_CPU_ISA_III; -		c->options = R4K_OPTS; -		c->tlbsize = 32;  		break;  	case PRID_IMP_R4300:  		c->cputype = CPU_R4300;  		__cpu_name[cpu] = "R4300"; -		c->isa_level = MIPS_CPU_ISA_III; +		set_isa(c, MIPS_CPU_ISA_III);  		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |  			     MIPS_CPU_LLSC;  		c->tlbsize = 32; @@ -595,7 +632,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  	case PRID_IMP_R4600:  		c->cputype = CPU_R4600;  		__cpu_name[cpu] = "R4600"; -		c->isa_level = MIPS_CPU_ISA_III; +		set_isa(c, MIPS_CPU_ISA_III);  		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |  			     MIPS_CPU_LLSC;  		c->tlbsize = 48; @@ -610,13 +647,13 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  		 */  		c->cputype = CPU_R4650;  		__cpu_name[cpu] = "R4650"; -		c->isa_level = MIPS_CPU_ISA_III; +		set_isa(c, MIPS_CPU_ISA_III);  		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;  		c->tlbsize = 48;  		break;  	#endif  	case PRID_IMP_TX39: -		c->isa_level = MIPS_CPU_ISA_I; +		set_isa(c, MIPS_CPU_ISA_I);  		c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE;  		if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) { @@ -641,7 +678,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  	case PRID_IMP_R4700:  		c->cputype = CPU_R4700;  		__cpu_name[cpu] = "R4700"; -		c->isa_level = MIPS_CPU_ISA_III; +		set_isa(c, MIPS_CPU_ISA_III);  		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |  			     MIPS_CPU_LLSC;  		c->tlbsize = 48; @@ -649,7 +686,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  	case PRID_IMP_TX49:  		c->cputype = CPU_TX49XX;  		__cpu_name[cpu] = "R49XX"; -		c->isa_level = MIPS_CPU_ISA_III; +		set_isa(c, MIPS_CPU_ISA_III);  		c->options = R4K_OPTS | MIPS_CPU_LLSC;  		if (!(c->processor_id & 0x08))  			c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; @@ -658,7 +695,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  	case PRID_IMP_R5000:  		c->cputype = CPU_R5000;  		__cpu_name[cpu] = "R5000"; -		c->isa_level = MIPS_CPU_ISA_IV; +		set_isa(c, MIPS_CPU_ISA_IV);  		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |  			     MIPS_CPU_LLSC;  		c->tlbsize = 48; @@ -666,7 +703,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  	case PRID_IMP_R5432:  		c->cputype = CPU_R5432;  		__cpu_name[cpu] = "R5432"; -		c->isa_level = MIPS_CPU_ISA_IV; +		set_isa(c, MIPS_CPU_ISA_IV);  		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |  			     MIPS_CPU_WATCH | MIPS_CPU_LLSC;  		c->tlbsize = 48; @@ -674,7 +711,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  	case PRID_IMP_R5500:  		c->cputype = CPU_R5500;  		__cpu_name[cpu] = "R5500"; -		c->isa_level = MIPS_CPU_ISA_IV; +		set_isa(c, MIPS_CPU_ISA_IV);  		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |  			     MIPS_CPU_WATCH | MIPS_CPU_LLSC;  		c->tlbsize = 48; @@ -682,7 +719,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  	case PRID_IMP_NEVADA:  		c->cputype = CPU_NEVADA;  		__cpu_name[cpu] = "Nevada"; -		c->isa_level = MIPS_CPU_ISA_IV; +		set_isa(c, MIPS_CPU_ISA_IV);  		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |  			     MIPS_CPU_DIVEC | MIPS_CPU_LLSC;  		c->tlbsize = 48; @@ -690,7 +727,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  	case PRID_IMP_R6000:  		c->cputype = CPU_R6000;  		__cpu_name[cpu] = "R6000"; -		c->isa_level = MIPS_CPU_ISA_II; +		set_isa(c, MIPS_CPU_ISA_II);  		c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |  			     MIPS_CPU_LLSC;  		c->tlbsize = 32; @@ -698,7 +735,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  	case PRID_IMP_R6000A:  		c->cputype = CPU_R6000A;  		__cpu_name[cpu] = "R6000A"; -		c->isa_level = MIPS_CPU_ISA_II; +		set_isa(c, MIPS_CPU_ISA_II);  		c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |  			     MIPS_CPU_LLSC;  		c->tlbsize = 32; @@ -706,38 +743,38 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  	case PRID_IMP_RM7000:  		c->cputype = CPU_RM7000;  		__cpu_name[cpu] = "RM7000"; -		c->isa_level = MIPS_CPU_ISA_IV; +		set_isa(c, MIPS_CPU_ISA_IV);  		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |  			     MIPS_CPU_LLSC;  		/* -		 * Undocumented RM7000:  Bit 29 in the info register of +		 * Undocumented RM7000:	 Bit 29 in the info register of  		 * the RM7000 v2.0 indicates if the TLB has 48 or 64  		 * entries.  		 * -		 * 29      1 =>    64 entry JTLB -		 *         0 =>    48 entry JTLB +		 * 29	   1 =>	   64 entry JTLB +		 *	   0 =>	   48 entry JTLB  		 */  		c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48;  		break;  	case PRID_IMP_RM9000:  		c->cputype = CPU_RM9000;  		__cpu_name[cpu] = "RM9000"; -		c->isa_level = MIPS_CPU_ISA_IV; +		set_isa(c, MIPS_CPU_ISA_IV);  		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |  			     MIPS_CPU_LLSC;  		/*  		 * Bit 29 in the info register of the RM9000  		 * indicates if the TLB has 48 or 64 entries.  		 * -		 * 29      1 =>    64 entry JTLB -		 *         0 =>    48 entry JTLB +		 * 29	   1 =>	   64 entry JTLB +		 *	   0 =>	   48 entry JTLB  		 */  		c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48;  		break;  	case PRID_IMP_R8000:  		c->cputype = CPU_R8000;  		__cpu_name[cpu] = "RM8000"; -		c->isa_level = MIPS_CPU_ISA_IV; +		set_isa(c, MIPS_CPU_ISA_IV);  		c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |  			     MIPS_CPU_FPU | MIPS_CPU_32FPR |  			     MIPS_CPU_LLSC; @@ -746,7 +783,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  	case PRID_IMP_R10000:  		c->cputype = CPU_R10000;  		__cpu_name[cpu] = "R10000"; -		c->isa_level = MIPS_CPU_ISA_IV; +		set_isa(c, MIPS_CPU_ISA_IV);  		c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |  			     MIPS_CPU_FPU | MIPS_CPU_32FPR |  			     MIPS_CPU_COUNTER | MIPS_CPU_WATCH | @@ -756,7 +793,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  	case PRID_IMP_R12000:  		c->cputype = CPU_R12000;  		__cpu_name[cpu] = "R12000"; -		c->isa_level = MIPS_CPU_ISA_IV; +		set_isa(c, MIPS_CPU_ISA_IV);  		c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |  			     MIPS_CPU_FPU | MIPS_CPU_32FPR |  			     MIPS_CPU_COUNTER | MIPS_CPU_WATCH | @@ -766,7 +803,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  	case PRID_IMP_R14000:  		c->cputype = CPU_R14000;  		__cpu_name[cpu] = "R14000"; -		c->isa_level = MIPS_CPU_ISA_IV; +		set_isa(c, MIPS_CPU_ISA_IV);  		c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |  			     MIPS_CPU_FPU | MIPS_CPU_32FPR |  			     MIPS_CPU_COUNTER | MIPS_CPU_WATCH | @@ -786,7 +823,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)  			break;  		} -		c->isa_level = MIPS_CPU_ISA_III; +		set_isa(c, MIPS_CPU_ISA_III);  		c->options = R4K_OPTS |  			     MIPS_CPU_FPU | MIPS_CPU_LLSC |  			     MIPS_CPU_32FPR; @@ -838,10 +875,13 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)  		__cpu_name[cpu] = "MIPS 20Kc";  		break;  	case PRID_IMP_24K: -	case PRID_IMP_24KE:  		c->cputype = CPU_24K;  		__cpu_name[cpu] = "MIPS 24Kc";  		break; +	case PRID_IMP_24KE: +		c->cputype = CPU_24K; +		__cpu_name[cpu] = "MIPS 24KEc"; +		break;  	case PRID_IMP_25KF:  		c->cputype = CPU_25KF;  		__cpu_name[cpu] = "MIPS 25Kc"; @@ -858,6 +898,10 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)  		c->cputype = CPU_M14KC;  		__cpu_name[cpu] = "MIPS M14Kc";  		break; +	case PRID_IMP_M14KEC: +		c->cputype = CPU_M14KEC; +		__cpu_name[cpu] = "MIPS M14KEc"; +		break;  	case PRID_IMP_1004K:  		c->cputype = CPU_1004K;  		__cpu_name[cpu] = "MIPS 1004Kc"; @@ -946,7 +990,7 @@ static inline void cpu_probe_nxp(struct cpuinfo_mips *c, unsigned int cpu)  	case PRID_IMP_PR4450:  		c->cputype = CPU_PR4450;  		__cpu_name[cpu] = "Philips PR4450"; -		c->isa_level = MIPS_CPU_ISA_M32R1; +		set_isa(c, MIPS_CPU_ISA_M32R1);  		break;  	}  } @@ -1053,12 +1097,12 @@ static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)  		return;  	} -	c->options = (MIPS_CPU_TLB       | -			MIPS_CPU_4KEX    | +	c->options = (MIPS_CPU_TLB	 | +			MIPS_CPU_4KEX	 |  			MIPS_CPU_COUNTER | -			MIPS_CPU_DIVEC   | -			MIPS_CPU_WATCH   | -			MIPS_CPU_EJTAG   | +			MIPS_CPU_DIVEC	 | +			MIPS_CPU_WATCH	 | +			MIPS_CPU_EJTAG	 |  			MIPS_CPU_LLSC);  	switch (c->processor_id & 0xff00) { @@ -1105,12 +1149,12 @@ static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)  	}  	if (c->cputype == CPU_XLP) { -		c->isa_level = MIPS_CPU_ISA_M64R2; +		set_isa(c, MIPS_CPU_ISA_M64R2);  		c->options |= (MIPS_CPU_FPU | MIPS_CPU_ULRI | MIPS_CPU_MCHECK);  		/* This will be updated again after all threads are woken up */  		c->tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1;  	} else { -		c->isa_level = MIPS_CPU_ISA_M64R1; +		set_isa(c, MIPS_CPU_ISA_M64R1);  		c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1;  	}  } @@ -1129,7 +1173,7 @@ __cpuinit void cpu_probe(void)  	struct cpuinfo_mips *c = ¤t_cpu_data;  	unsigned int cpu = smp_processor_id(); -	c->processor_id	= PRID_IMP_UNKNOWN; +	c->processor_id = PRID_IMP_UNKNOWN;  	c->fpu_id	= FPIR_IMP_NONE;  	c->cputype	= CPU_UNKNOWN; @@ -1186,10 +1230,8 @@ __cpuinit void cpu_probe(void)  	if (c->options & MIPS_CPU_FPU) {  		c->fpu_id = cpu_get_fpu_id(); -		if (c->isa_level == MIPS_CPU_ISA_M32R1 || -		    c->isa_level == MIPS_CPU_ISA_M32R2 || -		    c->isa_level == MIPS_CPU_ISA_M64R1 || -		    c->isa_level == MIPS_CPU_ISA_M64R2) { +		if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 | +				    MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) {  			if (c->fpu_id & MIPS_FPIR_3D)  				c->ases |= MIPS_ASE_MIPS3D;  		}  |