cpu-probe.c 28.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
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 23 24
#include <asm/cpu.h>
#include <asm/fpu.h>
#include <asm/mipsregs.h>
25
#include <asm/watch.h>
26
#include <asm/elf.h>
27
#include <asm/spram.h>
28 29
#include <asm/uaccess.h>

L
Linus Torvalds 已提交
30 31 32 33 34 35 36
/*
 * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
 * the implementation of the "wait" feature differs between CPU families. This
 * points to the function that implements CPU specific wait.
 * The wait instruction stops the pipeline and reduces the power consumption of
 * the CPU very much.
 */
37
void (*cpu_wait)(void);
38
EXPORT_SYMBOL(cpu_wait);
L
Linus Torvalds 已提交
39 40 41 42 43 44 45 46 47

static void r3081_wait(void)
{
	unsigned long cfg = read_c0_conf();
	write_c0_conf(cfg | R30XX_CONF_HALT);
}

static void r39xx_wait(void)
{
48 49 50 51
	local_irq_disable();
	if (!need_resched())
		write_c0_conf(read_c0_conf() | TX39_CONF_HALT);
	local_irq_enable();
L
Linus Torvalds 已提交
52 53
}

54
extern void r4k_wait(void);
55 56 57 58 59 60 61 62

/*
 * This variant is preferable as it allows testing need_resched and going to
 * sleep depending on the outcome atomically.  Unfortunately the "It is
 * implementation-dependent whether the pipeline restarts when a non-enabled
 * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes
 * using this version a gamble.
 */
63
void r4k_wait_irqoff(void)
64 65 66
{
	local_irq_disable();
	if (!need_resched())
67 68
		__asm__("	.set	push		\n"
			"	.set	mips3		\n"
69
			"	wait			\n"
70
			"	.set	pop		\n");
71
	local_irq_enable();
72 73
	__asm__(" 	.globl __pastwait	\n"
		"__pastwait:			\n");
L
Linus Torvalds 已提交
74 75
}

76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
/*
 * The RM7000 variant has to handle erratum 38.  The workaround is to not
 * have any pending stores when the WAIT instruction is executed.
 */
static void rm7k_wait_irqoff(void)
{
	local_irq_disable();
	if (!need_resched())
		__asm__(
		"	.set	push					\n"
		"	.set	mips3					\n"
		"	.set	noat					\n"
		"	mfc0	$1, $12					\n"
		"	sync						\n"
		"	mtc0	$1, $12		# stalls until W stage	\n"
		"	wait						\n"
		"	mtc0	$1, $12		# stalls until W stage	\n"
		"	.set	pop					\n");
	local_irq_enable();
}

97 98 99 100 101
/*
 * The Au1xxx wait is available only if using 32khz counter or
 * external timer source, but specifically not CP0 Counter.
 * alchemy/common/time.c may override cpu_wait!
 */
102
static void au1k_wait(void)
L
Linus Torvalds 已提交
103
{
104 105 106 107 108 109 110 111 112 113 114
	__asm__("	.set	mips3			\n"
		"	cache	0x14, 0(%0)		\n"
		"	cache	0x14, 32(%0)		\n"
		"	sync				\n"
		"	nop				\n"
		"	wait				\n"
		"	nop				\n"
		"	nop				\n"
		"	nop				\n"
		"	nop				\n"
		"	.set	mips0			\n"
R
Ralf Baechle 已提交
115
		: : "r" (au1k_wait));
L
Linus Torvalds 已提交
116 117
}

118
static int __initdata nowait;
119

120
static int __init wait_disable(char *s)
121 122 123 124 125 126 127 128
{
	nowait = 1;

	return 1;
}

__setup("nowait", wait_disable);

129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
static int __cpuinitdata mips_fpu_disabled;

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

	return 1;
}

__setup("nofpu", fpu_disable);

int __cpuinitdata mips_dsp_disabled;

static int __init dsp_disable(char *s)
{
	cpu_data[0].ases &= ~MIPS_ASE_DSP;
	mips_dsp_disabled = 1;

	return 1;
}

__setup("nodsp", dsp_disable);

