cpu-probe.c 31.3 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/pgtable-bits.h>
31
#include <asm/spram.h>
32 33
#include <asm/uaccess.h>

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

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

	return 1;
}

__setup("nofpu", fpu_disable);

46
int mips_dsp_disabled;
47 48 49

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

	return 1;
}

__setup("nodsp", dsp_disable);

58 59 60 61 62 63 64 65 66 67 68 69 70 71
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 已提交
72 73 74 75
static inline void check_errata(void)
{
	struct cpuinfo_mips *c = &current_cpu_data;

76
	switch (current_cpu_type()) {
M
Marc St-Jean 已提交
77 78 79
	case CPU_34K:
		/*
		 * Erratum "RPS May Cause Incorrect Instruction Execution"
R
Ralf Baechle 已提交
80
		 * This code only handles VPE0, any SMP/RTOS code
M
Marc St-Jean 已提交
81 82 83 84 85 86 87 88 89 90
		 * 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 已提交
91 92
void __init check_bugs32(void)
{
M
Marc St-Jean 已提交
93
	check_errata();
L
Linus Torvalds 已提交
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
}

/*
 * 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
}

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

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

	tmp = read_c0_status();
132
	__enable_fpu(FPU_AS_IS);
L
Linus Torvalds 已提交
133 134 135 136 137 138 139 140 141 142
	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)
{
R
Ralf Baechle 已提交
143
	return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE;
L
Linus Torvalds 已提交
144 145
}

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

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

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

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

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

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

	/* 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 已提交
205 206 207 208 209 210 211 212
		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();
213
		break;
L
Leonid Yegoshin 已提交
214 215 216
	}
}

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

	config0 = read_c0_config();

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

231 232 233 234 235
	isa = (config0 & MIPS_CONF_AT) >> 13;
	switch (isa) {
	case 0:
		switch ((config0 & MIPS_CONF_AR) >> 10) {
		case 0:
236
			set_isa(c, MIPS_CPU_ISA_M32R1);
237 238
			break;
		case 1:
239
			set_isa(c, MIPS_CPU_ISA_M32R2);
240 241 242 243 244 245 246 247
			break;
		default:
			goto unknown;
		}
		break;
	case 2:
		switch ((config0 & MIPS_CONF_AR) >> 10) {
		case 0:
248
			set_isa(c, MIPS_CPU_ISA_M64R1);
249 250
			break;
		case 1:
251
			set_isa(c, MIPS_CPU_ISA_M64R2);
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 284
			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 已提交
285
	if (cpu_has_tlb) {
286
		c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1;
L
Leonid Yegoshin 已提交
287 288 289
		c->tlbsizevtlb = c->tlbsize;
		c->tlbsizeftlbsets = 0;
	}
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311

	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();

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

	return config3 & MIPS_CONF_M;
}

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

	config4 = read_c0_config4();

354 355 356
	if (cpu_has_tlb) {
		if (((config4 & MIPS_CONF4_IE) >> 29) == 2)
			c->options |= MIPS_CPU_TLBINV;
L
Leonid Yegoshin 已提交
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 391
		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;
		}
392 393
	}

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

	return config4 & MIPS_CONF_M;
}

399 400 401 402 403 404 405 406
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);

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

412 413 414
	return config5 & MIPS_CONF_M;
}

415
static void decode_configs(struct cpuinfo_mips *c)
416 417 418 419 420 421 422 423 424
{
	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 已提交
425 426 427
	/* Enable FTLB if present */
	set_ftlb_enable(c, 1);

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

	mips_probe_watch_registers(c);

443 444 445 446 447 448 449 450 451
	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;
	}

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

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

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

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

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

783 784 785 786
		c->options = R4K_OPTS |
			     MIPS_CPU_FPU | MIPS_CPU_LLSC |
			     MIPS_CPU_32FPR;
		c->tlbsize = 64;
787
		c->writecombine = _CACHE_UNCACHED_ACCELERATED;
788
		break;
789
	case PRID_IMP_LOONGSON_32:  /* Loongson-1 */
790
		decode_configs(c);
791

792
		c->cputype = CPU_LOONGSON1;
L
Linus Torvalds 已提交
793

794 795 796
		switch (c->processor_id & PRID_REV_MASK) {
		case PRID_REV_LOONGSON1B:
			__cpu_name[cpu] = "Loongson 1B";
797 798
			break;
		}
799

800
		break;
L
Linus Torvalds 已提交
801 802 803
	}
}

