cpu-probe.c 30.4 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4
/*
 * Processor capabilities determination functions.
 *
 * Copyright (C) xxxx  the Anonymous
5
 * Copyright (C) 1994 - 2006 Ralf Baechle
6
 * Copyright (C) 2003, 2004  Maciej W. Rozycki
R
Ralf Baechle 已提交
7
 * Copyright (C) 2001, 2004, 2011, 2012	 MIPS Technologies, Inc.
L
Linus Torvalds 已提交
8 9 10 11 12 13 14 15 16
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ptrace.h>
17
#include <linux/smp.h>
L
Linus Torvalds 已提交
18
#include <linux/stddef.h>
19
#include <linux/export.h>
L
Linus Torvalds 已提交
20

21
#include <asm/bugs.h>
L
Linus Torvalds 已提交
22
#include <asm/cpu.h>
23
#include <asm/cpu-type.h>
L
Linus Torvalds 已提交
24 25
#include <asm/fpu.h>
#include <asm/mipsregs.h>
26
#include <asm/mipsmtregs.h>
P
Paul Burton 已提交
27
#include <asm/msa.h>
28
#include <asm/watch.h>
29
#include <asm/elf.h>
30
#include <asm/spram.h>
31 32
#include <asm/uaccess.h>

33
static int mips_fpu_disabled;
34 35 36 37 38 39 40 41 42 43 44

static int __init fpu_disable(char *s)
{
	cpu_data[0].options &= ~MIPS_CPU_FPU;
	mips_fpu_disabled = 1;

	return 1;
}

__setup("nofpu", fpu_disable);

45
int mips_dsp_disabled;
46 47 48

static int __init dsp_disable(char *s)
{
49
	cpu_data[0].ases &= ~(MIPS_ASE_DSP | MIPS_ASE_DSP2P);
50 51 52 53 54 55 56
	mips_dsp_disabled = 1;

	return 1;
}

__setup("nodsp", dsp_disable);

57 58 59 60 61 62 63 64 65 66 67 68 69 70
static int mips_htw_disabled;

static int __init htw_disable(char *s)
{
	mips_htw_disabled = 1;
	cpu_data[0].options &= ~MIPS_CPU_HTW;
	write_c0_pwctl(read_c0_pwctl() &
		       ~(1 << MIPS_PWCTL_PWEN_SHIFT));

	return 1;
}

__setup("nohtw", htw_disable);

M
Marc St-Jean 已提交
71 72 73 74
static inline void check_errata(void)
{
	struct cpuinfo_mips *c = &current_cpu_data;

75
	switch (current_cpu_type()) {
M
Marc St-Jean 已提交
76 77 78
	case CPU_34K:
		/*
		 * Erratum "RPS May Cause Incorrect Instruction Execution"
R
Ralf Baechle 已提交
79
		 * This code only handles VPE0, any SMP/RTOS code
M
Marc St-Jean 已提交
80 81 82 83 84 85 86 87 88 89
		 * making use of VPE1 will be responsable for that VPE.
		 */
		if ((c->processor_id & PRID_REV_MASK) <= PRID_REV_34K_V1_0_2)
			write_c0_config7(read_c0_config7() | MIPS_CONF7_RPS);
		break;
	default:
		break;
	}
}

L
Linus Torvalds 已提交
90 91
void __init check_bugs32(void)
{
M
Marc St-Jean 已提交
92
	check_errata();
L
Linus Torvalds 已提交
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
}

/*
 * Probe whether cpu has config register by trying to play with
 * alternate cache bit and see whether it matters.
 * It's used by cpu_probe to distinguish between R3000A and R3081.
 */
static inline int cpu_has_confreg(void)
{
#ifdef CONFIG_CPU_R3000
	extern unsigned long r3k_cache_size(unsigned long);
	unsigned long size1, size2;
	unsigned long cfg = read_c0_conf();

	size1 = r3k_cache_size(ST0_ISC);
	write_c0_conf(cfg ^ R30XX_CONF_AC);
	size2 = r3k_cache_size(ST0_ISC);
	write_c0_conf(cfg);
	return size1 != size2;
#else
	return 0;
#endif
}

117 118 119 120 121 122
static inline void set_elf_platform(int cpu, const char *plat)
{
	if (cpu == 0)
		__elf_platform = plat;
}

L
Linus Torvalds 已提交
123 124 125 126 127 128 129 130
/*
 * Get the FPU Implementation/Revision.
 */
static inline unsigned long cpu_get_fpu_id(void)
{
	unsigned long tmp, fpu_id;

	tmp = read_c0_status();
131
	__enable_fpu(FPU_AS_IS);
L
Linus Torvalds 已提交
132 133 134 135 136 137 138 139 140 141
	fpu_id = read_32bit_cp1_register(CP1_REVISION);
	write_c0_status(tmp);
	return fpu_id;
}

/*
 * Check the CPU has an FPU the official way.
 */
static inline int __cpu_has_fpu(void)
{
142
	return ((cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE);
L
Linus Torvalds 已提交
143 144
}

P
Paul Burton 已提交
145 146
static inline unsigned long cpu_get_msa_id(void)
{
147
	unsigned long status, msa_id;
P
Paul Burton 已提交
148 149 150 151 152

	status = read_c0_status();
	__enable_fpu(FPU_64BIT);
	enable_msa();
	msa_id = read_msa_ir();
153
	disable_msa();
P
Paul Burton 已提交
154 155 156 157
	write_c0_status(status);
	return msa_id;
}

158 159 160
static inline void cpu_probe_vmbits(struct cpuinfo_mips *c)
{
#ifdef __NEED_VMBITS_PROBE
161
	write_c0_entryhi(0x3fffffffffffe000ULL);
162
	back_to_back_c0_hazard();
163
	c->vmbits = fls64(read_c0_entryhi() & 0x3fffffffffffe000ULL);
164 165 166
#endif
}

167
static void set_isa(struct cpuinfo_mips *c, unsigned int isa)
168 169 170 171 172 173 174 175 176 177 178
{
	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:
179
		c->isa_level |= MIPS_CPU_ISA_II | MIPS_CPU_ISA_III;
180 181 182 183 184 185 186 187 188 189 190 191
		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;
		break;
	}
}

192
static char unknown_isa[] = KERN_ERR \
193 194
	"Unsupported ISA type, c0.config0: %d.";

