cpu-probe.c 32.8 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);

72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
static int mips_ftlb_disabled;
static int mips_has_ftlb_configured;

static void set_ftlb_enable(struct cpuinfo_mips *c, int enable);

static int __init ftlb_disable(char *s)
{
	unsigned int config4, mmuextdef;

	/*
	 * If the core hasn't done any FTLB configuration, there is nothing
	 * for us to do here.
	 */
	if (!mips_has_ftlb_configured)
		return 1;

	/* Disable it in the boot cpu */
	set_ftlb_enable(&cpu_data[0], 0);

	back_to_back_c0_hazard();

	config4 = read_c0_config4();

	/* Check that FTLB has been disabled */
	mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF;
	/* MMUSIZEEXT == VTLB ON, FTLB OFF */
	if (mmuextdef == MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT) {
		/* This should never happen */
		pr_warn("FTLB could not be disabled!\n");
		return 1;
	}

	mips_ftlb_disabled = 1;
	mips_has_ftlb_configured = 0;

	/*
	 * noftlb is mainly used for debug purposes so print
	 * an informative message instead of using pr_debug()
	 */
	pr_info("FTLB has been disabled\n");

	/*
	 * Some of these bits are duplicated in the decode_config4.
	 * MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT is the only possible case
	 * once FTLB has been disabled so undo what decode_config4 did.
	 */
	cpu_data[0].tlbsize -= cpu_data[0].tlbsizeftlbways *
			       cpu_data[0].tlbsizeftlbsets;
	cpu_data[0].tlbsizeftlbsets = 0;
	cpu_data[0].tlbsizeftlbways = 0;

	return 1;
}

__setup("noftlb", ftlb_disable);


M
Marc St-Jean 已提交
129 130 131 132
static inline void check_errata(void)
{
	struct cpuinfo_mips *c = &current_cpu_data;

133
	switch (current_cpu_type()) {
M
Marc St-Jean 已提交
134 135 136
	case CPU_34K:
		/*
		 * Erratum "RPS May Cause Incorrect Instruction Execution"
R
Ralf Baechle 已提交
137
		 * This code only handles VPE0, any SMP/RTOS code
M
Marc St-Jean 已提交
138 139 140 141 142 143 144 145 146 147
		 * 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 已提交
148 149
void __init check_bugs32(void)
{
M
Marc St-Jean 已提交
150
	check_errata();
L
Linus Torvalds 已提交
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
}

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

175 176 177 178 179 180
static inline void set_elf_platform(int cpu, const char *plat)
{
	if (cpu == 0)
		__elf_platform = plat;
}

L
Linus Torvalds 已提交
181 182 183 184 185 186 187 188
/*
 * Get the FPU Implementation/Revision.
 */
static inline unsigned long cpu_get_fpu_id(void)
{
	unsigned long tmp, fpu_id;

	tmp = read_c0_status();
189
	__enable_fpu(FPU_AS_IS);
L
Linus Torvalds 已提交
190 191 192 193 194 195 196 197 198 199
	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 已提交
200
	return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE;
L
Linus Torvalds 已提交
201 202
}

P
Paul Burton 已提交
203 204
static inline unsigned long cpu_get_msa_id(void)
{
205
	unsigned long status, msa_id;
P
Paul Burton 已提交
206 207 208 209 210

	status = read_c0_status();
	__enable_fpu(FPU_64BIT);
	enable_msa();
	msa_id = read_msa_ir();
211
	disable_msa();
P
Paul Burton 已提交
212 213 214 215
	write_c0_status(status);
	return msa_id;
}

216 217 218
static inline void cpu_probe_vmbits(struct cpuinfo_mips *c)
{
#ifdef __NEED_VMBITS_PROBE
219
	write_c0_entryhi(0x3fffffffffffe000ULL);
220
	back_to_back_c0_hazard();
221
	c->vmbits = fls64(read_c0_entryhi() & 0x3fffffffffffe000ULL);
222 223 224
#endif
}

225
static void set_isa(struct cpuinfo_mips *c, unsigned int isa)
226 227 228 229 230 231 232 233 234 235 236
{
	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:
237
		c->isa_level |= MIPS_CPU_ISA_II | MIPS_CPU_ISA_III;
238 239 240 241 242 243 244 245 246 247 248 249
		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;
	}
}

250
static char unknown_isa[] = KERN_ERR \
251 252
	"Unsupported ISA type, c0.config0: %d.";

L
Leonid Yegoshin 已提交
253 254 255
static void set_ftlb_enable(struct cpuinfo_mips *c, int enable)
{
	unsigned int config6;
256 257 258 259 260 261

	/* 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 已提交
262 263 264 265 266 267 268 269
		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();
270
		break;
L
Leonid Yegoshin 已提交
271 272 273
	}
}

274 275 276 277 278 279 280
static inline unsigned int decode_config0(struct cpuinfo_mips *c)
{
	unsigned int config0;
	int isa;

	config0 = read_c0_config();

L
Leonid Yegoshin 已提交
281 282 283 284 285
	/*
	 * Look for Standard TLB or Dual VTLB and FTLB
	 */
	if ((((config0 & MIPS_CONF_MT) >> 7) == 1) ||
	    (((config0 & MIPS_CONF_MT) >> 7) == 4))
286
		c->options |= MIPS_CPU_TLB;
L
Leonid Yegoshin 已提交
287

288 289 290 291 292
	isa = (config0 & MIPS_CONF_AT) >> 13;
	switch (isa) {
	case 0:
		switch ((config0 & MIPS_CONF_AR) >> 10) {
		case 0:
293
			set_isa(c, MIPS_CPU_ISA_M32R1);
294 295
			break;
		case 1:
296
			set_isa(c, MIPS_CPU_ISA_M32R2);
297 298 299 300 301 302 303 304
			break;
		default:
			goto unknown;
		}
		break;
	case 2:
		switch ((config0 & MIPS_CONF_AR) >> 10) {
		case 0:
305
			set_isa(c, MIPS_CPU_ISA_M64R1);
306 307
			break;
		case 1:
308
			set_isa(c, MIPS_CPU_ISA_M64R2);
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
			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 已提交
342
	if (cpu_has_tlb) {
343
		c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1;
L
Leonid Yegoshin 已提交
344 345 346
		c->tlbsizevtlb = c->tlbsize;
		c->tlbsizeftlbsets = 0;
	}
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368

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

369
	if (config3 & MIPS_CONF3_SM) {
370
		c->ases |= MIPS_ASE_SMARTMIPS;
371 372 373 374
		c->options |= MIPS_CPU_RIXI;
	}
	if (config3 & MIPS_CONF3_RXI)
		c->options |= MIPS_CPU_RIXI;
375 376
	if (config3 & MIPS_CONF3_DSP)
		c->ases |= MIPS_ASE_DSP;
377 378
	if (config3 & MIPS_CONF3_DSP2P)
		c->ases |= MIPS_ASE_DSP2P;
379 380 381 382 383 384 385 386
	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;
387 388
	if (config3 & MIPS_CONF3_ISA)
		c->options |= MIPS_CPU_MICROMIPS;
389 390
	if (config3 & MIPS_CONF3_VZ)
		c->ases |= MIPS_ASE_VZ;
391 392
	if (config3 & MIPS_CONF3_SC)
		c->options |= MIPS_CPU_SEGMENTS;
P
Paul Burton 已提交
393 394
	if (config3 & MIPS_CONF3_MSA)
		c->ases |= MIPS_ASE_MSA;
395 396 397
	/* Only tested on 32-bit cores */
	if ((config3 & MIPS_CONF3_PW) && config_enabled(CONFIG_32BIT))
		c->options |= MIPS_CPU_HTW;
398 399 400 401 402 403 404

	return config3 & MIPS_CONF_M;
}

static inline unsigned int decode_config4(struct cpuinfo_mips *c)
{
	unsigned int config4;
L
Leonid Yegoshin 已提交
405 406 407
	unsigned int newcf4;
	unsigned int mmuextdef;
	unsigned int ftlb_page = MIPS_CONF4_FTLBPAGESIZE;
408 409 410

	config4 = read_c0_config4();

411 412 413
	if (cpu_has_tlb) {
		if (((config4 & MIPS_CONF4_IE) >> 29) == 2)
			c->options |= MIPS_CPU_TLBINV;
L
Leonid Yegoshin 已提交
414 415 416 417 418 419 420 421 422 423 424 425 426 427
		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:
428 429
			if (mips_ftlb_disabled)
				break;
L
Leonid Yegoshin 已提交
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
			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;
449
			mips_has_ftlb_configured = 1;
L
Leonid Yegoshin 已提交
450 451
			break;
		}
452 453
	}

454 455 456 457 458
	c->kscratch_mask = (config4 >> 16) & 0xff;

	return config4 & MIPS_CONF_M;
}

459 460 461 462 463 464 465 466
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);

467 468
	if (config5 & MIPS_CONF5_EVA)
		c->options |= MIPS_CPU_EVA;
P
Paul Burton 已提交
469 470
	if (config5 & MIPS_CONF5_MRP)
		c->options |= MIPS_CPU_MAAR;
471

472 473 474
	return config5 & MIPS_CONF_M;
}

