cpu-probe.c 51.1 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-features.h>
24
#include <asm/cpu-type.h>
L
Linus Torvalds 已提交
25 26
#include <asm/fpu.h>
#include <asm/mipsregs.h>
27
#include <asm/mipsmtregs.h>
P
Paul Burton 已提交
28
#include <asm/msa.h>
29
#include <asm/watch.h>
30
#include <asm/elf.h>
31
#include <asm/pgtable-bits.h>
32
#include <asm/spram.h>
33 34
#include <asm/uaccess.h>

35 36 37
/* Hardware capabilities */
unsigned int elf_hwcap __read_mostly;

38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
/*
 * 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_AS_IS);
	fpu_id = read_32bit_cp1_register(CP1_REVISION);
	write_c0_status(tmp);
	return fpu_id;
}

/*
 * Check if the CPU has an external FPU.
 */
static inline int __cpu_has_fpu(void)
{
	return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE;
}

static inline unsigned long cpu_get_msa_id(void)
{
	unsigned long status, msa_id;

	status = read_c0_status();
	__enable_fpu(FPU_64BIT);
	enable_msa();
	msa_id = read_msa_ir();
	disable_msa();
	write_c0_status(status);
	return msa_id;
}

73 74 75 76 77 78 79
/*
 * Determine the FCSR mask for FPU hardware.
 */
static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_mips *c)
{
	unsigned long sr, mask, fcsr, fcsr0, fcsr1;

80
	fcsr = c->fpu_csr31;
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
	mask = FPU_CSR_ALL_X | FPU_CSR_ALL_E | FPU_CSR_ALL_S | FPU_CSR_RM;

	sr = read_c0_status();
	__enable_fpu(FPU_AS_IS);

	fcsr0 = fcsr & mask;
	write_32bit_cp1_register(CP1_STATUS, fcsr0);
	fcsr0 = read_32bit_cp1_register(CP1_STATUS);

	fcsr1 = fcsr | ~mask;
	write_32bit_cp1_register(CP1_STATUS, fcsr1);
	fcsr1 = read_32bit_cp1_register(CP1_STATUS);

	write_32bit_cp1_register(CP1_STATUS, fcsr);

	write_c0_status(sr);

	c->fpu_msk31 = ~(fcsr0 ^ fcsr1) & ~mask;
}

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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
/*
 * Determine the IEEE 754 NaN encodings and ABS.fmt/NEG.fmt execution modes
 * supported by FPU hardware.
 */
static void cpu_set_fpu_2008(struct cpuinfo_mips *c)
{
	if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
			    MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
			    MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
		unsigned long sr, fir, fcsr, fcsr0, fcsr1;

		sr = read_c0_status();
		__enable_fpu(FPU_AS_IS);

		fir = read_32bit_cp1_register(CP1_REVISION);
		if (fir & MIPS_FPIR_HAS2008) {
			fcsr = read_32bit_cp1_register(CP1_STATUS);

			fcsr0 = fcsr & ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
			write_32bit_cp1_register(CP1_STATUS, fcsr0);
			fcsr0 = read_32bit_cp1_register(CP1_STATUS);

			fcsr1 = fcsr | FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
			write_32bit_cp1_register(CP1_STATUS, fcsr1);
			fcsr1 = read_32bit_cp1_register(CP1_STATUS);

			write_32bit_cp1_register(CP1_STATUS, fcsr);

			if (!(fcsr0 & FPU_CSR_NAN2008))
				c->options |= MIPS_CPU_NAN_LEGACY;
			if (fcsr1 & FPU_CSR_NAN2008)
				c->options |= MIPS_CPU_NAN_2008;

			if ((fcsr0 ^ fcsr1) & FPU_CSR_ABS2008)
				c->fpu_msk31 &= ~FPU_CSR_ABS2008;
			else
				c->fpu_csr31 |= fcsr & FPU_CSR_ABS2008;

			if ((fcsr0 ^ fcsr1) & FPU_CSR_NAN2008)
				c->fpu_msk31 &= ~FPU_CSR_NAN2008;
			else
				c->fpu_csr31 |= fcsr & FPU_CSR_NAN2008;
		} else {
			c->options |= MIPS_CPU_NAN_LEGACY;
		}

		write_c0_status(sr);
	} else {
		c->options |= MIPS_CPU_NAN_LEGACY;
	}
}

/*
154 155 156 157 158 159 160 161 162 163
 * IEEE 754 conformance mode to use.  Affects the NaN encoding and the
 * ABS.fmt/NEG.fmt execution mode.
 */
static enum { STRICT, LEGACY, STD2008, RELAXED } ieee754 = STRICT;

/*
 * Set the IEEE 754 NaN encodings and the ABS.fmt/NEG.fmt execution modes
 * to support by the FPU emulator according to the IEEE 754 conformance
 * mode selected.  Note that "relaxed" straps the emulator so that it
 * allows 2008-NaN binaries even for legacy processors.
164 165 166
 */
static void cpu_set_nofpu_2008(struct cpuinfo_mips *c)
{
167
	c->options &= ~(MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY);
168
	c->fpu_csr31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
169 170 171 172 173 174 175 176 177 178 179 180 181 182
	c->fpu_msk31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);

	switch (ieee754) {
	case STRICT:
		if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
				    MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
				    MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
			c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY;
		} else {
			c->options |= MIPS_CPU_NAN_LEGACY;
			c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
		}
		break;
	case LEGACY:
183 184
		c->options |= MIPS_CPU_NAN_LEGACY;
		c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
185 186 187 188 189 190 191 192 193
		break;
	case STD2008:
		c->options |= MIPS_CPU_NAN_2008;
		c->fpu_csr31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
		c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
		break;
	case RELAXED:
		c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY;
		break;
194 195 196
	}
}

197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
/*
 * Override the IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode
 * according to the "ieee754=" parameter.
 */
static void cpu_set_nan_2008(struct cpuinfo_mips *c)
{
	switch (ieee754) {
	case STRICT:
		mips_use_nan_legacy = !!cpu_has_nan_legacy;
		mips_use_nan_2008 = !!cpu_has_nan_2008;
		break;
	case LEGACY:
		mips_use_nan_legacy = !!cpu_has_nan_legacy;
		mips_use_nan_2008 = !cpu_has_nan_legacy;
		break;
	case STD2008:
		mips_use_nan_legacy = !cpu_has_nan_2008;
		mips_use_nan_2008 = !!cpu_has_nan_2008;
		break;
	case RELAXED:
		mips_use_nan_legacy = true;
		mips_use_nan_2008 = true;
		break;
	}
}

/*
 * IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode override
 * settings:
 *
 * strict:  accept binaries that request a NaN encoding supported by the FPU
 * legacy:  only accept legacy-NaN binaries
 * 2008:    only accept 2008-NaN binaries
 * relaxed: accept any binaries regardless of whether supported by the FPU
 */
static int __init ieee754_setup(char *s)
{
	if (!s)
		return -1;
	else if (!strcmp(s, "strict"))
		ieee754 = STRICT;
	else if (!strcmp(s, "legacy"))
		ieee754 = LEGACY;
	else if (!strcmp(s, "2008"))
		ieee754 = STD2008;
	else if (!strcmp(s, "relaxed"))
		ieee754 = RELAXED;
	else
		return -1;

	if (!(boot_cpu_data.options & MIPS_CPU_FPU))
		cpu_set_nofpu_2008(&boot_cpu_data);
	cpu_set_nan_2008(&boot_cpu_data);

	return 0;
}

early_param("ieee754", ieee754_setup);

256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
/*
 * Set the FIR feature flags for the FPU emulator.
 */
static void cpu_set_nofpu_id(struct cpuinfo_mips *c)
{
	u32 value;

	value = 0;
	if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
			    MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
			    MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6))
		value |= MIPS_FPIR_D | MIPS_FPIR_S;
	if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
			    MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6))
		value |= MIPS_FPIR_F64 | MIPS_FPIR_L | MIPS_FPIR_W;
271 272
	if (c->options & MIPS_CPU_NAN_2008)
		value |= MIPS_FPIR_HAS2008;
273 274 275
	c->fpu_id = value;
}

276 277 278
/* Determined FPU emulator mask to use for the boot CPU with "nofpu".  */
static unsigned int mips_nofpu_msk31;

279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
/*
 * Set options for FPU hardware.
 */
static void cpu_set_fpu_opts(struct cpuinfo_mips *c)
{
	c->fpu_id = cpu_get_fpu_id();
	mips_nofpu_msk31 = c->fpu_msk31;

	if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
			    MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
			    MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
		if (c->fpu_id & MIPS_FPIR_3D)
			c->ases |= MIPS_ASE_MIPS3D;
		if (c->fpu_id & MIPS_FPIR_FREP)
			c->options |= MIPS_CPU_FRE;
	}

	cpu_set_fpu_fcsr_mask(c);
297
	cpu_set_fpu_2008(c);
298
	cpu_set_nan_2008(c);
299 300 301 302 303 304 305 306 307 308
}

/*
 * Set options for the FPU emulator.
 */
static void cpu_set_nofpu_opts(struct cpuinfo_mips *c)
{
	c->options &= ~MIPS_CPU_FPU;
	c->fpu_msk31 = mips_nofpu_msk31;

309
	cpu_set_nofpu_2008(c);
310
	cpu_set_nan_2008(c);
311 312 313
	cpu_set_nofpu_id(c);
}