L
Leonid Yegoshin 已提交
195 196 197
static void set_ftlb_enable(struct cpuinfo_mips *c, int enable)
{
	unsigned int config6;
198 199 200 201 202 203

	/* It's implementation dependent how the FTLB can be enabled */
	switch (c->cputype) {
	case CPU_PROAPTIV:
	case CPU_P5600:
		/* proAptiv & related cores use Config6 to enable the FTLB */
L
Leonid Yegoshin 已提交
204 205 206 207 208 209 210 211
		config6 = read_c0_config6();
		if (enable)
			/* Enable FTLB */
			write_c0_config6(config6 | MIPS_CONF6_FTLBEN);
		else
			/* Disable FTLB */
			write_c0_config6(config6 &  ~MIPS_CONF6_FTLBEN);
		back_to_back_c0_hazard();
212
		break;
L
Leonid Yegoshin 已提交
213 214 215
	}
}

216 217 218 219 220 221 222
static inline unsigned int decode_config0(struct cpuinfo_mips *c)
{
	unsigned int config0;
	int isa;

	config0 = read_c0_config();

L
Leonid Yegoshin 已提交
223 224 225 226 227
	/*
	 * Look for Standard TLB or Dual VTLB and FTLB
	 */
	if ((((config0 & MIPS_CONF_MT) >> 7) == 1) ||
	    (((config0 & MIPS_CONF_MT) >> 7) == 4))
228
		c->options |= MIPS_CPU_TLB;
L
Leonid Yegoshin 已提交
229

230 231 232 233 234
	isa = (config0 & MIPS_CONF_AT) >> 13;
	switch (isa) {
	case 0:
		switch ((config0 & MIPS_CONF_AR) >> 10) {
		case 0:
235
			set_isa(c, MIPS_CPU_ISA_M32R1);
236 237
			break;
		case 1:
238
			set_isa(c, MIPS_CPU_ISA_M32R2);
239 240 241 242 243 244 245 246
			break;
		default:
			goto unknown;
		}
		break;
	case 2:
		switch ((config0 & MIPS_CONF_AR) >> 10) {
		case 0:
247
			set_isa(c, MIPS_CPU_ISA_M64R1);
248 249
			break;
		case 1:
250
			set_isa(c, MIPS_CPU_ISA_M64R2);
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
			break;
		default:
			goto unknown;
		}
		break;
	default:
		goto unknown;
	}

	return config0 & MIPS_CONF_M;

unknown:
	panic(unknown_isa, config0);
}

static inline unsigned int decode_config1(struct cpuinfo_mips *c)
{
	unsigned int config1;

	config1 = read_c0_config1();

	if (config1 & MIPS_CONF1_MD)
		c->ases |= MIPS_ASE_MDMX;
	if (config1 & MIPS_CONF1_WR)
		c->options |= MIPS_CPU_WATCH;
	if (config1 & MIPS_CONF1_CA)
		c->ases |= MIPS_ASE_MIPS16;
	if (config1 & MIPS_CONF1_EP)
		c->options |= MIPS_CPU_EJTAG;
	if (config1 & MIPS_CONF1_FP) {
		c->options |= MIPS_CPU_FPU;
		c->options |= MIPS_CPU_32FPR;
	}
L
Leonid Yegoshin 已提交
284
	if (cpu_has_tlb) {
285
		c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1;
L
Leonid Yegoshin 已提交
286 287 288
		c->tlbsizevtlb = c->tlbsize;
		c->tlbsizeftlbsets = 0;
	}
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310

	return config1 & MIPS_CONF_M;
}

static inline unsigned int decode_config2(struct cpuinfo_mips *c)
{
	unsigned int config2;

	config2 = read_c0_config2();

	if (config2 & MIPS_CONF2_SL)
		c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;

	return config2 & MIPS_CONF_M;
}

static inline unsigned int decode_config3(struct cpuinfo_mips *c)
{
	unsigned int config3;

	config3 = read_c0_config3();

311
	if (config3 & MIPS_CONF3_SM) {
312
		c->ases |= MIPS_ASE_SMARTMIPS;
313 314 315 316
		c->options |= MIPS_CPU_RIXI;
	}
	if (config3 & MIPS_CONF3_RXI)
		c->options |= MIPS_CPU_RIXI;
317 318
	if (config3 & MIPS_CONF3_DSP)
		c->ases |= MIPS_ASE_DSP;
319 320
	if (config3 & MIPS_CONF3_DSP2P)
		c->ases |= MIPS_ASE_DSP2P;
321 322 323 324 325 326 327 328
	if (config3 & MIPS_CONF3_VINT)
		c->options |= MIPS_CPU_VINT;
	if (config3 & MIPS_CONF3_VEIC)
		c->options |= MIPS_CPU_VEIC;
	if (config3 & MIPS_CONF3_MT)
		c->ases |= MIPS_ASE_MIPSMT;
	if (config3 & MIPS_CONF3_ULRI)
		c->options |= MIPS_CPU_ULRI;
329 330
	if (config3 & MIPS_CONF3_ISA)
		c->options |= MIPS_CPU_MICROMIPS;
331 332
	if (config3 & MIPS_CONF3_VZ)
		c->ases |= MIPS_ASE_VZ;
333 334
	if (config3 & MIPS_CONF3_SC)
		c->options |= MIPS_CPU_SEGMENTS;
P
Paul Burton 已提交
335 336
	if (config3 & MIPS_CONF3_MSA)
		c->ases |= MIPS_ASE_MSA;
337 338 339
	/* Only tested on 32-bit cores */
	if ((config3 & MIPS_CONF3_PW) && config_enabled(CONFIG_32BIT))
		c->options |= MIPS_CPU_HTW;
340 341 342 343 344 345 346

	return config3 & MIPS_CONF_M;
}

static inline unsigned int decode_config4(struct cpuinfo_mips *c)
{
	unsigned int config4;
L
Leonid Yegoshin 已提交
347 348 349
	unsigned int newcf4;
	unsigned int mmuextdef;
	unsigned int ftlb_page = MIPS_CONF4_FTLBPAGESIZE;
350 351 352

	config4 = read_c0_config4();

353 354 355
	if (cpu_has_tlb) {
		if (((config4 & MIPS_CONF4_IE) >> 29) == 2)
			c->options |= MIPS_CPU_TLBINV;
L
Leonid Yegoshin 已提交
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
		mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF;
		switch (mmuextdef) {
		case MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT:
			c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
			c->tlbsizevtlb = c->tlbsize;
			break;
		case MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT:
			c->tlbsizevtlb +=
				((config4 & MIPS_CONF4_VTLBSIZEEXT) >>
				  MIPS_CONF4_VTLBSIZEEXT_SHIFT) * 0x40;
			c->tlbsize = c->tlbsizevtlb;
			ftlb_page = MIPS_CONF4_VFTLBPAGESIZE;
			/* fall through */
		case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT:
			newcf4 = (config4 & ~ftlb_page) |
				(page_size_ftlb(mmuextdef) <<
				 MIPS_CONF4_FTLBPAGESIZE_SHIFT);
			write_c0_config4(newcf4);
			back_to_back_c0_hazard();
			config4 = read_c0_config4();
			if (config4 != newcf4) {
				pr_err("PAGE_SIZE 0x%lx is not supported by FTLB (config4=0x%x)\n",
				       PAGE_SIZE, config4);
				/* Switch FTLB off */
				set_ftlb_enable(c, 0);
				break;
			}
			c->tlbsizeftlbsets = 1 <<
				((config4 & MIPS_CONF4_FTLBSETS) >>
				 MIPS_CONF4_FTLBSETS_SHIFT);
			c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >>
					      MIPS_CONF4_FTLBWAYS_SHIFT) + 2;
			c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets;
			break;
		}
391 392
	}