475
static void decode_configs(struct cpuinfo_mips *c)
476 477 478 479 480 481 482 483 484
{
	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;

485 486
	/* Enable FTLB if present and not disabled */
	set_ftlb_enable(c, !mips_ftlb_disabled);
L
Leonid Yegoshin 已提交
487

488
	ok = decode_config0(c);			/* Read Config registers.  */
R
Ralf Baechle 已提交
489
	BUG_ON(!ok);				/* Arch spec violation!	 */
490 491 492 493 494 495 496 497
	if (ok)
		ok = decode_config1(c);
	if (ok)
		ok = decode_config2(c);
	if (ok)
		ok = decode_config3(c);
	if (ok)
		ok = decode_config4(c);
498 499
	if (ok)
		ok = decode_config5(c);
500 501 502

	mips_probe_watch_registers(c);

503 504 505 506 507 508 509 510 511
	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;
	}

512
#ifndef CONFIG_MIPS_CPS
513
	if (cpu_has_mips_r2) {
514
		c->core = get_ebase_cpunum();
515 516 517
		if (cpu_has_mipsmt)
			c->core >>= fls(core_nvpes()) - 1;
	}
518
#endif
519 520
}

R
Ralf Baechle 已提交
521
#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \
L
Linus Torvalds 已提交
522 523
		| MIPS_CPU_COUNTER)

