mirror of
https://github.com/torvalds/linux.git
synced 2024-12-14 15:13:52 +00:00
5b4e28577b
We have several 44x machine check handlers defined in traps.c. It would be preferable if they were split out with the platforms that use them. Do that. In the process, drop get_mc_reason() and instead just open code the lookup of reason from regs->dsisr. This avoids a pointless layer of abstraction. We know to use regs->dsisr because 44x enables BOOKE which enables PPC_ADV_DEBUG_REGS, and FSL_BOOKE is not enabled on 44x builds. Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
90 lines
2.3 KiB
C
90 lines
2.3 KiB
C
/*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version
|
|
* 2 of the License, or (at your option) any later version.
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/printk.h>
|
|
#include <linux/ptrace.h>
|
|
|
|
#include <asm/reg.h>
|
|
|
|
int machine_check_440A(struct pt_regs *regs)
|
|
{
|
|
unsigned long reason = regs->dsisr;
|
|
|
|
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 & MCSR_DCFP)
|
|
printk("D-Cache Flush Parity Error\n");
|
|
if (mcsr & MCSR_IMPE)
|
|
printk("Machine Check exception is imprecise\n");
|
|
|
|
/* Clear MCSR */
|
|
mtspr(SPRN_MCSR, mcsr);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#ifdef CONFIG_PPC_47x
|
|
int machine_check_47x(struct pt_regs *regs)
|
|
{
|
|
unsigned long reason = regs->dsisr;
|
|
u32 mcsr;
|
|
|
|
printk(KERN_ERR "Machine check in kernel mode.\n");
|
|
if (reason & ESR_IMCP) {
|
|
printk(KERN_ERR "Instruction Synchronous Machine Check exception\n");
|
|
mtspr(SPRN_ESR, reason & ~ESR_IMCP);
|
|
return 0;
|
|
}
|
|
mcsr = mfspr(SPRN_MCSR);
|
|
if (mcsr & MCSR_IB)
|
|
printk(KERN_ERR "Instruction Read PLB Error\n");
|
|
if (mcsr & MCSR_DRB)
|
|
printk(KERN_ERR "Data Read PLB Error\n");
|
|
if (mcsr & MCSR_DWB)
|
|
printk(KERN_ERR "Data Write PLB Error\n");
|
|
if (mcsr & MCSR_TLBP)
|
|
printk(KERN_ERR "TLB Parity Error\n");
|
|
if (mcsr & MCSR_ICP) {
|
|
flush_instruction_cache();
|
|
printk(KERN_ERR "I-Cache Parity Error\n");
|
|
}
|
|
if (mcsr & MCSR_DCSP)
|
|
printk(KERN_ERR "D-Cache Search Parity Error\n");
|
|
if (mcsr & PPC47x_MCSR_GPR)
|
|
printk(KERN_ERR "GPR Parity Error\n");
|
|
if (mcsr & PPC47x_MCSR_FPR)
|
|
printk(KERN_ERR "FPR Parity Error\n");
|
|
if (mcsr & PPC47x_MCSR_IPR)
|
|
printk(KERN_ERR "Machine Check exception is imprecise\n");
|
|
|
|
/* Clear MCSR */
|
|
mtspr(SPRN_MCSR, mcsr);
|
|
|
|
return 0;
|
|
}
|
|
#endif /* CONFIG_PPC_47x */
|