393 394 395 396 397
	c->kscratch_mask = (config4 >> 16) & 0xff;

	return config4 & MIPS_CONF_M;
}

398 399 400 401 402 403 404 405
static inline unsigned int decode_config5(struct cpuinfo_mips *c)
{
	unsigned int config5;

	config5 = read_c0_config5();
	config5 &= ~MIPS_CONF5_UFR;
	write_c0_config5(config5);

406 407
	if (config5 & MIPS_CONF5_EVA)
		c->options |= MIPS_CPU_EVA;
P
Paul Burton 已提交
408 409
	if (config5 & MIPS_CONF5_MRP)
		c->options |= MIPS_CPU_MAAR;
410

411 412 413
	return config5 & MIPS_CONF_M;
}

414
static void decode_configs(struct cpuinfo_mips *c)
415 416 417 418 419 420 421 422 423
{
	int ok;

	/* MIPS32 or MIPS64 compliant CPU.  */
	c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER |
		     MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK;

	c->scache.flags = MIPS_CACHE_NOT_PRESENT;

L
Leonid Yegoshin 已提交
424 425 426
	/* Enable FTLB if present */
	set_ftlb_enable(c, 1);

427
	ok = decode_config0(c);			/* Read Config registers.  */
R
Ralf Baechle 已提交
428
	BUG_ON(!ok);				/* Arch spec violation!	 */
429 430 431 432 433 434 435 436
	if (ok)
		ok = decode_config1(c);
	if (ok)
		ok = decode_config2(c);
	if (ok)
		ok = decode_config3(c);
	if (ok)
		ok = decode_config4(c);
437 438
	if (ok)
		ok = decode_config5(c);
439 440 441

	mips_probe_watch_registers(c);

442 443 444 445 446 447 448 449 450
	if (cpu_has_rixi) {
		/* Enable the RIXI exceptions */
		write_c0_pagegrain(read_c0_pagegrain() | PG_IEC);
		back_to_back_c0_hazard();
		/* Verify the IEC bit is set */
		if (read_c0_pagegrain() & PG_IEC)
			c->options |= MIPS_CPU_RIXIEX;
	}

451
#ifndef CONFIG_MIPS_CPS
452
	if (cpu_has_mips_r2) {
453
		c->core = get_ebase_cpunum();
454 455 456
		if (cpu_has_mipsmt)
			c->core >>= fls(core_nvpes()) - 1;
	}
457
#endif
458 459
}

R
Ralf Baechle 已提交
460
#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \
L
Linus Torvalds 已提交
461 462
		| MIPS_CPU_COUNTER)