804
static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
805
{
806
	c->writecombine = _CACHE_UNCACHED_ACCELERATED;
807
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
808 809
	case PRID_IMP_4KC:
		c->cputype = CPU_4KC;
810
		c->writecombine = _CACHE_UNCACHED;
811
		__cpu_name[cpu] = "MIPS 4Kc";
L
Linus Torvalds 已提交
812 813
		break;
	case PRID_IMP_4KEC:
814 815
	case PRID_IMP_4KECR2:
		c->cputype = CPU_4KEC;
816
		c->writecombine = _CACHE_UNCACHED;
817
		__cpu_name[cpu] = "MIPS 4KEc";
818
		break;
L
Linus Torvalds 已提交
819
	case PRID_IMP_4KSC:
R
Ralf Baechle 已提交
820
	case PRID_IMP_4KSD:
L
Linus Torvalds 已提交
821
		c->cputype = CPU_4KSC;
822
		c->writecombine = _CACHE_UNCACHED;
823
		__cpu_name[cpu] = "MIPS 4KSc";
L
Linus Torvalds 已提交
824 825 826
		break;
	case PRID_IMP_5KC:
		c->cputype = CPU_5KC;
827
		c->writecombine = _CACHE_UNCACHED;
828
		__cpu_name[cpu] = "MIPS 5Kc";
L
Linus Torvalds 已提交
829
		break;
L
Leonid Yegoshin 已提交
830 831
	case PRID_IMP_5KE:
		c->cputype = CPU_5KE;
832
		c->writecombine = _CACHE_UNCACHED;
L
Leonid Yegoshin 已提交
833 834
		__cpu_name[cpu] = "MIPS 5KE";
		break;
L
Linus Torvalds 已提交
835 836
	case PRID_IMP_20KC:
		c->cputype = CPU_20KC;
837
		c->writecombine = _CACHE_UNCACHED;
838
		__cpu_name[cpu] = "MIPS 20Kc";
L
Linus Torvalds 已提交
839 840 841
		break;
	case PRID_IMP_24K:
		c->cputype = CPU_24K;
842
		c->writecombine = _CACHE_UNCACHED;
843
		__cpu_name[cpu] = "MIPS 24Kc";
L
Linus Torvalds 已提交
844
		break;
845 846
	case PRID_IMP_24KE:
		c->cputype = CPU_24K;
847
		c->writecombine = _CACHE_UNCACHED;
848 849
		__cpu_name[cpu] = "MIPS 24KEc";
		break;
L
Linus Torvalds 已提交
850 851
	case PRID_IMP_25KF:
		c->cputype = CPU_25KF;
852
		c->writecombine = _CACHE_UNCACHED;
853
		__cpu_name[cpu] = "MIPS 25Kc";
L
Linus Torvalds 已提交
854
		break;
R
Ralf Baechle 已提交
855 856
	case PRID_IMP_34K:
		c->cputype = CPU_34K;
857
		c->writecombine = _CACHE_UNCACHED;
858
		__cpu_name[cpu] = "MIPS 34Kc";
R
Ralf Baechle 已提交
859
		break;
860 861
	case PRID_IMP_74K:
		c->cputype = CPU_74K;
862
		c->writecombine = _CACHE_UNCACHED;
863
		__cpu_name[cpu] = "MIPS 74Kc";
864
		break;
865 866
	case PRID_IMP_M14KC:
		c->cputype = CPU_M14KC;
867
		c->writecombine = _CACHE_UNCACHED;
868 869
		__cpu_name[cpu] = "MIPS M14Kc";
		break;
870 871
	case PRID_IMP_M14KEC:
		c->cputype = CPU_M14KEC;
872
		c->writecombine = _CACHE_UNCACHED;
873 874
		__cpu_name[cpu] = "MIPS M14KEc";
		break;
875 876
	case PRID_IMP_1004K:
		c->cputype = CPU_1004K;
877
		c->writecombine = _CACHE_UNCACHED;
878
		__cpu_name[cpu] = "MIPS 1004Kc";
879
		break;
880
	case PRID_IMP_1074K:
881
		c->cputype = CPU_1074K;
882
		c->writecombine = _CACHE_UNCACHED;
883 884
		__cpu_name[cpu] = "MIPS 1074Kc";
		break;
885 886 887 888 889 890 891 892
	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;
893 894 895 896 897 898 899 900
	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 已提交
901 902 903 904
	case PRID_IMP_P5600:
		c->cputype = CPU_P5600;
		__cpu_name[cpu] = "MIPS P5600";
		break;
905 906 907 908
	case PRID_IMP_M5150:
		c->cputype = CPU_M5150;
		__cpu_name[cpu] = "MIPS M5150";
		break;
L
Linus Torvalds 已提交
909
	}
