Message ID | 20100301191323.20987.13284.sendpatchset@norville.austin.ibm.com (mailing list archive) |
---|---|
State | Superseded, archived |
Delegated to: | Josh Boyer |
Headers | show |
On Mon, Mar 01, 2010 at 05:13:23AM -0700, Dave Kleikamp wrote: > powerpc/476: add machine check handler for 47x core > > From: Dave Kleikamp <shaggy@linux.vnet.ibm.com> > > The 47x core's MCSR varies from 44x, so it needs it's own machine check > handler. > --- a/arch/powerpc/kernel/traps.c > +++ b/arch/powerpc/kernel/traps.c > @@ -376,6 +376,44 @@ int machine_check_440A(struct pt_regs *regs) > } > return 0; > } > + > +int machine_check_47x(struct pt_regs *regs) > +{ > + unsigned long reason = get_mc_reason(regs); > + > + printk("Machine check in kernel mode.\n"); It's quite possible that the other machine check handlers don't have printk KERN_-levels on them but it would be a good idea to use them here. > + if (reason & ESR_IMCP){ > + printk("Instruction Synchronous Machine Check exception\n"); > + mtspr(SPRN_ESR, reason & ~ESR_IMCP); > + } > + else { } else { Or, rather, add an early return above and you can just remove one level of indentation below. > + u32 mcsr = mfspr(SPRN_MCSR); > + if (mcsr & MCSR_IB) > + printk("Instruction Read PLB Error\n"); > + if (mcsr & MCSR_DRB) > + printk("Data Read PLB Error\n"); > + if (mcsr & MCSR_DWB) > + printk("Data Write PLB Error\n"); > + if (mcsr & MCSR_TLBP) > + printk("TLB Parity Error\n"); > + if (mcsr & MCSR_ICP){ > + flush_instruction_cache(); > + printk("I-Cache Parity Error\n"); > + } > + if (mcsr & MCSR_DCSP) > + printk("D-Cache Search Parity Error\n"); > + if (mcsr & PPC47x_MCSR_GPR) > + printk("GPR Parity Error\n"); > + if (mcsr & PPC47x_MCSR_FPR) > + printk("FPR Parity Error\n"); > + if (mcsr & PPC47x_MCSR_IMP) > + printk("Machine Check exception is imprecise\n"); > + > + /* Clear MCSR */ > + mtspr(SPRN_MCSR, mcsr); > + } > + return 0; > +}
On Mon, 2010-03-01 at 15:08 -0600, Olof Johansson wrote: > On Mon, Mar 01, 2010 at 05:13:23AM -0700, Dave Kleikamp wrote: > > powerpc/476: add machine check handler for 47x core > > > > From: Dave Kleikamp <shaggy@linux.vnet.ibm.com> > > > > The 47x core's MCSR varies from 44x, so it needs it's own machine check > > handler. > > > > --- a/arch/powerpc/kernel/traps.c > > +++ b/arch/powerpc/kernel/traps.c > > @@ -376,6 +376,44 @@ int machine_check_440A(struct pt_regs *regs) > > } > > return 0; > > } > > + > > +int machine_check_47x(struct pt_regs *regs) > > +{ > > + unsigned long reason = get_mc_reason(regs); > > + > > + printk("Machine check in kernel mode.\n"); > > It's quite possible that the other machine check handlers don't have > printk KERN_-levels on them but it would be a good idea to use them here. Right. As it's new code, it should be as correct as possible. > > + if (reason & ESR_IMCP){ > > + printk("Instruction Synchronous Machine Check exception\n"); > > + mtspr(SPRN_ESR, reason & ~ESR_IMCP); > > + } > > + else { > > } else { > > Or, rather, add an early return above and you can just remove one level of indentation below. agreed. Thanks, Shaggy
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 75b774e..9fff628 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -72,6 +72,7 @@ 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); +extern int machine_check_47x(struct pt_regs *regs); /* NOTE WELL: Update identify_cpu() if fields are added or removed! */ struct cpu_spec { diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index ee61a9d..a9245b9 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h @@ -194,7 +194,7 @@ #ifdef CONFIG_PPC_47x #define PPC47x_MCSR_GPR 0x01000000 /* GPR parity error */ #define PPC47x_MCSR_FPR 0x00800000 /* FPR parity error */ -#define PPC47x_MCSR_IPR 0x00400000 /* Imprecise Machine Check Exception */ +#define PPC47x_MCSR_IMP 0x00400000 /* Imprecise Machine Check Exception */ #endif #ifdef CONFIG_E500 diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 338ac47..7b2a67c 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1712,6 +1712,7 @@ static struct cpu_spec __initdata cpu_specs[] = { MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL, .icache_bsize = 32, .dcache_bsize = 128, + .machine_check = machine_check_47x, .platform = "ppc470", }, { /* default match */ diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index d069ff8..66617b6 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -376,6 +376,44 @@ int machine_check_440A(struct pt_regs *regs) } return 0; } + +int machine_check_47x(struct pt_regs *regs) +{ + unsigned long reason = get_mc_reason(regs); + + printk("Machine check in kernel mode.\n"); + if (reason & ESR_IMCP){ + printk("Instruction Synchronous Machine Check exception\n"); + mtspr(SPRN_ESR, reason & ~ESR_IMCP); + } + else { + u32 mcsr = mfspr(SPRN_MCSR); + if (mcsr & MCSR_IB) + printk("Instruction Read PLB Error\n"); + if (mcsr & MCSR_DRB) + printk("Data Read PLB Error\n"); + if (mcsr & MCSR_DWB) + printk("Data Write PLB Error\n"); + if (mcsr & MCSR_TLBP) + printk("TLB Parity Error\n"); + if (mcsr & MCSR_ICP){ + flush_instruction_cache(); + printk("I-Cache Parity Error\n"); + } + if (mcsr & MCSR_DCSP) + printk("D-Cache Search Parity Error\n"); + if (mcsr & PPC47x_MCSR_GPR) + printk("GPR Parity Error\n"); + if (mcsr & PPC47x_MCSR_FPR) + printk("FPR Parity Error\n"); + if (mcsr & PPC47x_MCSR_IMP) + printk("Machine Check exception is imprecise\n"); + + /* Clear MCSR */ + mtspr(SPRN_MCSR, mcsr); + } + return 0; +} #elif defined(CONFIG_E500) int machine_check_e500(struct pt_regs *regs) {