Reworking machine check handling and Fix 440/440A
Subsystems (2)
PATCH 1/20 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
@@ -207,7 +207,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 */
@@ -217,7 +216,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 */
Quoted 9 lines · On Thu, 13 Dec 2007 18:38:31 +1100 Benjamin Herrenschmidt…
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. =20
This removesCONFIG_440Awhich was a problem for multiplatform kernels and instead fixes up the IVOR at runtime from asetup_cpufunction. The "A" version of the machine check also tweaks theregs->trapvalue to differenciate the 2 versions at the C level.
[snip]
Quoted 2 lines
Index:
linux-merge/include/asm-ppc/reg_booke.h=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Quoted 1 line
---
linux-merge.orig/include/asm-ppc/reg_booke.h2007-12-11 16:21:38.0000=
00000 +1100
Quoted 1 line
+++
linux-merge/include/asm-ppc/reg_booke.h2007-12-11 16:23:21.000000000=
+1100
include/asm-ppc/reg_booke.h line 213
Quoted 9 lines
(quoted diff) +0
-0@@ -207,7 +207,7 @@ #define CCR1_TCS 0x00000080 /* Timer Clock Select */=20
/* Bit definitions for the MCSR. */include/asm-ppc/reg_booke.h +1
-1-#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 */
This breaks non-44x based arch/ppc platforms. For example ep405 in arch/ppc fails with:
/home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c: In function =E2=80=98m= achine_check_440A=E2=80=99:/home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:260: error: =E2=80=98MC= SR_IB=E2=80=99 undeclared (first use in this function) /home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:260: error: (Each undec= lared identifier is reported only once /home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:260: error: for each fu= nction it appears in.) /home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:262: error: =E2=80=98MC= SR_DRB=E2=80=99 undeclared (first use in this function) /home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:264: error: =E2=80=98MC= SR_DWB=E2=80=99 undeclared (first use in this function) /home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:266: error: =E2=80=98MC= SR_TLBP=E2=80=99 undeclared (first use in this function) /home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:268: error: =E2=80=98MC= SR_ICP=E2=80=99 undeclared (first use in this function) /home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:272: error: =E2=80=98MC= SR_DCSP=E2=80=99 undeclared (first use in this function) /home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:274: error: =E2=80=98MC= SR_DCFP=E2=80=99 undeclared (first use in this function) /home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:276: error: =E2=80=98MC= SR_IMPE=E2=80=99 undeclared (first use in this function) make[2]: *** [arch/ppc/kernel/traps.o] Error 1
The same is true for other platforms as well. Getting closer...
josh
Quoted 17 lines
This breaks non-44x based
arch/ppcplatforms. For example ep405 inarch/ppcfails with:
/home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c: In function ‘machine_check_440A’:/home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:260: error: ‘MCSR_IB’ undeclared (first use in this function)/home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:260: error: (Each undeclared identifier is reported only once/home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:260: error: for each function it appears in.)/home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:262: error: ‘MCSR_DRB’ undeclared (first use in this function)/home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:264: error: ‘MCSR_DWB’ undeclared (first use in this function)/home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:266: error: ‘MCSR_TLBP’ undeclared (first use in this function)/home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:268: error: ‘MCSR_ICP’ undeclared (first use in this function)/home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:272: error: ‘MCSR_DCSP’ undeclared (first use in this function)/home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:274: error: ‘MCSR_DCFP’ undeclared (first use in this function)/home/jwboyer/src/linux-2.6/arch/ppc/kernel/traps.c:276: error: ‘MCSR_IMPE’ undeclared (first use in this function) make[2]: *** [arch/ppc/kernel/traps.o] Error 1
Quoted 1 line
The same is true for other platforms as well. Getting closer...
True, I intended to use 4xx not 44x for the ifdef... very easy typo to make.
Ben.