314
static int mips_fpu_disabled;
315 316 317

static int __init fpu_disable(char *s)
{
318
	cpu_set_nofpu_opts(&boot_cpu_data);
319 320 321 322 323 324 325
	mips_fpu_disabled = 1;

	return 1;
}

__setup("nofpu", fpu_disable);

326
int mips_dsp_disabled;
327 328 329

static int __init dsp_disable(char *s)
{
330
	cpu_data[0].ases &= ~(MIPS_ASE_DSP | MIPS_ASE_DSP2P);
331 332 333 334 335 336 337
	mips_dsp_disabled = 1;

	return 1;
}

__setup("nodsp", dsp_disable);

338 339 340 341 342 343 344 345 346 347 348 349 350 351
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);

352 353 354
static int mips_ftlb_disabled;
static int mips_has_ftlb_configured;

355
static int set_ftlb_enable(struct cpuinfo_mips *c, int enable);
356 357 358 359 360 361 362 363 364 365 366 367 368

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 */
369 370 371 372
	if (set_ftlb_enable(&cpu_data[0], 0)) {
		pr_warn("Can't turn FTLB off\n");
		return 1;
	}
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

	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 已提交
412 413 414 415
static inline void check_errata(void)
{
	struct cpuinfo_mips *c = &current_cpu_data;

416
	switch (current_cpu_type()) {
M
Marc St-Jean 已提交
417 418 419
	case CPU_34K:
		/*
		 * Erratum "RPS May Cause Incorrect Instruction Execution"
R
Ralf Baechle 已提交
420
		 * This code only handles VPE0, any SMP/RTOS code
M
Marc St-Jean 已提交
421 422 423 424 425 426 427 428 429 430
		 * 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 已提交
431 432
void __init check_bugs32(void)
{
M
Marc St-Jean 已提交
433
	check_errata();
L
Linus Torvalds 已提交
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
}

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

458 459 460 461 462 463
static inline void set_elf_platform(int cpu, const char *plat)
{
	if (cpu == 0)
		__elf_platform = plat;
}

464 465 466
static inline void cpu_probe_vmbits(struct cpuinfo_mips *c)
{
#ifdef __NEED_VMBITS_PROBE
467
	write_c0_entryhi(0x3fffffffffffe000ULL);
468
	back_to_back_c0_hazard();
469
	c->vmbits = fls64(read_c0_entryhi() & 0x3fffffffffffe000ULL);
470 471 472
#endif
}

473
static void set_isa(struct cpuinfo_mips *c, unsigned int isa)
474 475 476 477 478 479 480 481 482 483 484
{
	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:
485
		c->isa_level |= MIPS_CPU_ISA_II | MIPS_CPU_ISA_III;
486 487
		break;

488 489 490 491 492 493 494
	/* R6 incompatible with everything else */
	case MIPS_CPU_ISA_M64R6:
		c->isa_level |= MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6;
	case MIPS_CPU_ISA_M32R6:
		c->isa_level |= MIPS_CPU_ISA_M32R6;
		/* Break here so we don't add incompatible ISAs */
		break;
495 496 497 498 499 500 501 502 503 504
	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;
	}
}

505
static char unknown_isa[] = KERN_ERR \
506 507
	"Unsupported ISA type, c0.config0: %d.";

508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533
static unsigned int calculate_ftlb_probability(struct cpuinfo_mips *c)
{

	unsigned int probability = c->tlbsize / c->tlbsizevtlb;

	/*
	 * 0 = All TLBWR instructions go to FTLB
	 * 1 = 15:1: For every 16 TBLWR instructions, 15 go to the
	 * FTLB and 1 goes to the VTLB.
	 * 2 = 7:1: As above with 7:1 ratio.
	 * 3 = 3:1: As above with 3:1 ratio.
	 *
	 * Use the linear midpoint as the probability threshold.
	 */
	if (probability >= 12)
		return 1;
	else if (probability >= 6)
		return 2;
	else
		/*
		 * So FTLB is less than 4 times bigger than VTLB.
		 * A 3:1 ratio can still be useful though.
		 */
		return 3;
}

534
static int set_ftlb_enable(struct cpuinfo_mips *c, int enable)
L
Leonid Yegoshin 已提交
535
{
536
	unsigned int config;
537 538 539 540 541

	/* It's implementation dependent how the FTLB can be enabled */
	switch (c->cputype) {
	case CPU_PROAPTIV:
	case CPU_P5600:
542
	case CPU_P6600:
543
		/* proAptiv & related cores use Config6 to enable the FTLB */
544
		config = read_c0_config6();
545
		/* Clear the old probability value */
546
		config &= ~(3 << MIPS_CONF6_FTLBP_SHIFT);
L
Leonid Yegoshin 已提交
547 548
		if (enable)
			/* Enable FTLB */
549
			write_c0_config6(config |
550 551 552
					 (calculate_ftlb_probability(c)
					  << MIPS_CONF6_FTLBP_SHIFT)
					 | MIPS_CONF6_FTLBEN);
L
Leonid Yegoshin 已提交
553 554
		else
			/* Disable FTLB */
555 556 557
			write_c0_config6(config &  ~MIPS_CONF6_FTLBEN);
		break;
	case CPU_I6400:
P
Paul Burton 已提交
558 559
		/* There's no way to disable the FTLB */
		return !enable;
560
	case CPU_LOONGSON3:
561 562 563
		/* Flush ITLB, DTLB, VTLB and FTLB */
		write_c0_diag(LOONGSON_DIAG_ITLB | LOONGSON_DIAG_DTLB |
			      LOONGSON_DIAG_VTLB | LOONGSON_DIAG_FTLB);
564 565 566 567 568 569 570 571 572
		/* Loongson-3 cores use Config6 to enable the FTLB */
		config = read_c0_config6();
		if (enable)
			/* Enable FTLB */
			write_c0_config6(config & ~MIPS_CONF6_FTLBDIS);
		else
			/* Disable FTLB */
			write_c0_config6(config | MIPS_CONF6_FTLBDIS);
		break;
573 574
	default:
		return 1;
L
Leonid Yegoshin 已提交
575
	}
576 577

	return 0;
L
Leonid Yegoshin 已提交
578 579
}