153
void __init check_wait(void)
L
Linus Torvalds 已提交
154 155 156
{
	struct cpuinfo_mips *c = &current_cpu_data;

157
	if (nowait) {
158
		printk("Wait instruction disabled.\n");
159 160 161
		return;
	}

L
Linus Torvalds 已提交
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
	switch (c->cputype) {
	case CPU_R3081:
	case CPU_R3081E:
		cpu_wait = r3081_wait;
		break;
	case CPU_TX3927:
		cpu_wait = r39xx_wait;
		break;
	case CPU_R4200:
/*	case CPU_R4300: */
	case CPU_R4600:
	case CPU_R4640:
	case CPU_R4650:
	case CPU_R4700:
	case CPU_R5000:
177
	case CPU_R5500:
L
Linus Torvalds 已提交
178 179 180 181 182 183
	case CPU_NEVADA:
	case CPU_4KC:
	case CPU_4KEC:
	case CPU_4KSC:
	case CPU_5KC:
	case CPU_25KF:
184
	case CPU_PR4450:
185 186 187 188
	case CPU_BMIPS3300:
	case CPU_BMIPS4350:
	case CPU_BMIPS4380:
	case CPU_BMIPS5000:
189
	case CPU_CAVIUM_OCTEON:
190
	case CPU_CAVIUM_OCTEON_PLUS:
191
	case CPU_CAVIUM_OCTEON2:
192
	case CPU_JZRISC:
193
	case CPU_LOONGSON1:
194
	case CPU_XLR:
J
Jayachandran C 已提交
195
	case CPU_XLP:
196 197 198
		cpu_wait = r4k_wait;
		break;

199 200 201 202
	case CPU_RM7000:
		cpu_wait = rm7k_wait_irqoff;
		break;

203
	case CPU_M14KC:
204
	case CPU_24K:
R
Ralf Baechle 已提交
205
	case CPU_34K:
206
	case CPU_1004K:
207 208 209 210 211
		cpu_wait = r4k_wait;
		if (read_c0_config7() & MIPS_CONF7_WII)
			cpu_wait = r4k_wait_irqoff;
		break;

212
	case CPU_74K:
L
Linus Torvalds 已提交
213
		cpu_wait = r4k_wait;
214 215
		if ((c->processor_id & 0xff) >= PRID_REV_ENCODE_332(2, 1, 0))
			cpu_wait = r4k_wait_irqoff;
L
Linus Torvalds 已提交
216
		break;
217

218 219 220
	case CPU_TX49XX:
		cpu_wait = r4k_wait_irqoff;
		break;
221
	case CPU_ALCHEMY:
222
		cpu_wait = au1k_wait;
L
Linus Torvalds 已提交
223
		break;
224 225 226 227 228 229 230 231 232
	case CPU_20KC:
		/*
		 * WAIT on Rev1.0 has E1, E2, E3 and E16.
		 * WAIT on Rev2.0 and Rev3.0 has E16.
		 * Rev3.1 WAIT is nop, why bother
		 */
		if ((c->processor_id & 0xff) <= 0x64)
			break;

233 234 235 236 237 238 239 240
		/*
		 * Another rev is incremeting c0_count at a reduced clock
		 * rate while in WAIT mode.  So we basically have the choice
		 * between using the cp0 timer as clocksource or avoiding
		 * the WAIT instruction.  Until more details are known,
		 * disable the use of WAIT for 20Kc entirely.
		   cpu_wait = r4k_wait;
		 */
241
		break;
242
	case CPU_RM9000:
243
		if ((c->processor_id & 0x00ff) >= 0x40)
244 245
			cpu_wait = r4k_wait;
		break;
L
Linus Torvalds 已提交
246 247 248 249 250
	default:
		break;
	}
}

