Reworking machine check handling and Fix 440/440A
Subsystems (2)
PATCH 1/21 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.
---
arch/powerpc/kernel/cpu_setup_44x.S | 9 +++ arch/powerpc/kernel/cputable.c | 105 ++++++++++++++++++++++++++++++++++++ arch/powerpc/kernel/head_44x.S | 14 +++- arch/powerpc/kernel/head_booke.h | 2 arch/powerpc/kernel/traps.c | 62 ++++++++++++++++----- arch/powerpc/platforms/44x/Kconfig | 5 - arch/ppc/kernel/traps.c | 98 ++++++++++++++++++++++----------- include/asm-powerpc/cputable.h | 13 ++++ include/asm-powerpc/ptrace.h | 3 - include/asm-powerpc/reg_booke.h | 3 - include/asm-ppc/reg_booke.h | 2 11 files changed, 258 insertions(+), 58 deletions(-)
arch/powerpc/kernel/cpu_setup_44x.S +9 -0
@@ -23,11 +23,20 @@ _GLOBAL(__setup_cpu_440epx) mflr r4 bl __init_fpu_44x bl __plb_disable_wrp + bl __fixup_440A_mcheck mtlr r4 blr _GLOBAL(__setup_cpu_440grx) 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 */ _GLOBAL(__init_fpu_44x)
arch/powerpc/kernel/cputable.c +105 -0
694 lines not on this page · raw message
arch/powerpc/kernel/head_44x.S +10 -4
@@ -289,11 +289,8 @@ interrupt_base: CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception) /* Machine Check Interrupt */ -#ifdef CONFIG_440A - MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception) -#else CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception) -#endif + MCHECK_EXCEPTION(0x0210, MachineCheckA, machine_check_exception) /* Data Storage Interrupt */ START_EXCEPTION(DataStorage)
@@ -674,6 +671,15 @@ finish_tlb_load: */ /* + * 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) * * The 44x core does not have an AltiVec unit.
arch/powerpc/kernel/traps.c +49 -13
117 lines not on this page · raw message
arch/powerpc/platforms/44x/Kconfig +0 -5
@@ -62,11 +62,6 @@ config 440GX config 440SP bool -config 440A - bool - depends on 440GX || 440EPX - default y - # 44x errata/workaround config symbols, selected by the CPU models above config IBM440EP_ERR42 bool
arch/powerpc/kernel/head_booke.h +1 -1
@@ -166,7 +166,7 @@ label:mfspr r5,SPRN_ESR ; \stw r5,_ESR (r11 ); \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, \ ret_from_mcheck_exc)
include/asm-powerpc/ptrace.h +2 -1
@@ -106,7 +106,8 @@ extern int ptrace_put_reg(struct task_st*/ #define FULL_REGS (regs) (((regs)->trap & 1) == 0)#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__ */ #define TRAP (regs) ((regs)->trap & ~0xF)#ifdef __powerpc64__
include/asm-powerpc/reg_booke.h +1 -2
@@ -218,7 +218,6 @@#define CCR1_TCS 0x00000080/* Timer Clock Select */ /* Bit definitions for the MCSR. */ -#ifdef CONFIG_440A #define MCSR_MCS 0x80000000/* Machine Check Summary */ #define MCSR_IB 0x40000000/* Instruction PLB Error */ #define MCSR_DRB 0x20000000/* Data Read PLB Error */
@@ -228,7 +227,7 @@#define MCSR_DCSP 0x02000000/* D-Cache Search Parity Error */ #define MCSR_DCFP 0x01000000/* D-Cache Flush Parity Error */ #define MCSR_IMPE 0x00800000/* Imprecise Machine Check Exception */ -#endif +#ifdef CONFIG_E500 #define MCSR_MCP 0x80000000UL/* Machine Check Input Pin */ #define MCSR_ICPERR 0x40000000UL/* I-Cache Parity Error */
include/asm-powerpc/cputable.h +13 -0
@@ -57,6 +57,14 @@ enum powerpc_pmc_type { 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! */ struct cpu_spec {/* CPU is matched via (PVR & pvr_mask) == pvr_value */
@@ -97,6 +105,11 @@ struct cpu_spec {/* Name of processor class, for the ELF AT_PLATFORM entry */ 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;
arch/ppc/kernel/traps.c +67 -31
147 lines not on this page · raw message
include/asm-ppc/reg_booke.h +1 -1
@@ -207,7 +207,7 @@#define CCR1_TCS 0x00000080/* Timer Clock Select */ /* Bit definitions for the MCSR. */ -#ifdef CONFIG_440A +#ifdef CONFIG_44x#define MCSR_MCS 0x80000000/* Machine Check Summary */ #define MCSR_IB 0x40000000/* Instruction PLB Error */ #define MCSR_DRB 0x20000000/* Data Read PLB Error */
include/asm-ppc/reg_booke.h line 210
Quoted 10 lines · On Fri, 21 Dec 2007 15:39:21 +1100 Benjamin Herrenschmidt…
Index:
linux-merge/include/asm-ppc/reg_booke.h
===================================================================include/asm-ppc/reg_booke.h +1
-1@@ -207,7 +207,7 @@#define CCR1_TCS 0x00000080/* Timer Clock Select */ /* Bit definitions for the MCSR. */ -#ifdef CONFIG_440A +#ifdef CONFIG_44x
Should be #ifdef CONFIG_4xx as I pointed out last time. I'll fix it when I commit.
josh
Quoted 11 lines · Josh Boyer
Quoted 7 lines · On Fri, 21 Dec 2007 15:39:21 +1100 Benjamin Herrenschmidt…
Index:
linux-merge/include/asm-ppc/reg_booke.h
===================================================================include/asm-ppc/reg_booke.h +0
-0@@ -207,7 +207,7 @@#define CCR1_TCS 0x00000080/* Timer Clock Select */
Quoted 6 lines
include/asm-ppc/reg_booke.h line 210
Quoted 3 lines
include/asm-ppc/reg_booke.h +1
-1/* Bit definitions for the MCSR. */ -#ifdef CONFIG_440A +#ifdef CONFIG_44xShould be #ifdef
CONFIG_4xxas I pointed out last time. I'll fix it when I commit.
Ah weird, I though I fixed it... I must have fixed powerpc and not ppc.
Ben.
Quoted 4 lines · On Fri, 21 Dec 2007 15:39:21 +1100 Benjamin Herrenschmidt…
Index:
linux-merge/arch/powerpc/kernel/traps.c
===================================================================arch/powerpc/kernel/traps.c +0
-0
[snip]
arch/powerpc/kernel/traps.c static int generic_machine_check_excepti · line 388
Quoted 5 lines
arch/powerpc/kernel/traps.c +4
-1-#elif defined (CONFIG_E500 ) + return 0; +} +#elif defined(CONFIG_E500) +int machine_check_e500 (struct pt_regs *regs)
This...
Quoted 7 lines
arch/powerpc/kernel/traps.c +3
-0+{ +unsigned long reason =get_mc_reason (regs); +printk ("Machine check in kernel mode.\n" );printk ("Caused by (from MCSR=%lx): " , reason);
arch/powerpc/kernel/traps.c static int generic_machine_check_excepti · line 423
Quoted 9 lines
arch/powerpc/kernel/traps.c +5
-1@@ -403,7 +416,14 @@ static int generic_machine_check_exceptiprintk ("Bus - Instruction Parity Error\n" );if (reason &MCSR_BUS_RPERR )printk ("Bus - Read Parity Error\n" ); -#elif defined (CONFIG_E200 ) + + return 0; +} +#elif defined(CONFIG_E200) +int machine_check_e200 (struct pt_regs *regs)
... and this cause build failures for most of the mpc8xxx defconfigs. The reason is that e200 and e500 are both lumped under CONFIG_FSL_BOOKE in cputable.c, but you have them segregated more here. I've added a fix that just does CONFIG_FSL_BOOKE here to match cputable.c.
josh
Quoted 24 lines · On Sun, 23 Dec 2007 19:32:10 -0600 Josh Boyer <[email protected]>…
Quoted 4 lines · On Fri, 21 Dec 2007 15:39:21 +1100 Benjamin Herrenschmidt…
Index:
linux-merge/arch/powerpc/kernel/traps.c
===================================================================arch/powerpc/kernel/traps.c +0
-0[snip]
arch/powerpc/kernel/traps.c static int generic_machine_check_excepti · line 388
Quoted 5 lines
arch/powerpc/kernel/traps.c +4
-1-#elif defined (CONFIG_E500 ) + return 0; +} +#elif defined(CONFIG_E500) +int machine_check_e500 (struct pt_regs *regs)This...
Quoted 6 lines
arch/powerpc/kernel/traps.c +3
-0+{ +unsigned long reason =get_mc_reason (regs); +printk ("Machine check in kernel mode.\n" );printk ("Caused by (from MCSR=%lx): " , reason);
Quoted 15 lines
arch/powerpc/kernel/traps.c static int generic_machine_check_excepti · line 423
Quoted 10 lines
arch/powerpc/kernel/traps.c +5
-1@@ -403,7 +416,14 @@ static int generic_machine_check_exceptiprintk ("Bus - Instruction Parity Error\n" );if (reason &MCSR_BUS_RPERR )printk ("Bus - Read Parity Error\n" ); -#elif defined (CONFIG_E200 ) + + return 0; +} +#elif defined(CONFIG_E200) +int machine_check_e200 (struct pt_regs *regs)... and this cause build failures for most of the mpc8xxx defconfigs. The reason is that e200 and e500 are both lumped under
CONFIG_FSL_BOOKEincputable.c, but you have them segregated more here. I've added a fix that just doesCONFIG_FSL_BOOKEhere to matchcputable.c.
Actually, reverse that. There are other places where e200 and e500 are separated by ifdefs, so I made cputable.c match the rest.
josh