580 581 582
static inline unsigned int decode_config0(struct cpuinfo_mips *c)
{
	unsigned int config0;
583
	int isa, mt;
584 585 586

	config0 = read_c0_config();

L
Leonid Yegoshin 已提交
587 588 589
	/*
	 * Look for Standard TLB or Dual VTLB and FTLB
	 */
590 591
	mt = config0 & MIPS_CONF_MT;
	if (mt == MIPS_CONF_MT_TLB)
592
		c->options |= MIPS_CPU_TLB;
593 594
	else if (mt == MIPS_CONF_MT_FTLB)
		c->options |= MIPS_CPU_TLB | MIPS_CPU_FTLB;
L
Leonid Yegoshin 已提交
595

596 597 598 599 600
	isa = (config0 & MIPS_CONF_AT) >> 13;
	switch (isa) {
	case 0:
		switch ((config0 & MIPS_CONF_AR) >> 10) {
		case 0:
601
			set_isa(c, MIPS_CPU_ISA_M32R1);
602 603
			break;
		case 1:
604
			set_isa(c, MIPS_CPU_ISA_M32R2);
605
			break;
606 607 608
		case 2:
			set_isa(c, MIPS_CPU_ISA_M32R6);
			break;
609 610 611 612 613 614 615
		default:
			goto unknown;
		}
		break;
	case 2:
		switch ((config0 & MIPS_CONF_AR) >> 10) {
		case 0:
616
			set_isa(c, MIPS_CPU_ISA_M64R1);
617 618
			break;
		case 1:
619
			set_isa(c, MIPS_CPU_ISA_M64R2);
620
			break;
621 622 623
		case 2:
			set_isa(c, MIPS_CPU_ISA_M64R6);
			break;
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645
		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;
J
James Hogan 已提交
646 647
	if (config1 & MIPS_CONF1_PC)
		c->options |= MIPS_CPU_PERF;
648 649 650 651 652 653 654 655 656 657
	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 已提交
658
	if (cpu_has_tlb) {
659
		c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1;
L
Leonid Yegoshin 已提交
660 661 662
		c->tlbsizevtlb = c->tlbsize;
		c->tlbsizeftlbsets = 0;
	}
663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684

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

685
	if (config3 & MIPS_CONF3_SM) {
686
		c->ases |= MIPS_ASE_SMARTMIPS;
687
		c->options |= MIPS_CPU_RIXI | MIPS_CPU_CTXTC;
688 689 690
	}
	if (config3 & MIPS_CONF3_RXI)
		c->options |= MIPS_CPU_RIXI;
691 692
	if (config3 & MIPS_CONF3_CTXTC)
		c->options |= MIPS_CPU_CTXTC;
693 694
	if (config3 & MIPS_CONF3_DSP)
		c->ases |= MIPS_ASE_DSP;
695
	if (config3 & MIPS_CONF3_DSP2P) {
696
		c->ases |= MIPS_ASE_DSP2P;
697 698 699
		if (cpu_has_mips_r6)
			c->ases |= MIPS_ASE_DSP3;
	}
700 701 702 703
	if (config3 & MIPS_CONF3_VINT)
		c->options |= MIPS_CPU_VINT;
	if (config3 & MIPS_CONF3_VEIC)
		c->options |= MIPS_CPU_VEIC;
704 705
	if (config3 & MIPS_CONF3_LPA)
		c->options |= MIPS_CPU_LPA;
706 707 708 709
	if (config3 & MIPS_CONF3_MT)
		c->ases |= MIPS_ASE_MIPSMT;
	if (config3 & MIPS_CONF3_ULRI)
		c->options |= MIPS_CPU_ULRI;
710 711
	if (config3 & MIPS_CONF3_ISA)
		c->options |= MIPS_CPU_MICROMIPS;
712 713
	if (config3 & MIPS_CONF3_VZ)
		c->ases |= MIPS_ASE_VZ;
714 715
	if (config3 & MIPS_CONF3_SC)
		c->options |= MIPS_CPU_SEGMENTS;
716 717 718 719
	if (config3 & MIPS_CONF3_BI)
		c->options |= MIPS_CPU_BADINSTR;
	if (config3 & MIPS_CONF3_BP)
		c->options |= MIPS_CPU_BADINSTRP;
P
Paul Burton 已提交
720 721
	if (config3 & MIPS_CONF3_MSA)
		c->ases |= MIPS_ASE_MSA;
722
	if (config3 & MIPS_CONF3_PW) {
723
		c->htw_seq = 0;
724
		c->options |= MIPS_CPU_HTW;
725
	}
726 727
	if (config3 & MIPS_CONF3_CDMM)
		c->options |= MIPS_CPU_CDMM;
728 729
	if (config3 & MIPS_CONF3_SP)
		c->options |= MIPS_CPU_SP;
730 731 732 733 734 735 736

	return config3 & MIPS_CONF_M;
}

static inline unsigned int decode_config4(struct cpuinfo_mips *c)
{
	unsigned int config4;
L
Leonid Yegoshin 已提交
737 738 739
	unsigned int newcf4;
	unsigned int mmuextdef;
	unsigned int ftlb_page = MIPS_CONF4_FTLBPAGESIZE;
P
Paul Burton 已提交
740
	unsigned long asid_mask;
741 742 743

	config4 = read_c0_config4();

744 745 746
	if (cpu_has_tlb) {
		if (((config4 & MIPS_CONF4_IE) >> 29) == 2)
			c->options |= MIPS_CPU_TLBINV;
J
James Hogan 已提交
747

748
		/*
J
James Hogan 已提交
749 750 751
		 * R6 has dropped the MMUExtDef field from config4.
		 * On R6 the fields always describe the FTLB, and only if it is
		 * present according to Config.MT.
752
		 */
J
James Hogan 已提交
753 754 755
		if (!cpu_has_mips_r6)
			mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF;
		else if (cpu_has_ftlb)
756 757
			mmuextdef = MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT;
		else
J
James Hogan 已提交
758
			mmuextdef = 0;
759

L
Leonid Yegoshin 已提交
760 761 762 763 764 765 766 767 768 769 770 771 772
		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:
773 774
			if (mips_ftlb_disabled)
				break;
L
Leonid Yegoshin 已提交
775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793
			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;
794
			mips_has_ftlb_configured = 1;
L
Leonid Yegoshin 已提交
795 796
			break;
		}
797 798
	}

799 800
	c->kscratch_mask = (config4 & MIPS_CONF4_KSCREXIST)
				>> MIPS_CONF4_KSCREXIST_SHIFT;
801

P
Paul Burton 已提交
802 803 804 805 806 807 808 809 810 811 812 813
	asid_mask = MIPS_ENTRYHI_ASID;
	if (config4 & MIPS_CONF4_AE)
		asid_mask |= MIPS_ENTRYHI_ASIDX;
	set_cpu_asid_mask(c, asid_mask);

	/*
	 * Warn if the computed ASID mask doesn't match the mask the kernel
	 * is built for. This may indicate either a serious problem or an
	 * easy optimisation opportunity, but either way should be addressed.
	 */
	WARN_ON(asid_mask != cpu_asid_mask(c));

814 815 816
	return config4 & MIPS_CONF_M;
}

817 818 819 820 821
static inline unsigned int decode_config5(struct cpuinfo_mips *c)
{
	unsigned int config5;

	config5 = read_c0_config5();
822
	config5 &= ~(MIPS_CONF5_UFR | MIPS_CONF5_UFE);
823 824
	write_c0_config5(config5);

825 826
	if (config5 & MIPS_CONF5_EVA)
		c->options |= MIPS_CPU_EVA;
P
Paul Burton 已提交
827 828
	if (config5 & MIPS_CONF5_MRP)
		c->options |= MIPS_CPU_MAAR;
829 830
	if (config5 & MIPS_CONF5_LLB)
		c->options |= MIPS_CPU_RW_LLB;
S
Steven J. Hill 已提交
831
	if (config5 & MIPS_CONF5_MVH)
832
		c->options |= MIPS_CPU_MVH;
833 834
	if (cpu_has_mips_r6 && (config5 & MIPS_CONF5_VP))
		c->options |= MIPS_CPU_VP;
835

836 837 838
	return config5 & MIPS_CONF_M;
}

839
static void decode_configs(struct cpuinfo_mips *c)
840 841 842 843 844 845 846 847 848
{
	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;

849 850
	/* Enable FTLB if present and not disabled */
	set_ftlb_enable(c, !mips_ftlb_disabled);
L
Leonid Yegoshin 已提交
851

852
	ok = decode_config0(c);			/* Read Config registers.  */
R
Ralf Baechle 已提交
853
	BUG_ON(!ok);				/* Arch spec violation!	 */
854 855 856 857 858 859 860 861
	if (ok)
		ok = decode_config1(c);
	if (ok)
		ok = decode_config2(c);
	if (ok)
		ok = decode_config3(c);
	if (ok)
		ok = decode_config4(c);
862 863
	if (ok)
		ok = decode_config5(c);
864

865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899
	/* Probe the EBase.WG bit */
	if (cpu_has_mips_r2_r6) {
		u64 ebase;
		unsigned int status;

		/* {read,write}_c0_ebase_64() may be UNDEFINED prior to r6 */
		ebase = cpu_has_mips64r6 ? read_c0_ebase_64()
					 : (s32)read_c0_ebase();
		if (ebase & MIPS_EBASE_WG) {
			/* WG bit already set, we can avoid the clumsy probe */
			c->options |= MIPS_CPU_EBASE_WG;
		} else {
			/* Its UNDEFINED to change EBase while BEV=0 */
			status = read_c0_status();
			write_c0_status(status | ST0_BEV);
			irq_enable_hazard();
			/*
			 * On pre-r6 cores, this may well clobber the upper bits
			 * of EBase. This is hard to avoid without potentially
			 * hitting UNDEFINED dm*c0 behaviour if EBase is 32-bit.
			 */
			if (cpu_has_mips64r6)
				write_c0_ebase_64(ebase | MIPS_EBASE_WG);
			else
				write_c0_ebase(ebase | MIPS_EBASE_WG);
			back_to_back_c0_hazard();
			/* Restore BEV */
			write_c0_status(status);
			if (read_c0_ebase() & MIPS_EBASE_WG) {
				c->options |= MIPS_CPU_EBASE_WG;
				write_c0_ebase(ebase);
			}
		}
	}

900 901
	mips_probe_watch_registers(c);

902
#ifndef CONFIG_MIPS_CPS
903
	if (cpu_has_mips_r2_r6) {
904
		c->core = get_ebase_cpunum();
905 906 907
		if (cpu_has_mipsmt)
			c->core >>= fls(core_nvpes()) - 1;
	}
908
#endif
909 910
}

911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 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 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139
/*
 * Probe for certain guest capabilities by writing config bits and reading back.
 * Finally write back the original value.
 */
#define probe_gc0_config(name, maxconf, bits)				\
do {									\
	unsigned int tmp;						\
	tmp = read_gc0_##name();					\
	write_gc0_##name(tmp | (bits));					\
	back_to_back_c0_hazard();					\
	maxconf = read_gc0_##name();					\
	write_gc0_##name(tmp);						\
} while (0)

/*
 * Probe for dynamic guest capabilities by changing certain config bits and
 * reading back to see if they change. Finally write back the original value.
 */
#define probe_gc0_config_dyn(name, maxconf, dynconf, bits)		\
do {									\
	maxconf = read_gc0_##name();					\
	write_gc0_##name(maxconf ^ (bits));				\
	back_to_back_c0_hazard();					\
	dynconf = maxconf ^ read_gc0_##name();				\
	write_gc0_##name(maxconf);					\
	maxconf |= dynconf;						\
} while (0)

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

	probe_gc0_config(config, config0, MIPS_CONF_M);

	if (config0 & MIPS_CONF_M)
		c->guest.conf |= BIT(1);
	return config0 & MIPS_CONF_M;
}