524
static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
525
{
526
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
527 528
	case PRID_IMP_R2000:
		c->cputype = CPU_R2000;
529
		__cpu_name[cpu] = "R2000";
R
Ralf Baechle 已提交
530
		c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
S
Steven J. Hill 已提交
531
			     MIPS_CPU_NOFPUEX;
L
Linus Torvalds 已提交
532 533 534 535 536
		if (__cpu_has_fpu())
			c->options |= MIPS_CPU_FPU;
		c->tlbsize = 64;
		break;
	case PRID_IMP_R3000:
537
		if ((c->processor_id & PRID_REV_MASK) == PRID_REV_R3000A) {
538
			if (cpu_has_confreg()) {
L
Linus Torvalds 已提交
539
				c->cputype = CPU_R3081E;
540 541
				__cpu_name[cpu] = "R3081";
			} else {
L
Linus Torvalds 已提交
542
				c->cputype = CPU_R3000A;
543 544 545
				__cpu_name[cpu] = "R3000A";
			}
		} else {
L
Linus Torvalds 已提交
546
			c->cputype = CPU_R3000;
547 548
			__cpu_name[cpu] = "R3000";
		}
R
Ralf Baechle 已提交
549
		c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
S
Steven J. Hill 已提交
550
			     MIPS_CPU_NOFPUEX;
L
Linus Torvalds 已提交
551 552 553 554 555 556
		if (__cpu_has_fpu())
			c->options |= MIPS_CPU_FPU;
		c->tlbsize = 64;
		break;
	case PRID_IMP_R4000:
		if (read_c0_config() & CONF_SC) {
557 558
			if ((c->processor_id & PRID_REV_MASK) >=
			    PRID_REV_R4400) {
L
Linus Torvalds 已提交
559
				c->cputype = CPU_R4400PC;
560 561
				__cpu_name[cpu] = "R4400PC";
			} else {
L
Linus Torvalds 已提交
562
				c->cputype = CPU_R4000PC;
563 564
				__cpu_name[cpu] = "R4000PC";
			}
L
Linus Torvalds 已提交
565
		} else {
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
			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;
			}
586 587
			if ((c->processor_id & PRID_REV_MASK) >=
			    PRID_REV_R4400) {
588 589
				c->cputype = mc ? CPU_R4400MC : CPU_R4400SC;
				__cpu_name[cpu] = mc ? "R4400MC" : "R4400SC";
590
			} else {
591 592
				c->cputype = mc ? CPU_R4000MC : CPU_R4000SC;
				__cpu_name[cpu] = mc ? "R4000MC" : "R4000SC";
593
			}
L
Linus Torvalds 已提交
594 595
		}

596
		set_isa(c, MIPS_CPU_ISA_III);
L
Linus Torvalds 已提交
597
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
598 599
			     MIPS_CPU_WATCH | MIPS_CPU_VCE |
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
600 601 602
		c->tlbsize = 48;
		break;
	case PRID_IMP_VR41XX:
603 604 605
		set_isa(c, MIPS_CPU_ISA_III);
		c->options = R4K_OPTS;
		c->tlbsize = 32;
L
Linus Torvalds 已提交
606 607 608
		switch (c->processor_id & 0xf0) {
		case PRID_REV_VR4111:
			c->cputype = CPU_VR4111;
609
			__cpu_name[cpu] = "NEC VR4111";
L
Linus Torvalds 已提交
610 611 612
			break;
		case PRID_REV_VR4121:
			c->cputype = CPU_VR4121;
613
			__cpu_name[cpu] = "NEC VR4121";
L
Linus Torvalds 已提交
614 615
			break;
		case PRID_REV_VR4122:
616
			if ((c->processor_id & 0xf) < 0x3) {
L
Linus Torvalds 已提交
617
				c->cputype = CPU_VR4122;
618 619
				__cpu_name[cpu] = "NEC VR4122";
			} else {
L
Linus Torvalds 已提交
620
				c->cputype = CPU_VR4181A;
621 622
				__cpu_name[cpu] = "NEC VR4181A";
			}
L
Linus Torvalds 已提交
623 624
			break;
		case PRID_REV_VR4130:
625
			if ((c->processor_id & 0xf) < 0x4) {
L
Linus Torvalds 已提交
626
				c->cputype = CPU_VR4131;
627 628
				__cpu_name[cpu] = "NEC VR4131";
			} else {
L
Linus Torvalds 已提交
629
				c->cputype = CPU_VR4133;
630
				c->options |= MIPS_CPU_LLSC;
631 632
				__cpu_name[cpu] = "NEC VR4133";
			}
L
Linus Torvalds 已提交
633 634 635 636
			break;
		default:
			printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
			c->cputype = CPU_VR41XX;
637
			__cpu_name[cpu] = "NEC Vr41xx";
L
Linus Torvalds 已提交
638 639 640 641 642
			break;
		}
		break;
	case PRID_IMP_R4300:
		c->cputype = CPU_R4300;
643
		__cpu_name[cpu] = "R4300";
644
		set_isa(c, MIPS_CPU_ISA_III);
L
Linus Torvalds 已提交
645
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
646
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
647 648 649 650
		c->tlbsize = 32;
		break;
	case PRID_IMP_R4600:
		c->cputype = CPU_R4600;
651
		__cpu_name[cpu] = "R4600";
652
		set_isa(c, MIPS_CPU_ISA_III);
T
Thiemo Seufer 已提交
653 654
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
655 656 657
		c->tlbsize = 48;
		break;
	#if 0
S
Steven J. Hill 已提交
658
	case PRID_IMP_R4650:
L
Linus Torvalds 已提交
659 660 661 662 663 664
		/*
		 * 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.
		 */
665
		c->cputype = CPU_R4650;
666
		__cpu_name[cpu] = "R4650";
667
		set_isa(c, MIPS_CPU_ISA_III);
L
Linus Torvalds 已提交
668
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
S
Steven J. Hill 已提交
669
		c->tlbsize = 48;
L
Linus Torvalds 已提交
670 671 672
		break;
	#endif
	case PRID_IMP_TX39:
R
Ralf Baechle 已提交
673
		c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE;
L
Linus Torvalds 已提交
674 675 676

		if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) {
			c->cputype = CPU_TX3927;
677
			__cpu_name[cpu] = "TX3927";
L
Linus Torvalds 已提交
678 679
			c->tlbsize = 64;
		} else {
680
			switch (c->processor_id & PRID_REV_MASK) {
L
Linus Torvalds 已提交
681 682
			case PRID_REV_TX3912:
				c->cputype = CPU_TX3912;
683
				__cpu_name[cpu] = "TX3912";
L
Linus Torvalds 已提交
684 685 686 687
				c->tlbsize = 32;
				break;
			case PRID_REV_TX3922:
				c->cputype = CPU_TX3922;
688
				__cpu_name[cpu] = "TX3922";
L
Linus Torvalds 已提交
689 690 691 692 693 694 695
				c->tlbsize = 64;
				break;
			}
		}
		break;
	case PRID_IMP_R4700:
		c->cputype = CPU_R4700;
696
		__cpu_name[cpu] = "R4700";
697
		set_isa(c, MIPS_CPU_ISA_III);
L
Linus Torvalds 已提交
698
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
699
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
700 701 702 703
		c->tlbsize = 48;
		break;
	case PRID_IMP_TX49:
		c->cputype = CPU_TX49XX;
704
		__cpu_name[cpu] = "R49XX";
705
		set_isa(c, MIPS_CPU_ISA_III);
L
Linus Torvalds 已提交
706 707 708 709 710 711 712
		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;
713
		__cpu_name[cpu] = "R5000";
714
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
715
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
716
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
717 718 719 720
		c->tlbsize = 48;
		break;
	case PRID_IMP_R5432:
		c->cputype = CPU_R5432;
721
		__cpu_name[cpu] = "R5432";
722
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
723
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
724
			     MIPS_CPU_WATCH | MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
725 726 727 728
		c->tlbsize = 48;
		break;
	case PRID_IMP_R5500:
		c->cputype = CPU_R5500;
729
		__cpu_name[cpu] = "R5500";
730
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
731
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
732
			     MIPS_CPU_WATCH | MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
733 734 735 736
		c->tlbsize = 48;
		break;
	case PRID_IMP_NEVADA:
		c->cputype = CPU_NEVADA;
737
		__cpu_name[cpu] = "Nevada";
738
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
739
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
740
			     MIPS_CPU_DIVEC | MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
741 742 743 744
		c->tlbsize = 48;
		break;
	case PRID_IMP_R6000:
		c->cputype = CPU_R6000;
745
		__cpu_name[cpu] = "R6000";
746
		set_isa(c, MIPS_CPU_ISA_II);
L
Linus Torvalds 已提交
747
		c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
S
Steven J. Hill 已提交
748
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
749 750 751 752
		c->tlbsize = 32;
		break;
	case PRID_IMP_R6000A:
		c->cputype = CPU_R6000A;
753
		__cpu_name[cpu] = "R6000A";
754
		set_isa(c, MIPS_CPU_ISA_II);
L
Linus Torvalds 已提交
755
		c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
S
Steven J. Hill 已提交
756
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
757 758 759 760
		c->tlbsize = 32;
		break;
	case PRID_IMP_RM7000:
		c->cputype = CPU_RM7000;
761
		__cpu_name[cpu] = "RM7000";
762
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
763
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
764
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
765
		/*
R
Ralf Baechle 已提交
766
		 * Undocumented RM7000:	 Bit 29 in the info register of
L
Linus Torvalds 已提交
767 768 769
		 * the RM7000 v2.0 indicates if the TLB has 48 or 64
		 * entries.
		 *
R
Ralf Baechle 已提交
770 771
		 * 29	   1 =>	   64 entry JTLB
		 *	   0 =>	   48 entry JTLB
L
Linus Torvalds 已提交
772 773 774 775 776
		 */
		c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48;
		break;
	case PRID_IMP_R8000:
		c->cputype = CPU_R8000;
777
		__cpu_name[cpu] = "RM8000";
778
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
779
		c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
S
Steven J. Hill 已提交
780 781
			     MIPS_CPU_FPU | MIPS_CPU_32FPR |
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
782 783 784 785
		c->tlbsize = 384;      /* has weird TLB: 3-way x 128 */
		break;
	case PRID_IMP_R10000:
		c->cputype = CPU_R10000;
786
		__cpu_name[cpu] = "R10000";
787
		set_isa(c, MIPS_CPU_ISA_IV);
788
		c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
S
Steven J. Hill 已提交
789
			     MIPS_CPU_FPU | MIPS_CPU_32FPR |
L
Linus Torvalds 已提交
790
			     MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
S
Steven J. Hill 已提交
791
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
792 793 794 795
		c->tlbsize = 64;
		break;
	case PRID_IMP_R12000:
		c->cputype = CPU_R12000;
796
		__cpu_name[cpu] = "R12000";
797
		set_isa(c, MIPS_CPU_ISA_IV);
798
		c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
S
Steven J. Hill 已提交
799
			     MIPS_CPU_FPU | MIPS_CPU_32FPR |
L
Linus Torvalds 已提交
800
			     MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
S
Steven J. Hill 已提交
801
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
802 803
		c->tlbsize = 64;
		break;
K
Kumba 已提交
804 805
	case PRID_IMP_R14000:
		c->cputype = CPU_R14000;
806
		__cpu_name[cpu] = "R14000";
807
		set_isa(c, MIPS_CPU_ISA_IV);
K
Kumba 已提交
808
		c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
S
Steven J. Hill 已提交
809
			     MIPS_CPU_FPU | MIPS_CPU_32FPR |
K
Kumba 已提交
810
			     MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
S
Steven J. Hill 已提交
811
			     MIPS_CPU_LLSC;
K
Kumba 已提交
812 813
		c->tlbsize = 64;
		break;
814
	case PRID_IMP_LOONGSON_64:  /* Loongson-2/3 */
815 816
		switch (c->processor_id & PRID_REV_MASK) {
		case PRID_REV_LOONGSON2E:
817 818
			c->cputype = CPU_LOONGSON2;
			__cpu_name[cpu] = "ICT Loongson-2";
819
			set_elf_platform(cpu, "loongson2e");
820
			set_isa(c, MIPS_CPU_ISA_III);
821 822
			break;
		case PRID_REV_LOONGSON2F:
823 824
			c->cputype = CPU_LOONGSON2;
			__cpu_name[cpu] = "ICT Loongson-2";
825
			set_elf_platform(cpu, "loongson2f");
826
			set_isa(c, MIPS_CPU_ISA_III);
827
			break;
828 829 830 831
		case PRID_REV_LOONGSON3A:
			c->cputype = CPU_LOONGSON3;
			__cpu_name[cpu] = "ICT Loongson-3";
			set_elf_platform(cpu, "loongson3a");
832
			set_isa(c, MIPS_CPU_ISA_M64R1);
833
			break;
H
Huacai Chen 已提交
834 835 836 837 838
		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");
839
			set_isa(c, MIPS_CPU_ISA_M64R1);
H
Huacai Chen 已提交
840
			break;
841 842
		}

843 844 845 846
		c->options = R4K_OPTS |
			     MIPS_CPU_FPU | MIPS_CPU_LLSC |
			     MIPS_CPU_32FPR;
		c->tlbsize = 64;
847
		c->writecombine = _CACHE_UNCACHED_ACCELERATED;
848
		break;
849
	case PRID_IMP_LOONGSON_32:  /* Loongson-1 */
850
		decode_configs(c);
851

852
		c->cputype = CPU_LOONGSON1;
L
Linus Torvalds 已提交
853

854 855 856
		switch (c->processor_id & PRID_REV_MASK) {
		case PRID_REV_LOONGSON1B:
			__cpu_name[cpu] = "Loongson 1B";
857 858
			break;
		}
859

860
		break;
L
Linus Torvalds 已提交
861 862 863
	}
}

864
static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
865
{
866
	c->writecombine = _CACHE_UNCACHED_ACCELERATED;
867
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
868 869
	case PRID_IMP_4KC:
		c->cputype = CPU_4KC;
870
		c->writecombine = _CACHE_UNCACHED;
871
		__cpu_name[cpu] = "MIPS 4Kc";
L
Linus Torvalds 已提交
872 873
		break;
	case PRID_IMP_4KEC:
874 875
	case PRID_IMP_4KECR2:
		c->cputype = CPU_4KEC;
876
		c->writecombine = _CACHE_UNCACHED;
877
		__cpu_name[cpu] = "MIPS 4KEc";
878
		break;
L
Linus Torvalds 已提交
879
	case PRID_IMP_4KSC:
R
Ralf Baechle 已提交
880
	case PRID_IMP_4KSD:
L
Linus Torvalds 已提交
881
		c->cputype = CPU_4KSC;
882
		c->writecombine = _CACHE_UNCACHED;
883
		__cpu_name[cpu] = "MIPS 4KSc";
L
Linus Torvalds 已提交
884 885 886
		break;
	case PRID_IMP_5KC:
		c->cputype = CPU_5KC;
887
		c->writecombine = _CACHE_UNCACHED;
888
		__cpu_name[cpu] = "MIPS 5Kc";
L
Linus Torvalds 已提交
889
		break;
L
Leonid Yegoshin 已提交
890 891
	case PRID_IMP_5KE:
		c->cputype = CPU_5KE;
892
		c->writecombine = _CACHE_UNCACHED;
L
Leonid Yegoshin 已提交
893 894
		__cpu_name[cpu] = "MIPS 5KE";
		break;
L
Linus Torvalds 已提交
895 896
	case PRID_IMP_20KC:
		c->cputype = CPU_20KC;
897
		c->writecombine = _CACHE_UNCACHED;
898
		__cpu_name[cpu] = "MIPS 20Kc";
L
Linus Torvalds 已提交
899 900 901
		break;
	case PRID_IMP_24K:
		c->cputype = CPU_24K;
902
		c->writecombine = _CACHE_UNCACHED;
903
		__cpu_name[cpu] = "MIPS 24Kc";
L
Linus Torvalds 已提交
904
		break;
905 906
	case PRID_IMP_24KE:
		c->cputype = CPU_24K;
907
		c->writecombine = _CACHE_UNCACHED;
908 909
		__cpu_name[cpu] = "MIPS 24KEc";
		break;
L
Linus Torvalds 已提交
910 911
	case PRID_IMP_25KF:
		c->cputype = CPU_25KF;
912
		c->writecombine = _CACHE_UNCACHED;
913
		__cpu_name[cpu] = "MIPS 25Kc";
L
Linus Torvalds 已提交
914
		break;
R
Ralf Baechle 已提交
915 916
	case PRID_IMP_34K:
		c->cputype = CPU_34K;
917
		c->writecombine = _CACHE_UNCACHED;
918
		__cpu_name[cpu] = "MIPS 34Kc";
R
Ralf Baechle 已提交
919
		break;
920 921
	case PRID_IMP_74K:
		c->cputype = CPU_74K;
922
		c->writecombine = _CACHE_UNCACHED;
923
		__cpu_name[cpu] = "MIPS 74Kc";
924
		break;
925 926
	case PRID_IMP_M14KC:
		c->cputype = CPU_M14KC;
927
		c->writecombine = _CACHE_UNCACHED;
928 929
		__cpu_name[cpu] = "MIPS M14Kc";
		break;
930 931
	case PRID_IMP_M14KEC:
		c->cputype = CPU_M14KEC;
932
		c->writecombine = _CACHE_UNCACHED;
933 934
		__cpu_name[cpu] = "MIPS M14KEc";
		break;
935 936
	case PRID_IMP_1004K:
		c->cputype = CPU_1004K;
937
		c->writecombine = _CACHE_UNCACHED;
938
		__cpu_name[cpu] = "MIPS 1004Kc";
939
		break;
940
	case PRID_IMP_1074K:
941
		c->cputype = CPU_1074K;
942
		c->writecombine = _CACHE_UNCACHED;
943 944
		__cpu_name[cpu] = "MIPS 1074Kc";
		break;
945 946 947 948 949 950 951 952
	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;
953 954 955 956 957 958 959 960
	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 已提交
961 962 963 964
	case PRID_IMP_P5600:
		c->cputype = CPU_P5600;
		__cpu_name[cpu] = "MIPS P5600";
		break;
965 966 967 968
	case PRID_IMP_M5150:
		c->cputype = CPU_M5150;
		__cpu_name[cpu] = "MIPS M5150";
		break;
L
Linus Torvalds 已提交
969
	}
C
Chris Dearman 已提交
970

L
Leonid Yegoshin 已提交
971 972
	decode_configs(c);

C
Chris Dearman 已提交
973
	spram_config();
L
Linus Torvalds 已提交
974 975
}

976
static inline void cpu_probe_alchemy(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
977
{
978
	decode_configs(c);
979
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
980 981
	case PRID_IMP_AU1_REV1:
	case PRID_IMP_AU1_REV2:
982
		c->cputype = CPU_ALCHEMY;
L
Linus Torvalds 已提交
983 984
		switch ((c->processor_id >> 24) & 0xff) {
		case 0:
985
			__cpu_name[cpu] = "Au1000";
L
Linus Torvalds 已提交
986 987
			break;
		case 1:
988
			__cpu_name[cpu] = "Au1500";
L
Linus Torvalds 已提交
989 990
			break;
		case 2:
991
			__cpu_name[cpu] = "Au1100";
L
Linus Torvalds 已提交
992 993
			break;
		case 3:
994
			__cpu_name[cpu] = "Au1550";
L
Linus Torvalds 已提交
995
			break;
P
Pete Popov 已提交
996
		case 4:
997
			__cpu_name[cpu] = "Au1200";
998
			if ((c->processor_id & PRID_REV_MASK) == 2)
999
				__cpu_name[cpu] = "Au1250";
1000 1001
			break;
		case 5:
1002
			__cpu_name[cpu] = "Au1210";
P
Pete Popov 已提交
1003
			break;
L
Linus Torvalds 已提交
1004
		default:
1005
			__cpu_name[cpu] = "Au1xxx";
L
Linus Torvalds 已提交
1006 1007 1008 1009 1010 1011
			break;
		}
		break;
	}
}

1012
static inline void cpu_probe_sibyte(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
1013
{
1014
	decode_configs(c);
R
Ralf Baechle 已提交
1015

1016
	c->writecombine = _CACHE_UNCACHED_ACCELERATED;
1017
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
1018 1019
	case PRID_IMP_SB1:
		c->cputype = CPU_SB1;
1020
		__cpu_name[cpu] = "SiByte SB1";
L
Linus Torvalds 已提交
1021
		/* FPU in pass1 is known to have issues. */
1022
		if ((c->processor_id & PRID_REV_MASK) < 0x02)
1023
			c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR);
L
Linus Torvalds 已提交
1024
		break;
A
Andrew Isaacson 已提交
1025 1026
	case PRID_IMP_SB1A:
		c->cputype = CPU_SB1A;
1027
		__cpu_name[cpu] = "SiByte SB1A";
A
Andrew Isaacson 已提交
1028
		break;
L
Linus Torvalds 已提交
1029 1030 1031
	}
}

1032
static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
1033
{
1034
	decode_configs(c);
1035
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
1036 1037
	case PRID_IMP_SR71000:
		c->cputype = CPU_SR71000;
1038
		__cpu_name[cpu] = "Sandcraft SR71000";
L
Linus Torvalds 已提交
1039 1040 1041 1042 1043 1044
		c->scache.ways = 8;
		c->tlbsize = 64;
		break;
	}
}

1045
static inline void cpu_probe_nxp(struct cpuinfo_mips *c, unsigned int cpu)
1046 1047
{
	decode_configs(c);
1048
	switch (c->processor_id & PRID_IMP_MASK) {
1049 1050
	case PRID_IMP_PR4450:
		c->cputype = CPU_PR4450;
1051
		__cpu_name[cpu] = "Philips PR4450";
1052
		set_isa(c, MIPS_CPU_ISA_M32R1);
1053 1054 1055 1056
		break;
	}
}