463
static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
464
{
465
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
466 467
	case PRID_IMP_R2000:
		c->cputype = CPU_R2000;
468
		__cpu_name[cpu] = "R2000";
R
Ralf Baechle 已提交
469
		c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
S
Steven J. Hill 已提交
470
			     MIPS_CPU_NOFPUEX;
L
Linus Torvalds 已提交
471 472 473 474 475
		if (__cpu_has_fpu())
			c->options |= MIPS_CPU_FPU;
		c->tlbsize = 64;
		break;
	case PRID_IMP_R3000:
476
		if ((c->processor_id & PRID_REV_MASK) == PRID_REV_R3000A) {
477
			if (cpu_has_confreg()) {
L
Linus Torvalds 已提交
478
				c->cputype = CPU_R3081E;
479 480
				__cpu_name[cpu] = "R3081";
			} else {
L
Linus Torvalds 已提交
481
				c->cputype = CPU_R3000A;
482 483 484
				__cpu_name[cpu] = "R3000A";
			}
		} else {
L
Linus Torvalds 已提交
485
			c->cputype = CPU_R3000;
486 487
			__cpu_name[cpu] = "R3000";
		}
R
Ralf Baechle 已提交
488
		c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
S
Steven J. Hill 已提交
489
			     MIPS_CPU_NOFPUEX;
L
Linus Torvalds 已提交
490 491 492 493 494 495
		if (__cpu_has_fpu())
			c->options |= MIPS_CPU_FPU;
		c->tlbsize = 64;
		break;
	case PRID_IMP_R4000:
		if (read_c0_config() & CONF_SC) {
496 497
			if ((c->processor_id & PRID_REV_MASK) >=
			    PRID_REV_R4400) {
L
Linus Torvalds 已提交
498
				c->cputype = CPU_R4400PC;
499 500
				__cpu_name[cpu] = "R4400PC";
			} else {
L
Linus Torvalds 已提交
501
				c->cputype = CPU_R4000PC;
502 503
				__cpu_name[cpu] = "R4000PC";
			}
L
Linus Torvalds 已提交
504
		} else {
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524
			int cca = read_c0_config() & CONF_CM_CMASK;
			int mc;

			/*
			 * SC and MC versions can't be reliably told apart,
			 * but only the latter support coherent caching
			 * modes so assume the firmware has set the KSEG0
			 * coherency attribute reasonably (if uncached, we
			 * assume SC).
			 */
			switch (cca) {
			case CONF_CM_CACHABLE_CE:
			case CONF_CM_CACHABLE_COW:
			case CONF_CM_CACHABLE_CUW:
				mc = 1;
				break;
			default:
				mc = 0;
				break;
			}
525 526
			if ((c->processor_id & PRID_REV_MASK) >=
			    PRID_REV_R4400) {
527 528
				c->cputype = mc ? CPU_R4400MC : CPU_R4400SC;
				__cpu_name[cpu] = mc ? "R4400MC" : "R4400SC";
529
			} else {
530 531
				c->cputype = mc ? CPU_R4000MC : CPU_R4000SC;
				__cpu_name[cpu] = mc ? "R4000MC" : "R4000SC";
532
			}
L
Linus Torvalds 已提交
533 534
		}

535
		set_isa(c, MIPS_CPU_ISA_III);
L
Linus Torvalds 已提交
536
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
537 538
			     MIPS_CPU_WATCH | MIPS_CPU_VCE |
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
539 540 541
		c->tlbsize = 48;
		break;
	case PRID_IMP_VR41XX:
542 543 544
		set_isa(c, MIPS_CPU_ISA_III);
		c->options = R4K_OPTS;
		c->tlbsize = 32;
L
Linus Torvalds 已提交
545 546 547
		switch (c->processor_id & 0xf0) {
		case PRID_REV_VR4111:
			c->cputype = CPU_VR4111;
548
			__cpu_name[cpu] = "NEC VR4111";
L
Linus Torvalds 已提交
549 550 551
			break;
		case PRID_REV_VR4121:
			c->cputype = CPU_VR4121;
552
			__cpu_name[cpu] = "NEC VR4121";
L
Linus Torvalds 已提交
553 554
			break;
		case PRID_REV_VR4122:
555
			if ((c->processor_id & 0xf) < 0x3) {
L
Linus Torvalds 已提交
556
				c->cputype = CPU_VR4122;
557 558
				__cpu_name[cpu] = "NEC VR4122";
			} else {
L
Linus Torvalds 已提交
559
				c->cputype = CPU_VR4181A;
560 561
				__cpu_name[cpu] = "NEC VR4181A";
			}
L
Linus Torvalds 已提交
562 563
			break;
		case PRID_REV_VR4130:
564
			if ((c->processor_id & 0xf) < 0x4) {
L
Linus Torvalds 已提交
565
				c->cputype = CPU_VR4131;
566 567
				__cpu_name[cpu] = "NEC VR4131";
			} else {
L
Linus Torvalds 已提交
568
				c->cputype = CPU_VR4133;
569
				c->options |= MIPS_CPU_LLSC;
570 571
				__cpu_name[cpu] = "NEC VR4133";
			}
L
Linus Torvalds 已提交
572 573 574 575
			break;
		default:
			printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
			c->cputype = CPU_VR41XX;
576
			__cpu_name[cpu] = "NEC Vr41xx";
L
Linus Torvalds 已提交
577 578 579 580 581
			break;
		}
		break;
	case PRID_IMP_R4300:
		c->cputype = CPU_R4300;
582
		__cpu_name[cpu] = "R4300";
583
		set_isa(c, MIPS_CPU_ISA_III);
L
Linus Torvalds 已提交
584
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
585
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
586 587 588 589
		c->tlbsize = 32;
		break;
	case PRID_IMP_R4600:
		c->cputype = CPU_R4600;
590
		__cpu_name[cpu] = "R4600";
591
		set_isa(c, MIPS_CPU_ISA_III);
T
Thiemo Seufer 已提交
592 593
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
594 595 596
		c->tlbsize = 48;
		break;
	#if 0
S
Steven J. Hill 已提交
597
	case PRID_IMP_R4650:
L
Linus Torvalds 已提交
598 599 600 601 602 603
		/*
		 * This processor doesn't have an MMU, so it's not
		 * "real easy" to run Linux on it. It is left purely
		 * for documentation.  Commented out because it shares
		 * it's c0_prid id number with the TX3900.
		 */
604
		c->cputype = CPU_R4650;
605
		__cpu_name[cpu] = "R4650";
606
		set_isa(c, MIPS_CPU_ISA_III);
L
Linus Torvalds 已提交
607
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
S
Steven J. Hill 已提交
608
		c->tlbsize = 48;
L
Linus Torvalds 已提交
609 610 611
		break;
	#endif
	case PRID_IMP_TX39:
R
Ralf Baechle 已提交
612
		c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE;
L
Linus Torvalds 已提交
613 614 615

		if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) {
			c->cputype = CPU_TX3927;
616
			__cpu_name[cpu] = "TX3927";
L
Linus Torvalds 已提交
617 618
			c->tlbsize = 64;
		} else {
619
			switch (c->processor_id & PRID_REV_MASK) {
L
Linus Torvalds 已提交
620 621
			case PRID_REV_TX3912:
				c->cputype = CPU_TX3912;
622
				__cpu_name[cpu] = "TX3912";
L
Linus Torvalds 已提交
623 624 625 626
				c->tlbsize = 32;
				break;
			case PRID_REV_TX3922:
				c->cputype = CPU_TX3922;
627
				__cpu_name[cpu] = "TX3922";
L
Linus Torvalds 已提交
628 629 630 631 632 633 634
				c->tlbsize = 64;
				break;
			}
		}
		break;
	case PRID_IMP_R4700:
		c->cputype = CPU_R4700;
635
		__cpu_name[cpu] = "R4700";
636
		set_isa(c, MIPS_CPU_ISA_III);
L
Linus Torvalds 已提交
637
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
638
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
639 640 641 642
		c->tlbsize = 48;
		break;
	case PRID_IMP_TX49:
		c->cputype = CPU_TX49XX;
643
		__cpu_name[cpu] = "R49XX";
644
		set_isa(c, MIPS_CPU_ISA_III);
L
Linus Torvalds 已提交
645 646 647 648 649 650 651
		c->options = R4K_OPTS | MIPS_CPU_LLSC;
		if (!(c->processor_id & 0x08))
			c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR;
		c->tlbsize = 48;
		break;
	case PRID_IMP_R5000:
		c->cputype = CPU_R5000;
652
		__cpu_name[cpu] = "R5000";
653
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
654
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
655
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
656 657 658 659
		c->tlbsize = 48;
		break;
	case PRID_IMP_R5432:
		c->cputype = CPU_R5432;
660
		__cpu_name[cpu] = "R5432";
661
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
662
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
663
			     MIPS_CPU_WATCH | MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
664 665 666 667
		c->tlbsize = 48;
		break;
	case PRID_IMP_R5500:
		c->cputype = CPU_R5500;
668
		__cpu_name[cpu] = "R5500";
669
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
670
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
671
			     MIPS_CPU_WATCH | MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
672 673 674 675
		c->tlbsize = 48;
		break;
	case PRID_IMP_NEVADA:
		c->cputype = CPU_NEVADA;
676
		__cpu_name[cpu] = "Nevada";
677
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
678
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
679
			     MIPS_CPU_DIVEC | MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
680 681 682 683
		c->tlbsize = 48;
		break;
	case PRID_IMP_R6000:
		c->cputype = CPU_R6000;
684
		__cpu_name[cpu] = "R6000";
685
		set_isa(c, MIPS_CPU_ISA_II);
L
Linus Torvalds 已提交
686
		c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
S
Steven J. Hill 已提交
687
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
688 689 690 691
		c->tlbsize = 32;
		break;
	case PRID_IMP_R6000A:
		c->cputype = CPU_R6000A;
692
		__cpu_name[cpu] = "R6000A";
693
		set_isa(c, MIPS_CPU_ISA_II);
L
Linus Torvalds 已提交
694
		c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