static inline unsigned int decode_guest_config1(struct cpuinfo_mips *c)
{
	unsigned int config1, config1_dyn;

	probe_gc0_config_dyn(config1, config1, config1_dyn,
			     MIPS_CONF_M | MIPS_CONF1_PC | MIPS_CONF1_WR |
			     MIPS_CONF1_FP);

	if (config1 & MIPS_CONF1_FP)
		c->guest.options |= MIPS_CPU_FPU;
	if (config1_dyn & MIPS_CONF1_FP)
		c->guest.options_dyn |= MIPS_CPU_FPU;

	if (config1 & MIPS_CONF1_WR)
		c->guest.options |= MIPS_CPU_WATCH;
	if (config1_dyn & MIPS_CONF1_WR)
		c->guest.options_dyn |= MIPS_CPU_WATCH;

	if (config1 & MIPS_CONF1_PC)
		c->guest.options |= MIPS_CPU_PERF;
	if (config1_dyn & MIPS_CONF1_PC)
		c->guest.options_dyn |= MIPS_CPU_PERF;

	if (config1 & MIPS_CONF_M)
		c->guest.conf |= BIT(2);
	return config1 & MIPS_CONF_M;
}

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

	probe_gc0_config(config2, config2, MIPS_CONF_M);

	if (config2 & MIPS_CONF_M)
		c->guest.conf |= BIT(3);
	return config2 & MIPS_CONF_M;
}

static inline unsigned int decode_guest_config3(struct cpuinfo_mips *c)
{
	unsigned int config3, config3_dyn;

	probe_gc0_config_dyn(config3, config3, config3_dyn,
			     MIPS_CONF_M | MIPS_CONF3_MSA | MIPS_CONF3_CTXTC);

	if (config3 & MIPS_CONF3_CTXTC)
		c->guest.options |= MIPS_CPU_CTXTC;
	if (config3_dyn & MIPS_CONF3_CTXTC)
		c->guest.options_dyn |= MIPS_CPU_CTXTC;

	if (config3 & MIPS_CONF3_PW)
		c->guest.options |= MIPS_CPU_HTW;

	if (config3 & MIPS_CONF3_SC)
		c->guest.options |= MIPS_CPU_SEGMENTS;

	if (config3 & MIPS_CONF3_BI)
		c->guest.options |= MIPS_CPU_BADINSTR;
	if (config3 & MIPS_CONF3_BP)
		c->guest.options |= MIPS_CPU_BADINSTRP;

	if (config3 & MIPS_CONF3_MSA)
		c->guest.ases |= MIPS_ASE_MSA;
	if (config3_dyn & MIPS_CONF3_MSA)
		c->guest.ases_dyn |= MIPS_ASE_MSA;

	if (config3 & MIPS_CONF_M)
		c->guest.conf |= BIT(4);
	return config3 & MIPS_CONF_M;
}

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

	probe_gc0_config(config4, config4,
			 MIPS_CONF_M | MIPS_CONF4_KSCREXIST);

	c->guest.kscratch_mask = (config4 & MIPS_CONF4_KSCREXIST)
				>> MIPS_CONF4_KSCREXIST_SHIFT;

	if (config4 & MIPS_CONF_M)
		c->guest.conf |= BIT(5);
	return config4 & MIPS_CONF_M;
}

static inline unsigned int decode_guest_config5(struct cpuinfo_mips *c)
{
	unsigned int config5, config5_dyn;

	probe_gc0_config_dyn(config5, config5, config5_dyn,
			 MIPS_CONF_M | MIPS_CONF5_MRP);

	if (config5 & MIPS_CONF5_MRP)
		c->guest.options |= MIPS_CPU_MAAR;
	if (config5_dyn & MIPS_CONF5_MRP)
		c->guest.options_dyn |= MIPS_CPU_MAAR;

	if (config5 & MIPS_CONF5_LLB)
		c->guest.options |= MIPS_CPU_RW_LLB;

	if (config5 & MIPS_CONF_M)
		c->guest.conf |= BIT(6);
	return config5 & MIPS_CONF_M;
}

static inline void decode_guest_configs(struct cpuinfo_mips *c)
{
	unsigned int ok;

	ok = decode_guest_config0(c);
	if (ok)
		ok = decode_guest_config1(c);
	if (ok)
		ok = decode_guest_config2(c);
	if (ok)
		ok = decode_guest_config3(c);
	if (ok)
		ok = decode_guest_config4(c);
	if (ok)
		decode_guest_config5(c);
}

static inline void cpu_probe_guestctl0(struct cpuinfo_mips *c)
{
	unsigned int guestctl0, temp;

	guestctl0 = read_c0_guestctl0();

	if (guestctl0 & MIPS_GCTL0_G0E)
		c->options |= MIPS_CPU_GUESTCTL0EXT;
	if (guestctl0 & MIPS_GCTL0_G1)
		c->options |= MIPS_CPU_GUESTCTL1;
	if (guestctl0 & MIPS_GCTL0_G2)
		c->options |= MIPS_CPU_GUESTCTL2;
	if (!(guestctl0 & MIPS_GCTL0_RAD)) {
		c->options |= MIPS_CPU_GUESTID;

		/*
		 * Probe for Direct Root to Guest (DRG). Set GuestCtl1.RID = 0
		 * first, otherwise all data accesses will be fully virtualised
		 * as if they were performed by guest mode.
		 */
		write_c0_guestctl1(0);
		tlbw_use_hazard();

		write_c0_guestctl0(guestctl0 | MIPS_GCTL0_DRG);
		back_to_back_c0_hazard();
		temp = read_c0_guestctl0();

		if (temp & MIPS_GCTL0_DRG) {
			write_c0_guestctl0(guestctl0);
			c->options |= MIPS_CPU_DRG;
		}
	}
}

static inline void cpu_probe_guestctl1(struct cpuinfo_mips *c)
{
	if (cpu_has_guestid) {
		/* determine the number of bits of GuestID available */
		write_c0_guestctl1(MIPS_GCTL1_ID);
		back_to_back_c0_hazard();
		c->guestid_mask = (read_c0_guestctl1() & MIPS_GCTL1_ID)
						>> MIPS_GCTL1_ID_SHIFT;
		write_c0_guestctl1(0);
	}
}

static inline void cpu_probe_gtoffset(struct cpuinfo_mips *c)
{
	/* determine the number of bits of GTOffset available */
	write_c0_gtoffset(0xffffffff);
	back_to_back_c0_hazard();
	c->gtoffset_mask = read_c0_gtoffset();
	write_c0_gtoffset(0);
}

static inline void cpu_probe_vz(struct cpuinfo_mips *c)
{
	cpu_probe_guestctl0(c);
	if (cpu_has_guestctl1)
		cpu_probe_guestctl1(c);

	cpu_probe_gtoffset(c);

	decode_guest_configs(c);
}

R
Ralf Baechle 已提交
1140
#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \
L
Linus Torvalds 已提交
1141 1142
		| MIPS_CPU_COUNTER)

1143
static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
1144
{
1145
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
1146 1147
	case PRID_IMP_R2000:
		c->cputype = CPU_R2000;
1148
		__cpu_name[cpu] = "R2000";
1149
		c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
R
Ralf Baechle 已提交
1150
		c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
S
Steven J. Hill 已提交
1151
			     MIPS_CPU_NOFPUEX;
L
Linus Torvalds 已提交
1152 1153 1154 1155 1156
		if (__cpu_has_fpu())
			c->options |= MIPS_CPU_FPU;
		c->tlbsize = 64;
		break;
	case PRID_IMP_R3000:
1157
		if ((c->processor_id & PRID_REV_MASK) == PRID_REV_R3000A) {
1158
			if (cpu_has_confreg()) {
L
Linus Torvalds 已提交
1159
				c->cputype = CPU_R3081E;
1160 1161
				__cpu_name[cpu] = "R3081";
			} else {
L
Linus Torvalds 已提交
1162
				c->cputype = CPU_R3000A;
1163 1164 1165
				__cpu_name[cpu] = "R3000A";
			}
		} else {
L
Linus Torvalds 已提交
1166
			c->cputype = CPU_R3000;
1167 1168
			__cpu_name[cpu] = "R3000";
		}
1169
		c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
R
Ralf Baechle 已提交
1170
		c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
S
Steven J. Hill 已提交
1171
			     MIPS_CPU_NOFPUEX;
L
Linus Torvalds 已提交
1172 1173 1174 1175 1176 1177
		if (__cpu_has_fpu())
			c->options |= MIPS_CPU_FPU;
		c->tlbsize = 64;
		break;
	case PRID_IMP_R4000:
		if (read_c0_config() & CONF_SC) {
1178 1179
			if ((c->processor_id & PRID_REV_MASK) >=
			    PRID_REV_R4400) {
L
Linus Torvalds 已提交
1180
				c->cputype = CPU_R4400PC;
1181 1182
				__cpu_name[cpu] = "R4400PC";
			} else {
L
Linus Torvalds 已提交
1183
				c->cputype = CPU_R4000PC;
1184 1185
				__cpu_name[cpu] = "R4000PC";
			}
L
Linus Torvalds 已提交
1186
		} else {
1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206
			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;
			}
1207 1208
			if ((c->processor_id & PRID_REV_MASK) >=
			    PRID_REV_R4400) {
1209 1210
				c->cputype = mc ? CPU_R4400MC : CPU_R4400SC;
				__cpu_name[cpu] = mc ? "R4400MC" : "R4400SC";
1211
			} else {
1212 1213
				c->cputype = mc ? CPU_R4000MC : CPU_R4000SC;
				__cpu_name[cpu] = mc ? "R4000MC" : "R4000SC";
1214
			}
L
Linus Torvalds 已提交
1215 1216
		}

1217
		set_isa(c, MIPS_CPU_ISA_III);
1218
		c->fpu_msk31 |= FPU_CSR_CONDX;