C
Chris Dearman 已提交
910

L
Leonid Yegoshin 已提交
911 912
	decode_configs(c);

C
Chris Dearman 已提交
913
	spram_config();
L
Linus Torvalds 已提交
914 915
}

916
static inline void cpu_probe_alchemy(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
917
{
918
	decode_configs(c);
919
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
920 921
	case PRID_IMP_AU1_REV1:
	case PRID_IMP_AU1_REV2:
922
		c->cputype = CPU_ALCHEMY;
L
Linus Torvalds 已提交
923 924
		switch ((c->processor_id >> 24) & 0xff) {
		case 0:
925
			__cpu_name[cpu] = "Au1000";
L
Linus Torvalds 已提交
926 927
			break;
		case 1:
928
			__cpu_name[cpu] = "Au1500";
L
Linus Torvalds 已提交
929 930
			break;
		case 2:
931
			__cpu_name[cpu] = "Au1100";
L
Linus Torvalds 已提交
932 933
			break;
		case 3:
934
			__cpu_name[cpu] = "Au1550";
L
Linus Torvalds 已提交
935
			break;
P
Pete Popov 已提交
936
		case 4:
937
			__cpu_name[cpu] = "Au1200";
938
			if ((c->processor_id & PRID_REV_MASK) == 2)
939
				__cpu_name[cpu] = "Au1250";
940 941
			break;
		case 5:
942
			__cpu_name[cpu] = "Au1210";
P
Pete Popov 已提交
943
			break;
L
Linus Torvalds 已提交
944
		default:
945
			__cpu_name[cpu] = "Au1xxx";
L
Linus Torvalds 已提交
946 947 948 949 950 951
			break;
		}
		break;
	}
}

952
static inline void cpu_probe_sibyte(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
953
{
954
	decode_configs(c);
R
Ralf Baechle 已提交
955

956
	c->writecombine = _CACHE_UNCACHED_ACCELERATED;
957
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
958 959
	case PRID_IMP_SB1:
		c->cputype = CPU_SB1;
960
		__cpu_name[cpu] = "SiByte SB1";
L
Linus Torvalds 已提交
961
		/* FPU in pass1 is known to have issues. */
962
		if ((c->processor_id & PRID_REV_MASK) < 0x02)
963
			c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR);
L
Linus Torvalds 已提交
964
		break;
A
Andrew Isaacson 已提交
965 966
	case PRID_IMP_SB1A:
		c->cputype = CPU_SB1A;
967
		__cpu_name[cpu] = "SiByte SB1A";
A
Andrew Isaacson 已提交
968
		break;
L
Linus Torvalds 已提交
969 970 971
	}
}

972
static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
973
{
974
	decode_configs(c);
975
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
976 977
	case PRID_IMP_SR71000:
		c->cputype = CPU_SR71000;
978
		__cpu_name[cpu] = "Sandcraft SR71000";
L
Linus Torvalds 已提交
979 980 981 982 983 984
		c->scache.ways = 8;
		c->tlbsize = 64;
		break;
	}
}

985
static inline void cpu_probe_nxp(struct cpuinfo_mips *c, unsigned int cpu)
986 987
{
	decode_configs(c);
988
	switch (c->processor_id & PRID_IMP_MASK) {
989 990
	case PRID_IMP_PR4450:
		c->cputype = CPU_PR4450;
991
		__cpu_name[cpu] = "Philips PR4450";
992
		set_isa(c, MIPS_CPU_ISA_M32R1);
993 994 995 996
		break;
	}
}

997
static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
998 999
{
	decode_configs(c);
1000
	switch (c->processor_id & PRID_IMP_MASK) {
1001 1002
	case PRID_IMP_BMIPS32_REV4:
	case PRID_IMP_BMIPS32_REV8:
1003 1004
		c->cputype = CPU_BMIPS32;
		__cpu_name[cpu] = "Broadcom BMIPS32";
1005
		set_elf_platform(cpu, "bmips32");
1006 1007 1008 1009 1010 1011
		break;
	case PRID_IMP_BMIPS3300:
	case PRID_IMP_BMIPS3300_ALT:
	case PRID_IMP_BMIPS3300_BUG:
		c->cputype = CPU_BMIPS3300;
		__cpu_name[cpu] = "Broadcom BMIPS3300";
1012
		set_elf_platform(cpu, "bmips3300");
1013 1014
		break;
	case PRID_IMP_BMIPS43XX: {
1015
		int rev = c->processor_id & PRID_REV_MASK;
1016 1017 1018 1019 1020

		if (rev >= PRID_REV_BMIPS4380_LO &&
				rev <= PRID_REV_BMIPS4380_HI) {
			c->cputype = CPU_BMIPS4380;
			__cpu_name[cpu] = "Broadcom BMIPS4380";
1021
			set_elf_platform(cpu, "bmips4380");
1022 1023 1024
		} else {
			c->cputype = CPU_BMIPS4350;
			__cpu_name[cpu] = "Broadcom BMIPS4350";
1025
			set_elf_platform(cpu, "bmips4350");
1026
		}
1027
		break;
1028 1029 1030 1031
	}
	case PRID_IMP_BMIPS5000:
		c->cputype = CPU_BMIPS5000;
		__cpu_name[cpu] = "Broadcom BMIPS5000";
1032
		set_elf_platform(cpu, "bmips5000");
1033
		c->options |= MIPS_CPU_ULRI;
1034
		break;
1035 1036 1037
	}
}

1038 1039 1040
static inline void cpu_probe_cavium(struct cpuinfo_mips *c, unsigned int cpu)
{
	decode_configs(c);
1041
	switch (c->processor_id & PRID_IMP_MASK) {
1042 1043 1044
	case PRID_IMP_CAVIUM_CN38XX:
	case PRID_IMP_CAVIUM_CN31XX:
	case PRID_IMP_CAVIUM_CN30XX:
1045 1046 1047
		c->cputype = CPU_CAVIUM_OCTEON;
		__cpu_name[cpu] = "Cavium Octeon";
		goto platform;
1048 1049 1050 1051
	case PRID_IMP_CAVIUM_CN58XX:
	case PRID_IMP_CAVIUM_CN56XX:
	case PRID_IMP_CAVIUM_CN50XX:
	case PRID_IMP_CAVIUM_CN52XX:
1052 1053 1054
		c->cputype = CPU_CAVIUM_OCTEON_PLUS;
		__cpu_name[cpu] = "Cavium Octeon+";
platform:
1055
		set_elf_platform(cpu, "octeon");
1056
		break;
1057
	case PRID_IMP_CAVIUM_CN61XX:
1058
	case PRID_IMP_CAVIUM_CN63XX:
1059 1060
	case PRID_IMP_CAVIUM_CN66XX:
	case PRID_IMP_CAVIUM_CN68XX:
1061
	case PRID_IMP_CAVIUM_CNF71XX:
1062 1063
		c->cputype = CPU_CAVIUM_OCTEON2;
		__cpu_name[cpu] = "Cavium Octeon II";
1064
		set_elf_platform(cpu, "octeon2");
1065
		break;
1066 1067 1068 1069 1070 1071
	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;
1072 1073 1074 1075 1076 1077 1078
	default:
		printk(KERN_INFO "Unknown Octeon chip!\n");
		c->cputype = CPU_UNKNOWN;
		break;
	}
}