1057
static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
1058 1059
{
	decode_configs(c);
1060
	switch (c->processor_id & PRID_IMP_MASK) {
1061 1062
	case PRID_IMP_BMIPS32_REV4:
	case PRID_IMP_BMIPS32_REV8:
1063 1064
		c->cputype = CPU_BMIPS32;
		__cpu_name[cpu] = "Broadcom BMIPS32";
1065
		set_elf_platform(cpu, "bmips32");
1066 1067 1068 1069 1070 1071
		break;
	case PRID_IMP_BMIPS3300:
	case PRID_IMP_BMIPS3300_ALT:
	case PRID_IMP_BMIPS3300_BUG:
		c->cputype = CPU_BMIPS3300;
		__cpu_name[cpu] = "Broadcom BMIPS3300";
1072
		set_elf_platform(cpu, "bmips3300");
1073 1074
		break;
	case PRID_IMP_BMIPS43XX: {
1075
		int rev = c->processor_id & PRID_REV_MASK;
1076 1077 1078 1079 1080

		if (rev >= PRID_REV_BMIPS4380_LO &&
				rev <= PRID_REV_BMIPS4380_HI) {
			c->cputype = CPU_BMIPS4380;
			__cpu_name[cpu] = "Broadcom BMIPS4380";
1081
			set_elf_platform(cpu, "bmips4380");
1082 1083 1084
		} else {
			c->cputype = CPU_BMIPS4350;
			__cpu_name[cpu] = "Broadcom BMIPS4350";
1085
			set_elf_platform(cpu, "bmips4350");
1086
		}
1087
		break;
1088 1089 1090 1091
	}
	case PRID_IMP_BMIPS5000:
		c->cputype = CPU_BMIPS5000;
		__cpu_name[cpu] = "Broadcom BMIPS5000";
1092
		set_elf_platform(cpu, "bmips5000");
1093
		c->options |= MIPS_CPU_ULRI;
1094
		break;
1095 1096 1097
	}
}

1098 1099 1100
static inline void cpu_probe_cavium(struct cpuinfo_mips *c, unsigned int cpu)
{
	decode_configs(c);
1101
	switch (c->processor_id & PRID_IMP_MASK) {
1102 1103 1104
	case PRID_IMP_CAVIUM_CN38XX:
	case PRID_IMP_CAVIUM_CN31XX:
	case PRID_IMP_CAVIUM_CN30XX:
1105 1106 1107
		c->cputype = CPU_CAVIUM_OCTEON;
		__cpu_name[cpu] = "Cavium Octeon";
		goto platform;
1108 1109 1110 1111
	case PRID_IMP_CAVIUM_CN58XX:
	case PRID_IMP_CAVIUM_CN56XX:
	case PRID_IMP_CAVIUM_CN50XX:
	case PRID_IMP_CAVIUM_CN52XX:
1112 1113 1114
		c->cputype = CPU_CAVIUM_OCTEON_PLUS;
		__cpu_name[cpu] = "Cavium Octeon+";
platform:
1115
		set_elf_platform(cpu, "octeon");
1116
		break;
1117
	case PRID_IMP_CAVIUM_CN61XX:
1118
	case PRID_IMP_CAVIUM_CN63XX:
1119 1120
	case PRID_IMP_CAVIUM_CN66XX:
	case PRID_IMP_CAVIUM_CN68XX:
1121
	case PRID_IMP_CAVIUM_CNF71XX:
1122 1123
		c->cputype = CPU_CAVIUM_OCTEON2;
		__cpu_name[cpu] = "Cavium Octeon II";
1124
		set_elf_platform(cpu, "octeon2");
1125
		break;
1126 1127 1128 1129 1130 1131
	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;
1132 1133 1134 1135 1136 1137 1138
	default:
		printk(KERN_INFO "Unknown Octeon chip!\n");
		c->cputype = CPU_UNKNOWN;
		break;
	}
}

1139 1140 1141 1142 1143
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;
1144
	BUG_ON(!__builtin_constant_p(cpu_has_counter) || cpu_has_counter);
1145
	switch (c->processor_id & PRID_IMP_MASK) {
1146 1147
	case PRID_IMP_JZRISC:
		c->cputype = CPU_JZRISC;
1148
		c->writecombine = _CACHE_UNCACHED_ACCELERATED;
1149 1150 1151 1152 1153 1154 1155 1156
		__cpu_name[cpu] = "Ingenic JZRISC";
		break;
	default:
		panic("Unknown Ingenic Processor ID!");
		break;
	}
}