L
Linus Torvalds 已提交
1219
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
1220 1221
			     MIPS_CPU_WATCH | MIPS_CPU_VCE |
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
1222 1223 1224
		c->tlbsize = 48;
		break;
	case PRID_IMP_VR41XX:
1225
		set_isa(c, MIPS_CPU_ISA_III);
1226
		c->fpu_msk31 |= FPU_CSR_CONDX;
1227 1228
		c->options = R4K_OPTS;
		c->tlbsize = 32;
L
Linus Torvalds 已提交
1229 1230 1231
		switch (c->processor_id & 0xf0) {
		case PRID_REV_VR4111:
			c->cputype = CPU_VR4111;
1232
			__cpu_name[cpu] = "NEC VR4111";
L
Linus Torvalds 已提交
1233 1234 1235
			break;
		case PRID_REV_VR4121:
			c->cputype = CPU_VR4121;
1236
			__cpu_name[cpu] = "NEC VR4121";
L
Linus Torvalds 已提交
1237 1238
			break;
		case PRID_REV_VR4122:
1239
			if ((c->processor_id & 0xf) < 0x3) {
L
Linus Torvalds 已提交
1240
				c->cputype = CPU_VR4122;
1241 1242
				__cpu_name[cpu] = "NEC VR4122";
			} else {
L
Linus Torvalds 已提交
1243
				c->cputype = CPU_VR4181A;
1244 1245
				__cpu_name[cpu] = "NEC VR4181A";
			}
L
Linus Torvalds 已提交
1246 1247
			break;
		case PRID_REV_VR4130:
1248
			if ((c->processor_id & 0xf) < 0x4) {
L
Linus Torvalds 已提交
1249
				c->cputype = CPU_VR4131;
1250 1251
				__cpu_name[cpu] = "NEC VR4131";
			} else {
L
Linus Torvalds 已提交
1252
				c->cputype = CPU_VR4133;
1253
				c->options |= MIPS_CPU_LLSC;
1254 1255
				__cpu_name[cpu] = "NEC VR4133";
			}
L
Linus Torvalds 已提交
1256 1257 1258 1259
			break;
		default:
			printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
			c->cputype = CPU_VR41XX;
1260
			__cpu_name[cpu] = "NEC Vr41xx";
L
Linus Torvalds 已提交
1261 1262 1263 1264 1265
			break;
		}
		break;
	case PRID_IMP_R4300:
		c->cputype = CPU_R4300;
1266
		__cpu_name[cpu] = "R4300";
1267
		set_isa(c, MIPS_CPU_ISA_III);
1268
		c->fpu_msk31 |= FPU_CSR_CONDX;
L
Linus Torvalds 已提交
1269
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
1270
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
1271 1272 1273 1274
		c->tlbsize = 32;
		break;
	case PRID_IMP_R4600:
		c->cputype = CPU_R4600;
1275
		__cpu_name[cpu] = "R4600";
1276
		set_isa(c, MIPS_CPU_ISA_III);
1277
		c->fpu_msk31 |= FPU_CSR_CONDX;
T
Thiemo Seufer 已提交
1278 1279
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
1280 1281 1282
		c->tlbsize = 48;
		break;
	#if 0
S
Steven J. Hill 已提交
1283
	case PRID_IMP_R4650:
L
Linus Torvalds 已提交
1284 1285 1286 1287 1288 1289
		/*
		 * 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.
		 */
1290
		c->cputype = CPU_R4650;
1291
		__cpu_name[cpu] = "R4650";
1292
		set_isa(c, MIPS_CPU_ISA_III);
1293
		c->fpu_msk31 |= FPU_CSR_CONDX;
L
Linus Torvalds 已提交
1294
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
S
Steven J. Hill 已提交
1295
		c->tlbsize = 48;
L
Linus Torvalds 已提交
1296 1297 1298
		break;
	#endif
	case PRID_IMP_TX39:
1299
		c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
R
Ralf Baechle 已提交
1300
		c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE;
L
Linus Torvalds 已提交
1301 1302 1303

		if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) {
			c->cputype = CPU_TX3927;
1304
			__cpu_name[cpu] = "TX3927";
L
Linus Torvalds 已提交
1305 1306
			c->tlbsize = 64;
		} else {
1307
			switch (c->processor_id & PRID_REV_MASK) {
L
Linus Torvalds 已提交
1308 1309
			case PRID_REV_TX3912:
				c->cputype = CPU_TX3912;
1310
				__cpu_name[cpu] = "TX3912";
L
Linus Torvalds 已提交
1311 1312 1313 1314
				c->tlbsize = 32;
				break;
			case PRID_REV_TX3922:
				c->cputype = CPU_TX3922;
1315
				__cpu_name[cpu] = "TX3922";
L
Linus Torvalds 已提交
1316 1317 1318 1319 1320 1321 1322
				c->tlbsize = 64;
				break;
			}
		}
		break;
	case PRID_IMP_R4700:
		c->cputype = CPU_R4700;
1323
		__cpu_name[cpu] = "R4700";
1324
		set_isa(c, MIPS_CPU_ISA_III);
1325
		c->fpu_msk31 |= FPU_CSR_CONDX;
L
Linus Torvalds 已提交
1326
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
1327
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
1328 1329 1330 1331
		c->tlbsize = 48;
		break;
	case PRID_IMP_TX49:
		c->cputype = CPU_TX49XX;
1332
		__cpu_name[cpu] = "R49XX";
1333
		set_isa(c, MIPS_CPU_ISA_III);
1334
		c->fpu_msk31 |= FPU_CSR_CONDX;
L
Linus Torvalds 已提交
1335 1336 1337 1338 1339 1340 1341
		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;
1342
		__cpu_name[cpu] = "R5000";
1343
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
1344
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
1345
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
1346 1347 1348 1349
		c->tlbsize = 48;
		break;
	case PRID_IMP_R5432:
		c->cputype = CPU_R5432;
1350
		__cpu_name[cpu] = "R5432";
1351
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
1352
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
1353
			     MIPS_CPU_WATCH | MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
1354 1355 1356 1357
		c->tlbsize = 48;
		break;
	case PRID_IMP_R5500:
		c->cputype = CPU_R5500;
1358
		__cpu_name[cpu] = "R5500";
1359
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
1360
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
1361
			     MIPS_CPU_WATCH | MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
1362 1363 1364 1365
		c->tlbsize = 48;
		break;
	case PRID_IMP_NEVADA:
		c->cputype = CPU_NEVADA;
1366
		__cpu_name[cpu] = "Nevada";
1367
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
1368
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
1369
			     MIPS_CPU_DIVEC | MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
1370 1371 1372 1373
		c->tlbsize = 48;
		break;
	case PRID_IMP_R6000:
		c->cputype = CPU_R6000;
1374
		__cpu_name[cpu] = "R6000";
1375
		set_isa(c, MIPS_CPU_ISA_II);
1376
		c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
L
Linus Torvalds 已提交
1377
		c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
S
Steven J. Hill 已提交
1378
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
1379 1380 1381 1382
		c->tlbsize = 32;
		break;
	case PRID_IMP_R6000A:
		c->cputype = CPU_R6000A;
1383
		__cpu_name[cpu] = "R6000A";
1384
		set_isa(c, MIPS_CPU_ISA_II);
1385
		c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
L
Linus Torvalds 已提交
1386
		c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
S
Steven J. Hill 已提交
1387
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
1388 1389 1390 1391
		c->tlbsize = 32;
		break;
	case PRID_IMP_RM7000:
		c->cputype = CPU_RM7000;
1392
		__cpu_name[cpu] = "RM7000";
1393
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
1394
		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
S
Steven J. Hill 已提交
1395
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
1396
		/*
R
Ralf Baechle 已提交
1397
		 * Undocumented RM7000:	 Bit 29 in the info register of
L
Linus Torvalds 已提交
1398 1399 1400
		 * the RM7000 v2.0 indicates if the TLB has 48 or 64
		 * entries.
		 *
R
Ralf Baechle 已提交
1401 1402
		 * 29	   1 =>	   64 entry JTLB
		 *	   0 =>	   48 entry JTLB
L
Linus Torvalds 已提交
1403 1404 1405 1406 1407
		 */
		c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48;
		break;
	case PRID_IMP_R8000:
		c->cputype = CPU_R8000;
1408
		__cpu_name[cpu] = "RM8000";
1409
		set_isa(c, MIPS_CPU_ISA_IV);
L
Linus Torvalds 已提交
1410
		c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
S
Steven J. Hill 已提交
1411 1412
			     MIPS_CPU_FPU | MIPS_CPU_32FPR |
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
1413 1414 1415 1416
		c->tlbsize = 384;      /* has weird TLB: 3-way x 128 */
		break;
	case PRID_IMP_R10000:
		c->cputype = CPU_R10000;
1417
		__cpu_name[cpu] = "R10000";
1418
		set_isa(c, MIPS_CPU_ISA_IV);
1419
		c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
S
Steven J. Hill 已提交
1420
			     MIPS_CPU_FPU | MIPS_CPU_32FPR |
L
Linus Torvalds 已提交
1421
			     MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
S
Steven J. Hill 已提交
1422
			     MIPS_CPU_LLSC;
L
Linus Torvalds 已提交
1423 1424 1425 1426
		c->tlbsize = 64;
		break;
	case PRID_IMP_R12000:
		c->cputype = CPU_R12000;