M
Marc St-Jean 已提交
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
static inline void check_errata(void)
{
	struct cpuinfo_mips *c = &current_cpu_data;

	switch (c->cputype) {
	case CPU_34K:
		/*
		 * Erratum "RPS May Cause Incorrect Instruction Execution"
		 * This code only handles VPE0, any SMP/SMTC/RTOS code
		 * 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 已提交
270 271
void __init check_bugs32(void)
{
M
Marc St-Jean 已提交
272
	check_errata();
L
Linus Torvalds 已提交
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
}

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

297 298 299 300 301 302
static inline void set_elf_platform(int cpu, const char *plat)
{
	if (cpu == 0)
		__elf_platform = plat;
}

L
Linus Torvalds 已提交
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
/*
 * Get the FPU Implementation/Revision.
 */
static inline unsigned long cpu_get_fpu_id(void)
{
	unsigned long tmp, fpu_id;

	tmp = read_c0_status();
	__enable_fpu();
	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)
{
	return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE);
}

325 326 327
static inline void cpu_probe_vmbits(struct cpuinfo_mips *c)
{
#ifdef __NEED_VMBITS_PROBE
328
	write_c0_entryhi(0x3fffffffffffe000ULL);
329
	back_to_back_c0_hazard();
330
	c->vmbits = fls64(read_c0_entryhi() & 0x3fffffffffffe000ULL);
331 332 333
#endif
}

334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 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 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423
static char unknown_isa[] __cpuinitdata = KERN_ERR \
	"Unsupported ISA type, c0.config0: %d.";

static inline unsigned int decode_config0(struct cpuinfo_mips *c)
{
	unsigned int config0;
	int isa;

	config0 = read_c0_config();

	if (((config0 & MIPS_CONF_MT) >> 7) == 1)
		c->options |= MIPS_CPU_TLB;
	isa = (config0 & MIPS_CONF_AT) >> 13;
	switch (isa) {
	case 0:
		switch ((config0 & MIPS_CONF_AR) >> 10) {
		case 0:
			c->isa_level = MIPS_CPU_ISA_M32R1;
			break;
		case 1:
			c->isa_level = MIPS_CPU_ISA_M32R2;
			break;
		default:
			goto unknown;
		}
		break;
	case 2:
		switch ((config0 & MIPS_CONF_AR) >> 10) {
		case 0:
			c->isa_level = MIPS_CPU_ISA_M64R1;
			break;
		case 1:
			c->isa_level = MIPS_CPU_ISA_M64R2;
			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;
	}
	if (cpu_has_tlb)
		c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1;

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

424
	if (config3 & MIPS_CONF3_SM) {
425
		c->ases |= MIPS_ASE_SMARTMIPS;
426 427 428 429
		c->options |= MIPS_CPU_RIXI;
	}
	if (config3 & MIPS_CONF3_RXI)
		c->options |= MIPS_CPU_RIXI;
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485
	if (config3 & MIPS_CONF3_DSP)
		c->ases |= MIPS_ASE_DSP;
	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;

	return config3 & MIPS_CONF_M;
}

static inline unsigned int decode_config4(struct cpuinfo_mips *c)
{
	unsigned int config4;

	config4 = read_c0_config4();

	if ((config4 & MIPS_CONF4_MMUEXTDEF) == MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT
	    && cpu_has_tlb)
		c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;

	c->kscratch_mask = (config4 >> 16) & 0xff;

	return config4 & MIPS_CONF_M;
}

static void __cpuinit decode_configs(struct cpuinfo_mips *c)
{
	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;

	ok = decode_config0(c);			/* Read Config registers.  */
	BUG_ON(!ok);				/* Arch spec violation!  */
	if (ok)
		ok = decode_config1(c);
	if (ok)
		ok = decode_config2(c);
	if (ok)
		ok = decode_config3(c);
	if (ok)
		ok = decode_config4(c);

	mips_probe_watch_registers(c);

	if (cpu_has_mips_r2)
		c->core = read_c0_ebase() & 0x3ff;
}

R
Ralf Baechle 已提交
486
#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \
L
Linus Torvalds 已提交
487 488
		| MIPS_CPU_COUNTER)

489
static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
490 491 492 493
{
	switch (c->processor_id & 0xff00) {
	case PRID_IMP_R2000:
		c->cputype = CPU_R2000;
494
		__cpu_name[cpu] = "R2000";
L
Linus Torvalds 已提交
495
		c->isa_level = MIPS_CPU_ISA_I;
R
Ralf Baechle 已提交
496
		c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
S
Steven J. Hill 已提交
497
			     MIPS_CPU_NOFPUEX;
L
Linus Torvalds 已提交
498 499 500 501 502
		if (__cpu_has_fpu())
			c->options |= MIPS_CPU_FPU;
		c->tlbsize = 64;
		break;
	case PRID_IMP_R3000:
503 504
		if ((c->processor_id & 0xff) == PRID_REV_R3000A) {
			if (cpu_has_confreg()) {
L
Linus Torvalds 已提交
505
				c->cputype = CPU_R3081E;
506 507
				__cpu_name[cpu] = "R3081";
			} else {
L
Linus Torvalds 已提交
508
				c->cputype = CPU_R3000A;
509 510 511 512
				__cpu_name[cpu] = "R3000A";
			}
			break;
		} else {
L
Linus Torvalds 已提交
513
			c->cputype = CPU_R3000;
514 515
			__cpu_name[cpu] = "R3000";
		}
L
Linus Torvalds 已提交
516
		c->isa_level = MIPS_CPU_ISA_I;
R
Ralf Baechle 已提交
517
		c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
S
Steven J. Hill 已提交
518
			     MIPS_CPU_NOFPUEX;
L
Linus Torvalds 已提交
519 520 521 522 523 524
		if (__cpu_has_fpu())
			c->options |= MIPS_CPU_FPU;
		c->tlbsize = 64;
		break;
	case PRID_IMP_R4000:
		if (read_c0_config() & CONF_SC) {
525
			if ((c->processor_id & 0xff) >= PRID_REV_R4400) {
L
Linus Torvalds 已提交
526
				c->cputype = CPU_R4400PC;
527 528
				__cpu_name[cpu] = "R4400PC";
			} else {
L
Linus Torvalds 已提交
529
				c->cputype = CPU_R4000PC;
530 531
				__cpu_name[cpu] = "R4000PC";
			}
L
Linus Torvalds 已提交
532
		} else {
533
			if ((c->processor_id & 0xff) >= PRID_REV_R4400) {
L
Linus Torvalds 已提交
534
				c->cputype = CPU_R4400SC;
535 536
				__cpu_name[cpu] = "R4400SC";
			} else {
L
Linus Torvalds 已提交
537
				c->cputype = CPU_R4000SC;
538 539
				__cpu_name[cpu] = "R4000SC";
			}
L
Linus Torvalds 已提交
540 541 542 543
		}

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

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

		switch (c->processor_id & PRID_REV_MASK) {
		case PRID_REV_LOONGSON2E:
			set_elf_platform(cpu, "loongson2e");
			break;
		case PRID_REV_LOONGSON2F:
			set_elf_platform(cpu, "loongson2f");
			break;
		}

788 789 790 791 792 793
		c->isa_level = MIPS_CPU_ISA_III;
		c->options = R4K_OPTS |
			     MIPS_CPU_FPU | MIPS_CPU_LLSC |
			     MIPS_CPU_32FPR;
		c->tlbsize = 64;
		break;
794 795
	case PRID_IMP_LOONGSON1:
		decode_configs(c);
796

797
		c->cputype = CPU_LOONGSON1;
L
Linus Torvalds 已提交
798

799 800 801
		switch (c->processor_id & PRID_REV_MASK) {
		case PRID_REV_LOONGSON1B:
			__cpu_name[cpu] = "Loongson 1B";
802 803
			break;
		}
804

805
		break;
L
Linus Torvalds 已提交
806 807 808
	}
}

809
static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
810
{
811
	decode_configs(c);
L
Linus Torvalds 已提交
812 813 814
	switch (c->processor_id & 0xff00) {
	case PRID_IMP_4KC:
		c->cputype = CPU_4KC;
815
		__cpu_name[cpu] = "MIPS 4Kc";
L
Linus Torvalds 已提交
816 817
		break;
	case PRID_IMP_4KEC:
818 819
	case PRID_IMP_4KECR2:
		c->cputype = CPU_4KEC;
820
		__cpu_name[cpu] = "MIPS 4KEc";
821
		break;
L
Linus Torvalds 已提交
822
	case PRID_IMP_4KSC:
R
Ralf Baechle 已提交
823
	case PRID_IMP_4KSD:
L
Linus Torvalds 已提交
824
		c->cputype = CPU_4KSC;
825
		__cpu_name[cpu] = "MIPS 4KSc";
L
Linus Torvalds 已提交
826 827 828
		break;
	case PRID_IMP_5KC:
		c->cputype = CPU_5KC;
829
		__cpu_name[cpu] = "MIPS 5Kc";
L
Linus Torvalds 已提交
830
		break;
L
Leonid Yegoshin 已提交
831 832 833 834
	case PRID_IMP_5KE:
		c->cputype = CPU_5KE;
		__cpu_name[cpu] = "MIPS 5KE";
		break;
L
Linus Torvalds 已提交
835 836
	case PRID_IMP_20KC:
		c->cputype = CPU_20KC;
837
		__cpu_name[cpu] = "MIPS 20Kc";
L
Linus Torvalds 已提交
838 839
		break;
	case PRID_IMP_24K:
840
	case PRID_IMP_24KE:
L
Linus Torvalds 已提交
841
		c->cputype = CPU_24K;
842
		__cpu_name[cpu] = "MIPS 24Kc";
L
Linus Torvalds 已提交
843 844 845
		break;
	case PRID_IMP_25KF:
		c->cputype = CPU_25KF;
846
		__cpu_name[cpu] = "MIPS 25Kc";
L
Linus Torvalds 已提交
847
		break;
R
Ralf Baechle 已提交
848 849
	case PRID_IMP_34K:
		c->cputype = CPU_34K;
850
		__cpu_name[cpu] = "MIPS 34Kc";
R
Ralf Baechle 已提交
851
		break;
852 853
	case PRID_IMP_74K:
		c->cputype = CPU_74K;
854
		__cpu_name[cpu] = "MIPS 74Kc";
855
		break;
856 857 858 859
	case PRID_IMP_M14KC:
		c->cputype = CPU_M14KC;
		__cpu_name[cpu] = "MIPS M14Kc";
		break;
860 861
	case PRID_IMP_1004K:
		c->cputype = CPU_1004K;
862
		__cpu_name[cpu] = "MIPS 1004Kc";
863
		break;
864 865 866 867
	case PRID_IMP_1074K:
		c->cputype = CPU_74K;
		__cpu_name[cpu] = "MIPS 1074Kc";
		break;
L
Linus Torvalds 已提交
868
	}
C
Chris Dearman 已提交
869 870

	spram_config();
L
Linus Torvalds 已提交
871 872
}

873
static inline void cpu_probe_alchemy(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
874
{
875
	decode_configs(c);
L
Linus Torvalds 已提交
876 877 878
	switch (c->processor_id & 0xff00) {
	case PRID_IMP_AU1_REV1:
	case PRID_IMP_AU1_REV2:
879
		c->cputype = CPU_ALCHEMY;
L
Linus Torvalds 已提交
880 881
		switch ((c->processor_id >> 24) & 0xff) {
		case 0:
882
			__cpu_name[cpu] = "Au1000";
L
Linus Torvalds 已提交
883 884
			break;
		case 1:
885
			__cpu_name[cpu] = "Au1500";
L
Linus Torvalds 已提交
886 887
			break;
		case 2:
888
			__cpu_name[cpu] = "Au1100";
L
Linus Torvalds 已提交
889 890
			break;
		case 3:
891
			__cpu_name[cpu] = "Au1550";
L
Linus Torvalds 已提交
892
			break;
P
Pete Popov 已提交
893
		case 4:
894
			__cpu_name[cpu] = "Au1200";
895
			if ((c->processor_id & 0xff) == 2)
896
				__cpu_name[cpu] = "Au1250";
897 898
			break;
		case 5:
899
			__cpu_name[cpu] = "Au1210";
P
Pete Popov 已提交
900
			break;
L
Linus Torvalds 已提交
901
		default:
902
			__cpu_name[cpu] = "Au1xxx";
L
Linus Torvalds 已提交
903 904 905 906 907 908
			break;
		}
		break;
	}
}

909
static inline void cpu_probe_sibyte(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
910
{
911
	decode_configs(c);
R
Ralf Baechle 已提交
912

L
Linus Torvalds 已提交
913 914 915
	switch (c->processor_id & 0xff00) {
	case PRID_IMP_SB1:
		c->cputype = CPU_SB1;
916
		__cpu_name[cpu] = "SiByte SB1";
L
Linus Torvalds 已提交
917
		/* FPU in pass1 is known to have issues. */
918
		if ((c->processor_id & 0xff) < 0x02)
919
			c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR);
L
Linus Torvalds 已提交
920
		break;
A
Andrew Isaacson 已提交
921 922
	case PRID_IMP_SB1A:
		c->cputype = CPU_SB1A;
923
		__cpu_name[cpu] = "SiByte SB1A";
A
Andrew Isaacson 已提交
924
		break;
L
Linus Torvalds 已提交
925 926 927
	}
}

928
static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
929
{
930
	decode_configs(c);
L
Linus Torvalds 已提交
931 932 933
	switch (c->processor_id & 0xff00) {
	case PRID_IMP_SR71000:
		c->cputype = CPU_SR71000;
934
		__cpu_name[cpu] = "Sandcraft SR71000";
L
Linus Torvalds 已提交
935 936 937 938 939 940
		c->scache.ways = 8;
		c->tlbsize = 64;
		break;
	}
}

941
static inline void cpu_probe_nxp(struct cpuinfo_mips *c, unsigned int cpu)
942 943 944 945 946
{
	decode_configs(c);
	switch (c->processor_id & 0xff00) {
	case PRID_IMP_PR4450:
		c->cputype = CPU_PR4450;
947
		__cpu_name[cpu] = "Philips PR4450";
948
		c->isa_level = MIPS_CPU_ISA_M32R1;
949 950 951 952
		break;
	}
}

953
static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
954 955 956
{
	decode_configs(c);
	switch (c->processor_id & 0xff00) {
957 958
	case PRID_IMP_BMIPS32_REV4:
	case PRID_IMP_BMIPS32_REV8:
959 960
		c->cputype = CPU_BMIPS32;
		__cpu_name[cpu] = "Broadcom BMIPS32";
961
		set_elf_platform(cpu, "bmips32");
962 963 964 965 966 967
		break;
	case PRID_IMP_BMIPS3300:
	case PRID_IMP_BMIPS3300_ALT:
	case PRID_IMP_BMIPS3300_BUG:
		c->cputype = CPU_BMIPS3300;
		__cpu_name[cpu] = "Broadcom BMIPS3300";
968
		set_elf_platform(cpu, "bmips3300");
969 970 971 972 973 974 975 976
		break;
	case PRID_IMP_BMIPS43XX: {
		int rev = c->processor_id & 0xff;

		if (rev >= PRID_REV_BMIPS4380_LO &&
				rev <= PRID_REV_BMIPS4380_HI) {
			c->cputype = CPU_BMIPS4380;
			__cpu_name[cpu] = "Broadcom BMIPS4380";
977
			set_elf_platform(cpu, "bmips4380");
978 979 980
		} else {
			c->cputype = CPU_BMIPS4350;
			__cpu_name[cpu] = "Broadcom BMIPS4350";
981
			set_elf_platform(cpu, "bmips4350");
982
		}
983
		break;
984 985 986 987
	}
	case PRID_IMP_BMIPS5000:
		c->cputype = CPU_BMIPS5000;
		__cpu_name[cpu] = "Broadcom BMIPS5000";
988
		set_elf_platform(cpu, "bmips5000");
989
		c->options |= MIPS_CPU_ULRI;
990
		break;
991 992 993
	}
}

994 995 996 997 998 999 1000
static inline void cpu_probe_cavium(struct cpuinfo_mips *c, unsigned int cpu)
{
	decode_configs(c);
	switch (c->processor_id & 0xff00) {
	case PRID_IMP_CAVIUM_CN38XX:
	case PRID_IMP_CAVIUM_CN31XX:
	case PRID_IMP_CAVIUM_CN30XX:
1001 1002 1003
		c->cputype = CPU_CAVIUM_OCTEON;
		__cpu_name[cpu] = "Cavium Octeon";
		goto platform;
1004 1005 1006 1007
	case PRID_IMP_CAVIUM_CN58XX:
	case PRID_IMP_CAVIUM_CN56XX:
	case PRID_IMP_CAVIUM_CN50XX:
	case PRID_IMP_CAVIUM_CN52XX:
1008 1009 1010
		c->cputype = CPU_CAVIUM_OCTEON_PLUS;
		__cpu_name[cpu] = "Cavium Octeon+";
platform:
1011
		set_elf_platform(cpu, "octeon");
1012
		break;
1013
	case PRID_IMP_CAVIUM_CN61XX:
1014
	case PRID_IMP_CAVIUM_CN63XX:
1015 1016
	case PRID_IMP_CAVIUM_CN66XX:
	case PRID_IMP_CAVIUM_CN68XX:
1017 1018
		c->cputype = CPU_CAVIUM_OCTEON2;
		__cpu_name[cpu] = "Cavium Octeon II";
1019
		set_elf_platform(cpu, "octeon2");
1020
		break;
1021 1022 1023 1024 1025 1026 1027
	default:
		printk(KERN_INFO "Unknown Octeon chip!\n");
		c->cputype = CPU_UNKNOWN;
		break;
	}
}

1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
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;
	switch (c->processor_id & 0xff00) {
	case PRID_IMP_JZRISC:
		c->cputype = CPU_JZRISC;
		__cpu_name[cpu] = "Ingenic JZRISC";
		break;
	default:
		panic("Unknown Ingenic Processor ID!");
		break;
	}
}

1044 1045 1046 1047
static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
{
	decode_configs(c);

M
Manuel Lauss 已提交
1048 1049 1050 1051 1052 1053 1054
	if ((c->processor_id & 0xff00) == PRID_IMP_NETLOGIC_AU13XX) {
		c->cputype = CPU_ALCHEMY;
		__cpu_name[cpu] = "Au1300";
		/* following stuff is not for Alchemy */
		return;
	}

1055 1056 1057 1058 1059 1060 1061 1062 1063
	c->options = (MIPS_CPU_TLB       |
			MIPS_CPU_4KEX    |
			MIPS_CPU_COUNTER |
			MIPS_CPU_DIVEC   |
			MIPS_CPU_WATCH   |
			MIPS_CPU_EJTAG   |
			MIPS_CPU_LLSC);

	switch (c->processor_id & 0xff00) {
1064 1065
	case PRID_IMP_NETLOGIC_XLP8XX:
	case PRID_IMP_NETLOGIC_XLP3XX:
J
Jayachandran C 已提交
1066 1067 1068 1069
		c->cputype = CPU_XLP;
		__cpu_name[cpu] = "Netlogic XLP";
		break;

1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099
	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 已提交
1100
		pr_info("Unknown Netlogic chip id [%02x]!\n",
1101 1102 1103 1104 1105
		       c->processor_id);
		c->cputype = CPU_XLR;
		break;
	}

J
Jayachandran C 已提交
1106 1107 1108 1109 1110 1111 1112 1113 1114
	if (c->cputype == CPU_XLP) {
		c->isa_level = MIPS_CPU_ISA_M64R2;
		c->options |= (MIPS_CPU_FPU | MIPS_CPU_ULRI | MIPS_CPU_MCHECK);
		/* This will be updated again after all threads are woken up */
		c->tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1;
	} else {
		c->isa_level = MIPS_CPU_ISA_M64R1;
		c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1;
	}
1115 1116
}

1117 1118 1119 1120 1121 1122
#ifdef CONFIG_64BIT
/* For use by uaccess.h */
u64 __ua_limit;
EXPORT_SYMBOL(__ua_limit);
#endif

1123
const char *__cpu_name[NR_CPUS];
1124
const char *__elf_platform;
1125

1126
__cpuinit void cpu_probe(void)
L
Linus Torvalds 已提交
1127 1128
{
	struct cpuinfo_mips *c = &current_cpu_data;
1129
	unsigned int cpu = smp_processor_id();
L
Linus Torvalds 已提交
1130 1131 1132 1133 1134 1135 1136 1137

	c->processor_id	= PRID_IMP_UNKNOWN;
	c->fpu_id	= FPIR_IMP_NONE;
	c->cputype	= CPU_UNKNOWN;

	c->processor_id = read_c0_prid();
	switch (c->processor_id & 0xff0000) {
	case PRID_COMP_LEGACY:
1138
		cpu_probe_legacy(c, cpu);
L
Linus Torvalds 已提交
1139 1140
		break;
	case PRID_COMP_MIPS:
1141
		cpu_probe_mips(c, cpu);
L
Linus Torvalds 已提交
1142 1143
		break;
	case PRID_COMP_ALCHEMY:
1144
		cpu_probe_alchemy(c, cpu);
L
Linus Torvalds 已提交
1145 1146
		break;
	case PRID_COMP_SIBYTE:
1147
		cpu_probe_sibyte(c, cpu);
L
Linus Torvalds 已提交
1148
		break;
1149
	case PRID_COMP_BROADCOM:
1150
		cpu_probe_broadcom(c, cpu);
1151
		break;
L
Linus Torvalds 已提交
1152
	case PRID_COMP_SANDCRAFT:
1153
		cpu_probe_sandcraft(c, cpu);
L
Linus Torvalds 已提交
1154
		break;
1155
	case PRID_COMP_NXP:
1156
		cpu_probe_nxp(c, cpu);
1157
		break;
1158 1159 1160
	case PRID_COMP_CAVIUM:
		cpu_probe_cavium(c, cpu);
		break;
1161 1162 1163
	case PRID_COMP_INGENIC:
		cpu_probe_ingenic(c, cpu);
		break;
1164 1165 1166
	case PRID_COMP_NETLOGIC:
		cpu_probe_netlogic(c, cpu);
		break;
L
Linus Torvalds 已提交
1167
	}
1168

1169 1170 1171
	BUG_ON(!__cpu_name[cpu]);
	BUG_ON(c->cputype == CPU_UNKNOWN);

1172 1173 1174 1175 1176 1177 1178
	/*
	 * 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);

1179 1180 1181 1182 1183 1184
	if (mips_fpu_disabled)
		c->options &= ~MIPS_CPU_FPU;

	if (mips_dsp_disabled)
		c->ases &= ~MIPS_ASE_DSP;

1185
	if (c->options & MIPS_CPU_FPU) {
L
Linus Torvalds 已提交
1186
		c->fpu_id = cpu_get_fpu_id();
1187

1188
		if (c->isa_level == MIPS_CPU_ISA_M32R1 ||
1189 1190 1191
		    c->isa_level == MIPS_CPU_ISA_M32R2 ||
		    c->isa_level == MIPS_CPU_ISA_M64R1 ||
		    c->isa_level == MIPS_CPU_ISA_M64R2) {
1192 1193 1194 1195
			if (c->fpu_id & MIPS_FPIR_3D)
				c->ases |= MIPS_ASE_MIPS3D;
		}
	}
1196

1197
	if (cpu_has_mips_r2) {
R
Ralf Baechle 已提交
1198
		c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
1199 1200 1201
		/* R2 has Performance Counter Interrupt indicator */
		c->options |= MIPS_CPU_PCI;
	}
R
Ralf Baechle 已提交
1202 1203
	else
		c->srsets = 1;
1204 1205

	cpu_probe_vmbits(c);
1206 1207 1208 1209 1210

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

1213
__cpuinit void cpu_report(void)
L
Linus Torvalds 已提交
1214 1215 1216
{
	struct cpuinfo_mips *c = &current_cpu_data;

1217 1218
	printk(KERN_INFO "CPU revision is: %08x (%s)\n",
	       c->processor_id, cpu_name_string());
L
Linus Torvalds 已提交
1219
	if (c->options & MIPS_CPU_FPU)
1220
		printk(KERN_INFO "FPU revision is: %08x\n", c->fpu_id);
L
Linus Torvalds 已提交
1221
}