Blame view
arch/mips/kernel/cpu-probe.c
27.8 KB
1da177e4c
|
1 2 3 4 |
/* * Processor capabilities determination functions. * * Copyright (C) xxxx the Anonymous |
010b853b3
|
5 |
* Copyright (C) 1994 - 2006 Ralf Baechle |
4194318c3
|
6 |
* Copyright (C) 2003, 2004 Maciej W. Rozycki |
4194318c3
|
7 |
* Copyright (C) 2001, 2004 MIPS Inc. |
1da177e4c
|
8 9 10 11 12 13 |
* * 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. */ |
1da177e4c
|
14 15 16 |
#include <linux/init.h> #include <linux/kernel.h> #include <linux/ptrace.h> |
631330f58
|
17 |
#include <linux/smp.h> |
1da177e4c
|
18 |
#include <linux/stddef.h> |
73bc256d4
|
19 |
#include <linux/export.h> |
1da177e4c
|
20 |
|
5759906ca
|
21 |
#include <asm/bugs.h> |
1da177e4c
|
22 23 24 25 |
#include <asm/cpu.h> #include <asm/fpu.h> #include <asm/mipsregs.h> #include <asm/system.h> |
654f57bfb
|
26 |
#include <asm/watch.h> |
06372a63e
|
27 |
#include <asm/elf.h> |
a074f0e89
|
28 |
#include <asm/spram.h> |
949e51bea
|
29 |
#include <asm/uaccess.h> |
1da177e4c
|
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. */ |
982f6ffee
|
37 |
void (*cpu_wait)(void); |
f8ede0f70
|
38 |
EXPORT_SYMBOL(cpu_wait); |
1da177e4c
|
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) { |
60a6c3777
|
48 49 50 51 |
local_irq_disable(); if (!need_resched()) write_c0_conf(read_c0_conf() | TX39_CONF_HALT); local_irq_enable(); |
1da177e4c
|
52 |
} |
c65a5480f
|
53 |
extern void r4k_wait(void); |
60a6c3777
|
54 55 56 57 58 59 60 61 |
/* * 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. */ |
8531a35e5
|
62 |
void r4k_wait_irqoff(void) |
60a6c3777
|
63 64 65 |
{ local_irq_disable(); if (!need_resched()) |
8531a35e5
|
66 67 68 69 |
__asm__(" .set push " " .set mips3 " |
60a6c3777
|
70 71 |
" wait " |
8531a35e5
|
72 73 |
" .set pop "); |
60a6c3777
|
74 |
local_irq_enable(); |
8531a35e5
|
75 76 77 78 |
__asm__(" .globl __pastwait " "__pastwait: "); |
1da177e4c
|
79 |
} |
5a8129992
|
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
/* * 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 " " .set mips3 " " .set noat " " mfc0 $1, $12 " " sync " " mtc0 $1, $12 # stalls until W stage " " wait " " mtc0 $1, $12 # stalls until W stage " " .set pop "); local_irq_enable(); } |
2882b0c63
|
109 110 111 112 113 |
/* * 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! */ |
494900af6
|
114 |
static void au1k_wait(void) |
1da177e4c
|
115 |
{ |
60a6c3777
|
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
__asm__(" .set mips3 " " cache 0x14, 0(%0) " " cache 0x14, 32(%0) " " sync " " nop " " wait " " nop " " nop " " nop " " nop " " .set mips0 " |
10f650db1
|
138 |
: : "r" (au1k_wait)); |
1da177e4c
|
139 |
} |
982f6ffee
|
140 |
static int __initdata nowait; |
55d04dff0
|
141 |
|
f49a747c4
|
142 |
static int __init wait_disable(char *s) |
55d04dff0
|
143 144 145 146 147 148 149 |
{ nowait = 1; return 1; } __setup("nowait", wait_disable); |
0103d23f4
|
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
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); |
c65a5480f
|
173 |
void __init check_wait(void) |
1da177e4c
|
174 175 |
{ struct cpuinfo_mips *c = ¤t_cpu_data; |
55d04dff0
|
176 |
if (nowait) { |
c23792300
|
177 178 |
printk("Wait instruction disabled. "); |
55d04dff0
|
179 180 |
return; } |
1da177e4c
|
181 182 183 184 |
switch (c->cputype) { case CPU_R3081: case CPU_R3081E: cpu_wait = r3081_wait; |
1da177e4c
|
185 186 187 |
break; case CPU_TX3927: cpu_wait = r39xx_wait; |
1da177e4c
|
188 189 190 191 192 193 194 195 |
break; case CPU_R4200: /* case CPU_R4300: */ case CPU_R4600: case CPU_R4640: case CPU_R4650: case CPU_R4700: case CPU_R5000: |
a644b2774
|
196 |
case CPU_R5500: |
1da177e4c
|
197 |
case CPU_NEVADA: |
1da177e4c
|
198 199 200 201 |
case CPU_4KC: case CPU_4KEC: case CPU_4KSC: case CPU_5KC: |
1da177e4c
|
202 |
case CPU_25KF: |
4b3e975e4
|
203 |
case CPU_PR4450: |
602977b0d
|
204 205 206 207 |
case CPU_BMIPS3300: case CPU_BMIPS4350: case CPU_BMIPS4380: case CPU_BMIPS5000: |
0dd4781bc
|
208 |
case CPU_CAVIUM_OCTEON: |
6f329468f
|
209 |
case CPU_CAVIUM_OCTEON_PLUS: |
0e56b3852
|
210 |
case CPU_CAVIUM_OCTEON2: |
83ccf69d8
|
211 |
case CPU_JZRISC: |
11d48aace
|
212 |
case CPU_XLR: |
a3d4fb2d2
|
213 |
case CPU_XLP: |
4b3e975e4
|
214 215 |
cpu_wait = r4k_wait; break; |
5a8129992
|
216 217 218 |
case CPU_RM7000: cpu_wait = rm7k_wait_irqoff; break; |
4b3e975e4
|
219 |
case CPU_24K: |
bbc7f22f6
|
220 |
case CPU_34K: |
39b8d5254
|
221 |
case CPU_1004K: |
4b3e975e4
|
222 223 224 225 |
cpu_wait = r4k_wait; if (read_c0_config7() & MIPS_CONF7_WII) cpu_wait = r4k_wait_irqoff; break; |
c620953c3
|
226 |
case CPU_74K: |
1da177e4c
|
227 |
cpu_wait = r4k_wait; |
4b3e975e4
|
228 229 |
if ((c->processor_id & 0xff) >= PRID_REV_ENCODE_332(2, 1, 0)) cpu_wait = r4k_wait_irqoff; |
1da177e4c
|
230 |
break; |
4b3e975e4
|
231 |
|
60a6c3777
|
232 233 |
case CPU_TX49XX: cpu_wait = r4k_wait_irqoff; |
60a6c3777
|
234 |
break; |
270717a8a
|
235 |
case CPU_ALCHEMY: |
0c694de12
|
236 |
cpu_wait = au1k_wait; |
1da177e4c
|
237 |
break; |
c8eae71dc
|
238 239 240 241 242 243 244 245 |
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; |
50da469a7
|
246 247 248 249 250 251 252 253 |
/* * 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; */ |
c8eae71dc
|
254 |
break; |
441ee341a
|
255 |
case CPU_RM9000: |
c23792300
|
256 |
if ((c->processor_id & 0x00ff) >= 0x40) |
441ee341a
|
257 |
cpu_wait = r4k_wait; |
441ee341a
|
258 |
break; |
1da177e4c
|
259 |
default: |
1da177e4c
|
260 261 262 |
break; } } |
9267a30d1
|
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
static inline void check_errata(void) { struct cpuinfo_mips *c = ¤t_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; } } |
1da177e4c
|
281 282 |
void __init check_bugs32(void) { |
9267a30d1
|
283 |
check_errata(); |
1da177e4c
|
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 |
} /* * 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 } |
c094c99e6
|
307 308 309 310 311 |
static inline void set_elf_platform(int cpu, const char *plat) { if (cpu == 0) __elf_platform = plat; } |
1da177e4c
|
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
/* * 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); } |
91dfc423c
|
333 334 335 |
static inline void cpu_probe_vmbits(struct cpuinfo_mips *c) { #ifdef __NEED_VMBITS_PROBE |
5b7efa898
|
336 |
write_c0_entryhi(0x3fffffffffffe000ULL); |
91dfc423c
|
337 |
back_to_back_c0_hazard(); |
5b7efa898
|
338 |
c->vmbits = fls64(read_c0_entryhi() & 0x3fffffffffffe000ULL); |
91dfc423c
|
339 340 |
#endif } |
02cf21196
|
341 |
#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \ |
1da177e4c
|
342 |
| MIPS_CPU_COUNTER) |
cea7e2dfd
|
343 |
static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) |
1da177e4c
|
344 345 346 347 |
{ switch (c->processor_id & 0xff00) { case PRID_IMP_R2000: c->cputype = CPU_R2000; |
cea7e2dfd
|
348 |
__cpu_name[cpu] = "R2000"; |
1da177e4c
|
349 |
c->isa_level = MIPS_CPU_ISA_I; |
02cf21196
|
350 351 |
c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE | MIPS_CPU_NOFPUEX; |
1da177e4c
|
352 353 354 355 356 |
if (__cpu_has_fpu()) c->options |= MIPS_CPU_FPU; c->tlbsize = 64; break; case PRID_IMP_R3000: |
cea7e2dfd
|
357 358 |
if ((c->processor_id & 0xff) == PRID_REV_R3000A) { if (cpu_has_confreg()) { |
1da177e4c
|
359 |
c->cputype = CPU_R3081E; |
cea7e2dfd
|
360 361 |
__cpu_name[cpu] = "R3081"; } else { |
1da177e4c
|
362 |
c->cputype = CPU_R3000A; |
cea7e2dfd
|
363 364 365 366 |
__cpu_name[cpu] = "R3000A"; } break; } else { |
1da177e4c
|
367 |
c->cputype = CPU_R3000; |
cea7e2dfd
|
368 369 |
__cpu_name[cpu] = "R3000"; } |
1da177e4c
|
370 |
c->isa_level = MIPS_CPU_ISA_I; |
02cf21196
|
371 372 |
c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE | MIPS_CPU_NOFPUEX; |
1da177e4c
|
373 374 375 376 377 378 |
if (__cpu_has_fpu()) c->options |= MIPS_CPU_FPU; c->tlbsize = 64; break; case PRID_IMP_R4000: if (read_c0_config() & CONF_SC) { |
cea7e2dfd
|
379 |
if ((c->processor_id & 0xff) >= PRID_REV_R4400) { |
1da177e4c
|
380 |
c->cputype = CPU_R4400PC; |
cea7e2dfd
|
381 382 |
__cpu_name[cpu] = "R4400PC"; } else { |
1da177e4c
|
383 |
c->cputype = CPU_R4000PC; |
cea7e2dfd
|
384 385 |
__cpu_name[cpu] = "R4000PC"; } |
1da177e4c
|
386 |
} else { |
cea7e2dfd
|
387 |
if ((c->processor_id & 0xff) >= PRID_REV_R4400) { |
1da177e4c
|
388 |
c->cputype = CPU_R4400SC; |
cea7e2dfd
|
389 390 |
__cpu_name[cpu] = "R4400SC"; } else { |
1da177e4c
|
391 |
c->cputype = CPU_R4000SC; |
cea7e2dfd
|
392 393 |
__cpu_name[cpu] = "R4000SC"; } |
1da177e4c
|
394 395 396 397 398 399 400 401 402 403 |
} c->isa_level = MIPS_CPU_ISA_III; c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_WATCH | MIPS_CPU_VCE | MIPS_CPU_LLSC; c->tlbsize = 48; break; case PRID_IMP_VR41XX: switch (c->processor_id & 0xf0) { |
1da177e4c
|
404 405 |
case PRID_REV_VR4111: c->cputype = CPU_VR4111; |
cea7e2dfd
|
406 |
__cpu_name[cpu] = "NEC VR4111"; |
1da177e4c
|
407 |
break; |
1da177e4c
|
408 409 |
case PRID_REV_VR4121: c->cputype = CPU_VR4121; |
cea7e2dfd
|
410 |
__cpu_name[cpu] = "NEC VR4121"; |
1da177e4c
|
411 412 |
break; case PRID_REV_VR4122: |
cea7e2dfd
|
413 |
if ((c->processor_id & 0xf) < 0x3) { |
1da177e4c
|
414 |
c->cputype = CPU_VR4122; |
cea7e2dfd
|
415 416 |
__cpu_name[cpu] = "NEC VR4122"; } else { |
1da177e4c
|
417 |
c->cputype = CPU_VR4181A; |
cea7e2dfd
|
418 419 |
__cpu_name[cpu] = "NEC VR4181A"; } |
1da177e4c
|
420 421 |
break; case PRID_REV_VR4130: |
cea7e2dfd
|
422 |
if ((c->processor_id & 0xf) < 0x4) { |
1da177e4c
|
423 |
c->cputype = CPU_VR4131; |
cea7e2dfd
|
424 425 |
__cpu_name[cpu] = "NEC VR4131"; } else { |
1da177e4c
|
426 |
c->cputype = CPU_VR4133; |
cea7e2dfd
|
427 428 |
__cpu_name[cpu] = "NEC VR4133"; } |
1da177e4c
|
429 430 431 432 433 |
break; default: printk(KERN_INFO "Unexpected CPU of NEC VR4100 series "); c->cputype = CPU_VR41XX; |
cea7e2dfd
|
434 |
__cpu_name[cpu] = "NEC Vr41xx"; |
1da177e4c
|
435 436 437 438 439 440 441 442 |
break; } c->isa_level = MIPS_CPU_ISA_III; c->options = R4K_OPTS; c->tlbsize = 32; break; case PRID_IMP_R4300: c->cputype = CPU_R4300; |
cea7e2dfd
|
443 |
__cpu_name[cpu] = "R4300"; |
1da177e4c
|
444 445 446 447 448 449 450 |
c->isa_level = MIPS_CPU_ISA_III; c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_LLSC; c->tlbsize = 32; break; case PRID_IMP_R4600: c->cputype = CPU_R4600; |
cea7e2dfd
|
451 |
__cpu_name[cpu] = "R4600"; |
1da177e4c
|
452 |
c->isa_level = MIPS_CPU_ISA_III; |
075e7502d
|
453 454 |
c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_LLSC; |
1da177e4c
|
455 456 457 458 459 460 461 462 463 464 |
c->tlbsize = 48; break; #if 0 case PRID_IMP_R4650: /* * 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. */ |
a3dddd560
|
465 |
c->cputype = CPU_R4650; |
cea7e2dfd
|
466 |
__cpu_name[cpu] = "R4650"; |
1da177e4c
|
467 468 469 470 471 472 473 |
c->isa_level = MIPS_CPU_ISA_III; c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; c->tlbsize = 48; break; #endif case PRID_IMP_TX39: c->isa_level = MIPS_CPU_ISA_I; |
02cf21196
|
474 |
c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE; |
1da177e4c
|
475 476 477 |
if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) { c->cputype = CPU_TX3927; |
cea7e2dfd
|
478 |
__cpu_name[cpu] = "TX3927"; |
1da177e4c
|
479 480 481 482 483 |
c->tlbsize = 64; } else { switch (c->processor_id & 0xff) { case PRID_REV_TX3912: c->cputype = CPU_TX3912; |
cea7e2dfd
|
484 |
__cpu_name[cpu] = "TX3912"; |
1da177e4c
|
485 486 487 488 |
c->tlbsize = 32; break; case PRID_REV_TX3922: c->cputype = CPU_TX3922; |
cea7e2dfd
|
489 |
__cpu_name[cpu] = "TX3922"; |
1da177e4c
|
490 491 |
c->tlbsize = 64; break; |
1da177e4c
|
492 493 494 495 496 |
} } break; case PRID_IMP_R4700: c->cputype = CPU_R4700; |
cea7e2dfd
|
497 |
__cpu_name[cpu] = "R4700"; |
1da177e4c
|
498 499 500 501 502 503 504 |
c->isa_level = MIPS_CPU_ISA_III; c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_LLSC; c->tlbsize = 48; break; case PRID_IMP_TX49: c->cputype = CPU_TX49XX; |
cea7e2dfd
|
505 |
__cpu_name[cpu] = "R49XX"; |
1da177e4c
|
506 507 508 509 510 511 512 513 |
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; |
cea7e2dfd
|
514 |
__cpu_name[cpu] = "R5000"; |
1da177e4c
|
515 516 517 518 519 520 521 |
c->isa_level = MIPS_CPU_ISA_IV; c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_LLSC; c->tlbsize = 48; break; case PRID_IMP_R5432: c->cputype = CPU_R5432; |
cea7e2dfd
|
522 |
__cpu_name[cpu] = "R5432"; |
1da177e4c
|
523 524 525 526 527 528 529 |
c->isa_level = MIPS_CPU_ISA_IV; c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_WATCH | MIPS_CPU_LLSC; c->tlbsize = 48; break; case PRID_IMP_R5500: c->cputype = CPU_R5500; |
cea7e2dfd
|
530 |
__cpu_name[cpu] = "R5500"; |
1da177e4c
|
531 532 533 534 535 536 537 |
c->isa_level = MIPS_CPU_ISA_IV; c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_WATCH | MIPS_CPU_LLSC; c->tlbsize = 48; break; case PRID_IMP_NEVADA: c->cputype = CPU_NEVADA; |
cea7e2dfd
|
538 |
__cpu_name[cpu] = "Nevada"; |
1da177e4c
|
539 540 541 542 543 544 545 |
c->isa_level = MIPS_CPU_ISA_IV; c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_DIVEC | MIPS_CPU_LLSC; c->tlbsize = 48; break; case PRID_IMP_R6000: c->cputype = CPU_R6000; |
cea7e2dfd
|
546 |
__cpu_name[cpu] = "R6000"; |
1da177e4c
|
547 548 549 550 551 552 553 |
c->isa_level = MIPS_CPU_ISA_II; c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | MIPS_CPU_LLSC; c->tlbsize = 32; break; case PRID_IMP_R6000A: c->cputype = CPU_R6000A; |
cea7e2dfd
|
554 |
__cpu_name[cpu] = "R6000A"; |
1da177e4c
|
555 556 557 558 559 560 561 |
c->isa_level = MIPS_CPU_ISA_II; c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | MIPS_CPU_LLSC; c->tlbsize = 32; break; case PRID_IMP_RM7000: c->cputype = CPU_RM7000; |
cea7e2dfd
|
562 |
__cpu_name[cpu] = "RM7000"; |
1da177e4c
|
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 |
c->isa_level = MIPS_CPU_ISA_IV; c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_LLSC; /* * 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; |
cea7e2dfd
|
578 |
__cpu_name[cpu] = "RM9000"; |
1da177e4c
|
579 580 581 582 583 584 585 586 587 588 589 590 591 592 |
c->isa_level = MIPS_CPU_ISA_IV; c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_LLSC; /* * 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; |
cea7e2dfd
|
593 |
__cpu_name[cpu] = "RM8000"; |
1da177e4c
|
594 595 596 597 598 599 600 601 |
c->isa_level = MIPS_CPU_ISA_IV; c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_LLSC; c->tlbsize = 384; /* has weird TLB: 3-way x 128 */ break; case PRID_IMP_R10000: c->cputype = CPU_R10000; |
cea7e2dfd
|
602 |
__cpu_name[cpu] = "R10000"; |
1da177e4c
|
603 |
c->isa_level = MIPS_CPU_ISA_IV; |
8b36612a2
|
604 |
c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | |
1da177e4c
|
605 606 607 608 609 610 611 |
MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_COUNTER | MIPS_CPU_WATCH | MIPS_CPU_LLSC; c->tlbsize = 64; break; case PRID_IMP_R12000: c->cputype = CPU_R12000; |
cea7e2dfd
|
612 |
__cpu_name[cpu] = "R12000"; |
1da177e4c
|
613 |
c->isa_level = MIPS_CPU_ISA_IV; |
8b36612a2
|
614 |
c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | |
1da177e4c
|
615 616 617 618 619 |
MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_COUNTER | MIPS_CPU_WATCH | MIPS_CPU_LLSC; c->tlbsize = 64; break; |
44d921b24
|
620 621 |
case PRID_IMP_R14000: c->cputype = CPU_R14000; |
cea7e2dfd
|
622 |
__cpu_name[cpu] = "R14000"; |
44d921b24
|
623 624 625 626 627 628 629 |
c->isa_level = MIPS_CPU_ISA_IV; c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_COUNTER | MIPS_CPU_WATCH | MIPS_CPU_LLSC; c->tlbsize = 64; break; |
2a21c7300
|
630 631 |
case PRID_IMP_LOONGSON2: c->cputype = CPU_LOONGSON2; |
cea7e2dfd
|
632 |
__cpu_name[cpu] = "ICT Loongson-2"; |
5aac1e8a3
|
633 634 635 636 637 638 639 640 641 |
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; } |
2a21c7300
|
642 643 644 645 646 647 |
c->isa_level = MIPS_CPU_ISA_III; c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC | MIPS_CPU_32FPR; c->tlbsize = 64; break; |
1da177e4c
|
648 649 |
} } |
234fcd148
|
650 |
static char unknown_isa[] __cpuinitdata = KERN_ERR \ |
b4672d372
|
651 |
"Unsupported ISA type, c0.config0: %d."; |
4194318c3
|
652 |
static inline unsigned int decode_config0(struct cpuinfo_mips *c) |
1da177e4c
|
653 |
{ |
4194318c3
|
654 655 |
unsigned int config0; int isa; |
1da177e4c
|
656 |
|
4194318c3
|
657 658 659 |
config0 = read_c0_config(); if (((config0 & MIPS_CONF_MT) >> 7) == 1) |
02cf21196
|
660 |
c->options |= MIPS_CPU_TLB; |
4194318c3
|
661 662 663 |
isa = (config0 & MIPS_CONF_AT) >> 13; switch (isa) { case 0: |
3a01c49ad
|
664 |
switch ((config0 & MIPS_CONF_AR) >> 10) { |
b4672d372
|
665 666 667 668 669 670 671 672 673 |
case 0: c->isa_level = MIPS_CPU_ISA_M32R1; break; case 1: c->isa_level = MIPS_CPU_ISA_M32R2; break; default: goto unknown; } |
4194318c3
|
674 675 |
break; case 2: |
3a01c49ad
|
676 |
switch ((config0 & MIPS_CONF_AR) >> 10) { |
b4672d372
|
677 678 679 680 681 682 683 684 685 |
case 0: c->isa_level = MIPS_CPU_ISA_M64R1; break; case 1: c->isa_level = MIPS_CPU_ISA_M64R2; break; default: goto unknown; } |
4194318c3
|
686 687 |
break; default: |
b4672d372
|
688 |
goto unknown; |
4194318c3
|
689 690 691 |
} return config0 & MIPS_CONF_M; |
b4672d372
|
692 693 694 |
unknown: panic(unknown_isa, config0); |
4194318c3
|
695 696 697 698 699 |
} static inline unsigned int decode_config1(struct cpuinfo_mips *c) { unsigned int config1; |
1da177e4c
|
700 |
|
1da177e4c
|
701 |
config1 = read_c0_config1(); |
4194318c3
|
702 703 704 705 |
if (config1 & MIPS_CONF1_MD) c->ases |= MIPS_ASE_MDMX; if (config1 & MIPS_CONF1_WR) |
1da177e4c
|
706 |
c->options |= MIPS_CPU_WATCH; |
4194318c3
|
707 708 709 |
if (config1 & MIPS_CONF1_CA) c->ases |= MIPS_ASE_MIPS16; if (config1 & MIPS_CONF1_EP) |
1da177e4c
|
710 |
c->options |= MIPS_CPU_EJTAG; |
4194318c3
|
711 |
if (config1 & MIPS_CONF1_FP) { |
1da177e4c
|
712 713 714 |
c->options |= MIPS_CPU_FPU; c->options |= MIPS_CPU_32FPR; } |
4194318c3
|
715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 |
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(); if (config3 & MIPS_CONF3_SM) c->ases |= MIPS_ASE_SMARTMIPS; |
e50c0a8fa
|
741 742 |
if (config3 & MIPS_CONF3_DSP) c->ases |= MIPS_ASE_DSP; |
8f40611d2
|
743 744 745 746 747 |
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) |
e0daad449
|
748 |
c->ases |= MIPS_ASE_MIPSMT; |
a36920200
|
749 750 |
if (config3 & MIPS_CONF3_ULRI) c->options |= MIPS_CPU_ULRI; |
4194318c3
|
751 752 753 |
return config3 & MIPS_CONF_M; } |
1b362e3e3
|
754 755 756 757 758 759 760 761 762 |
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; |
e77c32fe2
|
763 |
c->kscratch_mask = (config4 >> 16) & 0xff; |
1b362e3e3
|
764 765 |
return config4 & MIPS_CONF_M; } |
234fcd148
|
766 |
static void __cpuinit decode_configs(struct cpuinfo_mips *c) |
4194318c3
|
767 |
{ |
558ce1249
|
768 |
int ok; |
4194318c3
|
769 |
/* MIPS32 or MIPS64 compliant CPU. */ |
02cf21196
|
770 771 |
c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK; |
4194318c3
|
772 |
|
1da177e4c
|
773 |
c->scache.flags = MIPS_CACHE_NOT_PRESENT; |
558ce1249
|
774 775 776 777 778 779 780 781 |
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); |
1b362e3e3
|
782 783 |
if (ok) ok = decode_config4(c); |
558ce1249
|
784 785 |
mips_probe_watch_registers(c); |
0c2f4551d
|
786 787 788 |
if (cpu_has_mips_r2) c->core = read_c0_ebase() & 0x3ff; |
1da177e4c
|
789 |
} |
cea7e2dfd
|
790 |
static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) |
1da177e4c
|
791 |
{ |
4194318c3
|
792 |
decode_configs(c); |
1da177e4c
|
793 794 795 |
switch (c->processor_id & 0xff00) { case PRID_IMP_4KC: c->cputype = CPU_4KC; |
cea7e2dfd
|
796 |
__cpu_name[cpu] = "MIPS 4Kc"; |
1da177e4c
|
797 798 |
break; case PRID_IMP_4KEC: |
2b07bd023
|
799 800 |
case PRID_IMP_4KECR2: c->cputype = CPU_4KEC; |
cea7e2dfd
|
801 |
__cpu_name[cpu] = "MIPS 4KEc"; |
2b07bd023
|
802 |
break; |
1da177e4c
|
803 |
case PRID_IMP_4KSC: |
8afcb5d82
|
804 |
case PRID_IMP_4KSD: |
1da177e4c
|
805 |
c->cputype = CPU_4KSC; |
cea7e2dfd
|
806 |
__cpu_name[cpu] = "MIPS 4KSc"; |
1da177e4c
|
807 808 809 |
break; case PRID_IMP_5KC: c->cputype = CPU_5KC; |
cea7e2dfd
|
810 |
__cpu_name[cpu] = "MIPS 5Kc"; |
1da177e4c
|
811 812 813 |
break; case PRID_IMP_20KC: c->cputype = CPU_20KC; |
cea7e2dfd
|
814 |
__cpu_name[cpu] = "MIPS 20Kc"; |
1da177e4c
|
815 816 |
break; case PRID_IMP_24K: |
e50c0a8fa
|
817 |
case PRID_IMP_24KE: |
1da177e4c
|
818 |
c->cputype = CPU_24K; |
cea7e2dfd
|
819 |
__cpu_name[cpu] = "MIPS 24Kc"; |
1da177e4c
|
820 821 822 |
break; case PRID_IMP_25KF: c->cputype = CPU_25KF; |
cea7e2dfd
|
823 |
__cpu_name[cpu] = "MIPS 25Kc"; |
1da177e4c
|
824 |
break; |
bbc7f22f6
|
825 826 |
case PRID_IMP_34K: c->cputype = CPU_34K; |
cea7e2dfd
|
827 |
__cpu_name[cpu] = "MIPS 34Kc"; |
bbc7f22f6
|
828 |
break; |
c620953c3
|
829 830 |
case PRID_IMP_74K: c->cputype = CPU_74K; |
cea7e2dfd
|
831 |
__cpu_name[cpu] = "MIPS 74Kc"; |
c620953c3
|
832 |
break; |
39b8d5254
|
833 834 |
case PRID_IMP_1004K: c->cputype = CPU_1004K; |
cea7e2dfd
|
835 |
__cpu_name[cpu] = "MIPS 1004Kc"; |
39b8d5254
|
836 |
break; |
1da177e4c
|
837 |
} |
0b6d497fc
|
838 839 |
spram_config(); |
1da177e4c
|
840 |
} |
cea7e2dfd
|
841 |
static inline void cpu_probe_alchemy(struct cpuinfo_mips *c, unsigned int cpu) |
1da177e4c
|
842 |
{ |
4194318c3
|
843 |
decode_configs(c); |
1da177e4c
|
844 845 846 |
switch (c->processor_id & 0xff00) { case PRID_IMP_AU1_REV1: case PRID_IMP_AU1_REV2: |
270717a8a
|
847 |
c->cputype = CPU_ALCHEMY; |
1da177e4c
|
848 849 |
switch ((c->processor_id >> 24) & 0xff) { case 0: |
cea7e2dfd
|
850 |
__cpu_name[cpu] = "Au1000"; |
1da177e4c
|
851 852 |
break; case 1: |
cea7e2dfd
|
853 |
__cpu_name[cpu] = "Au1500"; |
1da177e4c
|
854 855 |
break; case 2: |
cea7e2dfd
|
856 |
__cpu_name[cpu] = "Au1100"; |
1da177e4c
|
857 858 |
break; case 3: |
cea7e2dfd
|
859 |
__cpu_name[cpu] = "Au1550"; |
1da177e4c
|
860 |
break; |
e3ad1c23b
|
861 |
case 4: |
cea7e2dfd
|
862 |
__cpu_name[cpu] = "Au1200"; |
270717a8a
|
863 |
if ((c->processor_id & 0xff) == 2) |
cea7e2dfd
|
864 |
__cpu_name[cpu] = "Au1250"; |
237cfee1d
|
865 866 |
break; case 5: |
cea7e2dfd
|
867 |
__cpu_name[cpu] = "Au1210"; |
e3ad1c23b
|
868 |
break; |
1da177e4c
|
869 |
default: |
270717a8a
|
870 |
__cpu_name[cpu] = "Au1xxx"; |
1da177e4c
|
871 872 |
break; } |
1da177e4c
|
873 874 875 |
break; } } |
cea7e2dfd
|
876 |
static inline void cpu_probe_sibyte(struct cpuinfo_mips *c, unsigned int cpu) |
1da177e4c
|
877 |
{ |
4194318c3
|
878 |
decode_configs(c); |
02cf21196
|
879 |
|
1da177e4c
|
880 881 882 |
switch (c->processor_id & 0xff00) { case PRID_IMP_SB1: c->cputype = CPU_SB1; |
cea7e2dfd
|
883 |
__cpu_name[cpu] = "SiByte SB1"; |
1da177e4c
|
884 |
/* FPU in pass1 is known to have issues. */ |
aa32374aa
|
885 |
if ((c->processor_id & 0xff) < 0x02) |
010b853b3
|
886 |
c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR); |
1da177e4c
|
887 |
break; |
93ce2f524
|
888 889 |
case PRID_IMP_SB1A: c->cputype = CPU_SB1A; |
cea7e2dfd
|
890 |
__cpu_name[cpu] = "SiByte SB1A"; |
93ce2f524
|
891 |
break; |
1da177e4c
|
892 893 |
} } |
cea7e2dfd
|
894 |
static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c, unsigned int cpu) |
1da177e4c
|
895 |
{ |
4194318c3
|
896 |
decode_configs(c); |
1da177e4c
|
897 898 899 |
switch (c->processor_id & 0xff00) { case PRID_IMP_SR71000: c->cputype = CPU_SR71000; |
cea7e2dfd
|
900 |
__cpu_name[cpu] = "Sandcraft SR71000"; |
1da177e4c
|
901 902 903 904 905 |
c->scache.ways = 8; c->tlbsize = 64; break; } } |
cea7e2dfd
|
906 |
static inline void cpu_probe_nxp(struct cpuinfo_mips *c, unsigned int cpu) |
bdf21b18b
|
907 908 909 910 911 |
{ decode_configs(c); switch (c->processor_id & 0xff00) { case PRID_IMP_PR4450: c->cputype = CPU_PR4450; |
cea7e2dfd
|
912 |
__cpu_name[cpu] = "Philips PR4450"; |
e7958bb90
|
913 |
c->isa_level = MIPS_CPU_ISA_M32R1; |
bdf21b18b
|
914 |
break; |
bdf21b18b
|
915 916 |
} } |
cea7e2dfd
|
917 |
static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) |
1c0c13eb9
|
918 919 920 |
{ decode_configs(c); switch (c->processor_id & 0xff00) { |
190fca3e4
|
921 922 |
case PRID_IMP_BMIPS32_REV4: case PRID_IMP_BMIPS32_REV8: |
602977b0d
|
923 924 |
c->cputype = CPU_BMIPS32; __cpu_name[cpu] = "Broadcom BMIPS32"; |
06785df09
|
925 |
set_elf_platform(cpu, "bmips32"); |
602977b0d
|
926 927 928 929 930 931 |
break; case PRID_IMP_BMIPS3300: case PRID_IMP_BMIPS3300_ALT: case PRID_IMP_BMIPS3300_BUG: c->cputype = CPU_BMIPS3300; __cpu_name[cpu] = "Broadcom BMIPS3300"; |
06785df09
|
932 |
set_elf_platform(cpu, "bmips3300"); |
602977b0d
|
933 934 935 936 937 938 939 940 |
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"; |
06785df09
|
941 |
set_elf_platform(cpu, "bmips4380"); |
602977b0d
|
942 943 944 |
} else { c->cputype = CPU_BMIPS4350; __cpu_name[cpu] = "Broadcom BMIPS4350"; |
06785df09
|
945 |
set_elf_platform(cpu, "bmips4350"); |
602977b0d
|
946 |
} |
0de663ef8
|
947 |
break; |
602977b0d
|
948 949 950 951 |
} case PRID_IMP_BMIPS5000: c->cputype = CPU_BMIPS5000; __cpu_name[cpu] = "Broadcom BMIPS5000"; |
06785df09
|
952 |
set_elf_platform(cpu, "bmips5000"); |
602977b0d
|
953 |
c->options |= MIPS_CPU_ULRI; |
0de663ef8
|
954 |
break; |
1c0c13eb9
|
955 956 |
} } |
0dd4781bc
|
957 958 959 960 961 962 963 |
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: |
6f329468f
|
964 965 966 |
c->cputype = CPU_CAVIUM_OCTEON; __cpu_name[cpu] = "Cavium Octeon"; goto platform; |
0dd4781bc
|
967 968 969 970 |
case PRID_IMP_CAVIUM_CN58XX: case PRID_IMP_CAVIUM_CN56XX: case PRID_IMP_CAVIUM_CN50XX: case PRID_IMP_CAVIUM_CN52XX: |
6f329468f
|
971 972 973 |
c->cputype = CPU_CAVIUM_OCTEON_PLUS; __cpu_name[cpu] = "Cavium Octeon+"; platform: |
c094c99e6
|
974 |
set_elf_platform(cpu, "octeon"); |
0dd4781bc
|
975 |
break; |
a1431b61a
|
976 |
case PRID_IMP_CAVIUM_CN61XX: |
0e56b3852
|
977 |
case PRID_IMP_CAVIUM_CN63XX: |
a1431b61a
|
978 979 |
case PRID_IMP_CAVIUM_CN66XX: case PRID_IMP_CAVIUM_CN68XX: |
0e56b3852
|
980 981 |
c->cputype = CPU_CAVIUM_OCTEON2; __cpu_name[cpu] = "Cavium Octeon II"; |
c094c99e6
|
982 |
set_elf_platform(cpu, "octeon2"); |
0e56b3852
|
983 |
break; |
0dd4781bc
|
984 985 986 987 988 989 990 |
default: printk(KERN_INFO "Unknown Octeon chip! "); c->cputype = CPU_UNKNOWN; break; } } |
83ccf69d8
|
991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 |
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; } } |
a7117c6bd
|
1006 1007 1008 |
static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu) { decode_configs(c); |
809f36c6f
|
1009 1010 1011 1012 1013 1014 |
if ((c->processor_id & 0xff00) == PRID_IMP_NETLOGIC_AU13XX) { c->cputype = CPU_ALCHEMY; __cpu_name[cpu] = "Au1300"; /* following stuff is not for Alchemy */ return; } |
a7117c6bd
|
1015 1016 1017 1018 1019 1020 1021 1022 1023 |
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) { |
2aa54b200
|
1024 1025 |
case PRID_IMP_NETLOGIC_XLP8XX: case PRID_IMP_NETLOGIC_XLP3XX: |
a3d4fb2d2
|
1026 1027 1028 |
c->cputype = CPU_XLP; __cpu_name[cpu] = "Netlogic XLP"; break; |
a7117c6bd
|
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 |
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: |
a3d4fb2d2
|
1059 1060 |
pr_info("Unknown Netlogic chip id [%02x]! ", |
a7117c6bd
|
1061 1062 1063 1064 |
c->processor_id); c->cputype = CPU_XLR; break; } |
a3d4fb2d2
|
1065 1066 1067 1068 1069 1070 1071 1072 1073 |
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; } |
a7117c6bd
|
1074 |
} |
949e51bea
|
1075 1076 1077 1078 1079 |
#ifdef CONFIG_64BIT /* For use by uaccess.h */ u64 __ua_limit; EXPORT_SYMBOL(__ua_limit); #endif |
9966db25d
|
1080 |
const char *__cpu_name[NR_CPUS]; |
874fd3b5a
|
1081 |
const char *__elf_platform; |
9966db25d
|
1082 |
|
234fcd148
|
1083 |
__cpuinit void cpu_probe(void) |
1da177e4c
|
1084 1085 |
{ struct cpuinfo_mips *c = ¤t_cpu_data; |
9966db25d
|
1086 |
unsigned int cpu = smp_processor_id(); |
1da177e4c
|
1087 1088 1089 1090 1091 1092 1093 1094 |
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: |
cea7e2dfd
|
1095 |
cpu_probe_legacy(c, cpu); |
1da177e4c
|
1096 1097 |
break; case PRID_COMP_MIPS: |
cea7e2dfd
|
1098 |
cpu_probe_mips(c, cpu); |
1da177e4c
|
1099 1100 |
break; case PRID_COMP_ALCHEMY: |
cea7e2dfd
|
1101 |
cpu_probe_alchemy(c, cpu); |
1da177e4c
|
1102 1103 |
break; case PRID_COMP_SIBYTE: |
cea7e2dfd
|
1104 |
cpu_probe_sibyte(c, cpu); |
1da177e4c
|
1105 |
break; |
1c0c13eb9
|
1106 |
case PRID_COMP_BROADCOM: |
cea7e2dfd
|
1107 |
cpu_probe_broadcom(c, cpu); |
1c0c13eb9
|
1108 |
break; |
1da177e4c
|
1109 |
case PRID_COMP_SANDCRAFT: |
cea7e2dfd
|
1110 |
cpu_probe_sandcraft(c, cpu); |
1da177e4c
|
1111 |
break; |
a92b05880
|
1112 |
case PRID_COMP_NXP: |
cea7e2dfd
|
1113 |
cpu_probe_nxp(c, cpu); |
a3dddd560
|
1114 |
break; |
0dd4781bc
|
1115 1116 1117 |
case PRID_COMP_CAVIUM: cpu_probe_cavium(c, cpu); break; |
83ccf69d8
|
1118 1119 1120 |
case PRID_COMP_INGENIC: cpu_probe_ingenic(c, cpu); break; |
a7117c6bd
|
1121 1122 1123 |
case PRID_COMP_NETLOGIC: cpu_probe_netlogic(c, cpu); break; |
1da177e4c
|
1124 |
} |
dec8b1ca9
|
1125 |
|
cea7e2dfd
|
1126 1127 |
BUG_ON(!__cpu_name[cpu]); BUG_ON(c->cputype == CPU_UNKNOWN); |
dec8b1ca9
|
1128 1129 1130 1131 1132 1133 |
/* * 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); |
0103d23f4
|
1134 1135 1136 1137 1138 |
if (mips_fpu_disabled) c->options &= ~MIPS_CPU_FPU; if (mips_dsp_disabled) c->ases &= ~MIPS_ASE_DSP; |
4194318c3
|
1139 |
if (c->options & MIPS_CPU_FPU) { |
1da177e4c
|
1140 |
c->fpu_id = cpu_get_fpu_id(); |
4194318c3
|
1141 |
|
e7958bb90
|
1142 |
if (c->isa_level == MIPS_CPU_ISA_M32R1 || |
b4672d372
|
1143 1144 1145 |
c->isa_level == MIPS_CPU_ISA_M32R2 || c->isa_level == MIPS_CPU_ISA_M64R1 || c->isa_level == MIPS_CPU_ISA_M64R2) { |
4194318c3
|
1146 1147 1148 1149 |
if (c->fpu_id & MIPS_FPIR_3D) c->ases |= MIPS_ASE_MIPS3D; } } |
9966db25d
|
1150 |
|
f6771dbb2
|
1151 1152 1153 1154 |
if (cpu_has_mips_r2) c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1; else c->srsets = 1; |
91dfc423c
|
1155 1156 |
cpu_probe_vmbits(c); |
949e51bea
|
1157 1158 1159 1160 1161 |
#ifdef CONFIG_64BIT if (cpu == 0) __ua_limit = ~((1ull << cpu_vmbits) - 1); #endif |
1da177e4c
|
1162 |
} |
234fcd148
|
1163 |
__cpuinit void cpu_report(void) |
1da177e4c
|
1164 1165 |
{ struct cpuinfo_mips *c = ¤t_cpu_data; |
9966db25d
|
1166 1167 1168 |
printk(KERN_INFO "CPU revision is: %08x (%s) ", c->processor_id, cpu_name_string()); |
1da177e4c
|
1169 |
if (c->options & MIPS_CPU_FPU) |
9966db25d
|
1170 1171 |
printk(KERN_INFO "FPU revision is: %08x ", c->fpu_id); |
1da177e4c
|
1172 |
} |