1427
		__cpu_name[cpu] = "R12000";
1428
		set_isa(c, MIPS_CPU_ISA_IV);
1429
		c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
S
Steven J. Hill 已提交
1430
			     MIPS_CPU_FPU | MIPS_CPU_32FPR |
L
Linus Torvalds 已提交
1431
			     MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
1432
			     MIPS_CPU_LLSC | MIPS_CPU_BP_GHIST;
L
Linus Torvalds 已提交
1433 1434
		c->tlbsize = 64;
		break;
K
Kumba 已提交
1435
	case PRID_IMP_R14000:
J
Joshua Kinard 已提交
1436 1437 1438 1439 1440 1441 1442
		if (((c->processor_id >> 4) & 0x0f) > 2) {
			c->cputype = CPU_R16000;
			__cpu_name[cpu] = "R16000";
		} else {
			c->cputype = CPU_R14000;
			__cpu_name[cpu] = "R14000";
		}
1443
		set_isa(c, MIPS_CPU_ISA_IV);
K
Kumba 已提交
1444
		c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
S
Steven J. Hill 已提交
1445
			     MIPS_CPU_FPU | MIPS_CPU_32FPR |
K
Kumba 已提交
1446
			     MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
1447
			     MIPS_CPU_LLSC | MIPS_CPU_BP_GHIST;
K
Kumba 已提交
1448 1449
		c->tlbsize = 64;
		break;
1450
	case PRID_IMP_LOONGSON_64:  /* Loongson-2/3 */
1451 1452
		switch (c->processor_id & PRID_REV_MASK) {
		case PRID_REV_LOONGSON2E:
1453 1454
			c->cputype = CPU_LOONGSON2;
			__cpu_name[cpu] = "ICT Loongson-2";
1455
			set_elf_platform(cpu, "loongson2e");
1456
			set_isa(c, MIPS_CPU_ISA_III);
1457
			c->fpu_msk31 |= FPU_CSR_CONDX;
1458 1459
			break;
		case PRID_REV_LOONGSON2F:
1460 1461
			c->cputype = CPU_LOONGSON2;
			__cpu_name[cpu] = "ICT Loongson-2";
1462
			set_elf_platform(cpu, "loongson2f");
1463
			set_isa(c, MIPS_CPU_ISA_III);
1464
			c->fpu_msk31 |= FPU_CSR_CONDX;
1465
			break;
1466
		case PRID_REV_LOONGSON3A_R1:
1467 1468 1469
			c->cputype = CPU_LOONGSON3;
			__cpu_name[cpu] = "ICT Loongson-3";
			set_elf_platform(cpu, "loongson3a");
1470
			set_isa(c, MIPS_CPU_ISA_M64R1);
1471
			break;
H
Huacai Chen 已提交
1472 1473 1474 1475 1476
		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");
1477
			set_isa(c, MIPS_CPU_ISA_M64R1);
H
Huacai Chen 已提交
1478
			break;
1479 1480
		}

1481 1482 1483 1484
		c->options = R4K_OPTS |
			     MIPS_CPU_FPU | MIPS_CPU_LLSC |
			     MIPS_CPU_32FPR;
		c->tlbsize = 64;
1485
		c->writecombine = _CACHE_UNCACHED_ACCELERATED;
1486
		break;
1487
	case PRID_IMP_LOONGSON_32:  /* Loongson-1 */
1488
		decode_configs(c);
1489

1490
		c->cputype = CPU_LOONGSON1;
L
Linus Torvalds 已提交
1491

1492 1493 1494
		switch (c->processor_id & PRID_REV_MASK) {
		case PRID_REV_LOONGSON1B:
			__cpu_name[cpu] = "Loongson 1B";
1495 1496
			break;
		}
1497

1498
		break;
L
Linus Torvalds 已提交
1499 1500 1501
	}
}

1502
static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
1503
{
1504
	c->writecombine = _CACHE_UNCACHED_ACCELERATED;
1505
	switch (c->processor_id & PRID_IMP_MASK) {
1506 1507 1508 1509 1510
	case PRID_IMP_QEMU_GENERIC:
		c->writecombine = _CACHE_UNCACHED;
		c->cputype = CPU_QEMU_GENERIC;
		__cpu_name[cpu] = "MIPS GENERIC QEMU";
		break;
L
Linus Torvalds 已提交
1511 1512
	case PRID_IMP_4KC:
		c->cputype = CPU_4KC;
1513
		c->writecombine = _CACHE_UNCACHED;
1514
		__cpu_name[cpu] = "MIPS 4Kc";
L
Linus Torvalds 已提交
1515 1516
		break;
	case PRID_IMP_4KEC:
1517 1518
	case PRID_IMP_4KECR2:
		c->cputype = CPU_4KEC;
1519
		c->writecombine = _CACHE_UNCACHED;
1520
		__cpu_name[cpu] = "MIPS 4KEc";
1521
		break;
L
Linus Torvalds 已提交
1522
	case PRID_IMP_4KSC:
R
Ralf Baechle 已提交
1523
	case PRID_IMP_4KSD:
L
Linus Torvalds 已提交
1524
		c->cputype = CPU_4KSC;
1525
		c->writecombine = _CACHE_UNCACHED;
1526
		__cpu_name[cpu] = "MIPS 4KSc";
L
Linus Torvalds 已提交
1527 1528 1529
		break;
	case PRID_IMP_5KC:
		c->cputype = CPU_5KC;
1530
		c->writecombine = _CACHE_UNCACHED;
1531
		__cpu_name[cpu] = "MIPS 5Kc";
L
Linus Torvalds 已提交
1532
		break;
L
Leonid Yegoshin 已提交
1533 1534
	case PRID_IMP_5KE:
		c->cputype = CPU_5KE;
1535
		c->writecombine = _CACHE_UNCACHED;
L
Leonid Yegoshin 已提交
1536 1537
		__cpu_name[cpu] = "MIPS 5KE";
		break;
L
Linus Torvalds 已提交
1538 1539
	case PRID_IMP_20KC:
		c->cputype = CPU_20KC;
1540
		c->writecombine = _CACHE_UNCACHED;
1541
		__cpu_name[cpu] = "MIPS 20Kc";
L
Linus Torvalds 已提交
1542 1543 1544
		break;
	case PRID_IMP_24K:
		c->cputype = CPU_24K;
1545
		c->writecombine = _CACHE_UNCACHED;
1546
		__cpu_name[cpu] = "MIPS 24Kc";
L
Linus Torvalds 已提交
1547
		break;
1548 1549
	case PRID_IMP_24KE:
		c->cputype = CPU_24K;
1550
		c->writecombine = _CACHE_UNCACHED;
1551 1552
		__cpu_name[cpu] = "MIPS 24KEc";
		break;
L
Linus Torvalds 已提交
1553 1554
	case PRID_IMP_25KF:
		c->cputype = CPU_25KF;
1555
		c->writecombine = _CACHE_UNCACHED;
1556
		__cpu_name[cpu] = "MIPS 25Kc";
L
Linus Torvalds 已提交
1557
		break;
R
Ralf Baechle 已提交
1558 1559
	case PRID_IMP_34K:
		c->cputype = CPU_34K;
1560
		c->writecombine = _CACHE_UNCACHED;
1561
		__cpu_name[cpu] = "MIPS 34Kc";
R
Ralf Baechle 已提交
1562
		break;
1563 1564
	case PRID_IMP_74K:
		c->cputype = CPU_74K;
1565
		c->writecombine = _CACHE_UNCACHED;
1566
		__cpu_name[cpu] = "MIPS 74Kc";
1567
		break;
1568 1569
	case PRID_IMP_M14KC:
		c->cputype = CPU_M14KC;
1570
		c->writecombine = _CACHE_UNCACHED;
1571 1572
		__cpu_name[cpu] = "MIPS M14Kc";
		break;
1573 1574
	case PRID_IMP_M14KEC:
		c->cputype = CPU_M14KEC;
1575
		c->writecombine = _CACHE_UNCACHED;
1576 1577
		__cpu_name[cpu] = "MIPS M14KEc";
		break;
1578 1579
	case PRID_IMP_1004K:
		c->cputype = CPU_1004K;
1580
		c->writecombine = _CACHE_UNCACHED;
1581
		__cpu_name[cpu] = "MIPS 1004Kc";
1582
		break;
1583
	case PRID_IMP_1074K:
1584
		c->cputype = CPU_1074K;
1585
		c->writecombine = _CACHE_UNCACHED;
1586 1587
		__cpu_name[cpu] = "MIPS 1074Kc";
		break;
1588 1589 1590 1591 1592 1593 1594 1595
	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;
1596 1597 1598 1599 1600 1601 1602 1603
	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 已提交
1604 1605 1606 1607
	case PRID_IMP_P5600:
		c->cputype = CPU_P5600;
		__cpu_name[cpu] = "MIPS P5600";
		break;
P
Paul Burton 已提交
1608 1609 1610 1611
	case PRID_IMP_P6600:
		c->cputype = CPU_P6600;
		__cpu_name[cpu] = "MIPS P6600";
		break;
1612 1613 1614 1615
	case PRID_IMP_I6400:
		c->cputype = CPU_I6400;
		__cpu_name[cpu] = "MIPS I6400";
		break;
1616 1617 1618 1619
	case PRID_IMP_M5150:
		c->cputype = CPU_M5150;
		__cpu_name[cpu] = "MIPS M5150";
		break;
P
Paul Burton 已提交
1620 1621 1622 1623
	case PRID_IMP_M6250:
		c->cputype = CPU_M6250;
		__cpu_name[cpu] = "MIPS M6250";
		break;
L
Linus Torvalds 已提交
1624
	}
C
Chris Dearman 已提交
1625

L
Leonid Yegoshin 已提交
1626 1627
	decode_configs(c);

C
Chris Dearman 已提交
1628
	spram_config();
L
Linus Torvalds 已提交
1629 1630
}

1631
static inline void cpu_probe_alchemy(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
1632
{
1633
	decode_configs(c);
1634
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
1635 1636
	case PRID_IMP_AU1_REV1:
	case PRID_IMP_AU1_REV2:
1637
		c->cputype = CPU_ALCHEMY;
L
Linus Torvalds 已提交
1638 1639
		switch ((c->processor_id >> 24) & 0xff) {
		case 0:
1640
			__cpu_name[cpu] = "Au1000";
L
Linus Torvalds 已提交
1641 1642
			break;
		case 1:
1643
			__cpu_name[cpu] = "Au1500";
L
Linus Torvalds 已提交
1644 1645
			break;
		case 2:
1646
			__cpu_name[cpu] = "Au1100";
L
Linus Torvalds 已提交
1647 1648
			break;
		case 3:
1649
			__cpu_name[cpu] = "Au1550";
L
Linus Torvalds 已提交
1650
			break;
P
Pete Popov 已提交
1651
		case 4:
1652
			__cpu_name[cpu] = "Au1200";
1653
			if ((c->processor_id & PRID_REV_MASK) == 2)
1654
				__cpu_name[cpu] = "Au1250";
1655 1656
			break;
		case 5:
1657
			__cpu_name[cpu] = "Au1210";
P
Pete Popov 已提交
1658
			break;
L
Linus Torvalds 已提交
1659
		default:
1660
			__cpu_name[cpu] = "Au1xxx";
L
Linus Torvalds 已提交
1661 1662 1663 1664 1665 1666
			break;
		}
		break;
	}
}

1667
static inline void cpu_probe_sibyte(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
1668
{
1669
	decode_configs(c);
R
Ralf Baechle 已提交
1670

1671
	c->writecombine = _CACHE_UNCACHED_ACCELERATED;
1672
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
1673 1674
	case PRID_IMP_SB1:
		c->cputype = CPU_SB1;
1675
		__cpu_name[cpu] = "SiByte SB1";
L
Linus Torvalds 已提交
1676
		/* FPU in pass1 is known to have issues. */
1677
		if ((c->processor_id & PRID_REV_MASK) < 0x02)
1678
			c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR);
L
Linus Torvalds 已提交
1679
		break;
A
Andrew Isaacson 已提交
1680 1681
	case PRID_IMP_SB1A:
		c->cputype = CPU_SB1A;
1682
		__cpu_name[cpu] = "SiByte SB1A";
A
Andrew Isaacson 已提交
1683
		break;
L
Linus Torvalds 已提交
1684 1685 1686
	}
}

1687
static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c, unsigned int cpu)
L
Linus Torvalds 已提交
1688
{
1689
	decode_configs(c);
1690
	switch (c->processor_id & PRID_IMP_MASK) {
L
Linus Torvalds 已提交
1691 1692
	case PRID_IMP_SR71000:
		c->cputype = CPU_SR71000;
1693
		__cpu_name[cpu] = "Sandcraft SR71000";
L
Linus Torvalds 已提交
1694 1695 1696 1697 1698 1699
		c->scache.ways = 8;
		c->tlbsize = 64;
		break;
	}
}

1700
static inline void cpu_probe_nxp(struct cpuinfo_mips *c, unsigned int cpu)
1701 1702
{
	decode_configs(c);
1703
	switch (c->processor_id & PRID_IMP_MASK) {
1704 1705
	case PRID_IMP_PR4450:
		c->cputype = CPU_PR4450;
1706
		__cpu_name[cpu] = "Philips PR4450";
1707
		set_isa(c, MIPS_CPU_ISA_M32R1);
1708 1709 1710 1711
		break;
	}
}

1712
static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
1713 1714
{
	decode_configs(c);
1715
	switch (c->processor_id & PRID_IMP_MASK) {
1716 1717
	case PRID_IMP_BMIPS32_REV4:
	case PRID_IMP_BMIPS32_REV8:
1718 1719
		c->cputype = CPU_BMIPS32;
		__cpu_name[cpu] = "Broadcom BMIPS32";
1720
		set_elf_platform(cpu, "bmips32");
1721 1722 1723 1724 1725 1726
		break;
	case PRID_IMP_BMIPS3300:
	case PRID_IMP_BMIPS3300_ALT:
	case PRID_IMP_BMIPS3300_BUG:
		c->cputype = CPU_BMIPS3300;
		__cpu_name[cpu] = "Broadcom BMIPS3300";
1727
		set_elf_platform(cpu, "bmips3300");
1728 1729
		break;
	case PRID_IMP_BMIPS43XX: {
1730
		int rev = c->processor_id & PRID_REV_MASK;
1731 1732 1733 1734 1735

		if (rev >= PRID_REV_BMIPS4380_LO &&
				rev <= PRID_REV_BMIPS4380_HI) {
			c->cputype = CPU_BMIPS4380;
			__cpu_name[cpu] = "Broadcom BMIPS4380";
1736
			set_elf_platform(cpu, "bmips4380");
1737
			c->options |= MIPS_CPU_RIXI;
1738 1739 1740
		} else {
			c->cputype = CPU_BMIPS4350;
			__cpu_name[cpu] = "Broadcom BMIPS4350";
1741
			set_elf_platform(cpu, "bmips4350");
1742
		}
1743
		break;
1744 1745
	}
	case PRID_IMP_BMIPS5000:
1746
	case PRID_IMP_BMIPS5200:
1747
		c->cputype = CPU_BMIPS5000;
1748 1749 1750 1751
		if ((c->processor_id & PRID_IMP_MASK) == PRID_IMP_BMIPS5200)
			__cpu_name[cpu] = "Broadcom BMIPS5200";
		else
			__cpu_name[cpu] = "Broadcom BMIPS5000";
1752
		set_elf_platform(cpu, "bmips5000");
1753
		c->options |= MIPS_CPU_ULRI | MIPS_CPU_RIXI;
1754
		break;
1755 1756 1757
	}
}

1758 1759 1760
static inline void cpu_probe_cavium(struct cpuinfo_mips *c, unsigned int cpu)
{
	decode_configs(c);
1761
	switch (c->processor_id & PRID_IMP_MASK) {
1762 1763 1764
	case PRID_IMP_CAVIUM_CN38XX:
	case PRID_IMP_CAVIUM_CN31XX:
	case PRID_IMP_CAVIUM_CN30XX:
1765 1766 1767
		c->cputype = CPU_CAVIUM_OCTEON;
		__cpu_name[cpu] = "Cavium Octeon";
		goto platform;
1768 1769 1770 1771
	case PRID_IMP_CAVIUM_CN58XX:
	case PRID_IMP_CAVIUM_CN56XX:
	case PRID_IMP_CAVIUM_CN50XX:
	case PRID_IMP_CAVIUM_CN52XX:
1772 1773 1774
		c->cputype = CPU_CAVIUM_OCTEON_PLUS;
		__cpu_name[cpu] = "Cavium Octeon+";
platform:
1775
		set_elf_platform(cpu, "octeon");
1776
		break;
1777
	case PRID_IMP_CAVIUM_CN61XX:
1778
	case PRID_IMP_CAVIUM_CN63XX:
1779 1780
	case PRID_IMP_CAVIUM_CN66XX:
	case PRID_IMP_CAVIUM_CN68XX:
1781
	case PRID_IMP_CAVIUM_CNF71XX:
1782 1783
		c->cputype = CPU_CAVIUM_OCTEON2;
		__cpu_name[cpu] = "Cavium Octeon II";
1784
		set_elf_platform(cpu, "octeon2");
1785
		break;
1786
	case PRID_IMP_CAVIUM_CN70XX:
1787 1788
	case PRID_IMP_CAVIUM_CN73XX:
	case PRID_IMP_CAVIUM_CNF75XX:
1789 1790 1791 1792 1793
	case PRID_IMP_CAVIUM_CN78XX:
		c->cputype = CPU_CAVIUM_OCTEON3;
		__cpu_name[cpu] = "Cavium Octeon III";
		set_elf_platform(cpu, "octeon3");
		break;
1794 1795 1796 1797 1798 1799 1800
	default:
		printk(KERN_INFO "Unknown Octeon chip!\n");
		c->cputype = CPU_UNKNOWN;
		break;
	}
}

1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814
static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
{
	switch (c->processor_id & PRID_IMP_MASK) {
	case PRID_IMP_LOONGSON_64:  /* Loongson-2/3 */
		switch (c->processor_id & PRID_REV_MASK) {
		case PRID_REV_LOONGSON3A_R2:
			c->cputype = CPU_LOONGSON3;
			__cpu_name[cpu] = "ICT Loongson-3";
			set_elf_platform(cpu, "loongson3a");
			set_isa(c, MIPS_CPU_ISA_M64R2);
			break;
		}

		decode_configs(c);
1815
		c->options |= MIPS_CPU_TLBINV | MIPS_CPU_LDPTE;
1816 1817 1818 1819 1820 1821 1822 1823
		c->writecombine = _CACHE_UNCACHED_ACCELERATED;
		break;
	default:
		panic("Unknown Loongson Processor ID!");
		break;
	}
}

