Commit 47c0bd1a authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Josh Boyer

[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: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarJosh Boyer <jwboyer@linux.vnet.ibm.com>
parent c2a7dcad
...@@ -23,11 +23,20 @@ _GLOBAL(__setup_cpu_440epx) ...@@ -23,11 +23,20 @@ _GLOBAL(__setup_cpu_440epx)
mflr r4 mflr r4
bl __init_fpu_44x bl __init_fpu_44x
bl __plb_disable_wrp bl __plb_disable_wrp
bl __fixup_440A_mcheck
mtlr r4 mtlr r4
blr blr
_GLOBAL(__setup_cpu_440grx) _GLOBAL(__setup_cpu_440grx)
b __plb_disable_wrp b __plb_disable_wrp
_GLOBAL(__setup_cpu_440gx)
_GLOBAL(__setup_cpu_440spe)
b __fixup_440A_mcheck
/* Temporary fixup for arch/ppc until we kill the whole thing */
#ifndef CONFIG_PPC_MERGE
_GLOBAL(__fixup_440A_mcheck)
blr
#endif
/* enable APU between CPU and FPU */ /* enable APU between CPU and FPU */
_GLOBAL(__init_fpu_44x) _GLOBAL(__init_fpu_44x)
......
...@@ -33,7 +33,9 @@ EXPORT_SYMBOL(cur_cpu_spec); ...@@ -33,7 +33,9 @@ EXPORT_SYMBOL(cur_cpu_spec);
#ifdef CONFIG_PPC32 #ifdef CONFIG_PPC32
extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_440gx(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_440grx(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_440grx(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_440spe(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
...@@ -85,6 +87,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -85,6 +87,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/power3", .oprofile_cpu_type = "ppc64/power3",
.oprofile_type = PPC_OPROFILE_RS64, .oprofile_type = PPC_OPROFILE_RS64,
.machine_check = machine_check_generic,
.platform = "power3", .platform = "power3",
}, },
{ /* Power3+ */ { /* Power3+ */
...@@ -99,6 +102,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -99,6 +102,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/power3", .oprofile_cpu_type = "ppc64/power3",
.oprofile_type = PPC_OPROFILE_RS64, .oprofile_type = PPC_OPROFILE_RS64,
.machine_check = machine_check_generic,
.platform = "power3", .platform = "power3",
}, },
{ /* Northstar */ { /* Northstar */
...@@ -113,6 +117,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -113,6 +117,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/rs64", .oprofile_cpu_type = "ppc64/rs64",
.oprofile_type = PPC_OPROFILE_RS64, .oprofile_type = PPC_OPROFILE_RS64,
.machine_check = machine_check_generic,
.platform = "rs64", .platform = "rs64",
}, },
{ /* Pulsar */ { /* Pulsar */
...@@ -127,6 +132,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -127,6 +132,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/rs64", .oprofile_cpu_type = "ppc64/rs64",
.oprofile_type = PPC_OPROFILE_RS64, .oprofile_type = PPC_OPROFILE_RS64,
.machine_check = machine_check_generic,
.platform = "rs64", .platform = "rs64",
}, },
{ /* I-star */ { /* I-star */
...@@ -141,6 +147,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -141,6 +147,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/rs64", .oprofile_cpu_type = "ppc64/rs64",
.oprofile_type = PPC_OPROFILE_RS64, .oprofile_type = PPC_OPROFILE_RS64,
.machine_check = machine_check_generic,
.platform = "rs64", .platform = "rs64",
}, },
{ /* S-star */ { /* S-star */
...@@ -155,6 +162,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -155,6 +162,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/rs64", .oprofile_cpu_type = "ppc64/rs64",
.oprofile_type = PPC_OPROFILE_RS64, .oprofile_type = PPC_OPROFILE_RS64,
.machine_check = machine_check_generic,
.platform = "rs64", .platform = "rs64",
}, },
{ /* Power4 */ { /* Power4 */
...@@ -169,6 +177,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -169,6 +177,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/power4", .oprofile_cpu_type = "ppc64/power4",
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.machine_check = machine_check_generic,
.platform = "power4", .platform = "power4",
}, },
{ /* Power4+ */ { /* Power4+ */
...@@ -183,6 +192,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -183,6 +192,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/power4", .oprofile_cpu_type = "ppc64/power4",
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.machine_check = machine_check_generic,
.platform = "power4", .platform = "power4",
}, },
{ /* PPC970 */ { /* PPC970 */
...@@ -200,6 +210,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -200,6 +210,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_restore = __restore_cpu_ppc970, .cpu_restore = __restore_cpu_ppc970,
.oprofile_cpu_type = "ppc64/970", .oprofile_cpu_type = "ppc64/970",
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.machine_check = machine_check_generic,
.platform = "ppc970", .platform = "ppc970",
}, },
{ /* PPC970FX */ { /* PPC970FX */
...@@ -217,6 +228,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -217,6 +228,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_restore = __restore_cpu_ppc970, .cpu_restore = __restore_cpu_ppc970,
.oprofile_cpu_type = "ppc64/970", .oprofile_cpu_type = "ppc64/970",
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.machine_check = machine_check_generic,
.platform = "ppc970", .platform = "ppc970",
}, },
{ /* PPC970MP DD1.0 - no DEEPNAP, use regular 970 init */ { /* PPC970MP DD1.0 - no DEEPNAP, use regular 970 init */
...@@ -234,6 +246,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -234,6 +246,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_restore = __restore_cpu_ppc970, .cpu_restore = __restore_cpu_ppc970,
.oprofile_cpu_type = "ppc64/970MP", .oprofile_cpu_type = "ppc64/970MP",
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.machine_check = machine_check_generic,
.platform = "ppc970", .platform = "ppc970",
}, },
{ /* PPC970MP */ { /* PPC970MP */
...@@ -251,6 +264,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -251,6 +264,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_restore = __restore_cpu_ppc970, .cpu_restore = __restore_cpu_ppc970,
.oprofile_cpu_type = "ppc64/970MP", .oprofile_cpu_type = "ppc64/970MP",
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.machine_check = machine_check_generic,
.platform = "ppc970", .platform = "ppc970",
}, },
{ /* PPC970GX */ { /* PPC970GX */
...@@ -267,6 +281,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -267,6 +281,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_ppc970, .cpu_setup = __setup_cpu_ppc970,
.oprofile_cpu_type = "ppc64/970", .oprofile_cpu_type = "ppc64/970",
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.machine_check = machine_check_generic,
.platform = "ppc970", .platform = "ppc970",
}, },
{ /* Power5 GR */ { /* Power5 GR */
...@@ -286,6 +301,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -286,6 +301,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
*/ */
.oprofile_mmcra_sihv = MMCRA_SIHV, .oprofile_mmcra_sihv = MMCRA_SIHV,
.oprofile_mmcra_sipr = MMCRA_SIPR, .oprofile_mmcra_sipr = MMCRA_SIPR,
.machine_check = machine_check_generic,
.platform = "power5", .platform = "power5",
}, },
{ /* Power5++ */ { /* Power5++ */
...@@ -301,6 +317,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -301,6 +317,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.oprofile_mmcra_sihv = MMCRA_SIHV, .oprofile_mmcra_sihv = MMCRA_SIHV,
.oprofile_mmcra_sipr = MMCRA_SIPR, .oprofile_mmcra_sipr = MMCRA_SIPR,
.machine_check = machine_check_generic,
.platform = "power5+", .platform = "power5+",
}, },
{ /* Power5 GS */ { /* Power5 GS */
...@@ -317,6 +334,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -317,6 +334,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.oprofile_type = PPC_OPROFILE_POWER4, .oprofile_type = PPC_OPROFILE_POWER4,
.oprofile_mmcra_sihv = MMCRA_SIHV, .oprofile_mmcra_sihv = MMCRA_SIHV,
.oprofile_mmcra_sipr = MMCRA_SIPR, .oprofile_mmcra_sipr = MMCRA_SIPR,
.machine_check = machine_check_generic,
.platform = "power5+", .platform = "power5+",
}, },
{ /* POWER6 in P5+ mode; 2.04-compliant processor */ { /* POWER6 in P5+ mode; 2.04-compliant processor */
...@@ -327,6 +345,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -327,6 +345,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_POWER5_PLUS, .cpu_user_features = COMMON_USER_POWER5_PLUS,
.icache_bsize = 128, .icache_bsize = 128,
.dcache_bsize = 128, .dcache_bsize = 128,
.machine_check = machine_check_generic,
.platform = "power5+", .platform = "power5+",
}, },
{ /* Power6 */ { /* Power6 */
...@@ -346,6 +365,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -346,6 +365,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.oprofile_mmcra_sipr = POWER6_MMCRA_SIPR, .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR,
.oprofile_mmcra_clear = POWER6_MMCRA_THRM | .oprofile_mmcra_clear = POWER6_MMCRA_THRM |
POWER6_MMCRA_OTHER, POWER6_MMCRA_OTHER,
.machine_check = machine_check_generic,
.platform = "power6x", .platform = "power6x",
}, },
{ /* 2.05-compliant processor, i.e. Power6 "architected" mode */ { /* 2.05-compliant processor, i.e. Power6 "architected" mode */
...@@ -356,6 +376,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -356,6 +376,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_POWER6, .cpu_user_features = COMMON_USER_POWER6,
.icache_bsize = 128, .icache_bsize = 128,
.dcache_bsize = 128, .dcache_bsize = 128,
.machine_check = machine_check_generic,
.platform = "power6", .platform = "power6",
}, },
{ /* Cell Broadband Engine */ { /* Cell Broadband Engine */
...@@ -372,6 +393,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -372,6 +393,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/cell-be", .oprofile_cpu_type = "ppc64/cell-be",
.oprofile_type = PPC_OPROFILE_CELL, .oprofile_type = PPC_OPROFILE_CELL,
.machine_check = machine_check_generic,
.platform = "ppc-cell-be", .platform = "ppc-cell-be",
}, },
{ /* PA Semi PA6T */ { /* PA Semi PA6T */
...@@ -388,6 +410,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -388,6 +410,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_restore = __restore_cpu_pa6t, .cpu_restore = __restore_cpu_pa6t,
.oprofile_cpu_type = "ppc64/pa6t", .oprofile_cpu_type = "ppc64/pa6t",
.oprofile_type = PPC_OPROFILE_PA6T, .oprofile_type = PPC_OPROFILE_PA6T,
.machine_check = machine_check_generic,
.platform = "pa6t", .platform = "pa6t",
}, },
{ /* default match */ { /* default match */
...@@ -400,6 +423,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -400,6 +423,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 128, .dcache_bsize = 128,
.num_pmcs = 6, .num_pmcs = 6,
.pmc_type = PPC_PMC_IBM, .pmc_type = PPC_PMC_IBM,
.machine_check = machine_check_generic,
.platform = "power4", .platform = "power4",
} }
#endif /* CONFIG_PPC64 */ #endif /* CONFIG_PPC64 */
...@@ -414,6 +438,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -414,6 +438,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB, PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_generic,
.platform = "ppc601", .platform = "ppc601",
}, },
{ /* 603 */ { /* 603 */
...@@ -425,6 +450,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -425,6 +450,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_603, .cpu_setup = __setup_cpu_603,
.machine_check = machine_check_generic,
.platform = "ppc603", .platform = "ppc603",
}, },
{ /* 603e */ { /* 603e */
...@@ -436,6 +462,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -436,6 +462,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_603, .cpu_setup = __setup_cpu_603,
.machine_check = machine_check_generic,
.platform = "ppc603", .platform = "ppc603",
}, },
{ /* 603ev */ { /* 603ev */
...@@ -447,6 +474,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -447,6 +474,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_603, .cpu_setup = __setup_cpu_603,
.machine_check = machine_check_generic,
.platform = "ppc603", .platform = "ppc603",
}, },
{ /* 604 */ { /* 604 */
...@@ -459,6 +487,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -459,6 +487,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 2, .num_pmcs = 2,
.cpu_setup = __setup_cpu_604, .cpu_setup = __setup_cpu_604,
.machine_check = machine_check_generic,
.platform = "ppc604", .platform = "ppc604",
}, },
{ /* 604e */ { /* 604e */
...@@ -471,6 +500,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -471,6 +500,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_604, .cpu_setup = __setup_cpu_604,
.machine_check = machine_check_generic,
.platform = "ppc604", .platform = "ppc604",
}, },
{ /* 604r */ { /* 604r */
...@@ -483,6 +513,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -483,6 +513,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_604, .cpu_setup = __setup_cpu_604,
.machine_check = machine_check_generic,
.platform = "ppc604", .platform = "ppc604",
}, },
{ /* 604ev */ { /* 604ev */
...@@ -495,6 +526,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -495,6 +526,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_604, .cpu_setup = __setup_cpu_604,
.machine_check = machine_check_generic,
.platform = "ppc604", .platform = "ppc604",
}, },
{ /* 740/750 (0x4202, don't support TAU ?) */ { /* 740/750 (0x4202, don't support TAU ?) */
...@@ -507,6 +539,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -507,6 +539,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_750, .cpu_setup = __setup_cpu_750,
.machine_check = machine_check_generic,
.platform = "ppc750", .platform = "ppc750",
}, },
{ /* 750CX (80100 and 8010x?) */ { /* 750CX (80100 and 8010x?) */
...@@ -519,6 +552,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -519,6 +552,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_750cx, .cpu_setup = __setup_cpu_750cx,
.machine_check = machine_check_generic,
.platform = "ppc750", .platform = "ppc750",
}, },
{ /* 750CX (82201 and 82202) */ { /* 750CX (82201 and 82202) */
...@@ -531,6 +565,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -531,6 +565,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_750cx, .cpu_setup = __setup_cpu_750cx,
.machine_check = machine_check_generic,
.platform = "ppc750", .platform = "ppc750",
}, },
{ /* 750CXe (82214) */ { /* 750CXe (82214) */
...@@ -543,6 +578,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -543,6 +578,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_750cx, .cpu_setup = __setup_cpu_750cx,
.machine_check = machine_check_generic,
.platform = "ppc750", .platform = "ppc750",
}, },
{ /* 750CXe "Gekko" (83214) */ { /* 750CXe "Gekko" (83214) */
...@@ -555,6 +591,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -555,6 +591,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_750cx, .cpu_setup = __setup_cpu_750cx,
.machine_check = machine_check_generic,
.platform = "ppc750", .platform = "ppc750",
}, },
{ /* 750CL */ { /* 750CL */
...@@ -567,6 +604,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -567,6 +604,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_750, .cpu_setup = __setup_cpu_750,
.machine_check = machine_check_generic,
.platform = "ppc750", .platform = "ppc750",
}, },
{ /* 745/755 */ { /* 745/755 */
...@@ -579,6 +617,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -579,6 +617,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_750, .cpu_setup = __setup_cpu_750,
.machine_check = machine_check_generic,
.platform = "ppc750", .platform = "ppc750",
}, },
{ /* 750FX rev 1.x */ { /* 750FX rev 1.x */
...@@ -591,6 +630,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -591,6 +630,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_750, .cpu_setup = __setup_cpu_750,
.machine_check = machine_check_generic,
.platform = "ppc750", .platform = "ppc750",
}, },
{ /* 750FX rev 2.0 must disable HID0[DPM] */ { /* 750FX rev 2.0 must disable HID0[DPM] */
...@@ -603,6 +643,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -603,6 +643,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_750, .cpu_setup = __setup_cpu_750,
.machine_check = machine_check_generic,
.platform = "ppc750", .platform = "ppc750",
}, },
{ /* 750FX (All revs except 2.0) */ { /* 750FX (All revs except 2.0) */
...@@ -615,6 +656,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -615,6 +656,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_750fx, .cpu_setup = __setup_cpu_750fx,
.machine_check = machine_check_generic,
.platform = "ppc750", .platform = "ppc750",
}, },
{ /* 750GX */ { /* 750GX */
...@@ -627,6 +669,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -627,6 +669,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_750fx, .cpu_setup = __setup_cpu_750fx,
.machine_check = machine_check_generic,
.platform = "ppc750", .platform = "ppc750",
}, },
{ /* 740/750 (L2CR bit need fixup for 740) */ { /* 740/750 (L2CR bit need fixup for 740) */
...@@ -639,6 +682,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -639,6 +682,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_750, .cpu_setup = __setup_cpu_750,
.machine_check = machine_check_generic,
.platform = "ppc750", .platform = "ppc750",
}, },
{ /* 7400 rev 1.1 ? (no TAU) */ { /* 7400 rev 1.1 ? (no TAU) */
...@@ -652,6 +696,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -652,6 +696,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_7400, .cpu_setup = __setup_cpu_7400,
.machine_check = machine_check_generic,
.platform = "ppc7400", .platform = "ppc7400",
}, },
{ /* 7400 */ { /* 7400 */
...@@ -665,6 +710,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -665,6 +710,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_7400, .cpu_setup = __setup_cpu_7400,
.machine_check = machine_check_generic,
.platform = "ppc7400", .platform = "ppc7400",
}, },
{ /* 7410 */ { /* 7410 */
...@@ -678,6 +724,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -678,6 +724,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.dcache_bsize = 32, .dcache_bsize = 32,
.num_pmcs = 4, .num_pmcs = 4,
.cpu_setup = __setup_cpu_7410, .cpu_setup = __setup_cpu_7410,
.machine_check = machine_check_generic,
.platform = "ppc7400", .platform = "ppc7400",
}, },
{ /* 7450 2.0 - no doze/nap */ { /* 7450 2.0 - no doze/nap */
...@@ -693,6 +740,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -693,6 +740,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_745x, .cpu_setup = __setup_cpu_745x,
.oprofile_cpu_type = "ppc/7450", .oprofile_cpu_type = "ppc/7450",
.oprofile_type = PPC_OPROFILE_G4, .oprofile_type = PPC_OPROFILE_G4,
.machine_check = machine_check_generic,
.platform = "ppc7450", .platform = "ppc7450",
}, },
{ /* 7450 2.1 */ { /* 7450 2.1 */
...@@ -708,6 +756,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -708,6 +756,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_745x, .cpu_setup = __setup_cpu_745x,
.oprofile_cpu_type = "ppc/7450", .oprofile_cpu_type = "ppc/7450",
.oprofile_type = PPC_OPROFILE_G4, .oprofile_type = PPC_OPROFILE_G4,
.machine_check = machine_check_generic,
.platform = "ppc7450", .platform = "ppc7450",
}, },
{ /* 7450 2.3 and newer */ { /* 7450 2.3 and newer */
...@@ -723,6 +772,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -723,6 +772,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_745x, .cpu_setup = __setup_cpu_745x,
.oprofile_cpu_type = "ppc/7450", .oprofile_cpu_type = "ppc/7450",
.oprofile_type = PPC_OPROFILE_G4, .oprofile_type = PPC_OPROFILE_G4,
.machine_check = machine_check_generic,
.platform = "ppc7450", .platform = "ppc7450",
}, },
{ /* 7455 rev 1.x */ { /* 7455 rev 1.x */
...@@ -738,6 +788,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -738,6 +788,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_745x, .cpu_setup = __setup_cpu_745x,
.oprofile_cpu_type = "ppc/7450", .oprofile_cpu_type = "ppc/7450",
.oprofile_type = PPC_OPROFILE_G4, .oprofile_type = PPC_OPROFILE_G4,
.machine_check = machine_check_generic,
.platform = "ppc7450", .platform = "ppc7450",
}, },
{ /* 7455 rev 2.0 */ { /* 7455 rev 2.0 */
...@@ -753,6 +804,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -753,6 +804,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_745x, .cpu_setup = __setup_cpu_745x,
.oprofile_cpu_type = "ppc/7450", .oprofile_cpu_type = "ppc/7450",
.oprofile_type = PPC_OPROFILE_G4, .oprofile_type = PPC_OPROFILE_G4,
.machine_check = machine_check_generic,
.platform = "ppc7450", .platform = "ppc7450",
}, },
{ /* 7455 others */ { /* 7455 others */
...@@ -768,6 +820,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -768,6 +820,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_745x, .cpu_setup = __setup_cpu_745x,
.oprofile_cpu_type = "ppc/7450", .oprofile_cpu_type = "ppc/7450",
.oprofile_type = PPC_OPROFILE_G4, .oprofile_type = PPC_OPROFILE_G4,
.machine_check = machine_check_generic,
.platform = "ppc7450", .platform = "ppc7450",
}, },
{ /* 7447/7457 Rev 1.0 */ { /* 7447/7457 Rev 1.0 */
...@@ -783,6 +836,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -783,6 +836,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_745x, .cpu_setup = __setup_cpu_745x,
.oprofile_cpu_type = "ppc/7450", .oprofile_cpu_type = "ppc/7450",
.oprofile_type = PPC_OPROFILE_G4, .oprofile_type = PPC_OPROFILE_G4,
.machine_check = machine_check_generic,
.platform = "ppc7450", .platform = "ppc7450",
}, },
{ /* 7447/7457 Rev 1.1 */ { /* 7447/7457 Rev 1.1 */
...@@ -798,6 +852,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -798,6 +852,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_745x, .cpu_setup = __setup_cpu_745x,
.oprofile_cpu_type = "ppc/7450", .oprofile_cpu_type = "ppc/7450",
.oprofile_type = PPC_OPROFILE_G4, .oprofile_type = PPC_OPROFILE_G4,
.machine_check = machine_check_generic,
.platform = "ppc7450", .platform = "ppc7450",
}, },
{ /* 7447/7457 Rev 1.2 and later */ { /* 7447/7457 Rev 1.2 and later */
...@@ -812,6 +867,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -812,6 +867,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_745x, .cpu_setup = __setup_cpu_745x,
.oprofile_cpu_type = "ppc/7450", .oprofile_cpu_type = "ppc/7450",
.oprofile_type = PPC_OPROFILE_G4, .oprofile_type = PPC_OPROFILE_G4,
.machine_check = machine_check_generic,
.platform = "ppc7450", .platform = "ppc7450",
}, },
{ /* 7447A */ { /* 7447A */
...@@ -827,6 +883,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -827,6 +883,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_745x, .cpu_setup = __setup_cpu_745x,
.oprofile_cpu_type = "ppc/7450", .oprofile_cpu_type = "ppc/7450",
.oprofile_type = PPC_OPROFILE_G4, .oprofile_type = PPC_OPROFILE_G4,
.machine_check = machine_check_generic,
.platform = "ppc7450", .platform = "ppc7450",
}, },
{ /* 7448 */ { /* 7448 */
...@@ -842,6 +899,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -842,6 +899,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_745x, .cpu_setup = __setup_cpu_745x,
.oprofile_cpu_type = "ppc/7450", .oprofile_cpu_type = "ppc/7450",
.oprofile_type = PPC_OPROFILE_G4, .oprofile_type = PPC_OPROFILE_G4,
.machine_check = machine_check_generic,
.platform = "ppc7450", .platform = "ppc7450",
}, },
{ /* 82xx (8240, 8245, 8260 are all 603e cores) */ { /* 82xx (8240, 8245, 8260 are all 603e cores) */
...@@ -853,6 +911,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -853,6 +911,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_603, .cpu_setup = __setup_cpu_603,
.machine_check = machine_check_generic,
.platform = "ppc603", .platform = "ppc603",
}, },
{ /* All G2_LE (603e core, plus some) have the same pvr */ { /* All G2_LE (603e core, plus some) have the same pvr */
...@@ -864,6 +923,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -864,6 +923,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_603, .cpu_setup = __setup_cpu_603,
.machine_check = machine_check_generic,
.platform = "ppc603", .platform = "ppc603",
}, },
{ /* e300c1 (a 603e core, plus some) on 83xx */ { /* e300c1 (a 603e core, plus some) on 83xx */
...@@ -875,6 +935,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -875,6 +935,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_603, .cpu_setup = __setup_cpu_603,
.machine_check = machine_check_generic,
.platform = "ppc603", .platform = "ppc603",
}, },
{ /* e300c2 (an e300c1 core, plus some, minus FPU) on 83xx */ { /* e300c2 (an e300c1 core, plus some, minus FPU) on 83xx */
...@@ -886,6 +947,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -886,6 +947,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_603, .cpu_setup = __setup_cpu_603,
.machine_check = machine_check_generic,
.platform = "ppc603", .platform = "ppc603",
}, },
{ /* e300c3 (e300c1, plus one IU, half cache size) on 83xx */ { /* e300c3 (e300c1, plus one IU, half cache size) on 83xx */
...@@ -908,6 +970,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -908,6 +970,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_603, .cpu_setup = __setup_cpu_603,
.machine_check = machine_check_generic,
.platform = "ppc603", .platform = "ppc603",
}, },
{ /* default match, we assume split I/D cache & TB (non-601)... */ { /* default match, we assume split I/D cache & TB (non-601)... */
...@@ -918,6 +981,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -918,6 +981,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER, .cpu_user_features = COMMON_USER,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_generic,
.platform = "ppc603", .platform = "ppc603",
}, },
#endif /* CLASSIC_PPC */ #endif /* CLASSIC_PPC */
...@@ -944,6 +1008,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -944,6 +1008,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 16, .icache_bsize = 16,
.dcache_bsize = 16, .dcache_bsize = 16,
.machine_check = machine_check_4xx,
.platform = "ppc403", .platform = "ppc403",
}, },
{ /* 403GCX */ { /* 403GCX */
...@@ -955,6 +1020,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -955,6 +1020,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB, PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB,
.icache_bsize = 16, .icache_bsize = 16,
.dcache_bsize = 16, .dcache_bsize = 16,
.machine_check = machine_check_4xx,
.platform = "ppc403", .platform = "ppc403",
}, },
{ /* 403G ?? */ { /* 403G ?? */
...@@ -965,6 +1031,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -965,6 +1031,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 16, .icache_bsize = 16,
.dcache_bsize = 16, .dcache_bsize = 16,
.machine_check = machine_check_4xx,
.platform = "ppc403", .platform = "ppc403",
}, },
{ /* 405GP */ { /* 405GP */
...@@ -976,6 +1043,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -976,6 +1043,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc405", .platform = "ppc405",
}, },
{ /* STB 03xxx */ { /* STB 03xxx */
...@@ -987,6 +1055,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -987,6 +1055,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc405", .platform = "ppc405",
}, },
{ /* STB 04xxx */ { /* STB 04xxx */
...@@ -998,6 +1067,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -998,6 +1067,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc405", .platform = "ppc405",
}, },
{ /* NP405L */ { /* NP405L */
...@@ -1009,6 +1079,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1009,6 +1079,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc405", .platform = "ppc405",
}, },
{ /* NP4GS3 */ { /* NP4GS3 */
...@@ -1020,6 +1091,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1020,6 +1091,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc405", .platform = "ppc405",
}, },
{ /* NP405H */ { /* NP405H */
...@@ -1031,6 +1103,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1031,6 +1103,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc405", .platform = "ppc405",
}, },
{ /* 405GPr */ { /* 405GPr */
...@@ -1042,6 +1115,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1042,6 +1115,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc405", .platform = "ppc405",
}, },
{ /* STBx25xx */ { /* STBx25xx */
...@@ -1053,6 +1127,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1053,6 +1127,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc405", .platform = "ppc405",
}, },
{ /* 405LP */ { /* 405LP */
...@@ -1063,6 +1138,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1063,6 +1138,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc405", .platform = "ppc405",
}, },
{ /* Xilinx Virtex-II Pro */ { /* Xilinx Virtex-II Pro */
...@@ -1074,6 +1150,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1074,6 +1150,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc405", .platform = "ppc405",
}, },
{ /* Xilinx Virtex-4 FX */ { /* Xilinx Virtex-4 FX */
...@@ -1085,6 +1162,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1085,6 +1162,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc405", .platform = "ppc405",
}, },
{ /* 405EP */ { /* 405EP */
...@@ -1096,6 +1174,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1096,6 +1174,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc405", .platform = "ppc405",
}, },
{ /* 405EX */ { /* 405EX */
...@@ -1107,6 +1186,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1107,6 +1186,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc405", .platform = "ppc405",
}, },
...@@ -1120,6 +1200,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1120,6 +1200,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_BOOKE, .cpu_user_features = COMMON_USER_BOOKE,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc440", .platform = "ppc440",
}, },
{ /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */ { /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */
...@@ -1131,6 +1212,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1131,6 +1212,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_440ep, .cpu_setup = __setup_cpu_440ep,
.machine_check = machine_check_4xx,
.platform = "ppc440", .platform = "ppc440",
}, },
{ {
...@@ -1141,6 +1223,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1141,6 +1223,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc440", .platform = "ppc440",
}, },
{ /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */ { /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */
...@@ -1152,6 +1235,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1152,6 +1235,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_440ep, .cpu_setup = __setup_cpu_440ep,
.machine_check = machine_check_4xx,
.platform = "ppc440", .platform = "ppc440",
}, },
{ /* 440GRX */ { /* 440GRX */
...@@ -1163,6 +1247,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1163,6 +1247,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_440grx, .cpu_setup = __setup_cpu_440grx,
.machine_check = machine_check_4xx,
.platform = "ppc440", .platform = "ppc440",
}, },
{ /* Use logical PVR for 440EPx (logical pvr = pvr | 0x8) */ { /* Use logical PVR for 440EPx (logical pvr = pvr | 0x8) */
...@@ -1174,6 +1259,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1174,6 +1259,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_440epx, .cpu_setup = __setup_cpu_440epx,
.machine_check = machine_check_440A,
.platform = "ppc440", .platform = "ppc440",
}, },
{ /* 440GP Rev. B */ { /* 440GP Rev. B */
...@@ -1184,6 +1270,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1184,6 +1270,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_BOOKE, .cpu_user_features = COMMON_USER_BOOKE,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc440gp", .platform = "ppc440gp",
}, },
{ /* 440GP Rev. C */ { /* 440GP Rev. C */
...@@ -1194,6 +1281,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1194,6 +1281,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_BOOKE, .cpu_user_features = COMMON_USER_BOOKE,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc440gp", .platform = "ppc440gp",
}, },
{ /* 440GX Rev. A */ { /* 440GX Rev. A */
...@@ -1204,6 +1292,8 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1204,6 +1292,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_BOOKE, .cpu_user_features = COMMON_USER_BOOKE,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_440gx,
.machine_check = machine_check_440A,
.platform = "ppc440", .platform = "ppc440",
}, },
{ /* 440GX Rev. B */ { /* 440GX Rev. B */
...@@ -1214,6 +1304,8 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1214,6 +1304,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_BOOKE, .cpu_user_features = COMMON_USER_BOOKE,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_440gx,
.machine_check = machine_check_440A,
.platform = "ppc440", .platform = "ppc440",
}, },
{ /* 440GX Rev. C */ { /* 440GX Rev. C */
...@@ -1224,6 +1316,8 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1224,6 +1316,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_BOOKE, .cpu_user_features = COMMON_USER_BOOKE,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_440gx,
.machine_check = machine_check_440A,
.platform = "ppc440", .platform = "ppc440",
}, },
{ /* 440GX Rev. F */ { /* 440GX Rev. F */
...@@ -1234,6 +1328,8 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1234,6 +1328,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_BOOKE, .cpu_user_features = COMMON_USER_BOOKE,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_440gx,
.machine_check = machine_check_440A,
.platform = "ppc440", .platform = "ppc440",
}, },
{ /* 440SP Rev. A */ { /* 440SP Rev. A */
...@@ -1244,6 +1340,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1244,6 +1340,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_BOOKE, .cpu_user_features = COMMON_USER_BOOKE,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_4xx,
.platform = "ppc440", .platform = "ppc440",
}, },
{ /* 440SPe Rev. A */ { /* 440SPe Rev. A */
...@@ -1254,6 +1351,8 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1254,6 +1351,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_BOOKE, .cpu_user_features = COMMON_USER_BOOKE,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_440spe,
.machine_check = machine_check_440A,
.platform = "ppc440", .platform = "ppc440",
}, },
{ /* 440SPe Rev. B */ { /* 440SPe Rev. B */
...@@ -1264,6 +1363,8 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1264,6 +1363,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_user_features = COMMON_USER_BOOKE, .cpu_user_features = COMMON_USER_BOOKE,
.icache_bsize = 32, .icache_bsize = 32,
.dcache_bsize = 32, .dcache_bsize = 32,
.cpu_setup = __setup_cpu_440spe,
.machine_check = machine_check_440A,
.platform = "ppc440", .platform = "ppc440",
}, },
#endif /* CONFIG_44x */ #endif /* CONFIG_44x */
...@@ -1278,6 +1379,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1278,6 +1379,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_HAS_EFP_SINGLE | PPC_FEATURE_HAS_EFP_SINGLE |
PPC_FEATURE_UNIFIED_CACHE, PPC_FEATURE_UNIFIED_CACHE,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_e200,
.platform = "ppc5554", .platform = "ppc5554",
}, },
{ /* e200z6 */ { /* e200z6 */
...@@ -1291,6 +1393,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1291,6 +1393,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_HAS_EFP_SINGLE_COMP | PPC_FEATURE_HAS_EFP_SINGLE_COMP |
PPC_FEATURE_UNIFIED_CACHE, PPC_FEATURE_UNIFIED_CACHE,
.dcache_bsize = 32, .dcache_bsize = 32,
.machine_check = machine_check_e200,
.platform = "ppc5554", .platform = "ppc5554",
}, },
{ /* e500 */ { /* e500 */
...@@ -1307,6 +1410,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1307,6 +1410,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.num_pmcs = 4, .num_pmcs = 4,
.oprofile_cpu_type = "ppc/e500", .oprofile_cpu_type = "ppc/e500",
.oprofile_type = PPC_OPROFILE_BOOKE, .oprofile_type = PPC_OPROFILE_BOOKE,
.machine_check = machine_check_e500,
.platform = "ppc8540", .platform = "ppc8540",
}, },
{ /* e500v2 */ { /* e500v2 */
...@@ -1324,6 +1428,7 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -1324,6 +1428,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.num_pmcs = 4, .num_pmcs = 4,
.oprofile_cpu_type = "ppc/e500", .oprofile_cpu_type = "ppc/e500",
.oprofile_type = PPC_OPROFILE_BOOKE, .oprofile_type = PPC_OPROFILE_BOOKE,
.machine_check = machine_check_e500,
.platform = "ppc8548", .platform = "ppc8548",
}, },
#endif #endif
......
...@@ -289,11 +289,8 @@ interrupt_base: ...@@ -289,11 +289,8 @@ interrupt_base:
CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception) CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
/* Machine Check Interrupt */ /* Machine Check Interrupt */
#ifdef CONFIG_440A
MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
#else
CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception) CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
#endif MCHECK_EXCEPTION(0x0210, MachineCheckA, machine_check_exception)
/* Data Storage Interrupt */ /* Data Storage Interrupt */
START_EXCEPTION(DataStorage) START_EXCEPTION(DataStorage)
...@@ -673,6 +670,15 @@ finish_tlb_load: ...@@ -673,6 +670,15 @@ finish_tlb_load:
* Global functions * Global functions
*/ */
/*
* Adjust the machine check IVOR on 440A cores
*/
_GLOBAL(__fixup_440A_mcheck)
li r3,MachineCheckA@l
mtspr SPRN_IVOR1,r3
sync
blr
/* /*
* extern void giveup_altivec(struct task_struct *prev) * extern void giveup_altivec(struct task_struct *prev)
* *
......
...@@ -166,7 +166,7 @@ ...@@ -166,7 +166,7 @@
mfspr r5,SPRN_ESR; \ mfspr r5,SPRN_ESR; \
stw r5,_ESR(r11); \ stw r5,_ESR(r11); \
addi r3,r1,STACK_FRAME_OVERHEAD; \ addi r3,r1,STACK_FRAME_OVERHEAD; \
EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ EXC_XFER_TEMPLATE(hdlr, n+4, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
NOCOPY, mcheck_transfer_to_handler, \ NOCOPY, mcheck_transfer_to_handler, \
ret_from_mcheck_exc) ret_from_mcheck_exc)
......
...@@ -334,18 +334,25 @@ static inline int check_io_access(struct pt_regs *regs) ...@@ -334,18 +334,25 @@ static inline int check_io_access(struct pt_regs *regs)
#define clear_single_step(regs) ((regs)->msr &= ~MSR_SE) #define clear_single_step(regs) ((regs)->msr &= ~MSR_SE)
#endif #endif
static int generic_machine_check_exception(struct pt_regs *regs) #if defined(CONFIG_4xx)
int machine_check_4xx(struct pt_regs *regs)
{ {
unsigned long reason = get_mc_reason(regs); unsigned long reason = get_mc_reason(regs);
#if defined(CONFIG_4xx) && !defined(CONFIG_440A)
if (reason & ESR_IMCP) { if (reason & ESR_IMCP) {
printk("Instruction"); printk("Instruction");
mtspr(SPRN_ESR, reason & ~ESR_IMCP); mtspr(SPRN_ESR, reason & ~ESR_IMCP);
} else } else
printk("Data"); printk("Data");
printk(" machine check in kernel mode.\n"); printk(" machine check in kernel mode.\n");
#elif defined(CONFIG_440A)
return 0;
}
int machine_check_440A(struct pt_regs *regs)
{
unsigned long reason = get_mc_reason(regs);
printk("Machine check in kernel mode.\n"); printk("Machine check in kernel mode.\n");
if (reason & ESR_IMCP){ if (reason & ESR_IMCP){
printk("Instruction Synchronous Machine Check exception\n"); printk("Instruction Synchronous Machine Check exception\n");
...@@ -375,7 +382,13 @@ static int generic_machine_check_exception(struct pt_regs *regs) ...@@ -375,7 +382,13 @@ static int generic_machine_check_exception(struct pt_regs *regs)
/* Clear MCSR */ /* Clear MCSR */
mtspr(SPRN_MCSR, mcsr); mtspr(SPRN_MCSR, mcsr);
} }
#elif defined (CONFIG_E500) return 0;
}
#elif defined(CONFIG_E500)
int machine_check_e500(struct pt_regs *regs)
{
unsigned long reason = get_mc_reason(regs);
printk("Machine check in kernel mode.\n"); printk("Machine check in kernel mode.\n");
printk("Caused by (from MCSR=%lx): ", reason); printk("Caused by (from MCSR=%lx): ", reason);
...@@ -403,7 +416,14 @@ static int generic_machine_check_exception(struct pt_regs *regs) ...@@ -403,7 +416,14 @@ static int generic_machine_check_exception(struct pt_regs *regs)
printk("Bus - Instruction Parity Error\n"); printk("Bus - Instruction Parity Error\n");
if (reason & MCSR_BUS_RPERR) if (reason & MCSR_BUS_RPERR)
printk("Bus - Read Parity Error\n"); printk("Bus - Read Parity Error\n");
#elif defined (CONFIG_E200)
return 0;
}
#elif defined(CONFIG_E200)
int machine_check_e200(struct pt_regs *regs)
{
unsigned long reason = get_mc_reason(regs);
printk("Machine check in kernel mode.\n"); printk("Machine check in kernel mode.\n");
printk("Caused by (from MCSR=%lx): ", reason); printk("Caused by (from MCSR=%lx): ", reason);
...@@ -421,7 +441,14 @@ static int generic_machine_check_exception(struct pt_regs *regs) ...@@ -421,7 +441,14 @@ static int generic_machine_check_exception(struct pt_regs *regs)
printk("Bus - Read Bus Error on data load\n"); printk("Bus - Read Bus Error on data load\n");
if (reason & MCSR_BUS_WRERR) if (reason & MCSR_BUS_WRERR)
printk("Bus - Write Bus Error on buffered store or cache line push\n"); printk("Bus - Write Bus Error on buffered store or cache line push\n");
#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */
return 0;
}
#else
int machine_check_generic(struct pt_regs *regs)
{
unsigned long reason = get_mc_reason(regs);
printk("Machine check in kernel mode.\n"); printk("Machine check in kernel mode.\n");
printk("Caused by (from SRR1=%lx): ", reason); printk("Caused by (from SRR1=%lx): ", reason);
switch (reason & 0x601F0000) { switch (reason & 0x601F0000) {
...@@ -451,22 +478,26 @@ static int generic_machine_check_exception(struct pt_regs *regs) ...@@ -451,22 +478,26 @@ static int generic_machine_check_exception(struct pt_regs *regs)
default: default:
printk("Unknown values in msr\n"); printk("Unknown values in msr\n");
} }
#endif /* CONFIG_4xx */
return 0; return 0;
} }
#endif /* everything else */
void machine_check_exception(struct pt_regs *regs) void machine_check_exception(struct pt_regs *regs)
{ {
int recover = 0; int recover = 0;
/* See if any machine dependent calls */ /* See if any machine dependent calls. In theory, we would want
* to call the CPU first, and call the ppc_md. one if the CPU
* one returns a positive number. However there is existing code
* that assumes the board gets a first chance, so let's keep it
* that way for now and fix things later. --BenH.
*/
if (ppc_md.machine_check_exception) if (ppc_md.machine_check_exception)
recover = ppc_md.machine_check_exception(regs); recover = ppc_md.machine_check_exception(regs);
else else if (cur_cpu_spec->machine_check)
recover = generic_machine_check_exception(regs); recover = cur_cpu_spec->machine_check(regs);
if (recover) if (recover > 0)
return; return;
if (user_mode(regs)) { if (user_mode(regs)) {
...@@ -476,7 +507,12 @@ void machine_check_exception(struct pt_regs *regs) ...@@ -476,7 +507,12 @@ void machine_check_exception(struct pt_regs *regs)
} }
#if defined(CONFIG_8xx) && defined(CONFIG_PCI) #if defined(CONFIG_8xx) && defined(CONFIG_PCI)
/* the qspan pci read routines can cause machine checks -- Cort */ /* the qspan pci read routines can cause machine checks -- Cort
*
* yuck !!! that totally needs to go away ! There are better ways
* to deal with that than having a wart in the mcheck handler.
* -- BenH
*/
bad_page_fault(regs, regs->dar, SIGBUS); bad_page_fault(regs, regs->dar, SIGBUS);
return; return;
#endif #endif
......
...@@ -62,11 +62,6 @@ config 440GX ...@@ -62,11 +62,6 @@ config 440GX
config 440SP config 440SP
bool bool
config 440A
bool
depends on 440GX || 440EPX
default y
# 44x errata/workaround config symbols, selected by the CPU models above # 44x errata/workaround config symbols, selected by the CPU models above
config IBM440EP_ERR42 config IBM440EP_ERR42
bool bool
...@@ -231,39 +231,25 @@ platform_machine_check(struct pt_regs *regs) ...@@ -231,39 +231,25 @@ platform_machine_check(struct pt_regs *regs)
{ {
} }
void machine_check_exception(struct pt_regs *regs) #if defined(CONFIG_4xx)
int machine_check_4xx(struct pt_regs *regs)
{ {
unsigned long reason = get_mc_reason(regs); unsigned long reason = get_mc_reason(regs);
if (user_mode(regs)) {
regs->msr |= MSR_RI;
_exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
return;
}
#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
/* the qspan pci read routines can cause machine checks -- Cort */
bad_page_fault(regs, regs->dar, SIGBUS);
return;
#endif
if (debugger_fault_handler) {
debugger_fault_handler(regs);
regs->msr |= MSR_RI;
return;
}
if (check_io_access(regs))
return;
#if defined(CONFIG_4xx) && !defined(CONFIG_440A)
if (reason & ESR_IMCP) { if (reason & ESR_IMCP) {
printk("Instruction"); printk("Instruction");
mtspr(SPRN_ESR, reason & ~ESR_IMCP); mtspr(SPRN_ESR, reason & ~ESR_IMCP);
} else } else
printk("Data"); printk("Data");
printk(" machine check in kernel mode.\n"); printk(" machine check in kernel mode.\n");
#elif defined(CONFIG_440A)
return 0;
}
int machine_check_440A(struct pt_regs *regs)
{
unsigned long reason = get_mc_reason(regs);
printk("Machine check in kernel mode.\n"); printk("Machine check in kernel mode.\n");
if (reason & ESR_IMCP){ if (reason & ESR_IMCP){
printk("Instruction Synchronous Machine Check exception\n"); printk("Instruction Synchronous Machine Check exception\n");
...@@ -293,7 +279,13 @@ void machine_check_exception(struct pt_regs *regs) ...@@ -293,7 +279,13 @@ void machine_check_exception(struct pt_regs *regs)
/* Clear MCSR */ /* Clear MCSR */
mtspr(SPRN_MCSR, mcsr); mtspr(SPRN_MCSR, mcsr);
} }
#elif defined (CONFIG_E500) return 0;
}
#elif defined(CONFIG_E500)
int machine_check_e500(struct pt_regs *regs)
{
unsigned long reason = get_mc_reason(regs);
printk("Machine check in kernel mode.\n"); printk("Machine check in kernel mode.\n");
printk("Caused by (from MCSR=%lx): ", reason); printk("Caused by (from MCSR=%lx): ", reason);
...@@ -305,8 +297,6 @@ void machine_check_exception(struct pt_regs *regs) ...@@ -305,8 +297,6 @@ void machine_check_exception(struct pt_regs *regs)
printk("Data Cache Push Parity Error\n"); printk("Data Cache Push Parity Error\n");
if (reason & MCSR_DCPERR) if (reason & MCSR_DCPERR)
printk("Data Cache Parity Error\n"); printk("Data Cache Parity Error\n");
if (reason & MCSR_GL_CI)
printk("Guarded Load or Cache-Inhibited stwcx.\n");
if (reason & MCSR_BUS_IAERR) if (reason & MCSR_BUS_IAERR)
printk("Bus - Instruction Address Error\n"); printk("Bus - Instruction Address Error\n");
if (reason & MCSR_BUS_RAERR) if (reason & MCSR_BUS_RAERR)
...@@ -318,12 +308,19 @@ void machine_check_exception(struct pt_regs *regs) ...@@ -318,12 +308,19 @@ void machine_check_exception(struct pt_regs *regs)
if (reason & MCSR_BUS_RBERR) if (reason & MCSR_BUS_RBERR)
printk("Bus - Read Data Bus Error\n"); printk("Bus - Read Data Bus Error\n");
if (reason & MCSR_BUS_WBERR) if (reason & MCSR_BUS_WBERR)
printk("Bus - Write Data Bus Error\n"); printk("Bus - Read Data Bus Error\n");
if (reason & MCSR_BUS_IPERR) if (reason & MCSR_BUS_IPERR)
printk("Bus - Instruction Parity Error\n"); printk("Bus - Instruction Parity Error\n");
if (reason & MCSR_BUS_RPERR) if (reason & MCSR_BUS_RPERR)
printk("Bus - Read Parity Error\n"); printk("Bus - Read Parity Error\n");
#elif defined (CONFIG_E200)
return 0;
}
#elif defined(CONFIG_E200)
int machine_check_e200(struct pt_regs *regs)
{
unsigned long reason = get_mc_reason(regs);
printk("Machine check in kernel mode.\n"); printk("Machine check in kernel mode.\n");
printk("Caused by (from MCSR=%lx): ", reason); printk("Caused by (from MCSR=%lx): ", reason);
...@@ -341,7 +338,14 @@ void machine_check_exception(struct pt_regs *regs) ...@@ -341,7 +338,14 @@ void machine_check_exception(struct pt_regs *regs)
printk("Bus - Read Bus Error on data load\n"); printk("Bus - Read Bus Error on data load\n");
if (reason & MCSR_BUS_WRERR) if (reason & MCSR_BUS_WRERR)
printk("Bus - Write Bus Error on buffered store or cache line push\n"); printk("Bus - Write Bus Error on buffered store or cache line push\n");
#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */
return 0;
}
#else
int machine_check_generic(struct pt_regs *regs)
{
unsigned long reason = get_mc_reason(regs);
printk("Machine check in kernel mode.\n"); printk("Machine check in kernel mode.\n");
printk("Caused by (from SRR1=%lx): ", reason); printk("Caused by (from SRR1=%lx): ", reason);
switch (reason & 0x601F0000) { switch (reason & 0x601F0000) {
...@@ -371,7 +375,39 @@ void machine_check_exception(struct pt_regs *regs) ...@@ -371,7 +375,39 @@ void machine_check_exception(struct pt_regs *regs)
default: default:
printk("Unknown values in msr\n"); printk("Unknown values in msr\n");
} }
#endif /* CONFIG_4xx */ return 0;
}
#endif /* everything else */
void machine_check_exception(struct pt_regs *regs)
{
int recover = 0;
if (cur_cpu_spec->machine_check)
recover = cur_cpu_spec->machine_check(regs);
if (recover > 0)
return;
if (user_mode(regs)) {
regs->msr |= MSR_RI;
_exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
return;
}
#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
/* the qspan pci read routines can cause machine checks -- Cort */
bad_page_fault(regs, regs->dar, SIGBUS);
return;
#endif
if (debugger_fault_handler) {
debugger_fault_handler(regs);
regs->msr |= MSR_RI;
return;
}
if (check_io_access(regs))
return;
/* /*
* Optional platform-provided routine to print out * Optional platform-provided routine to print out
......
...@@ -57,6 +57,14 @@ enum powerpc_pmc_type { ...@@ -57,6 +57,14 @@ enum powerpc_pmc_type {
PPC_PMC_PA6T = 2, PPC_PMC_PA6T = 2,
}; };
struct pt_regs;
extern int machine_check_generic(struct pt_regs *regs);
extern int machine_check_4xx(struct pt_regs *regs);
extern int machine_check_440A(struct pt_regs *regs);
extern int machine_check_e500(struct pt_regs *regs);
extern int machine_check_e200(struct pt_regs *regs);
/* NOTE WELL: Update identify_cpu() if fields are added or removed! */ /* NOTE WELL: Update identify_cpu() if fields are added or removed! */
struct cpu_spec { struct cpu_spec {
/* CPU is matched via (PVR & pvr_mask) == pvr_value */ /* CPU is matched via (PVR & pvr_mask) == pvr_value */
...@@ -97,6 +105,11 @@ struct cpu_spec { ...@@ -97,6 +105,11 @@ struct cpu_spec {
/* Name of processor class, for the ELF AT_PLATFORM entry */ /* Name of processor class, for the ELF AT_PLATFORM entry */
char *platform; char *platform;
/* Processor specific machine check handling. Return negative
* if the error is fatal, 1 if it was fully recovered and 0 to
* pass up (not CPU originated) */
int (*machine_check)(struct pt_regs *regs);
}; };
extern struct cpu_spec *cur_cpu_spec; extern struct cpu_spec *cur_cpu_spec;
......
...@@ -106,7 +106,8 @@ extern int ptrace_put_reg(struct task_struct *task, int regno, ...@@ -106,7 +106,8 @@ extern int ptrace_put_reg(struct task_struct *task, int regno,
*/ */
#define FULL_REGS(regs) (((regs)->trap & 1) == 0) #define FULL_REGS(regs) (((regs)->trap & 1) == 0)
#ifndef __powerpc64__ #ifndef __powerpc64__
#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) == 0) #define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0)
#define IS_MCHECK_EXC(regs) (((regs)->trap & 4) != 0)
#endif /* ! __powerpc64__ */ #endif /* ! __powerpc64__ */
#define TRAP(regs) ((regs)->trap & ~0xF) #define TRAP(regs) ((regs)->trap & ~0xF)
#ifdef __powerpc64__ #ifdef __powerpc64__
......
...@@ -218,7 +218,6 @@ ...@@ -218,7 +218,6 @@
#define CCR1_TCS 0x00000080 /* Timer Clock Select */ #define CCR1_TCS 0x00000080 /* Timer Clock Select */
/* Bit definitions for the MCSR. */ /* Bit definitions for the MCSR. */
#ifdef CONFIG_440A
#define MCSR_MCS 0x80000000 /* Machine Check Summary */ #define MCSR_MCS 0x80000000 /* Machine Check Summary */
#define MCSR_IB 0x40000000 /* Instruction PLB Error */ #define MCSR_IB 0x40000000 /* Instruction PLB Error */
#define MCSR_DRB 0x20000000 /* Data Read PLB Error */ #define MCSR_DRB 0x20000000 /* Data Read PLB Error */
...@@ -228,7 +227,7 @@ ...@@ -228,7 +227,7 @@
#define MCSR_DCSP 0x02000000 /* D-Cache Search Parity Error */ #define MCSR_DCSP 0x02000000 /* D-Cache Search Parity Error */
#define MCSR_DCFP 0x01000000 /* D-Cache Flush Parity Error */ #define MCSR_DCFP 0x01000000 /* D-Cache Flush Parity Error */
#define MCSR_IMPE 0x00800000 /* Imprecise Machine Check Exception */ #define MCSR_IMPE 0x00800000 /* Imprecise Machine Check Exception */
#endif
#ifdef CONFIG_E500 #ifdef CONFIG_E500
#define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */ #define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */
#define MCSR_ICPERR 0x40000000UL /* I-Cache Parity Error */ #define MCSR_ICPERR 0x40000000UL /* I-Cache Parity Error */
......
...@@ -207,7 +207,7 @@ ...@@ -207,7 +207,7 @@
#define CCR1_TCS 0x00000080 /* Timer Clock Select */ #define CCR1_TCS 0x00000080 /* Timer Clock Select */
/* Bit definitions for the MCSR. */ /* Bit definitions for the MCSR. */
#ifdef CONFIG_440A #ifdef CONFIG_4xx
#define MCSR_MCS 0x80000000 /* Machine Check Summary */ #define MCSR_MCS 0x80000000 /* Machine Check Summary */
#define MCSR_IB 0x40000000 /* Instruction PLB Error */ #define MCSR_IB 0x40000000 /* Instruction PLB Error */
#define MCSR_DRB 0x20000000 /* Data Read PLB Error */ #define MCSR_DRB 0x20000000 /* Data Read PLB Error */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment