aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-12-20 23:39:21 -0500
committerJosh Boyer <jwboyer@linux.vnet.ibm.com>2007-12-23 14:11:59 -0500
commit47c0bd1ae24c34e851cf0f2b02ef2a6847d7ae15 (patch)
tree86fab68618a4afa03660cc576c9e7da3e5a0b520
parentc2a7dcad9f0d92d7a96e735abb8bec7b9c621536 (diff)
[POWERPC] Reworking machine check handling and Fix 440/440A
This adds a cputable function pointer for the CPU-side machine check handling. The semantic is still the same as the old one, the one in ppc_md. overrides the one in cputable, though ultimately we'll want to change that so the CPU gets first. This removes CONFIG_440A which was a problem for multiplatform kernels and instead fixes up the IVOR at runtime from a setup_cpu function. The "A" version of the machine check also tweaks the regs->trap value to differenciate the 2 versions at the C level. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
-rw-r--r--arch/powerpc/kernel/cpu_setup_44x.S9
-rw-r--r--arch/powerpc/kernel/cputable.c105
-rw-r--r--arch/powerpc/kernel/head_44x.S14
-rw-r--r--arch/powerpc/kernel/head_booke.h2
-rw-r--r--arch/powerpc/kernel/traps.c62
-rw-r--r--arch/powerpc/platforms/44x/Kconfig5
-rw-r--r--arch/ppc/kernel/traps.c98
-rw-r--r--include/asm-powerpc/cputable.h13
-rw-r--r--include/asm-powerpc/ptrace.h3
-rw-r--r--include/asm-powerpc/reg_booke.h3
-rw-r--r--include/asm-ppc/reg_booke.h2
11 files changed, 258 insertions, 58 deletions
diff --git a/arch/powerpc/kernel/cpu_setup_44x.S b/arch/powerpc/kernel/cpu_setup_44x.S
index 8e1812e2f3e..0de3edbd4bb 100644
--- a/arch/powerpc/kernel/cpu_setup_44x.S
+++ b/arch/powerpc/kernel/cpu_setup_44x.S
@@ -23,11 +23,20 @@ _GLOBAL(__setup_cpu_440epx)
23 mflr r4 23 mflr r4
24 bl __init_fpu_44x 24 bl __init_fpu_44x
25 bl __plb_disable_wrp 25 bl __plb_disable_wrp
26 bl __fixup_440A_mcheck
26 mtlr r4 27 mtlr r4
27 blr 28 blr
28_GLOBAL(__setup_cpu_440grx) 29_GLOBAL(__setup_cpu_440grx)
29 b __plb_disable_wrp 30 b __plb_disable_wrp
31_GLOBAL(__setup_cpu_440gx)
32_GLOBAL(__setup_cpu_440spe)
33 b __fixup_440A_mcheck
30 34
35 /* Temporary fixup for arch/ppc until we kill the whole thing */
36#ifndef CONFIG_PPC_MERGE
37_GLOBAL(__fixup_440A_mcheck)
38 blr
39#endif
31 40
32/* enable APU between CPU and FPU */ 41/* enable APU between CPU and FPU */
33_GLOBAL(__init_fpu_44x) 42_GLOBAL(__init_fpu_44x)
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 7c21f52d982..b0dcd47b803 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -33,7 +33,9 @@ EXPORT_SYMBOL(cur_cpu_spec);
33#ifdef CONFIG_PPC32 33#ifdef CONFIG_PPC32
34extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec); 34extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec);
35extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec); 35extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec);
36extern void __setup_cpu_440gx(unsigned long offset, struct cpu_spec* spec);
36extern void __setup_cpu_440grx(unsigned long offset, struct cpu_spec* spec); 37extern void __setup_cpu_440grx(unsigned long offset, struct cpu_spec* spec);
38extern void __setup_cpu_440spe(unsigned long offset, struct cpu_spec* spec);
37extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec); 39extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
38extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec); 40extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
39extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec); 41extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
@@ -85,6 +87,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
85 .pmc_type = PPC_PMC_IBM, 87 .pmc_type = PPC_PMC_IBM,
86 .oprofile_cpu_type = "ppc64/power3", 88 .oprofile_cpu_type = "ppc64/power3",
87 .oprofile_type = PPC_OPROFILE_RS64, 89 .oprofile_type = PPC_OPROFILE_RS64,
90 .machine_check = machine_check_generic,
88 .platform = "power3", 91 .platform = "power3",
89 }, 92 },
90 { /* Power3+ */ 93 { /* Power3+ */
@@ -99,6 +102,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
99 .pmc_type = PPC_PMC_IBM, 102 .pmc_type = PPC_PMC_IBM,
100 .oprofile_cpu_type = "ppc64/power3", 103 .oprofile_cpu_type = "ppc64/power3",
101 .oprofile_type = PPC_OPROFILE_RS64, 104 .oprofile_type = PPC_OPROFILE_RS64,
105 .machine_check = machine_check_generic,
102 .platform = "power3", 106 .platform = "power3",
103 }, 107 },
104 { /* Northstar */ 108 { /* Northstar */
@@ -113,6 +117,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
113 .pmc_type = PPC_PMC_IBM, 117 .pmc_type = PPC_PMC_IBM,
114 .oprofile_cpu_type = "ppc64/rs64", 118 .oprofile_cpu_type = "ppc64/rs64",
115 .oprofile_type = PPC_OPROFILE_RS64, 119 .oprofile_type = PPC_OPROFILE_RS64,
120 .machine_check = machine_check_generic,
116 .platform = "rs64", 121 .platform = "rs64",
117 }, 122 },
118 { /* Pulsar */ 123 { /* Pulsar */
@@ -127,6 +132,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
127 .pmc_type = PPC_PMC_IBM, 132 .pmc_type = PPC_PMC_IBM,
128 .oprofile_cpu_type = "ppc64/rs64", 133 .oprofile_cpu_type = "ppc64/rs64",
129 .oprofile_type = PPC_OPROFILE_RS64, 134 .oprofile_type = PPC_OPROFILE_RS64,
135 .machine_check = machine_check_generic,
130 .platform = "rs64", 136 .platform = "rs64",
131 }, 137 },
132 { /* I-star */ 138 { /* I-star */
@@ -141,6 +147,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
141 .pmc_type = PPC_PMC_IBM, 147 .pmc_type = PPC_PMC_IBM,
142 .oprofile_cpu_type = "ppc64/rs64", 148 .oprofile_cpu_type = "ppc64/rs64",
143 .oprofile_type = PPC_OPROFILE_RS64, 149 .oprofile_type = PPC_OPROFILE_RS64,
150 .machine_check = machine_check_generic,
144 .platform = "rs64", 151 .platform = "rs64",
145 }, 152 },
146 { /* S-star */ 153 { /* S-star */
@@ -155,6 +162,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
155 .pmc_type = PPC_PMC_IBM, 162 .pmc_type = PPC_PMC_IBM,
156 .oprofile_cpu_type = "ppc64/rs64", 163 .oprofile_cpu_type = "ppc64/rs64",
157 .oprofile_type = PPC_OPROFILE_RS64, 164 .oprofile_type = PPC_OPROFILE_RS64,
165 .machine_check = machine_check_generic,
158 .platform = "rs64", 166 .platform = "rs64",
159 }, 167 },
160 { /* Power4 */ 168 { /* Power4 */
@@ -169,6 +177,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
169 .pmc_type = PPC_PMC_IBM, 177 .pmc_type = PPC_PMC_IBM,
170 .oprofile_cpu_type = "ppc64/power4", 178 .oprofile_cpu_type = "ppc64/power4",
171 .oprofile_type = PPC_OPROFILE_POWER4, 179 .oprofile_type = PPC_OPROFILE_POWER4,
180 .machine_check = machine_check_generic,
172 .platform = "power4", 181 .platform = "power4",
173 }, 182 },
174 { /* Power4+ */ 183 { /* Power4+ */
@@ -183,6 +192,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
183 .pmc_type = PPC_PMC_IBM, 192 .pmc_type = PPC_PMC_IBM,
184 .oprofile_cpu_type = "ppc64/power4", 193 .oprofile_cpu_type = "ppc64/power4",
185 .oprofile_type = PPC_OPROFILE_POWER4, 194 .oprofile_type = PPC_OPROFILE_POWER4,
195 .machine_check = machine_check_generic,
186 .platform = "power4", 196 .platform = "power4",
187 }, 197 },
188 { /* PPC970 */ 198 { /* PPC970 */
@@ -200,6 +210,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
200 .cpu_restore = __restore_cpu_ppc970, 210 .cpu_restore = __restore_cpu_ppc970,
201 .oprofile_cpu_type = "ppc64/970", 211 .oprofile_cpu_type = "ppc64/970",
202 .oprofile_type = PPC_OPROFILE_POWER4, 212 .oprofile_type = PPC_OPROFILE_POWER4,
213 .machine_check = machine_check_generic,
203 .platform = "ppc970", 214 .platform = "ppc970",
204 }, 215 },
205 { /* PPC970FX */ 216 { /* PPC970FX */
@@ -217,6 +228,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
217 .cpu_restore = __restore_cpu_ppc970, 228 .cpu_restore = __restore_cpu_ppc970,
218 .oprofile_cpu_type = "ppc64/970", 229 .oprofile_cpu_type = "ppc64/970",
219 .oprofile_type = PPC_OPROFILE_POWER4, 230 .oprofile_type = PPC_OPROFILE_POWER4,
231 .machine_check = machine_check_generic,
220 .platform = "ppc970", 232 .platform = "ppc970",
221 }, 233 },
222 { /* PPC970MP DD1.0 - no DEEPNAP, use regular 970 init */ 234 { /* PPC970MP DD1.0 - no DEEPNAP, use regular 970 init */
@@ -234,6 +246,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
234 .cpu_restore = __restore_cpu_ppc970, 246 .cpu_restore = __restore_cpu_ppc970,
235 .oprofile_cpu_type = "ppc64/970MP", 247 .oprofile_cpu_type = "ppc64/970MP",
236 .oprofile_type = PPC_OPROFILE_POWER4, 248 .oprofile_type = PPC_OPROFILE_POWER4,
249 .machine_check = machine_check_generic,
237 .platform = "ppc970", 250 .platform = "ppc970",
238 }, 251 },
239 { /* PPC970MP */ 252 { /* PPC970MP */
@@ -251,6 +264,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
251 .cpu_restore = __restore_cpu_ppc970, 264 .cpu_restore = __restore_cpu_ppc970,
252 .oprofile_cpu_type = "ppc64/970MP", 265 .oprofile_cpu_type = "ppc64/970MP",
253 .oprofile_type = PPC_OPROFILE_POWER4, 266 .oprofile_type = PPC_OPROFILE_POWER4,
267 .machine_check = machine_check_generic,
254 .platform = "ppc970", 268 .platform = "ppc970",
255 }, 269 },
256 { /* PPC970GX */ 270 { /* PPC970GX */
@@ -267,6 +281,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
267 .cpu_setup = __setup_cpu_ppc970, 281 .cpu_setup = __setup_cpu_ppc970,
268 .oprofile_cpu_type = "ppc64/970", 282 .oprofile_cpu_type = "ppc64/970",
269 .oprofile_type = PPC_OPROFILE_POWER4, 283 .oprofile_type = PPC_OPROFILE_POWER4,
284 .machine_check = machine_check_generic,
270 .platform = "ppc970", 285 .platform = "ppc970",
271 }, 286 },
272 { /* Power5 GR */ 287 { /* Power5 GR */
@@ -286,6 +301,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
286 */ 301 */
287 .oprofile_mmcra_sihv = MMCRA_SIHV, 302 .oprofile_mmcra_sihv = MMCRA_SIHV,
288 .oprofile_mmcra_sipr = MMCRA_SIPR, 303 .oprofile_mmcra_sipr = MMCRA_SIPR,
304 .machine_check = machine_check_generic,
289 .platform = "power5", 305 .platform = "power5",
290 }, 306 },
291 { /* Power5++ */ 307 { /* Power5++ */
@@ -301,6 +317,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
301 .oprofile_type = PPC_OPROFILE_POWER4, 317 .oprofile_type = PPC_OPROFILE_POWER4,
302 .oprofile_mmcra_sihv = MMCRA_SIHV, 318 .oprofile_mmcra_sihv = MMCRA_SIHV,
303 .oprofile_mmcra_sipr = MMCRA_SIPR, 319 .oprofile_mmcra_sipr = MMCRA_SIPR,
320 .machine_check = machine_check_generic,
304 .platform = "power5+", 321 .platform = "power5+",
305 }, 322 },
306 { /* Power5 GS */ 323 { /* Power5 GS */
@@ -317,6 +334,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
317 .oprofile_type = PPC_OPROFILE_POWER4, 334 .oprofile_type = PPC_OPROFILE_POWER4,
318 .oprofile_mmcra_sihv = MMCRA_SIHV, 335 .oprofile_mmcra_sihv = MMCRA_SIHV,
319 .oprofile_mmcra_sipr = MMCRA_SIPR, 336 .oprofile_mmcra_sipr = MMCRA_SIPR,
337 .machine_check = machine_check_generic,
320 .platform = "power5+", 338 .platform = "power5+",
321 }, 339 },
322 { /* POWER6 in P5+ mode; 2.04-compliant processor */ 340 { /* POWER6 in P5+ mode; 2.04-compliant processor */
@@ -327,6 +345,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
327 .cpu_user_features = COMMON_USER_POWER5_PLUS, 345 .cpu_user_features = COMMON_USER_POWER5_PLUS,
328 .icache_bsize = 128, 346 .icache_bsize = 128,
329 .dcache_bsize = 128, 347 .dcache_bsize = 128,
348 .machine_check = machine_check_generic,
330 .platform = "power5+", 349 .platform = "power5+",
331 }, 350 },
332 { /* Power6 */ 351 { /* Power6 */
@@ -346,6 +365,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
346 .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR, 365 .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR,
347 .oprofile_mmcra_clear = POWER6_MMCRA_THRM | 366 .oprofile_mmcra_clear = POWER6_MMCRA_THRM |
348 POWER6_MMCRA_OTHER, 367 POWER6_MMCRA_OTHER,
368 .machine_check = machine_check_generic,
349 .platform = "power6x", 369 .platform = "power6x",
350 }, 370 },
351 { /* 2.05-compliant processor, i.e. Power6 "architected" mode */ 371 { /* 2.05-compliant processor, i.e. Power6 "architected" mode */
@@ -356,6 +376,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
356 .cpu_user_features = COMMON_USER_POWER6, 376 .cpu_user_features = COMMON_USER_POWER6,
357 .icache_bsize = 128, 377 .icache_bsize = 128,
358 .dcache_bsize = 128, 378 .dcache_bsize = 128,
379 .machine_check = machine_check_generic,
359 .platform = "power6", 380 .platform = "power6",
360 }, 381 },
361 { /* Cell Broadband Engine */ 382 { /* Cell Broadband Engine */
@@ -372,6 +393,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
372 .pmc_type = PPC_PMC_IBM, 393 .pmc_type = PPC_PMC_IBM,
373 .oprofile_cpu_type = "ppc64/cell-be", 394 .oprofile_cpu_type = "ppc64/cell-be",
374 .oprofile_type = PPC_OPROFILE_CELL, 395 .oprofile_type = PPC_OPROFILE_CELL,
396 .machine_check = machine_check_generic,
375 .platform = "ppc-cell-be", 397 .platform = "ppc-cell-be",
376 }, 398 },
377 { /* PA Semi PA6T */ 399 { /* PA Semi PA6T */
@@ -388,6 +410,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
388 .cpu_restore = __restore_cpu_pa6t, 410 .cpu_restore = __restore_cpu_pa6t,
389 .oprofile_cpu_type = "ppc64/pa6t", 411 .oprofile_cpu_type = "ppc64/pa6t",
390 .oprofile_type = PPC_OPROFILE_PA6T, 412 .oprofile_type = PPC_OPROFILE_PA6T,
413 .machine_check = machine_check_generic,
391 .platform = "pa6t", 414 .platform = "pa6t",
392 }, 415 },
393 { /* default match */ 416 { /* default match */
@@ -400,6 +423,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
400 .dcache_bsize = 128, 423 .dcache_bsize = 128,
401 .num_pmcs = 6, 424 .num_pmcs = 6,
402 .pmc_type = PPC_PMC_IBM, 425 .pmc_type = PPC_PMC_IBM,
426 .machine_check = machine_check_generic,
403 .platform = "power4", 427 .platform = "power4",
404 } 428 }
405#endif /* CONFIG_PPC64 */ 429#endif /* CONFIG_PPC64 */
@@ -414,6 +438,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
414 PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB, 438 PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB,
415 .icache_bsize = 32, 439 .icache_bsize = 32,
416 .dcache_bsize = 32, 440 .dcache_bsize = 32,
441 .machine_check = machine_check_generic,
417 .platform = "ppc601", 442 .platform = "ppc601",
418 }, 443 },
419 { /* 603 */ 444 { /* 603 */
@@ -425,6 +450,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
425 .icache_bsize = 32, 450 .icache_bsize = 32,
426 .dcache_bsize = 32, 451 .dcache_bsize = 32,
427 .cpu_setup = __setup_cpu_603, 452 .cpu_setup = __setup_cpu_603,
453 .machine_check = machine_check_generic,
428 .platform = "ppc603", 454 .platform = "ppc603",
429 }, 455 },
430 { /* 603e */ 456 { /* 603e */
@@ -436,6 +462,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
436 .icache_bsize = 32, 462 .icache_bsize = 32,
437 .dcache_bsize = 32, 463 .dcache_bsize = 32,
438 .cpu_setup = __setup_cpu_603, 464 .cpu_setup = __setup_cpu_603,
465 .machine_check = machine_check_generic,
439 .platform = "ppc603", 466 .platform = "ppc603",
440 }, 467 },
441 { /* 603ev */ 468 { /* 603ev */
@@ -447,6 +474,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
447 .icache_bsize = 32, 474 .icache_bsize = 32,
448 .dcache_bsize = 32, 475 .dcache_bsize = 32,
449 .cpu_setup = __setup_cpu_603, 476 .cpu_setup = __setup_cpu_603,
477 .machine_check = machine_check_generic,
450 .platform = "ppc603", 478 .platform = "ppc603",
451 }, 479 },
452 { /* 604 */ 480 { /* 604 */
@@ -459,6 +487,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
459 .dcache_bsize = 32, 487 .dcache_bsize = 32,
460 .num_pmcs = 2, 488 .num_pmcs = 2,
461 .cpu_setup = __setup_cpu_604, 489 .cpu_setup = __setup_cpu_604,
490 .machine_check = machine_check_generic,
462 .platform = "ppc604", 491 .platform = "ppc604",
463 }, 492 },
464 { /* 604e */ 493 { /* 604e */
@@ -471,6 +500,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
471 .dcache_bsize = 32, 500 .dcache_bsize = 32,
472 .num_pmcs = 4, 501 .num_pmcs = 4,
473 .cpu_setup = __setup_cpu_604, 502 .cpu_setup = __setup_cpu_604,
503 .machine_check = machine_check_generic,
474 .platform = "ppc604", 504 .platform = "ppc604",
475 }, 505 },
476 { /* 604r */ 506 { /* 604r */
@@ -483,6 +513,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
483 .dcache_bsize = 32, 513 .dcache_bsize = 32,
484 .num_pmcs = 4, 514 .num_pmcs = 4,
485 .cpu_setup = __setup_cpu_604, 515 .cpu_setup = __setup_cpu_604,
516 .machine_check = machine_check_generic,
486 .platform = "ppc604", 517 .platform = "ppc604",
487 }, 518 },
488 { /* 604ev */ 519 { /* 604ev */
@@ -495,6 +526,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
495 .dcache_bsize = 32, 526 .dcache_bsize = 32,
496 .num_pmcs = 4, 527 .num_pmcs = 4,
497 .cpu_setup = __setup_cpu_604, 528 .cpu_setup = __setup_cpu_604,
529 .machine_check = machine_check_generic,
498 .platform = "ppc604", 530 .platform = "ppc604",
499 }, 531 },
500 { /* 740/750 (0x4202, don't support TAU ?) */ 532 { /* 740/750 (0x4202, don't support TAU ?) */
@@ -507,6 +539,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
507 .dcache_bsize = 32, 539 .dcache_bsize = 32,
508 .num_pmcs = 4, 540 .num_pmcs = 4,
509 .cpu_setup = __setup_cpu_750, 541 .cpu_setup = __setup_cpu_750,
542 .machine_check = machine_check_generic,
510 .platform = "ppc750", 543 .platform = "ppc750",
511 }, 544 },
512 { /* 750CX (80100 and 8010x?) */ 545 { /* 750CX (80100 and 8010x?) */
@@ -519,6 +552,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
519 .dcache_bsize = 32, 552 .dcache_bsize = 32,
520 .num_pmcs = 4, 553 .num_pmcs = 4,
521 .cpu_setup = __setup_cpu_750cx, 554 .cpu_setup = __setup_cpu_750cx,
555 .machine_check = machine_check_generic,
522 .platform = "ppc750", 556 .platform = "ppc750",
523 }, 557 },
524 { /* 750CX (82201 and 82202) */ 558 { /* 750CX (82201 and 82202) */
@@ -531,6 +565,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
531 .dcache_bsize = 32, 565 .dcache_bsize = 32,
532 .num_pmcs = 4, 566 .num_pmcs = 4,
533 .cpu_setup = __setup_cpu_750cx, 567 .cpu_setup = __setup_cpu_750cx,
568 .machine_check = machine_check_generic,
534 .platform = "ppc750", 569 .platform = "ppc750",
535 }, 570 },
536 { /* 750CXe (82214) */ 571 { /* 750CXe (82214) */
@@ -543,6 +578,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
543 .dcache_bsize = 32, 578 .dcache_bsize = 32,
544 .num_pmcs = 4, 579 .num_pmcs = 4,
545 .cpu_setup = __setup_cpu_750cx, 580 .cpu_setup = __setup_cpu_750cx,
581 .machine_check = machine_check_generic,
546 .platform = "ppc750", 582 .platform = "ppc750",
547 }, 583 },
548 { /* 750CXe "Gekko" (83214) */ 584 { /* 750CXe "Gekko" (83214) */
@@ -555,6 +591,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
555 .dcache_bsize = 32, 591 .dcache_bsize = 32,
556 .num_pmcs = 4, 592 .num_pmcs = 4,
557 .cpu_setup = __setup_cpu_750cx, 593 .cpu_setup = __setup_cpu_750cx,
594 .machine_check = machine_check_generic,
558 .platform = "ppc750", 595 .platform = "ppc750",
559 }, 596 },
560 { /* 750CL */ 597 { /* 750CL */
@@ -567,6 +604,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
567 .dcache_bsize = 32, 604 .dcache_bsize = 32,
568 .num_pmcs = 4, 605 .num_pmcs = 4,
569 .cpu_setup = __setup_cpu_750, 606 .cpu_setup = __setup_cpu_750,
607 .machine_check = machine_check_generic,
570 .platform = "ppc750", 608 .platform = "ppc750",
571 }, 609 },
572 { /* 745/755 */ 610 { /* 745/755 */
@@ -579,6 +617,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
579 .dcache_bsize = 32, 617 .dcache_bsize = 32,
580 .num_pmcs = 4, 618 .num_pmcs = 4,
581 .cpu_setup = __setup_cpu_750, 619 .cpu_setup = __setup_cpu_750,
620 .machine_check = machine_check_generic,
582 .platform = "ppc750", 621 .platform = "ppc750",
583 }, 622 },
584 { /* 750FX rev 1.x */ 623 { /* 750FX rev 1.x */
@@ -591,6 +630,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
591 .dcache_bsize = 32, 630 .dcache_bsize = 32,
592 .num_pmcs = 4, 631 .num_pmcs = 4,
593 .cpu_setup = __setup_cpu_750, 632 .cpu_setup = __setup_cpu_750,
633 .machine_check = machine_check_generic,
594 .platform = "ppc750", 634 .platform = "ppc750",
595 }, 635 },
596 { /* 750FX rev 2.0 must disable HID0[DPM] */ 636 { /* 750FX rev 2.0 must disable HID0[DPM] */
@@ -603,6 +643,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
603 .dcache_bsize = 32, 643 .dcache_bsize = 32,
604 .num_pmcs = 4, 644 .num_pmcs = 4,
605 .cpu_setup = __setup_cpu_750, 645 .cpu_setup = __setup_cpu_750,
646 .machine_check = machine_check_generic,
606 .platform = "ppc750", 647 .platform = "ppc750",
607 }, 648 },
608 { /* 750FX (All revs except 2.0) */ 649 { /* 750FX (All revs except 2.0) */
@@ -615,6 +656,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
615 .dcache_bsize = 32, 656 .dcache_bsize = 32,
616 .num_pmcs = 4, 657 .num_pmcs = 4,
617 .cpu_setup = __setup_cpu_750fx, 658 .cpu_setup = __setup_cpu_750fx,
659 .machine_check = machine_check_generic,
618 .platform = "ppc750", 660 .platform = "ppc750",
619 }, 661 },
620 { /* 750GX */ 662 { /* 750GX */
@@ -627,6 +669,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
627 .dcache_bsize = 32, 669 .dcache_bsize = 32,
628 .num_pmcs = 4, 670 .num_pmcs = 4,
629 .cpu_setup = __setup_cpu_750fx, 671 .cpu_setup = __setup_cpu_750fx,
672 .machine_check = machine_check_generic,
630 .platform = "ppc750", 673 .platform = "ppc750",
631 }, 674 },
632 { /* 740/750 (L2CR bit need fixup for 740) */ 675 { /* 740/750 (L2CR bit need fixup for 740) */
@@ -639,6 +682,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
639 .dcache_bsize = 32, 682 .dcache_bsize = 32,
640 .num_pmcs = 4, 683 .num_pmcs = 4,
641 .cpu_setup = __setup_cpu_750, 684 .cpu_setup = __setup_cpu_750,
685 .machine_check = machine_check_generic,
642 .platform = "ppc750", 686 .platform = "ppc750",
643 }, 687 },
644 { /* 7400 rev 1.1 ? (no TAU) */ 688 { /* 7400 rev 1.1 ? (no TAU) */
@@ -652,6 +696,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
652 .dcache_bsize = 32, 696 .dcache_bsize = 32,
653 .num_pmcs = 4, 697 .num_pmcs = 4,
654 .cpu_setup = __setup_cpu_7400, 698 .cpu_setup = __setup_cpu_7400,
699 .machine_check = machine_check_generic,
655 .platform = "ppc7400", 700 .platform = "ppc7400",
656 }, 701 },
657 { /* 7400 */ 702 { /* 7400 */
@@ -665,6 +710,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
665 .dcache_bsize = 32, 710 .dcache_bsize = 32,
666 .num_pmcs = 4, 711 .num_pmcs = 4,
667 .cpu_setup = __setup_cpu_7400, 712 .cpu_setup = __setup_cpu_7400,
713 .machine_check = machine_check_generic,
668 .platform = "ppc7400", 714 .platform = "ppc7400",
669 }, 715 },
670 { /* 7410 */ 716 { /* 7410 */
@@ -678,6 +724,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
678 .dcache_bsize = 32, 724 .dcache_bsize = 32,
679 .num_pmcs = 4, 725 .num_pmcs = 4,
680 .cpu_setup = __setup_cpu_7410, 726 .cpu_setup = __setup_cpu_7410,
727 .machine_check = machine_check_generic,
681 .platform = "ppc7400", 728 .platform = "ppc7400",
682 }, 729 },
683 { /* 7450 2.0 - no doze/nap */ 730 { /* 7450 2.0 - no doze/nap */
@@ -693,6 +740,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
693 .cpu_setup = __setup_cpu_745x, 740 .cpu_setup = __setup_cpu_745x,
694 .oprofile_cpu_type = "ppc/7450", 741 .oprofile_cpu_type = "ppc/7450",
695 .oprofile_type = PPC_OPROFILE_G4, 742 .oprofile_type = PPC_OPROFILE_G4,
743 .machine_check = machine_check_generic,
696 .platform = "ppc7450", 744 .platform = "ppc7450",
697 }, 745 },
698 { /* 7450 2.1 */ 746 { /* 7450 2.1 */
@@ -708,6 +756,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
708 .cpu_setup = __setup_cpu_745x, 756 .cpu_setup = __setup_cpu_745x,
709 .oprofile_cpu_type = "ppc/7450", 757 .oprofile_cpu_type = "ppc/7450",
710 .oprofile_type = PPC_OPROFILE_G4, 758 .oprofile_type = PPC_OPROFILE_G4,
759 .machine_check = machine_check_generic,
711 .platform = "ppc7450", 760 .platform = "ppc7450",
712 }, 761 },
713 { /* 7450 2.3 and newer */ 762 { /* 7450 2.3 and newer */
@@ -723,6 +772,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
723 .cpu_setup = __setup_cpu_745x, 772 .cpu_setup = __setup_cpu_745x,
724 .oprofile_cpu_type = "ppc/7450", 773 .oprofile_cpu_type = "ppc/7450",
725 .oprofile_type = PPC_OPROFILE_G4, 774 .oprofile_type = PPC_OPROFILE_G4,
775 .machine_check = machine_check_generic,
726 .platform = "ppc7450", 776 .platform = "ppc7450",
727 }, 777 },
728 { /* 7455 rev 1.x */ 778 { /* 7455 rev 1.x */
@@ -738,6 +788,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
738 .cpu_setup = __setup_cpu_745x, 788 .cpu_setup = __setup_cpu_745x,
739 .oprofile_cpu_type = "ppc/7450", 789 .oprofile_cpu_type = "ppc/7450",
740 .oprofile_type = PPC_OPROFILE_G4, 790 .oprofile_type = PPC_OPROFILE_G4,
791 .machine_check = machine_check_generic,
741 .platform = "ppc7450", 792 .platform = "ppc7450",
742 }, 793 },
743 { /* 7455 rev 2.0 */ 794 { /* 7455 rev 2.0 */
@@ -753,6 +804,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
753 .cpu_setup = __setup_cpu_745x, 804 .cpu_setup = __setup_cpu_745x,
754 .oprofile_cpu_type = "ppc/7450", 805 .oprofile_cpu_type = "ppc/7450",
755 .oprofile_type = PPC_OPROFILE_G4, 806 .oprofile_type = PPC_OPROFILE_G4,
807 .machine_check = machine_check_generic,
756 .platform = "ppc7450", 808 .platform = "ppc7450",
757 }, 809 },
758 { /* 7455 others */ 810 { /* 7455 others */
@@ -768,6 +820,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
768 .cpu_setup = __setup_cpu_745x, 820 .cpu_setup = __setup_cpu_745x,
769 .oprofile_cpu_type = "ppc/7450", 821 .oprofile_cpu_type = "ppc/7450",
770 .oprofile_type = PPC_OPROFILE_G4, 822 .oprofile_type = PPC_OPROFILE_G4,
823 .machine_check = machine_check_generic,
771 .platform = "ppc7450", 824 .platform = "ppc7450",
772 }, 825 },
773 { /* 7447/7457 Rev 1.0 */ 826 { /* 7447/7457 Rev 1.0 */
@@ -783,6 +836,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
783 .cpu_setup = __setup_cpu_745x, 836 .cpu_setup = __setup_cpu_745x,
784 .oprofile_cpu_type = "ppc/7450", 837 .oprofile_cpu_type = "ppc/7450",
785 .oprofile_type = PPC_OPROFILE_G4, 838 .oprofile_type = PPC_OPROFILE_G4,
839 .machine_check = machine_check_generic,
786 .platform = "ppc7450", 840 .platform = "ppc7450",
787 }, 841 },
788 { /* 7447/7457 Rev 1.1 */ 842 { /* 7447/7457 Rev 1.1 */
@@ -798,6 +852,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
798 .cpu_setup = __setup_cpu_745x, 852 .cpu_setup = __setup_cpu_745x,
799 .oprofile_cpu_type = "ppc/7450", 853 .oprofile_cpu_type = "ppc/7450",
800 .oprofile_type = PPC_OPROFILE_G4, 854 .oprofile_type = PPC_OPROFILE_G4,
855 .machine_check = machine_check_generic,
801 .platform = "ppc7450", 856 .platform = "ppc7450",
802 }, 857 },
803 { /* 7447/7457 Rev 1.2 and later */ 858 { /* 7447/7457 Rev 1.2 and later */
@@ -812,6 +867,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
812 .cpu_setup = __setup_cpu_745x, 867 .cpu_setup = __setup_cpu_745x,
813 .oprofile_cpu_type = "ppc/7450", 868 .oprofile_cpu_type = "ppc/7450",
814 .oprofile_type = PPC_OPROFILE_G4, 869 .oprofile_type = PPC_OPROFILE_G4,
870 .machine_check = machine_check_generic,
815 .platform = "ppc7450", 871 .platform = "ppc7450",
816 }, 872 },
817 { /* 7447A */ 873 { /* 7447A */
@@ -827,6 +883,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
827 .cpu_setup = __setup_cpu_745x, 883 .cpu_setup = __setup_cpu_745x,
828 .oprofile_cpu_type = "ppc/7450", 884 .oprofile_cpu_type = "ppc/7450",
829 .oprofile_type = PPC_OPROFILE_G4, 885 .oprofile_type = PPC_OPROFILE_G4,
886 .machine_check = machine_check_generic,
830 .platform = "ppc7450", 887 .platform = "ppc7450",
831 }, 888 },
832 { /* 7448 */ 889 { /* 7448 */
@@ -842,6 +899,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
842 .cpu_setup = __setup_cpu_745x, 899 .cpu_setup = __setup_cpu_745x,
843 .oprofile_cpu_type = "ppc/7450", 900 .oprofile_cpu_type = "ppc/7450",
844 .oprofile_type = PPC_OPROFILE_G4, 901 .oprofile_type = PPC_OPROFILE_G4,
902 .machine_check = machine_check_generic,
845 .platform = "ppc7450", 903 .platform = "ppc7450",
846 }, 904 },
847 { /* 82xx (8240, 8245, 8260 are all 603e cores) */ 905 { /* 82xx (8240, 8245, 8260 are all 603e cores) */
@@ -853,6 +911,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
853 .icache_bsize = 32, 911 .icache_bsize = 32,
854 .dcache_bsize = 32, 912 .dcache_bsize = 32,
855 .cpu_setup = __setup_cpu_603, 913 .cpu_setup = __setup_cpu_603,
914 .machine_check = machine_check_generic,
856 .platform = "ppc603", 915 .platform = "ppc603",
857 }, 916 },
858 { /* All G2_LE (603e core, plus some) have the same pvr */ 917 { /* All G2_LE (603e core, plus some) have the same pvr */
@@ -864,6 +923,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
864 .icache_bsize = 32, 923 .icache_bsize = 32,
865 .dcache_bsize = 32, 924 .dcache_bsize = 32,
866 .cpu_setup = __setup_cpu_603, 925 .cpu_setup = __setup_cpu_603,
926 .machine_check = machine_check_generic,
867 .platform = "ppc603", 927 .platform = "ppc603",
868 }, 928 },
869 { /* e300c1 (a 603e core, plus some) on 83xx */ 929 { /* e300c1 (a 603e core, plus some) on 83xx */
@@ -875,6 +935,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
875 .icache_bsize = 32, 935 .icache_bsize = 32,
876 .dcache_bsize = 32, 936 .dcache_bsize = 32,
877 .cpu_setup = __setup_cpu_603, 937 .cpu_setup = __setup_cpu_603,
938 .machine_check = machine_check_generic,
878 .platform = "ppc603", 939 .platform = "ppc603",
879 }, 940 },
880 { /* e300c2 (an e300c1 core, plus some, minus FPU) on 83xx */ 941 { /* e300c2 (an e300c1 core, plus some, minus FPU) on 83xx */
@@ -886,6 +947,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
886 .icache_bsize = 32, 947 .icache_bsize = 32,
887 .dcache_bsize = 32, 948 .dcache_bsize = 32,
888 .cpu_setup = __setup_cpu_603, 949 .cpu_setup = __setup_cpu_603,
950 .machine_check = machine_check_generic,
889 .platform = "ppc603", 951 .platform = "ppc603",
890 }, 952 },
891 { /* e300c3 (e300c1, plus one IU, half cache size) on 83xx */ 953 { /* e300c3 (e300c1, plus one IU, half cache size) on 83xx */
@@ -908,6 +970,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
908 .icache_bsize = 32, 970 .icache_bsize = 32,
909 .dcache_bsize = 32, 971 .dcache_bsize = 32,
910 .cpu_setup = __setup_cpu_603, 972 .cpu_setup = __setup_cpu_603,
973 .machine_check = machine_check_generic,
911 .platform = "ppc603", 974 .platform = "ppc603",
912 }, 975 },
913 { /* default match, we assume split I/D cache & TB (non-601)... */ 976 { /* default match, we assume split I/D cache & TB (non-601)... */
@@ -918,6 +981,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
918 .cpu_user_features = COMMON_USER, 981 .cpu_user_features = COMMON_USER,
919 .icache_bsize = 32, 982 .icache_bsize = 32,
920 .dcache_bsize = 32, 983 .dcache_bsize = 32,
984 .machine_check = machine_check_generic,
921 .platform = "ppc603", 985 .platform = "ppc603",
922 }, 986 },
923#endif /* CLASSIC_PPC */ 987#endif /* CLASSIC_PPC */
@@ -944,6 +1008,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
944 .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, 1008 .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
945 .icache_bsize = 16, 1009 .icache_bsize = 16,
946 .dcache_bsize = 16, 1010 .dcache_bsize = 16,
1011 .machine_check = machine_check_4xx,
947 .platform = "ppc403", 1012 .platform = "ppc403",
948 }, 1013 },
949 { /* 403GCX */ 1014 { /* 403GCX */
@@ -955,6 +1020,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
955 PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB, 1020 PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB,
956 .icache_bsize = 16, 1021 .icache_bsize = 16,
957 .dcache_bsize = 16, 1022 .dcache_bsize = 16,
1023 .machine_check = machine_check_4xx,
958 .platform = "ppc403", 1024 .platform = "ppc403",
959 }, 1025 },
960 { /* 403G ?? */ 1026 { /* 403G ?? */
@@ -965,6 +1031,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
965 .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, 1031 .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
966 .icache_bsize = 16, 1032 .icache_bsize = 16,
967 .dcache_bsize = 16, 1033 .dcache_bsize = 16,
1034 .machine_check = machine_check_4xx,
968 .platform = "ppc403", 1035 .platform = "ppc403",
969 }, 1036 },
970 { /* 405GP */ 1037 { /* 405GP */
@@ -976,6 +1043,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
976 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, 1043 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
977 .icache_bsize = 32, 1044 .icache_bsize = 32,
978 .dcache_bsize = 32, 1045 .dcache_bsize = 32,
1046 .machine_check = machine_check_4xx,
979 .platform = "ppc405", 1047 .platform = "ppc405",
980 }, 1048 },
981 { /* STB 03xxx */ 1049 { /* STB 03xxx */
@@ -987,6 +1055,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
987 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, 1055 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
988 .icache_bsize = 32, 1056 .icache_bsize = 32,
989 .dcache_bsize = 32, 1057 .dcache_bsize = 32,
1058 .machine_check = machine_check_4xx,
990 .platform = "ppc405", 1059 .platform = "ppc405",
991 }, 1060 },
992 { /* STB 04xxx */ 1061 { /* STB 04xxx */
@@ -998,6 +1067,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
998 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, 1067 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
999 .icache_bsize = 32, 1068 .icache_bsize = 32,
1000 .dcache_bsize = 32, 1069 .dcache_bsize = 32,
1070 .machine_check = machine_check_4xx,
1001 .platform = "ppc405", 1071 .platform = "ppc405",
1002 }, 1072 },
1003 { /* NP405L */ 1073 { /* NP405L */
@@ -1009,6 +1079,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1009 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, 1079 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
1010 .icache_bsize = 32, 1080 .icache_bsize = 32,
1011 .dcache_bsize = 32, 1081 .dcache_bsize = 32,
1082 .machine_check = machine_check_4xx,
1012 .platform = "ppc405", 1083 .platform = "ppc405",
1013 }, 1084 },
1014 { /* NP4GS3 */ 1085 { /* NP4GS3 */
@@ -1020,6 +1091,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1020 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, 1091 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
1021 .icache_bsize = 32, 1092 .icache_bsize = 32,
1022 .dcache_bsize = 32, 1093 .dcache_bsize = 32,
1094 .machine_check = machine_check_4xx,
1023 .platform = "ppc405", 1095 .platform = "ppc405",
1024 }, 1096 },
1025 { /* NP405H */ 1097 { /* NP405H */
@@ -1031,6 +1103,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1031 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, 1103 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
1032 .icache_bsize = 32, 1104 .icache_bsize = 32,
1033 .dcache_bsize = 32, 1105 .dcache_bsize = 32,
1106 .machine_check = machine_check_4xx,
1034 .platform = "ppc405", 1107 .platform = "ppc405",
1035 }, 1108 },
1036 { /* 405GPr */ 1109 { /* 405GPr */
@@ -1042,6 +1115,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1042 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, 1115 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
1043 .icache_bsize = 32, 1116 .icache_bsize = 32,
1044 .dcache_bsize = 32, 1117 .dcache_bsize = 32,
1118 .machine_check = machine_check_4xx,
1045 .platform = "ppc405", 1119 .platform = "ppc405",
1046 }, 1120 },
1047 { /* STBx25xx */ 1121 { /* STBx25xx */
@@ -1053,6 +1127,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1053 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, 1127 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
1054 .icache_bsize = 32, 1128 .icache_bsize = 32,
1055 .dcache_bsize = 32, 1129 .dcache_bsize = 32,
1130 .machine_check = machine_check_4xx,
1056 .platform = "ppc405", 1131 .platform = "ppc405",
1057 }, 1132 },
1058 { /* 405LP */ 1133 { /* 405LP */
@@ -1063,6 +1138,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1063 .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, 1138 .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
1064 .icache_bsize = 32, 1139 .icache_bsize = 32,
1065 .dcache_bsize = 32, 1140 .dcache_bsize = 32,
1141 .machine_check = machine_check_4xx,
1066 .platform = "ppc405", 1142 .platform = "ppc405",
1067 }, 1143 },
1068 { /* Xilinx Virtex-II Pro */ 1144 { /* Xilinx Virtex-II Pro */
@@ -1074,6 +1150,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1074 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, 1150 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
1075 .icache_bsize = 32, 1151 .icache_bsize = 32,
1076 .dcache_bsize = 32, 1152 .dcache_bsize = 32,
1153 .machine_check = machine_check_4xx,
1077 .platform = "ppc405", 1154 .platform = "ppc405",
1078 }, 1155 },
1079 { /* Xilinx Virtex-4 FX */ 1156 { /* Xilinx Virtex-4 FX */
@@ -1085,6 +1162,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1085 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, 1162 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
1086 .icache_bsize = 32, 1163 .icache_bsize = 32,
1087 .dcache_bsize = 32, 1164 .dcache_bsize = 32,
1165 .machine_check = machine_check_4xx,
1088 .platform = "ppc405", 1166 .platform = "ppc405",
1089 }, 1167 },
1090 { /* 405EP */ 1168 { /* 405EP */
@@ -1096,6 +1174,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1096 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, 1174 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
1097 .icache_bsize = 32, 1175 .icache_bsize = 32,
1098 .dcache_bsize = 32, 1176 .dcache_bsize = 32,
1177 .machine_check = machine_check_4xx,
1099 .platform = "ppc405", 1178 .platform = "ppc405",
1100 }, 1179 },
1101 { /* 405EX */ 1180 { /* 405EX */
@@ -1107,6 +1186,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1107 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, 1186 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
1108 .icache_bsize = 32, 1187 .icache_bsize = 32,
1109 .dcache_bsize = 32, 1188 .dcache_bsize = 32,
1189 .machine_check = machine_check_4xx,
1110 .platform = "ppc405", 1190 .platform = "ppc405",
1111 }, 1191 },
1112 1192
@@ -1120,6 +1200,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1120 .cpu_user_features = COMMON_USER_BOOKE, 1200 .cpu_user_features = COMMON_USER_BOOKE,
1121 .icache_bsize = 32, 1201 .icache_bsize = 32,
1122 .dcache_bsize = 32, 1202 .dcache_bsize = 32,
1203 .machine_check = machine_check_4xx,
1123 .platform = "ppc440", 1204 .platform = "ppc440",
1124 }, 1205 },
1125 { /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */ 1206 { /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */
@@ -1131,6 +1212,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1131 .icache_bsize = 32, 1212 .icache_bsize = 32,
1132 .dcache_bsize = 32, 1213 .dcache_bsize = 32,
1133 .cpu_setup = __setup_cpu_440ep, 1214 .cpu_setup = __setup_cpu_440ep,
1215 .machine_check = machine_check_4xx,
1134 .platform = "ppc440", 1216 .platform = "ppc440",
1135 }, 1217 },
1136 { 1218 {
@@ -1141,6 +1223,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1141 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, 1223 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
1142 .icache_bsize = 32, 1224 .icache_bsize = 32,
1143 .dcache_bsize = 32, 1225 .dcache_bsize = 32,
1226 .machine_check = machine_check_4xx,
1144 .platform = "ppc440", 1227 .platform = "ppc440",
1145 }, 1228 },
1146 { /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */ 1229 { /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */
@@ -1152,6 +1235,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1152 .icache_bsize = 32, 1235 .icache_bsize = 32,
1153 .dcache_bsize = 32, 1236 .dcache_bsize = 32,
1154 .cpu_setup = __setup_cpu_440ep, 1237 .cpu_setup = __setup_cpu_440ep,
1238 .machine_check = machine_check_4xx,
1155 .platform = "ppc440", 1239 .platform = "ppc440",
1156 }, 1240 },
1157 { /* 440GRX */ 1241 { /* 440GRX */
@@ -1163,6 +1247,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1163 .icache_bsize = 32, 1247 .icache_bsize = 32,
1164 .dcache_bsize = 32, 1248 .dcache_bsize = 32,
1165 .cpu_setup = __setup_cpu_440grx, 1249 .cpu_setup = __setup_cpu_440grx,
1250 .machine_check = machine_check_4xx,
1166 .platform = "ppc440", 1251 .platform = "ppc440",
1167 }, 1252 },
1168 { /* Use logical PVR for 440EPx (logical pvr = pvr | 0x8) */ 1253 { /* Use logical PVR for 440EPx (logical pvr = pvr | 0x8) */
@@ -1174,6 +1259,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1174 .icache_bsize = 32, 1259 .icache_bsize = 32,
1175 .dcache_bsize = 32, 1260 .dcache_bsize = 32,
1176 .cpu_setup = __setup_cpu_440epx, 1261 .cpu_setup = __setup_cpu_440epx,
1262 .machine_check = machine_check_440A,
1177 .platform = "ppc440", 1263 .platform = "ppc440",
1178 }, 1264 },
1179 { /* 440GP Rev. B */ 1265 { /* 440GP Rev. B */
@@ -1184,6 +1270,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1184 .cpu_user_features = COMMON_USER_BOOKE, 1270 .cpu_user_features = COMMON_USER_BOOKE,
1185 .icache_bsize = 32, 1271 .icache_bsize = 32,
1186 .dcache_bsize = 32, 1272 .dcache_bsize = 32,
1273 .machine_check = machine_check_4xx,
1187 .platform = "ppc440gp", 1274 .platform = "ppc440gp",
1188 }, 1275 },
1189 { /* 440GP Rev. C */ 1276 { /* 440GP Rev. C */
@@ -1194,6 +1281,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1194 .cpu_user_features = COMMON_USER_BOOKE, 1281 .cpu_user_features = COMMON_USER_BOOKE,
1195 .icache_bsize = 32, 1282 .icache_bsize = 32,
1196 .dcache_bsize = 32, 1283 .dcache_bsize = 32,
1284 .machine_check = machine_check_4xx,
1197 .platform = "ppc440gp", 1285 .platform = "ppc440gp",
1198 }, 1286 },
1199 { /* 440GX Rev. A */ 1287 { /* 440GX Rev. A */
@@ -1204,6 +1292,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
1204 .cpu_user_features = COMMON_USER_BOOKE, 1292 .cpu_user_features = COMMON_USER_BOOKE,
1205 .icache_bsize = 32, 1293 .icache_bsize = 32,
1206 .dcache_bsize = 32, 1294 .dcache_bsize = 32,
1295 .cpu_setup = __setup_cpu_440gx,
1296 .machine_check = machine_check_440A,
1207 .platform = "ppc440", 1297 .platform = "ppc440",
1208 }, 1298 },
1209 { /* 440GX Rev. B */ 1299 { /* 440GX Rev. B */
@@ -1214,6 +1304,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
1214 .cpu_user_features = COMMON_USER_BOOKE, 1304 .cpu_user_features = COMMON_USER_BOOKE,
1215 .icache_bsize = 32, 1305 .icache_bsize = 32,
1216 .dcache_bsize = 32, 1306 .dcache_bsize = 32,
1307 .cpu_setup = __setup_cpu_440gx,
1308 .machine_check = machine_check_440A,
1217 .platform = "ppc440", 1309 .platform = "ppc440",
1218 }, 1310 },
1219 { /* 440GX Rev. C */ 1311 { /* 440GX Rev. C */
@@ -1224,6 +1316,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
1224 .cpu_user_features = COMMON_USER_BOOKE, 1316 .cpu_user_features = COMMON_USER_BOOKE,
1225 .icache_bsize = 32, 1317 .icache_bsize = 32,
1226 .dcache_bsize = 32, 1318 .dcache_bsize = 32,
1319 .cpu_setup = __setup_cpu_440gx,
1320 .machine_check = machine_check_440A,
1227 .platform = "ppc440", 1321 .platform = "ppc440",
1228 }, 1322 },
1229 { /* 440GX Rev. F */ 1323 { /* 440GX Rev. F */
@@ -1234,6 +1328,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
1234 .cpu_user_features = COMMON_USER_BOOKE, 1328 .cpu_user_features = COMMON_USER_BOOKE,
1235 .icache_bsize = 32, 1329 .icache_bsize = 32,
1236 .dcache_bsize = 32, 1330 .dcache_bsize = 32,
1331 .cpu_setup = __setup_cpu_440gx,
1332 .machine_check = machine_check_440A,
1237 .platform = "ppc440", 1333 .platform = "ppc440",
1238 }, 1334 },
1239 { /* 440SP Rev. A */ 1335 { /* 440SP Rev. A */
@@ -1244,6 +1340,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1244 .cpu_user_features = COMMON_USER_BOOKE, 1340 .cpu_user_features = COMMON_USER_BOOKE,
1245 .icache_bsize = 32, 1341 .icache_bsize = 32,
1246 .dcache_bsize = 32, 1342 .dcache_bsize = 32,
1343 .machine_check = machine_check_4xx,
1247 .platform = "ppc440", 1344 .platform = "ppc440",
1248 }, 1345 },
1249 { /* 440SPe Rev. A */ 1346 { /* 440SPe Rev. A */
@@ -1254,6 +1351,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
1254 .cpu_user_features = COMMON_USER_BOOKE, 1351 .cpu_user_features = COMMON_USER_BOOKE,
1255 .icache_bsize = 32, 1352 .icache_bsize = 32,
1256 .dcache_bsize = 32, 1353 .dcache_bsize = 32,
1354 .cpu_setup = __setup_cpu_440spe,
1355 .machine_check = machine_check_440A,
1257 .platform = "ppc440", 1356 .platform = "ppc440",
1258 }, 1357 },
1259 { /* 440SPe Rev. B */ 1358 { /* 440SPe Rev. B */
@@ -1264,6 +1363,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
1264 .cpu_user_features = COMMON_USER_BOOKE, 1363 .cpu_user_features = COMMON_USER_BOOKE,
1265 .icache_bsize = 32, 1364 .icache_bsize = 32,
1266 .dcache_bsize = 32, 1365 .dcache_bsize = 32,
1366 .cpu_setup = __setup_cpu_440spe,
1367 .machine_check = machine_check_440A,
1267 .platform = "ppc440", 1368 .platform = "ppc440",
1268 }, 1369 },
1269#endif /* CONFIG_44x */ 1370#endif /* CONFIG_44x */
@@ -1278,6 +1379,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1278 PPC_FEATURE_HAS_EFP_SINGLE | 1379 PPC_FEATURE_HAS_EFP_SINGLE |
1279 PPC_FEATURE_UNIFIED_CACHE, 1380 PPC_FEATURE_UNIFIED_CACHE,
1280 .dcache_bsize = 32, 1381 .dcache_bsize = 32,
1382 .machine_check = machine_check_e200,
1281 .platform = "ppc5554", 1383 .platform = "ppc5554",
1282 }, 1384 },
1283 { /* e200z6 */ 1385 { /* e200z6 */
@@ -1291,6 +1393,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1291 PPC_FEATURE_HAS_EFP_SINGLE_COMP | 1393 PPC_FEATURE_HAS_EFP_SINGLE_COMP |
1292 PPC_FEATURE_UNIFIED_CACHE, 1394 PPC_FEATURE_UNIFIED_CACHE,
1293 .dcache_bsize = 32, 1395 .dcache_bsize = 32,
1396 .machine_check = machine_check_e200,
1294 .platform = "ppc5554", 1397 .platform = "ppc5554",
1295 }, 1398 },
1296 { /* e500 */ 1399 { /* e500 */
@@ -1307,6 +1410,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1307 .num_pmcs = 4, 1410 .num_pmcs = 4,
1308 .oprofile_cpu_type = "ppc/e500", 1411 .oprofile_cpu_type = "ppc/e500",
1309 .oprofile_type = PPC_OPROFILE_BOOKE, 1412 .oprofile_type = PPC_OPROFILE_BOOKE,
1413 .machine_check = machine_check_e500,
1310 .platform = "ppc8540", 1414 .platform = "ppc8540",
1311 }, 1415 },
1312 { /* e500v2 */ 1416 { /* e500v2 */
@@ -1324,6 +1428,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
1324 .num_pmcs = 4, 1428 .num_pmcs = 4,
1325 .oprofile_cpu_type = "ppc/e500", 1429 .oprofile_cpu_type = "ppc/e500",
1326 .oprofile_type = PPC_OPROFILE_BOOKE, 1430 .oprofile_type = PPC_OPROFILE_BOOKE,
1431 .machine_check = machine_check_e500,
1327 .platform = "ppc8548", 1432 .platform = "ppc8548",
1328 }, 1433 },
1329#endif 1434#endif
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index 56aba84c1f6..ad071a146a8 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -289,11 +289,8 @@ interrupt_base:
289 CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception) 289 CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
290 290
291 /* Machine Check Interrupt */ 291 /* Machine Check Interrupt */
292#ifdef CONFIG_440A
293 MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
294#else
295 CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception) 292 CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
296#endif 293 MCHECK_EXCEPTION(0x0210, MachineCheckA, machine_check_exception)
297 294
298 /* Data Storage Interrupt */ 295 /* Data Storage Interrupt */
299 START_EXCEPTION(DataStorage) 296 START_EXCEPTION(DataStorage)
@@ -674,6 +671,15 @@ finish_tlb_load:
674 */ 671 */
675 672
676/* 673/*
674 * Adjust the machine check IVOR on 440A cores
675 */
676_GLOBAL(__fixup_440A_mcheck)
677 li r3,MachineCheckA@l
678 mtspr SPRN_IVOR1,r3
679 sync
680 blr
681
682/*
677 * extern void giveup_altivec(struct task_struct *prev) 683 * extern void giveup_altivec(struct task_struct *prev)
678 * 684 *
679 * The 44x core does not have an AltiVec unit. 685 * The 44x core does not have an AltiVec unit.
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index 8536e767616..ba9393f8e77 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -166,7 +166,7 @@ label:
166 mfspr r5,SPRN_ESR; \ 166 mfspr r5,SPRN_ESR; \
167 stw r5,_ESR(r11); \ 167 stw r5,_ESR(r11); \
168 addi r3,r1,STACK_FRAME_OVERHEAD; \ 168 addi r3,r1,STACK_FRAME_OVERHEAD; \
169 EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ 169 EXC_XFER_TEMPLATE(hdlr, n+4, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
170 NOCOPY, mcheck_transfer_to_handler, \ 170 NOCOPY, mcheck_transfer_to_handler, \
171 ret_from_mcheck_exc) 171 ret_from_mcheck_exc)
172 172
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index cad64840fce..848a20475db 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -334,18 +334,25 @@ static inline int check_io_access(struct pt_regs *regs)
334#define clear_single_step(regs) ((regs)->msr &= ~MSR_SE) 334#define clear_single_step(regs) ((regs)->msr &= ~MSR_SE)
335#endif 335#endif
336 336
337static int generic_machine_check_exception(struct pt_regs *regs) 337#if defined(CONFIG_4xx)
338int machine_check_4xx(struct pt_regs *regs)
338{ 339{
339 unsigned long reason = get_mc_reason(regs); 340 unsigned long reason = get_mc_reason(regs);
340 341
341#if defined(CONFIG_4xx) && !defined(CONFIG_440A)
342 if (reason & ESR_IMCP) { 342 if (reason & ESR_IMCP) {
343 printk("Instruction"); 343 printk("Instruction");
344 mtspr(SPRN_ESR, reason & ~ESR_IMCP); 344 mtspr(SPRN_ESR, reason & ~ESR_IMCP);
345 } else 345 } else
346 printk("Data"); 346 printk("Data");
347 printk(" machine check in kernel mode.\n"); 347 printk(" machine check in kernel mode.\n");
348#elif defined(CONFIG_440A) 348
349 return 0;
350}
351
352int machine_check_440A(struct pt_regs *regs)
353{
354 unsigned long reason = get_mc_reason(regs);
355
349 printk("Machine check in kernel mode.\n"); 356 printk("Machine check in kernel mode.\n");
350 if (reason & ESR_IMCP){ 357 if (reason & ESR_IMCP){
351 printk("Instruction Synchronous Machine Check exception\n"); 358 printk("Instruction Synchronous Machine Check exception\n");
@@ -375,7 +382,13 @@ static int generic_machine_check_exception(struct pt_regs *regs)
375 /* Clear MCSR */ 382 /* Clear MCSR */
376 mtspr(SPRN_MCSR, mcsr); 383 mtspr(SPRN_MCSR, mcsr);
377 } 384 }
378#elif defined (CONFIG_E500) 385 return 0;
386}
387#elif defined(CONFIG_E500)
388int machine_check_e500(struct pt_regs *regs)
389{
390 unsigned long reason = get_mc_reason(regs);
391
379 printk("Machine check in kernel mode.\n"); 392 printk("Machine check in kernel mode.\n");
380 printk("Caused by (from MCSR=%lx): ", reason); 393 printk("Caused by (from MCSR=%lx): ", reason);
381 394
@@ -403,7 +416,14 @@ static int generic_machine_check_exception(struct pt_regs *regs)
403 printk("Bus - Instruction Parity Error\n"); 416 printk("Bus - Instruction Parity Error\n");
404 if (reason & MCSR_BUS_RPERR) 417 if (reason & MCSR_BUS_RPERR)
405 printk("Bus - Read Parity Error\n"); 418 printk("Bus - Read Parity Error\n");
406#elif defined (CONFIG_E200) 419
420 return 0;
421}
422#elif defined(CONFIG_E200)
423int machine_check_e200(struct pt_regs *regs)
424{
425 unsigned long reason = get_mc_reason(regs);
426
407 printk("Machine check in kernel mode.\n"); 427 printk("Machine check in kernel mode.\n");
408 printk("Caused by (from MCSR=%lx): ", reason); 428 printk("Caused by (from MCSR=%lx): ", reason);
409 429
@@ -421,7 +441,14 @@ static int generic_machine_check_exception(struct pt_regs *regs)
421 printk("Bus - Read Bus Error on data load\n"); 441 printk("Bus - Read Bus Error on data load\n");
422 if (reason & MCSR_BUS_WRERR) 442 if (reason & MCSR_BUS_WRERR)
423 printk("Bus - Write Bus Error on buffered store or cache line push\n"); 443 printk("Bus - Write Bus Error on buffered store or cache line push\n");
424#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */ 444
445 return 0;
446}
447#else
448int machine_check_generic(struct pt_regs *regs)
449{
450 unsigned long reason = get_mc_reason(regs);
451
425 printk("Machine check in kernel mode.\n"); 452 printk("Machine check in kernel mode.\n");
426 printk("Caused by (from SRR1=%lx): ", reason); 453 printk("Caused by (from SRR1=%lx): ", reason);
427 switch (reason & 0x601F0000) { 454 switch (reason & 0x601F0000) {
@@ -451,22 +478,26 @@ static int generic_machine_check_exception(struct pt_regs *regs)
451 default: 478 default:
452 printk("Unknown values in msr\n"); 479 printk("Unknown values in msr\n");
453 } 480 }
454#endif /* CONFIG_4xx */
455
456 return 0; 481 return 0;
457} 482}
483#endif /* everything else */
458 484
459void machine_check_exception(struct pt_regs *regs) 485void machine_check_exception(struct pt_regs *regs)
460{ 486{
461 int recover = 0; 487 int recover = 0;
462 488
463 /* See if any machine dependent calls */ 489 /* See if any machine dependent calls. In theory, we would want
490 * to call the CPU first, and call the ppc_md. one if the CPU
491 * one returns a positive number. However there is existing code
492 * that assumes the board gets a first chance, so let's keep it
493 * that way for now and fix things later. --BenH.
494 */
464 if (ppc_md.machine_check_exception) 495 if (ppc_md.machine_check_exception)
465 recover = ppc_md.machine_check_exception(regs); 496 recover = ppc_md.machine_check_exception(regs);
466 else 497 else if (cur_cpu_spec->machine_check)
467 recover = generic_machine_check_exception(regs); 498 recover = cur_cpu_spec->machine_check(regs);
468 499
469 if (recover) 500 if (recover > 0)
470 return; 501 return;
471 502
472 if (user_mode(regs)) { 503 if (user_mode(regs)) {
@@ -476,7 +507,12 @@ void machine_check_exception(struct pt_regs *regs)
476 } 507 }
477 508
478#if defined(CONFIG_8xx) && defined(CONFIG_PCI) 509#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
479 /* the qspan pci read routines can cause machine checks -- Cort */ 510 /* the qspan pci read routines can cause machine checks -- Cort
511 *
512 * yuck !!! that totally needs to go away ! There are better ways
513 * to deal with that than having a wart in the mcheck handler.
514 * -- BenH
515 */
480 bad_page_fault(regs, regs->dar, SIGBUS); 516 bad_page_fault(regs, regs->dar, SIGBUS);
481 return; 517 return;
482#endif 518#endif
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index 8390cc16413..905d8362145 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -62,11 +62,6 @@ config 440GX
62config 440SP 62config 440SP
63 bool 63 bool
64 64
65config 440A
66 bool
67 depends on 440GX || 440EPX
68 default y
69
70# 44x errata/workaround config symbols, selected by the CPU models above 65# 44x errata/workaround config symbols, selected by the CPU models above
71config IBM440EP_ERR42 66config IBM440EP_ERR42
72 bool 67 bool
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index c78568905c3..25a1085fbd0 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -231,39 +231,25 @@ platform_machine_check(struct pt_regs *regs)
231{ 231{
232} 232}
233 233
234void machine_check_exception(struct pt_regs *regs) 234#if defined(CONFIG_4xx)
235int machine_check_4xx(struct pt_regs *regs)
235{ 236{
236 unsigned long reason = get_mc_reason(regs); 237 unsigned long reason = get_mc_reason(regs);
237 238
238 if (user_mode(regs)) {
239 regs->msr |= MSR_RI;
240 _exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
241 return;
242 }
243
244#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
245 /* the qspan pci read routines can cause machine checks -- Cort */
246 bad_page_fault(regs, regs->dar, SIGBUS);
247 return;
248#endif
249
250 if (debugger_fault_handler) {
251 debugger_fault_handler(regs);
252 regs->msr |= MSR_RI;
253 return;
254 }
255
256 if (check_io_access(regs))
257 return;
258
259#if defined(CONFIG_4xx) && !defined(CONFIG_440A)
260 if (reason & ESR_IMCP) { 239 if (reason & ESR_IMCP) {
261 printk("Instruction"); 240 printk("Instruction");
262 mtspr(SPRN_ESR, reason & ~ESR_IMCP); 241 mtspr(SPRN_ESR, reason & ~ESR_IMCP);
263 } else 242 } else
264 printk("Data"); 243 printk("Data");
265 printk(" machine check in kernel mode.\n"); 244 printk(" machine check in kernel mode.\n");
266#elif defined(CONFIG_440A) 245
246 return 0;
247}
248
249int machine_check_440A(struct pt_regs *regs)
250{
251 unsigned long reason = get_mc_reason(regs);
252
267 printk("Machine check in kernel mode.\n"); 253 printk("Machine check in kernel mode.\n");
268 if (reason & ESR_IMCP){ 254 if (reason & ESR_IMCP){
269 printk("Instruction Synchronous Machine Check exception\n"); 255 printk("Instruction Synchronous Machine Check exception\n");
@@ -293,7 +279,13 @@ void machine_check_exception(struct pt_regs *regs)
293 /* Clear MCSR */ 279 /* Clear MCSR */
294 mtspr(SPRN_MCSR, mcsr); 280 mtspr(SPRN_MCSR, mcsr);
295 } 281 }
296#elif defined (CONFIG_E500) 282 return 0;
283}
284#elif defined(CONFIG_E500)
285int machine_check_e500(struct pt_regs *regs)
286{
287 unsigned long reason = get_mc_reason(regs);
288
297 printk("Machine check in kernel mode.\n"); 289 printk("Machine check in kernel mode.\n");
298 printk("Caused by (from MCSR=%lx): ", reason); 290 printk("Caused by (from MCSR=%lx): ", reason);
299 291
@@ -305,8 +297,6 @@ void machine_check_exception(struct pt_regs *regs)
305 printk("Data Cache Push Parity Error\n"); 297 printk("Data Cache Push Parity Error\n");
306 if (reason & MCSR_DCPERR) 298 if (reason & MCSR_DCPERR)
307 printk("Data Cache Parity Error\n"); 299 printk("Data Cache Parity Error\n");
308 if (reason & MCSR_GL_CI)
309 printk("Guarded Load or Cache-Inhibited stwcx.\n");
310 if (reason & MCSR_BUS_IAERR) 300 if (reason & MCSR_BUS_IAERR)
311 printk("Bus - Instruction Address Error\n"); 301 printk("Bus - Instruction Address Error\n");
312 if (reason & MCSR_BUS_RAERR) 302 if (reason & MCSR_BUS_RAERR)
@@ -318,12 +308,19 @@ void machine_check_exception(struct pt_regs *regs)
318 if (reason & MCSR_BUS_RBERR) 308 if (reason & MCSR_BUS_RBERR)
319 printk("Bus - Read Data Bus Error\n"); 309 printk("Bus - Read Data Bus Error\n");
320 if (reason & MCSR_BUS_WBERR) 310 if (reason & MCSR_BUS_WBERR)
321 printk("Bus - Write Data Bus Error\n"); 311 printk("Bus - Read Data Bus Error\n");
322 if (reason & MCSR_BUS_IPERR) 312 if (reason & MCSR_BUS_IPERR)
323 printk("Bus - Instruction Parity Error\n"); 313 printk("Bus - Instruction Parity Error\n");
324 if (reason & MCSR_BUS_RPERR) 314 if (reason & MCSR_BUS_RPERR)
325 printk("Bus - Read Parity Error\n"); 315 printk("Bus - Read Parity Error\n");
326#elif defined (CONFIG_E200) 316
317 return 0;
318}
319#elif defined(CONFIG_E200)
320int machine_check_e200(struct pt_regs *regs)
321{
322 unsigned long reason = get_mc_reason(regs);
323
327 printk("Machine check in kernel mode.\n"); 324 printk("Machine check in kernel mode.\n");
328 printk("Caused by (from MCSR=%lx): ", reason); 325 printk("Caused by (from MCSR=%lx): ", reason);
329 326
@@ -341,7 +338,14 @@ void machine_check_exception(struct pt_regs *regs)
341 printk("Bus - Read Bus Error on data load\n"); 338 printk("Bus - Read Bus Error on data load\n");
342 if (reason & MCSR_BUS_WRERR) 339 if (reason & MCSR_BUS_WRERR)
343 printk("Bus - Write Bus Error on buffered store or cache line push\n"); 340 printk("Bus - Write Bus Error on buffered store or cache line push\n");
344#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */ 341
342 return 0;
343}
344#else
345int machine_check_generic(struct pt_regs *regs)
346{
347 unsigned long reason = get_mc_reason(regs);
348
345 printk("Machine check in kernel mode.\n"); 349 printk("Machine check in kernel mode.\n");
346 printk("Caused by (from SRR1=%lx): ", reason); 350 printk("Caused by (from SRR1=%lx): ", reason);
347 switch (reason & 0x601F0000) { 351 switch (reason & 0x601F0000) {
@@ -371,7 +375,39 @@ void machine_check_exception(struct pt_regs *regs)
371 default: 375 default:
372 printk("Unknown values in msr\n"); 376 printk("Unknown values in msr\n");
373 } 377 }
374#endif /* CONFIG_4xx */ 378 return 0;
379}
380#endif /* everything else */
381
382void machine_check_exception(struct pt_regs *regs)
383{
384 int recover = 0;
385
386 if (cur_cpu_spec->machine_check)
387 recover = cur_cpu_spec->machine_check(regs);
388 if (recover > 0)
389 return;
390
391 if (user_mode(regs)) {
392 regs->msr |= MSR_RI;
393 _exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
394 return;
395 }
396
397#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
398 /* the qspan pci read routines can cause machine checks -- Cort */
399 bad_page_fault(regs, regs->dar, SIGBUS);
400 return;
401#endif
402
403 if (debugger_fault_handler) {
404 debugger_fault_handler(regs);
405 regs->msr |= MSR_RI;
406 return;
407 }
408
409 if (check_io_access(regs))
410 return;
375 411
376 /* 412 /*
377 * Optional platform-provided routine to print out 413 * Optional platform-provided routine to print out
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
index 4525c784dfd..528ef183c22 100644
--- a/include/asm-powerpc/cputable.h
+++ b/include/asm-powerpc/cputable.h
@@ -57,6 +57,14 @@ enum powerpc_pmc_type {
57 PPC_PMC_PA6T = 2, 57 PPC_PMC_PA6T = 2,
58}; 58};
59 59
60struct pt_regs;
61
62extern int machine_check_generic(struct pt_regs *regs);
63extern int machine_check_4xx(struct pt_regs *regs);
64extern int machine_check_440A(struct pt_regs *regs);
65extern int machine_check_e500(struct pt_regs *regs);
66extern int machine_check_e200(struct pt_regs *regs);
67
60/* NOTE WELL: Update identify_cpu() if fields are added or removed! */ 68/* NOTE WELL: Update identify_cpu() if fields are added or removed! */
61struct cpu_spec { 69struct cpu_spec {
62 /* CPU is matched via (PVR & pvr_mask) == pvr_value */ 70 /* CPU is matched via (PVR & pvr_mask) == pvr_value */
@@ -97,6 +105,11 @@ struct cpu_spec {
97 105
98 /* Name of processor class, for the ELF AT_PLATFORM entry */ 106 /* Name of processor class, for the ELF AT_PLATFORM entry */
99 char *platform; 107 char *platform;
108
109 /* Processor specific machine check handling. Return negative
110 * if the error is fatal, 1 if it was fully recovered and 0 to
111 * pass up (not CPU originated) */
112 int (*machine_check)(struct pt_regs *regs);
100}; 113};
101 114
102extern struct cpu_spec *cur_cpu_spec; 115extern struct cpu_spec *cur_cpu_spec;
diff --git a/include/asm-powerpc/ptrace.h b/include/asm-powerpc/ptrace.h
index 13fccc5a411..c662287efd8 100644
--- a/include/asm-powerpc/ptrace.h
+++ b/include/asm-powerpc/ptrace.h
@@ -106,7 +106,8 @@ extern int ptrace_put_reg(struct task_struct *task, int regno,
106 */ 106 */
107#define FULL_REGS(regs) (((regs)->trap & 1) == 0) 107#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
108#ifndef __powerpc64__ 108#ifndef __powerpc64__
109#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) == 0) 109#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0)
110#define IS_MCHECK_EXC(regs) (((regs)->trap & 4) != 0)
110#endif /* ! __powerpc64__ */ 111#endif /* ! __powerpc64__ */
111#define TRAP(regs) ((regs)->trap & ~0xF) 112#define TRAP(regs) ((regs)->trap & ~0xF)
112#ifdef __powerpc64__ 113#ifdef __powerpc64__
diff --git a/include/asm-powerpc/reg_booke.h b/include/asm-powerpc/reg_booke.h
index d3e8dd0fc73..0405ef47981 100644
--- a/include/asm-powerpc/reg_booke.h
+++ b/include/asm-powerpc/reg_booke.h
@@ -218,7 +218,6 @@
218#define CCR1_TCS 0x00000080 /* Timer Clock Select */ 218#define CCR1_TCS 0x00000080 /* Timer Clock Select */
219 219
220/* Bit definitions for the MCSR. */ 220/* Bit definitions for the MCSR. */
221#ifdef CONFIG_440A
222#define MCSR_MCS 0x80000000 /* Machine Check Summary */ 221#define MCSR_MCS 0x80000000 /* Machine Check Summary */
223#define MCSR_IB 0x40000000 /* Instruction PLB Error */ 222#define MCSR_IB 0x40000000 /* Instruction PLB Error */
224#define MCSR_DRB 0x20000000 /* Data Read PLB Error */ 223#define MCSR_DRB 0x20000000 /* Data Read PLB Error */
@@ -228,7 +227,7 @@
228#define MCSR_DCSP 0x02000000 /* D-Cache Search Parity Error */ 227#define MCSR_DCSP 0x02000000 /* D-Cache Search Parity Error */
229#define MCSR_DCFP 0x01000000 /* D-Cache Flush Parity Error */ 228#define MCSR_DCFP 0x01000000 /* D-Cache Flush Parity Error */
230#define MCSR_IMPE 0x00800000 /* Imprecise Machine Check Exception */ 229#define MCSR_IMPE 0x00800000 /* Imprecise Machine Check Exception */
231#endif 230
232#ifdef CONFIG_E500 231#ifdef CONFIG_E500
233#define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */ 232#define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */
234#define MCSR_ICPERR 0x40000000UL /* I-Cache Parity Error */ 233#define MCSR_ICPERR 0x40000000UL /* I-Cache Parity Error */
diff --git a/include/asm-ppc/reg_booke.h b/include/asm-ppc/reg_booke.h
index 4cad45a055d..2f1a2afcfc2 100644
--- a/include/asm-ppc/reg_booke.h
+++ b/include/asm-ppc/reg_booke.h
@@ -207,7 +207,7 @@
207#define CCR1_TCS 0x00000080 /* Timer Clock Select */ 207#define CCR1_TCS 0x00000080 /* Timer Clock Select */
208 208
209/* Bit definitions for the MCSR. */ 209/* Bit definitions for the MCSR. */
210#ifdef CONFIG_440A 210#ifdef CONFIG_4xx
211#define MCSR_MCS 0x80000000 /* Machine Check Summary */ 211#define MCSR_MCS 0x80000000 /* Machine Check Summary */
212#define MCSR_IB 0x40000000 /* Instruction PLB Error */ 212#define MCSR_IB 0x40000000 /* Instruction PLB Error */
213#define MCSR_DRB 0x20000000 /* Data Read PLB Error */ 213#define MCSR_DRB 0x20000000 /* Data Read PLB Error */