S
Steven J. Hill 已提交
695
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
696 697 698 699
		c->tlbsize = 32;
		break;
	case PRID_IMP_RM7000:
		c->cputype = CPU_RM7000;
700
		__cpu_name[cpu] = "RM7000";
701
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
702
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
703
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
704
		/*
R
Ralf Baechle 已提交
705
		 * Undocumented RM7000:	 Bit 29 in the info register of
L
Linus Torvalds 已提交
706 707 708
		 * the RM7000 v2.0 indicates if the TLB has 48 or 64
		 * entries.
		 *
R
Ralf Baechle 已提交
709 710
		 * 29	   1 =>	   64 entry JTLB
		 *	   0 =>	   48 entry JTLB
L
Linus Torvalds 已提交
711 712 713 714 715
		 */
		c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48;
		break;
	case PRID_IMP_R8000:
		c->cputype = CPU_R8000;
716
		__cpu_name[cpu] = "RM8000";
717
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
718
		c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
S
Steven J. Hill 已提交
719 720
			     MIPS_CPU_FPU | MIPS_CPU_32FPR |
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
721 722 723 724
		c->tlbsize = 384;      /* has weird TLB: 3-way x 128 */
		break;
	case PRID_IMP_R10000:
		c->cputype = CPU_R10000;
725
		__cpu_name[cpu] = "R10000";
726
		set_isa(c, MIPS_CPU_ISA_IV);
727
		c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
S
Steven J. Hill 已提交
728
			     MIPS_CPU_FPU | MIPS_CPU_32FPR |
L
Linus Torvalds 已提交
729
			     MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
S
Steven J. Hill 已提交
730
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
731 732 733 734
		c->tlbsize = 64;
		break;
	case PRID_IMP_R12000:
		c->cputype = CPU_R12000;
735
		__cpu_name[cpu] = "R12000";
736
		set_isa(c, MIPS_CPU_ISA_IV);
737
		c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
S
Steven J. Hill 已提交
738
			     MIPS_CPU_FPU | MIPS_CPU_32FPR |
L
Linus Torvalds 已提交
739
			     MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
S
Steven J. Hill 已提交
740
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
741 742
		c->tlbsize = 64;
		break;
K
Kumba 已提交
743 744
	case PRID_IMP_R14000:
		c->cputype = CPU_R14000;
745
		__cpu_name[cpu] = "R14000";
746
		set_isa(c, MIPS_CPU_ISA_IV);
K
Kumba 已提交
747
		c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
S
Steven J. Hill 已提交
748
			     MIPS_CPU_FPU | MIPS_CPU_32FPR |
K
Kumba 已提交
749
			     MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
S
Steven J. Hill 已提交
750
			     MIPS_CPU_LLSC;
K
Kumba 已提交
751 752
		c->tlbsize = 64;
		break;
753
	case PRID_IMP_LOONGSON_64:  /* Loongson-2/3 */
754 755
		switch (c->processor_id & PRID_REV_MASK) {
		case PRID_REV_LOONGSON2E:
756 757
			c->cputype = CPU_LOONGSON2;
			__cpu_name[cpu] = "ICT Loongson-2";
758 759 760
			set_elf_platform(cpu, "loongson2e");
			break;
		case PRID_REV_LOONGSON2F:
761 762
			c->cputype = CPU_LOONGSON2;
			__cpu_name[cpu] = "ICT Loongson-2";
763 764
			set_elf_platform(cpu, "loongson2f");
			break;
765 766 767 768 769
		case PRID_REV_LOONGSON3A:
			c->cputype = CPU_LOONGSON3;
			__cpu_name[cpu] = "ICT Loongson-3";
			set_elf_platform(cpu, "loongson3a");
			break;
H
Huacai Chen 已提交
770 771 772 773 774 775
		case PRID_REV_LOONGSON3B_R1:
		case PRID_REV_LOONGSON3B_R2:
			c->cputype = CPU_LOONGSON3;
			__cpu_name[cpu] = "ICT Loongson-3";
			set_elf_platform(cpu, "loongson3b");
			break;
776 777
		}

778
		set_isa(c, MIPS_CPU_ISA_III);
779 780 781 782 783
		c->options = R4K_OPTS |
			     MIPS_CPU_FPU | MIPS_CPU_LLSC |
			     MIPS_CPU_32FPR;
		c->tlbsize = 64;
		break;
784
	case PRID_IMP_LOONGSON_32:  /* Loongson-1 */
785
		decode_configs(c);
786

787
		c->cputype = CPU_LOONGSON1;
L
Linus Torvalds 已提交
788

789 790 791
		switch (c->processor_id & PRID_REV_MASK) {
		case PRID_REV_LOONGSON1B:
			__cpu_name[cpu] = "Loongson 1B";
792 793
			break;
		}
794

795
		break;
L
Linus Torvalds 已提交
796 797 798
	}
}

799
static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
800
{
801
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
802 803
	case PRID_IMP_4KC:
		c->cputype = CPU_4KC;
804
		__cpu_name[cpu] = "MIPS 4Kc";
L
Linus Torvalds 已提交
805 806
		break;
	case PRID_IMP_4KEC:
807 808
	case PRID_IMP_4KECR2:
		c->cputype = CPU_4KEC;
809
		__cpu_name[cpu] = "MIPS 4KEc";
810
		break;
L
Linus Torvalds 已提交
811
	case PRID_IMP_4KSC:
R
Ralf Baechle 已提交
812
	case PRID_IMP_4KSD:
L
Linus Torvalds 已提交
813
		c->cputype = CPU_4KSC;
814
		__cpu_name[cpu] = "MIPS 4KSc";
L
Linus Torvalds 已提交
815 816 817
		break;
	case PRID_IMP_5KC:
		c->cputype = CPU_5KC;
818
		__cpu_name[cpu] = "MIPS 5Kc";
L
Linus Torvalds 已提交
819
		break;
L
Leonid Yegoshin 已提交
820 821 822 823
	case PRID_IMP_5KE:
		c->cputype = CPU_5KE;
		__cpu_name[cpu] = "MIPS 5KE";
		break;
L
Linus Torvalds 已提交
824 825
	case PRID_IMP_20KC:
		c->cputype = CPU_20KC;
826
		__cpu_name[cpu] = "MIPS 20Kc";
L
Linus Torvalds 已提交
827 828 829
		break;
	case PRID_IMP_24K:
		c->cputype = CPU_24K;
830
		__cpu_name[cpu] = "MIPS 24Kc";
L
Linus Torvalds 已提交
831
		break;
832 833 834 835
	case PRID_IMP_24KE:
		c->cputype = CPU_24K;
		__cpu_name[cpu] = "MIPS 24KEc";
		break;
L
Linus Torvalds 已提交
836 837
	case PRID_IMP_25KF:
		c->cputype = CPU_25KF;
838
		__cpu_name[cpu] = "MIPS 25Kc";
L
Linus Torvalds 已提交
839
		break;
R
Ralf Baechle 已提交
840 841
	case PRID_IMP_34K:
		c->cputype = CPU_34K;
842
		__cpu_name[cpu] = "MIPS 34Kc";
R
Ralf Baechle 已提交
843
		break;
844 845
	case PRID_IMP_74K:
		c->cputype = CPU_74K;
846
		__cpu_name[cpu] = "MIPS 74Kc";
847
		break;
848 849 850 851
	case PRID_IMP_M14KC:
		c->cputype = CPU_M14KC;
		__cpu_name[cpu] = "MIPS M14Kc";
		break;
852 853 854 855
	case PRID_IMP_M14KEC:
		c->cputype = CPU_M14KEC;
		__cpu_name[cpu] = "MIPS M14KEc";
		break;
856 857
	case PRID_IMP_1004K:
		c->cputype = CPU_1004K;
858
		__cpu_name[cpu] = "MIPS 1004Kc";
859
		break;
860
	case PRID_IMP_1074K:
861
		c->cputype = CPU_1074K;
862 863
		__cpu_name[cpu] = "MIPS 1074Kc";
		break;
864 865 866 867 868 869 870 871
	case PRID_IMP_INTERAPTIV_UP:
		c->cputype = CPU_INTERAPTIV;
		__cpu_name[cpu] = "MIPS interAptiv";
		break;
	case PRID_IMP_INTERAPTIV_MP:
		c->cputype = CPU_INTERAPTIV;
		__cpu_name[cpu] = "MIPS interAptiv (multi)";
		break;
872 873 874 875 876 877 878 879
	case PRID_IMP_PROAPTIV_UP:
		c->cputype = CPU_PROAPTIV;
		__cpu_name[cpu] = "MIPS proAptiv";
		break;
	case PRID_IMP_PROAPTIV_MP:
		c->cputype = CPU_PROAPTIV;
		__cpu_name[cpu] = "MIPS proAptiv (multi)";
		break;
J
James Hogan 已提交
880 881 882 883
	case PRID_IMP_P5600:
		c->cputype = CPU_P5600;
		__cpu_name[cpu] = "MIPS P5600";
		break;
884 885 886 887
	case PRID_IMP_M5150:
		c->cputype = CPU_M5150;
		__cpu_name[cpu] = "MIPS M5150";
		break;
L
Linus Torvalds 已提交
888
	}
C
Chris Dearman 已提交
889

L
Leonid Yegoshin 已提交
890 891
	decode_configs(c);

C
Chris Dearman 已提交
892
	spram_config();
L
Linus Torvalds 已提交
893 894
}

895
static inline void cpu_probe_alchemy(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
896
{
897
	decode_configs(c);
898
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
899 900
	case PRID_IMP_AU1_REV1:
	case PRID_IMP_AU1_REV2:
901
		c->cputype = CPU_ALCHEMY;
L
Linus Torvalds 已提交
902 903
		switch ((c->processor_id >> 24) & 0xff) {
		case 0:
904
			__cpu_name[cpu] = "Au1000";
L
Linus Torvalds 已提交
905 906
			break;
		case 1:
907
			__cpu_name[cpu] = "Au1500";
L
Linus Torvalds 已提交
908 909
			break;
		case 2:
910
			__cpu_name[cpu] = "Au1100";
L
Linus Torvalds 已提交
911 912
			break;
		case 3:
913
			__cpu_name[cpu] = "Au1550";
L
Linus Torvalds 已提交
914
			break;
P
Pete Popov 已提交
915
		case 4:
916
			__cpu_name[cpu] = "Au1200";
917
			if ((c->processor_id & PRID_REV_MASK) == 2)
918
				__cpu_name[cpu] = "Au1250";
919 920
			break;
		case 5:
921
			__cpu_name[cpu] = "Au1210";
P
Pete Popov 已提交
922
			break;
L
Linus Torvalds 已提交
923
		default:
924
			__cpu_name[cpu] = "Au1xxx";
L
Linus Torvalds 已提交
925 926 927 928 929 930
			break;
		}
		break;
	}
}

931
static inline void cpu_probe_sibyte(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
932
{
933
	decode_configs(c);
R
Ralf Baechle 已提交
934

935
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
936 937
	case PRID_IMP_SB1:
		c->cputype = CPU_SB1;
938
		__cpu_name[cpu] = "SiByte SB1";
L
Linus Torvalds 已提交
939
		/* FPU in pass1 is known to have issues. */
940
		if ((c->processor_id & PRID_REV_MASK) < 0x02)
941
			c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR);
L
Linus Torvalds 已提交
942
		break;
A
Andrew Isaacson 已提交
943 944
	case PRID_IMP_SB1A:
		c->cputype = CPU_SB1A;
945
		__cpu_name[cpu] = "SiByte SB1A";
A
Andrew Isaacson 已提交
946
		break;
L
Linus Torvalds 已提交
947 948 949
	}
}

950
static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
951
{
952
	decode_configs(c);
953
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
954 955
	case PRID_IMP_SR71000:
		c->cputype = CPU_SR71000;
956
		__cpu_name[cpu] = "Sandcraft SR71000";
L
Linus Torvalds 已提交
957 958 959 960 961 962
		c->scache.ways = 8;
		c->tlbsize = 64;
		break;
	}
}

963
static inline void cpu_probe_nxp(struct cpuinfo_mips *c, unsigned int cpu)
964 965
{
	decode_configs(c);
966
	switch (c->processor_id & PRID_IMP_MASK) {
967 968
	case PRID_IMP_PR4450:
		c->cputype = CPU_PR4450;
969
		__cpu_name[cpu] = "Philips PR4450";
970
		set_isa(c, MIPS_CPU_ISA_M32R1);
971 972 973 974
		break;
	}
}