1824 1825 1826 1827 1828
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;
1829
	BUG_ON(!__builtin_constant_p(cpu_has_counter) || cpu_has_counter);
1830
	switch (c->processor_id & PRID_IMP_MASK) {
1831 1832
	case PRID_IMP_JZRISC:
		c->cputype = CPU_JZRISC;
1833
		c->writecombine = _CACHE_UNCACHED_ACCELERATED;
1834 1835 1836 1837 1838 1839 1840 1841
		__cpu_name[cpu] = "Ingenic JZRISC";
		break;
	default:
		panic("Unknown Ingenic Processor ID!");
		break;
	}
}

1842 1843 1844 1845
static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
{
	decode_configs(c);

1846
	if ((c->processor_id & PRID_IMP_MASK) == PRID_IMP_NETLOGIC_AU13XX) {
M
Manuel Lauss 已提交
1847 1848 1849 1850 1851 1852
		c->cputype = CPU_ALCHEMY;
		__cpu_name[cpu] = "Au1300";
		/* following stuff is not for Alchemy */
		return;
	}

R
Ralf Baechle 已提交
1853 1854
	c->options = (MIPS_CPU_TLB	 |
			MIPS_CPU_4KEX	 |
1855
			MIPS_CPU_COUNTER |
R
Ralf Baechle 已提交
1856 1857 1858
			MIPS_CPU_DIVEC	 |
			MIPS_CPU_WATCH	 |
			MIPS_CPU_EJTAG	 |
1859 1860
			MIPS_CPU_LLSC);

1861
	switch (c->processor_id & PRID_IMP_MASK) {
1862
	case PRID_IMP_NETLOGIC_XLP2XX:
1863
	case PRID_IMP_NETLOGIC_XLP9XX:
1864
	case PRID_IMP_NETLOGIC_XLP5XX:
1865 1866 1867 1868
		c->cputype = CPU_XLP;
		__cpu_name[cpu] = "Broadcom XLPII";
		break;

1869 1870
	case PRID_IMP_NETLOGIC_XLP8XX:
	case PRID_IMP_NETLOGIC_XLP3XX:
J
Jayachandran C 已提交
1871 1872 1873 1874
		c->cputype = CPU_XLP;
		__cpu_name[cpu] = "Netlogic XLP";
		break;

1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904
	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 已提交
1905
		pr_info("Unknown Netlogic chip id [%02x]!\n",
1906 1907 1908 1909 1910
		       c->processor_id);
		c->cputype = CPU_XLR;
		break;
	}

J
Jayachandran C 已提交
1911
	if (c->cputype == CPU_XLP) {
1912
		set_isa(c, MIPS_CPU_ISA_M64R2);
J
Jayachandran C 已提交
1913 1914 1915 1916
		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 {
1917
		set_isa(c, MIPS_CPU_ISA_M64R1);
J
Jayachandran C 已提交
1918 1919
		c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1;
	}
1920
	c->kscratch_mask = 0xf;
1921 1922
}

1923 1924 1925 1926 1927 1928
#ifdef CONFIG_64BIT
/* For use by uaccess.h */
u64 __ua_limit;
EXPORT_SYMBOL(__ua_limit);
#endif

1929
const char *__cpu_name[NR_CPUS];
1930
const char *__elf_platform;
1931

1932
void cpu_probe(void)
L
Linus Torvalds 已提交
1933 1934
{
	struct cpuinfo_mips *c = &current_cpu_data;
1935
	unsigned int cpu = smp_processor_id();
L
Linus Torvalds 已提交
1936

R
Ralf Baechle 已提交
1937
	c->processor_id = PRID_IMP_UNKNOWN;
L
Linus Torvalds 已提交
1938 1939
	c->fpu_id	= FPIR_IMP_NONE;
	c->cputype	= CPU_UNKNOWN;
1940
	c->writecombine = _CACHE_UNCACHED;
L
Linus Torvalds 已提交
1941

1942 1943 1944
	c->fpu_csr31	= FPU_CSR_RN;
	c->fpu_msk31	= FPU_CSR_RSVD | FPU_CSR_ABS2008 | FPU_CSR_NAN2008;

L
Linus Torvalds 已提交
1945
	c->processor_id = read_c0_prid();
1946
	switch (c->processor_id & PRID_COMP_MASK) {
L
Linus Torvalds 已提交
1947
	case PRID_COMP_LEGACY:
1948
		cpu_probe_legacy(c, cpu);
L
Linus Torvalds 已提交
1949 1950
		break;
	case PRID_COMP_MIPS:
1951
		cpu_probe_mips(c, cpu);
L
Linus Torvalds 已提交
1952 1953
		break;
	case PRID_COMP_ALCHEMY:
1954
		cpu_probe_alchemy(c, cpu);
L
Linus Torvalds 已提交
1955 1956
		break;
	case PRID_COMP_SIBYTE:
1957
		cpu_probe_sibyte(c, cpu);
L
Linus Torvalds 已提交
1958
		break;
1959
	case PRID_COMP_BROADCOM:
1960
		cpu_probe_broadcom(c, cpu);
1961
		break;
L
Linus Torvalds 已提交
1962
	case PRID_COMP_SANDCRAFT:
1963
		cpu_probe_sandcraft(c, cpu);
L
Linus Torvalds 已提交
1964
		break;
1965
	case PRID_COMP_NXP:
1966
		cpu_probe_nxp(c, cpu);
1967
		break;
1968 1969 1970
	case PRID_COMP_CAVIUM:
		cpu_probe_cavium(c, cpu);
		break;
1971 1972 1973
	case PRID_COMP_LOONGSON:
		cpu_probe_loongson(c, cpu);
		break;
1974 1975 1976
	case PRID_COMP_INGENIC_D0:
	case PRID_COMP_INGENIC_D1:
	case PRID_COMP_INGENIC_E1:
1977 1978
		cpu_probe_ingenic(c, cpu);
		break;
1979 1980 1981
	case PRID_COMP_NETLOGIC:
		cpu_probe_netlogic(c, cpu);
		break;
L
Linus Torvalds 已提交
1982
	}
1983

1984 1985 1986
	BUG_ON(!__cpu_name[cpu]);
	BUG_ON(c->cputype == CPU_UNKNOWN);

1987 1988 1989 1990 1991 1992 1993
	/*
	 * 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);

1994 1995 1996 1997 1998 1999 2000 2001 2002
	if (cpu_has_rixi) {
		/* Enable the RIXI exceptions */
		set_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;
	}

2003 2004 2005 2006
	if (mips_fpu_disabled)
		c->options &= ~MIPS_CPU_FPU;

	if (mips_dsp_disabled)
2007
		c->ases &= ~(MIPS_ASE_DSP | MIPS_ASE_DSP2P);
2008

2009 2010 2011 2012 2013 2014
	if (mips_htw_disabled) {
		c->options &= ~MIPS_CPU_HTW;
		write_c0_pwctl(read_c0_pwctl() &
			       ~(1 << MIPS_PWCTL_PWEN_SHIFT));
	}

2015 2016 2017 2018
	if (c->options & MIPS_CPU_FPU)
		cpu_set_fpu_opts(c);
	else
		cpu_set_nofpu_opts(c);
2019

2020 2021 2022 2023
	if (cpu_has_bp_ghist)
		write_c0_r10k_diag(read_c0_r10k_diag() |
				   R10K_DIAG_E_GHIST);

2024
	if (cpu_has_mips_r2_r6) {
R
Ralf Baechle 已提交
2025
		c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
2026 2027 2028
		/* R2 has Performance Counter Interrupt indicator */
		c->options |= MIPS_CPU_PCI;
	}
R
Ralf Baechle 已提交
2029 2030
	else
		c->srsets = 1;
2031

2032 2033 2034
	if (cpu_has_mips_r6)
		elf_hwcap |= HWCAP_MIPS_R6;

2035
	if (cpu_has_msa) {
P
Paul Burton 已提交
2036
		c->msa_id = cpu_get_msa_id();
2037 2038
		WARN(c->msa_id & MSA_IR_WRPF,
		     "Vector register partitioning unimplemented!");
2039
		elf_hwcap |= HWCAP_MIPS_MSA;
2040
	}
P
Paul Burton 已提交
2041

2042 2043 2044
	if (cpu_has_vz)
		cpu_probe_vz(c);

2045
	cpu_probe_vmbits(c);
2046 2047 2048 2049 2050

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

2053
void cpu_report(void)
L
Linus Torvalds 已提交
2054 2055 2056
{
	struct cpuinfo_mips *c = &current_cpu_data;

2057 2058
	pr_info("CPU%d revision is: %08x (%s)\n",
		smp_processor_id(), c->processor_id, cpu_name_string());
L
Linus Torvalds 已提交
2059
	if (c->options & MIPS_CPU_FPU)
2060
		printk(KERN_INFO "FPU revision is: %08x\n", c->fpu_id);
P
Paul Burton 已提交
2061 2062
	if (cpu_has_msa)
		pr_info("MSA revision is: %08x\n", c->msa_id);
L
Linus Torvalds 已提交
2063
}