1157 1158 1159 1160
static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
{
	decode_configs(c);

1161
	if ((c->processor_id & PRID_IMP_MASK) == PRID_IMP_NETLOGIC_AU13XX) {
M
Manuel Lauss 已提交
1162 1163 1164 1165 1166 1167
		c->cputype = CPU_ALCHEMY;
		__cpu_name[cpu] = "Au1300";
		/* following stuff is not for Alchemy */
		return;
	}

R
Ralf Baechle 已提交
1168 1169
	c->options = (MIPS_CPU_TLB	 |
			MIPS_CPU_4KEX	 |
1170
			MIPS_CPU_COUNTER |
R
Ralf Baechle 已提交
1171 1172 1173
			MIPS_CPU_DIVEC	 |
			MIPS_CPU_WATCH	 |
			MIPS_CPU_EJTAG	 |
1174 1175
			MIPS_CPU_LLSC);

1176
	switch (c->processor_id & PRID_IMP_MASK) {
1177
	case PRID_IMP_NETLOGIC_XLP2XX:
1178
	case PRID_IMP_NETLOGIC_XLP9XX:
1179
	case PRID_IMP_NETLOGIC_XLP5XX:
1180 1181 1182 1183
		c->cputype = CPU_XLP;
		__cpu_name[cpu] = "Broadcom XLPII";
		break;

1184 1185
	case PRID_IMP_NETLOGIC_XLP8XX:
	case PRID_IMP_NETLOGIC_XLP3XX:
J
Jayachandran C 已提交
1186 1187 1188 1189
		c->cputype = CPU_XLP;
		__cpu_name[cpu] = "Netlogic XLP";
		break;

1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219
	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 已提交
1220
		pr_info("Unknown Netlogic chip id [%02x]!\n",
1221 1222 1223 1224 1225
		       c->processor_id);
		c->cputype = CPU_XLR;
		break;
	}

J
Jayachandran C 已提交
1226
	if (c->cputype == CPU_XLP) {
1227
		set_isa(c, MIPS_CPU_ISA_M64R2);
J
Jayachandran C 已提交
1228 1229 1230 1231
		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 {
1232
		set_isa(c, MIPS_CPU_ISA_M64R1);
J
Jayachandran C 已提交
1233 1234
		c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1;
	}
1235
	c->kscratch_mask = 0xf;
1236 1237
}

1238 1239 1240 1241 1242 1243
#ifdef CONFIG_64BIT
/* For use by uaccess.h */
u64 __ua_limit;
EXPORT_SYMBOL(__ua_limit);
#endif

1244
const char *__cpu_name[NR_CPUS];
1245
const char *__elf_platform;
1246

1247
void cpu_probe(void)
L
Linus Torvalds 已提交
1248 1249
{
	struct cpuinfo_mips *c = &current_cpu_data;
1250
	unsigned int cpu = smp_processor_id();
L
Linus Torvalds 已提交
1251

R
Ralf Baechle 已提交
1252
	c->processor_id = PRID_IMP_UNKNOWN;
L
Linus Torvalds 已提交
1253 1254
	c->fpu_id	= FPIR_IMP_NONE;
	c->cputype	= CPU_UNKNOWN;
1255
	c->writecombine = _CACHE_UNCACHED;
L
Linus Torvalds 已提交
1256 1257

	c->processor_id = read_c0_prid();
1258
	switch (c->processor_id & PRID_COMP_MASK) {
L
Linus Torvalds 已提交
1259
	case PRID_COMP_LEGACY:
1260
		cpu_probe_legacy(c, cpu);
L
Linus Torvalds 已提交
1261 1262
		break;
	case PRID_COMP_MIPS:
1263
		cpu_probe_mips(c, cpu);
L
Linus Torvalds 已提交
1264 1265
		break;
	case PRID_COMP_ALCHEMY:
1266
		cpu_probe_alchemy(c, cpu);
L
Linus Torvalds 已提交
1267 1268
		break;
	case PRID_COMP_SIBYTE:
1269
		cpu_probe_sibyte(c, cpu);
L
Linus Torvalds 已提交
1270
		break;
1271
	case PRID_COMP_BROADCOM:
1272
		cpu_probe_broadcom(c, cpu);
1273
		break;
L
Linus Torvalds 已提交
1274
	case PRID_COMP_SANDCRAFT:
1275
		cpu_probe_sandcraft(c, cpu);
L
Linus Torvalds 已提交
1276
		break;
1277
	case PRID_COMP_NXP:
1278
		cpu_probe_nxp(c, cpu);
1279
		break;
1280 1281 1282
	case PRID_COMP_CAVIUM:
		cpu_probe_cavium(c, cpu);
		break;
1283 1284 1285
	case PRID_COMP_INGENIC:
		cpu_probe_ingenic(c, cpu);
		break;
1286 1287 1288
	case PRID_COMP_NETLOGIC:
		cpu_probe_netlogic(c, cpu);
		break;
L
Linus Torvalds 已提交
1289
	}
1290

1291 1292 1293
	BUG_ON(!__cpu_name[cpu]);
	BUG_ON(c->cputype == CPU_UNKNOWN);

1294 1295 1296 1297 1298 1299 1300
	/*
	 * 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);

1301 1302 1303 1304
	if (mips_fpu_disabled)
		c->options &= ~MIPS_CPU_FPU;

	if (mips_dsp_disabled)
1305
		c->ases &= ~(MIPS_ASE_DSP | MIPS_ASE_DSP2P);
1306

1307 1308 1309 1310 1311 1312
	if (mips_htw_disabled) {
		c->options &= ~MIPS_CPU_HTW;
		write_c0_pwctl(read_c0_pwctl() &
			       ~(1 << MIPS_PWCTL_PWEN_SHIFT));
	}

1313
	if (c->options & MIPS_CPU_FPU) {
L
Linus Torvalds 已提交
1314
		c->fpu_id = cpu_get_fpu_id();
1315

1316 1317
		if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 |
				    MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) {
1318 1319
			if (c->fpu_id & MIPS_FPIR_3D)
				c->ases |= MIPS_ASE_MIPS3D;
1320 1321
			if (c->fpu_id & MIPS_FPIR_FREP)
				c->options |= MIPS_CPU_FRE;
1322 1323
		}
	}
1324

1325
	if (cpu_has_mips_r2) {
R
Ralf Baechle 已提交
1326
		c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
1327 1328 1329
		/* R2 has Performance Counter Interrupt indicator */
		c->options |= MIPS_CPU_PCI;
	}
R
Ralf Baechle 已提交
1330 1331
	else
		c->srsets = 1;
1332

1333
	if (cpu_has_msa) {
P
Paul Burton 已提交
1334
		c->msa_id = cpu_get_msa_id();
1335 1336 1337
		WARN(c->msa_id & MSA_IR_WRPF,
		     "Vector register partitioning unimplemented!");
	}
P
Paul Burton 已提交
1338

1339
	cpu_probe_vmbits(c);
1340 1341 1342 1343 1344

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

1347
void cpu_report(void)
L
Linus Torvalds 已提交
1348 1349 1350
{
	struct cpuinfo_mips *c = &current_cpu_data;

1351 1352
	pr_info("CPU%d revision is: %08x (%s)\n",
		smp_processor_id(), c->processor_id, cpu_name_string());
L
Linus Torvalds 已提交
1353
	if (c->options & MIPS_CPU_FPU)
1354
		printk(KERN_INFO "FPU revision is: %08x\n", c->fpu_id);
P
Paul Burton 已提交
1355 1356
	if (cpu_has_msa)
		pr_info("MSA revision is: %08x\n", c->msa_id);
L
Linus Torvalds 已提交
1357
}