975
static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
976 977
{
	decode_configs(c);
978
	switch (c->processor_id & PRID_IMP_MASK) {
979 980
	case PRID_IMP_BMIPS32_REV4:
	case PRID_IMP_BMIPS32_REV8:
981 982
		c->cputype = CPU_BMIPS32;
		__cpu_name[cpu] = "Broadcom BMIPS32";
983
		set_elf_platform(cpu, "bmips32");
984 985 986 987 988 989
		break;
	case PRID_IMP_BMIPS3300:
	case PRID_IMP_BMIPS3300_ALT:
	case PRID_IMP_BMIPS3300_BUG:
		c->cputype = CPU_BMIPS3300;
		__cpu_name[cpu] = "Broadcom BMIPS3300";
990
		set_elf_platform(cpu, "bmips3300");
991 992
		break;
	case PRID_IMP_BMIPS43XX: {
993
		int rev = c->processor_id & PRID_REV_MASK;
994 995 996 997 998

		if (rev >= PRID_REV_BMIPS4380_LO &&
				rev <= PRID_REV_BMIPS4380_HI) {
			c->cputype = CPU_BMIPS4380;
			__cpu_name[cpu] = "Broadcom BMIPS4380";
999
			set_elf_platform(cpu, "bmips4380");
1000 1001 1002
		} else {
			c->cputype = CPU_BMIPS4350;
			__cpu_name[cpu] = "Broadcom BMIPS4350";
1003
			set_elf_platform(cpu, "bmips4350");
1004
		}
1005
		break;
1006 1007 1008 1009
	}
	case PRID_IMP_BMIPS5000:
		c->cputype = CPU_BMIPS5000;
		__cpu_name[cpu] = "Broadcom BMIPS5000";
1010
		set_elf_platform(cpu, "bmips5000");
1011
		c->options |= MIPS_CPU_ULRI;
1012
		break;
1013 1014 1015
	}
}

1016 1017 1018
static inline void cpu_probe_cavium(struct cpuinfo_mips *c, unsigned int cpu)
{
	decode_configs(c);
1019
	switch (c->processor_id & PRID_IMP_MASK) {
1020 1021 1022
	case PRID_IMP_CAVIUM_CN38XX:
	case PRID_IMP_CAVIUM_CN31XX:
	case PRID_IMP_CAVIUM_CN30XX:
1023 1024 1025
		c->cputype = CPU_CAVIUM_OCTEON;
		__cpu_name[cpu] = "Cavium Octeon";
		goto platform;
1026 1027 1028 1029
	case PRID_IMP_CAVIUM_CN58XX:
	case PRID_IMP_CAVIUM_CN56XX:
	case PRID_IMP_CAVIUM_CN50XX:
	case PRID_IMP_CAVIUM_CN52XX:
1030 1031 1032
		c->cputype = CPU_CAVIUM_OCTEON_PLUS;
		__cpu_name[cpu] = "Cavium Octeon+";
platform:
1033
		set_elf_platform(cpu, "octeon");
1034
		break;
1035
	case PRID_IMP_CAVIUM_CN61XX:
1036
	case PRID_IMP_CAVIUM_CN63XX:
1037 1038
	case PRID_IMP_CAVIUM_CN66XX:
	case PRID_IMP_CAVIUM_CN68XX:
1039
	case PRID_IMP_CAVIUM_CNF71XX:
1040 1041
		c->cputype = CPU_CAVIUM_OCTEON2;
		__cpu_name[cpu] = "Cavium Octeon II";
1042
		set_elf_platform(cpu, "octeon2");
1043
		break;
1044 1045 1046 1047 1048 1049
	case PRID_IMP_CAVIUM_CN70XX:
	case PRID_IMP_CAVIUM_CN78XX:
		c->cputype = CPU_CAVIUM_OCTEON3;
		__cpu_name[cpu] = "Cavium Octeon III";
		set_elf_platform(cpu, "octeon3");
		break;
1050 1051 1052 1053 1054 1055 1056
	default:
		printk(KERN_INFO "Unknown Octeon chip!\n");
		c->cputype = CPU_UNKNOWN;
		break;
	}
}

1057 1058 1059 1060 1061
static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
{
	decode_configs(c);
	/* JZRISC does not implement the CP0 counter. */
	c->options &= ~MIPS_CPU_COUNTER;
1062
	BUG_ON(!__builtin_constant_p(cpu_has_counter) || cpu_has_counter);
1063
	switch (c->processor_id & PRID_IMP_MASK) {
1064 1065 1066 1067 1068 1069 1070 1071 1072 1073
	case PRID_IMP_JZRISC:
		c->cputype = CPU_JZRISC;
		__cpu_name[cpu] = "Ingenic JZRISC";
		break;
	default:
		panic("Unknown Ingenic Processor ID!");
		break;
	}
}