1079 1080 1081 1082 1083
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;
1084
	BUG_ON(!__builtin_constant_p(cpu_has_counter) || cpu_has_counter);
1085
	switch (c->processor_id & PRID_IMP_MASK) {
1086 1087
	case PRID_IMP_JZRISC:
		c->cputype = CPU_JZRISC;
1088
		c->writecombine = _CACHE_UNCACHED_ACCELERATED;
1089 1090 1091 1092 1093 1094 1095 1096
		__cpu_name[cpu] = "Ingenic JZRISC";
		break;
	default:
		panic("Unknown Ingenic Processor ID!");
		break;
	}
}

1097 1098 1099 1100
static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
{
	decode_configs(c);

1101
	if ((c->processor_id & PRID_IMP_MASK) == PRID_IMP_NETLOGIC_AU13XX) {
M
Manuel Lauss 已提交
1102 1103 1104 1105 1106 1107
		c->cputype = CPU_ALCHEMY;
		__cpu_name[cpu] = "Au1300";
		/* following stuff is not for Alchemy */
		return;
	}

R
Ralf Baechle 已提交
1108 1109
	c->options = (MIPS_CPU_TLB	 |
			MIPS_CPU_4KEX	 |
1110
			MIPS_CPU_COUNTER |
R
Ralf Baechle 已提交
1111 1112 1113
			MIPS_CPU_DIVEC	 |
			MIPS_CPU_WATCH	 |
			MIPS_CPU_EJTAG	 |
1114 1115
			MIPS_CPU_LLSC);

1116
	switch (c->processor_id & PRID_IMP_MASK) {
1117
	case PRID_IMP_NETLOGIC_XLP2XX:
1118
	case PRID_IMP_NETLOGIC_XLP9XX:
1119
	case PRID_IMP_NETLOGIC_XLP5XX:
1120 1121 1122 1123
		c->cputype = CPU_XLP;
		__cpu_name[cpu] = "Broadcom XLPII";
		break;

1124 1125
	case PRID_IMP_NETLOGIC_XLP8XX:
	case PRID_IMP_NETLOGIC_XLP3XX:
J
Jayachandran C 已提交
1126 1127 1128 1129
		c->cputype = CPU_XLP;
		__cpu_name[cpu] = "Netlogic XLP";
		break;

1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159
	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 已提交
1160
		pr_info("Unknown Netlogic chip id [%02x]!\n",
1161 1162 1163 1164 1165
		       c->processor_id);
		c->cputype = CPU_XLR;
		break;
	}

J
Jayachandran C 已提交
1166
	if (c->cputype == CPU_XLP) {
1167
		set_isa(c, MIPS_CPU_ISA_M64R2);
J
Jayachandran C 已提交
1168 1169 1170 1171
		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 {
1172
		set_isa(c, MIPS_CPU_ISA_M64R1);
J
Jayachandran C 已提交
1173 1174
		c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1;
	}
1175
	c->kscratch_mask = 0xf;
1176 1177
}

1178 1179 1180 1181 1182 1183
#ifdef CONFIG_64BIT
/* For use by uaccess.h */
u64 __ua_limit;
EXPORT_SYMBOL(__ua_limit);
#endif

1184
const char *__cpu_name[NR_CPUS];
1185
const char *__elf_platform;
1186

1187
void cpu_probe(void)
L
Linus Torvalds 已提交
1188 1189
{
	struct cpuinfo_mips *c = &current_cpu_data;
1190
	unsigned int cpu = smp_processor_id();
L
Linus Torvalds 已提交
1191

R
Ralf Baechle 已提交
1192
	c->processor_id = PRID_IMP_UNKNOWN;
L
Linus Torvalds 已提交
1193 1194
	c->fpu_id	= FPIR_IMP_NONE;
	c->cputype	= CPU_UNKNOWN;
1195
	c->writecombine = _CACHE_UNCACHED;
L
Linus Torvalds 已提交
1196 1197

	c->processor_id = read_c0_prid();
1198
	switch (c->processor_id & PRID_COMP_MASK) {
L
Linus Torvalds 已提交
1199
	case PRID_COMP_LEGACY:
1200
		cpu_probe_legacy(c, cpu);
L
Linus Torvalds 已提交
1201 1202
		break;
	case PRID_COMP_MIPS:
1203
		cpu_probe_mips(c, cpu);
L
Linus Torvalds 已提交
1204 1205
		break;
	case PRID_COMP_ALCHEMY:
1206
		cpu_probe_alchemy(c, cpu);
L
Linus Torvalds 已提交
1207 1208
		break;
	case PRID_COMP_SIBYTE:
1209
		cpu_probe_sibyte(c, cpu);
L
Linus Torvalds 已提交
1210
		break;
1211
	case PRID_COMP_BROADCOM:
1212
		cpu_probe_broadcom(c, cpu);
1213
		break;
L
Linus Torvalds 已提交
1214
	case PRID_COMP_SANDCRAFT:
1215
		cpu_probe_sandcraft(c, cpu);
L
Linus Torvalds 已提交
1216
		break;
1217
	case PRID_COMP_NXP:
1218
		cpu_probe_nxp(c, cpu);
1219
		break;
1220 1221 1222
	case PRID_COMP_CAVIUM:
		cpu_probe_cavium(c, cpu);
		break;
1223 1224 1225
	case PRID_COMP_INGENIC:
		cpu_probe_ingenic(c, cpu);
		break;
1226 1227 1228
	case PRID_COMP_NETLOGIC:
		cpu_probe_netlogic(c, cpu);
		break;
L
Linus Torvalds 已提交
1229
	}
1230

1231 1232 1233
	BUG_ON(!__cpu_name[cpu]);
	BUG_ON(c->cputype == CPU_UNKNOWN);

1234 1235 1236 1237 1238 1239 1240
	/*
	 * 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);

1241 1242 1243 1244
	if (mips_fpu_disabled)
		c->options &= ~MIPS_CPU_FPU;

	if (mips_dsp_disabled)
1245
		c->ases &= ~(MIPS_ASE_DSP | MIPS_ASE_DSP2P);
1246

1247 1248 1249 1250 1251 1252
	if (mips_htw_disabled) {
		c->options &= ~MIPS_CPU_HTW;
		write_c0_pwctl(read_c0_pwctl() &
			       ~(1 << MIPS_PWCTL_PWEN_SHIFT));
	}

1253
	if (c->options & MIPS_CPU_FPU) {
L
Linus Torvalds 已提交
1254
		c->fpu_id = cpu_get_fpu_id();
1255

1256 1257
		if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 |
				    MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) {
1258 1259 1260 1261
			if (c->fpu_id & MIPS_FPIR_3D)
				c->ases |= MIPS_ASE_MIPS3D;
		}
	}
1262

1263
	if (cpu_has_mips_r2) {
R
Ralf Baechle 已提交
1264
		c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
1265 1266 1267
		/* R2 has Performance Counter Interrupt indicator */
		c->options |= MIPS_CPU_PCI;
	}
R
Ralf Baechle 已提交
1268 1269
	else
		c->srsets = 1;
1270

1271
	if (cpu_has_msa) {
P
Paul Burton 已提交
1272
		c->msa_id = cpu_get_msa_id();
1273 1274 1275
		WARN(c->msa_id & MSA_IR_WRPF,
		     "Vector register partitioning unimplemented!");
	}
P
Paul Burton 已提交
1276

1277
	cpu_probe_vmbits(c);
1278 1279 1280 1281 1282

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

1285
void cpu_report(void)
L
Linus Torvalds 已提交
1286 1287 1288
{
	struct cpuinfo_mips *c = &current_cpu_data;

1289 1290
	pr_info("CPU%d revision is: %08x (%s)\n",
		smp_processor_id(), c->processor_id, cpu_name_string());
L
Linus Torvalds 已提交
1291
	if (c->options & MIPS_CPU_FPU)
1292
		printk(KERN_INFO "FPU revision is: %08x\n", c->fpu_id);
P
Paul Burton 已提交
1293 1294
	if (cpu_has_msa)
		pr_info("MSA revision is: %08x\n", c->msa_id);
L
Linus Torvalds 已提交
1295
}