1074 1075 1076 1077
static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
{
	decode_configs(c);

1078
	if ((c->processor_id & PRID_IMP_MASK) == PRID_IMP_NETLOGIC_AU13XX) {
M
Manuel Lauss 已提交
1079 1080 1081 1082 1083 1084
		c->cputype = CPU_ALCHEMY;
		__cpu_name[cpu] = "Au1300";
		/* following stuff is not for Alchemy */
		return;
	}

R
Ralf Baechle 已提交
1085 1086
	c->options = (MIPS_CPU_TLB	 |
			MIPS_CPU_4KEX	 |
1087
			MIPS_CPU_COUNTER |
R
Ralf Baechle 已提交
1088 1089 1090
			MIPS_CPU_DIVEC	 |
			MIPS_CPU_WATCH	 |
			MIPS_CPU_EJTAG	 |
1091 1092
			MIPS_CPU_LLSC);

1093
	switch (c->processor_id & PRID_IMP_MASK) {
1094
	case PRID_IMP_NETLOGIC_XLP2XX:
1095
	case PRID_IMP_NETLOGIC_XLP9XX:
1096
	case PRID_IMP_NETLOGIC_XLP5XX:
1097 1098 1099 1100
		c->cputype = CPU_XLP;
		__cpu_name[cpu] = "Broadcom XLPII";
		break;

1101 1102
	case PRID_IMP_NETLOGIC_XLP8XX:
	case PRID_IMP_NETLOGIC_XLP3XX:
J
Jayachandran C 已提交
1103 1104 1105 1106
		c->cputype = CPU_XLP;
		__cpu_name[cpu] = "Netlogic XLP";
		break;

1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136
	case PRID_IMP_NETLOGIC_XLR732:
	case PRID_IMP_NETLOGIC_XLR716:
	case PRID_IMP_NETLOGIC_XLR532:
	case PRID_IMP_NETLOGIC_XLR308:
	case PRID_IMP_NETLOGIC_XLR532C:
	case PRID_IMP_NETLOGIC_XLR516C:
	case PRID_IMP_NETLOGIC_XLR508C:
	case PRID_IMP_NETLOGIC_XLR308C:
		c->cputype = CPU_XLR;
		__cpu_name[cpu] = "Netlogic XLR";
		break;

	case PRID_IMP_NETLOGIC_XLS608:
	case PRID_IMP_NETLOGIC_XLS408:
	case PRID_IMP_NETLOGIC_XLS404:
	case PRID_IMP_NETLOGIC_XLS208:
	case PRID_IMP_NETLOGIC_XLS204:
	case PRID_IMP_NETLOGIC_XLS108:
	case PRID_IMP_NETLOGIC_XLS104:
	case PRID_IMP_NETLOGIC_XLS616B:
	case PRID_IMP_NETLOGIC_XLS608B:
	case PRID_IMP_NETLOGIC_XLS416B:
	case PRID_IMP_NETLOGIC_XLS412B:
	case PRID_IMP_NETLOGIC_XLS408B:
	case PRID_IMP_NETLOGIC_XLS404B:
		c->cputype = CPU_XLR;
		__cpu_name[cpu] = "Netlogic XLS";
		break;

	default:
J
Jayachandran C 已提交
1137
		pr_info("Unknown Netlogic chip id [%02x]!\n",
1138 1139 1140 1141 1142
		       c->processor_id);
		c->cputype = CPU_XLR;
		break;
	}

J
Jayachandran C 已提交
1143
	if (c->cputype == CPU_XLP) {
1144
		set_isa(c, MIPS_CPU_ISA_M64R2);
J
Jayachandran C 已提交
1145 1146 1147 1148
		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 {
1149
		set_isa(c, MIPS_CPU_ISA_M64R1);
J
Jayachandran C 已提交
1150 1151
		c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1;
	}
1152
	c->kscratch_mask = 0xf;
1153 1154
}

1155 1156 1157 1158 1159 1160
#ifdef CONFIG_64BIT
/* For use by uaccess.h */
u64 __ua_limit;
EXPORT_SYMBOL(__ua_limit);
#endif

1161
const char *__cpu_name[NR_CPUS];
1162
const char *__elf_platform;
1163

1164
void cpu_probe(void)
L
Linus Torvalds 已提交
1165 1166
{
	struct cpuinfo_mips *c = &current_cpu_data;
1167
	unsigned int cpu = smp_processor_id();
L
Linus Torvalds 已提交
1168

R
Ralf Baechle 已提交
1169
	c->processor_id = PRID_IMP_UNKNOWN;
L
Linus Torvalds 已提交
1170 1171 1172 1173
	c->fpu_id	= FPIR_IMP_NONE;
	c->cputype	= CPU_UNKNOWN;

	c->processor_id = read_c0_prid();
1174
	switch (c->processor_id & PRID_COMP_MASK) {
L
Linus Torvalds 已提交
1175
	case PRID_COMP_LEGACY:
1176
		cpu_probe_legacy(c, cpu);
L
Linus Torvalds 已提交
1177 1178
		break;
	case PRID_COMP_MIPS:
1179
		cpu_probe_mips(c, cpu);
L
Linus Torvalds 已提交
1180 1181
		break;
	case PRID_COMP_ALCHEMY:
1182
		cpu_probe_alchemy(c, cpu);
L
Linus Torvalds 已提交
1183 1184
		break;
	case PRID_COMP_SIBYTE:
1185
		cpu_probe_sibyte(c, cpu);
L
Linus Torvalds 已提交
1186
		break;
1187
	case PRID_COMP_BROADCOM:
1188
		cpu_probe_broadcom(c, cpu);
1189
		break;
L
Linus Torvalds 已提交
1190
	case PRID_COMP_SANDCRAFT:
1191
		cpu_probe_sandcraft(c, cpu);
L
Linus Torvalds 已提交
1192
		break;
1193
	case PRID_COMP_NXP:
1194
		cpu_probe_nxp(c, cpu);
1195
		break;
1196 1197 1198
	case PRID_COMP_CAVIUM:
		cpu_probe_cavium(c, cpu);
		break;
1199 1200 1201
	case PRID_COMP_INGENIC:
		cpu_probe_ingenic(c, cpu);
		break;
1202 1203 1204
	case PRID_COMP_NETLOGIC:
		cpu_probe_netlogic(c, cpu);
		break;
L
Linus Torvalds 已提交
1205
	}
1206

1207 1208 1209
	BUG_ON(!__cpu_name[cpu]);
	BUG_ON(c->cputype == CPU_UNKNOWN);

1210 1211 1212 1213 1214 1215 1216
	/*
	 * Platform code can force the cpu type to optimize code
	 * generation. In that case be sure the cpu type is correctly
	 * manually setup otherwise it could trigger some nasty bugs.
	 */
	BUG_ON(current_cpu_type() != c->cputype);

1217 1218 1219 1220
	if (mips_fpu_disabled)
		c->options &= ~MIPS_CPU_FPU;

	if (mips_dsp_disabled)
1221
		c->ases &= ~(MIPS_ASE_DSP | MIPS_ASE_DSP2P);
1222

1223 1224 1225 1226 1227 1228
	if (mips_htw_disabled) {
		c->options &= ~MIPS_CPU_HTW;
		write_c0_pwctl(read_c0_pwctl() &
			       ~(1 << MIPS_PWCTL_PWEN_SHIFT));
	}

1229
	if (c->options & MIPS_CPU_FPU) {
L
Linus Torvalds 已提交
1230
		c->fpu_id = cpu_get_fpu_id();
1231

1232 1233
		if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 |
				    MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) {
1234 1235 1236 1237
			if (c->fpu_id & MIPS_FPIR_3D)
				c->ases |= MIPS_ASE_MIPS3D;
		}
	}
1238

1239
	if (cpu_has_mips_r2) {
R
Ralf Baechle 已提交
1240
		c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
1241 1242 1243
		/* R2 has Performance Counter Interrupt indicator */
		c->options |= MIPS_CPU_PCI;
	}
R
Ralf Baechle 已提交
1244 1245
	else
		c->srsets = 1;
1246

1247
	if (cpu_has_msa) {
P
Paul Burton 已提交
1248
		c->msa_id = cpu_get_msa_id();
1249 1250 1251
		WARN(c->msa_id & MSA_IR_WRPF,
		     "Vector register partitioning unimplemented!");
	}
P
Paul Burton 已提交
1252

1253
	cpu_probe_vmbits(c);
1254 1255 1256 1257 1258

#ifdef CONFIG_64BIT
	if (cpu == 0)
		__ua_limit = ~((1ull << cpu_vmbits) - 1);
#endif
L
Linus Torvalds 已提交
1259 1260
}

1261
void cpu_report(void)
L
Linus Torvalds 已提交
1262 1263 1264
{
	struct cpuinfo_mips *c = &current_cpu_data;

1265 1266
	pr_info("CPU%d revision is: %08x (%s)\n",
		smp_processor_id(), c->processor_id, cpu_name_string());
L
Linus Torvalds 已提交
1267
	if (c->options & MIPS_CPU_FPU)
1268
		printk(KERN_INFO "FPU revision is: %08x\n", c->fpu_id);
P
Paul Burton 已提交
1269 1270
	if (cpu_has_msa)
		pr_info("MSA revision is: %08x\n", c->msa_id);
L
Linus Torvalds 已提交
1271
}