Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 67291
b: refs/heads/master
c: cd78341
h: refs/heads/master
i:
  67289: 3a89552
  67287: 5dc43a9
v: v3
  • Loading branch information
Olof Johansson authored and Paul Mackerras committed Sep 13, 2007
1 parent 3ca653b commit 3240c76
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2e1957fd47b9d4b7bf35be2ec3d4b5e3eefe5cc0
refs/heads/master: cd7834167ffb66b470e4d9edb10efb5c1a2dfe7f
110 changes: 106 additions & 4 deletions trunk/arch/powerpc/platforms/pasemi/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,21 @@

#include "pasemi.h"

/* SDC reset register, must be pre-mapped at reset time */
static void __iomem *reset_reg;

/* Various error status registers, must be pre-mapped at MCE time */

#define MAX_MCE_REGS 32
struct mce_regs {
char *name;
void __iomem *addr;
};

static struct mce_regs mce_regs[MAX_MCE_REGS];
static int num_mce_regs;


static void pas_restart(char *cmd)
{
printk("Restarting...\n");
Expand Down Expand Up @@ -106,6 +119,59 @@ void __init pas_setup_arch(void)
pasemi_idle_init();
}

static int __init pas_setup_mce_regs(void)
{
struct pci_dev *dev;
int reg;

if (!machine_is(pasemi))
return -ENODEV;

/* Remap various SoC status registers for use by the MCE handler */

reg = 0;

dev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa00a, NULL);
while (dev && reg < MAX_MCE_REGS) {
mce_regs[reg].name = kasprintf(GFP_KERNEL,
"mc%d_mcdebug_errsta", reg);
mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0x730);
dev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa00a, dev);
reg++;
}

dev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
if (dev && reg+4 < MAX_MCE_REGS) {
mce_regs[reg].name = "iobdbg_IntStatus1";
mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0x438);
reg++;
mce_regs[reg].name = "iobdbg_IOCTbusIntDbgReg";
mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0x454);
reg++;
mce_regs[reg].name = "iobiom_IntStatus";
mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0xc10);
reg++;
mce_regs[reg].name = "iobiom_IntDbgReg";
mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0xc1c);
reg++;
}

dev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa009, NULL);
if (dev && reg+2 < MAX_MCE_REGS) {
mce_regs[reg].name = "l2csts_IntStatus";
mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0x200);
reg++;
mce_regs[reg].name = "l2csts_Cnt";
mce_regs[reg].addr = pasemi_pci_getcfgaddr(dev, 0x214);
reg++;
}

num_mce_regs = reg;

return 0;
}
device_initcall(pas_setup_mce_regs);

static __init void pas_init_IRQ(void)
{
struct device_node *np;
Expand Down Expand Up @@ -166,39 +232,75 @@ static int pas_machine_check_handler(struct pt_regs *regs)
{
int cpu = smp_processor_id();
unsigned long srr0, srr1, dsisr;
int dump_slb = 0;
int i;

srr0 = regs->nip;
srr1 = regs->msr;
dsisr = mfspr(SPRN_DSISR);
printk(KERN_ERR "Machine Check on CPU %d\n", cpu);
printk(KERN_ERR "SRR0 0x%016lx SRR1 0x%016lx\n", srr0, srr1);
printk(KERN_ERR "DSISR 0x%016lx DAR 0x%016lx\n", dsisr, regs->dar);
printk(KERN_ERR "SRR0 0x%016lx SRR1 0x%016lx\n", srr0, srr1);
printk(KERN_ERR "DSISR 0x%016lx DAR 0x%016lx\n", dsisr, regs->dar);
printk(KERN_ERR "BER 0x%016lx MER 0x%016lx\n", mfspr(SPRN_PA6T_BER),
mfspr(SPRN_PA6T_MER));
printk(KERN_ERR "IER 0x%016lx DER 0x%016lx\n", mfspr(SPRN_PA6T_IER),
mfspr(SPRN_PA6T_DER));
printk(KERN_ERR "Cause:\n");

if (srr1 & 0x200000)
printk(KERN_ERR "Signalled by SDC\n");

if (srr1 & 0x100000) {
printk(KERN_ERR "Load/Store detected error:\n");
if (dsisr & 0x8000)
printk(KERN_ERR "D-cache ECC double-bit error or bus error\n");
if (dsisr & 0x4000)
printk(KERN_ERR "LSU snoop response error\n");
if (dsisr & 0x2000)
if (dsisr & 0x2000) {
printk(KERN_ERR "MMU SLB multi-hit or invalid B field\n");
dump_slb = 1;
}
if (dsisr & 0x1000)
printk(KERN_ERR "Recoverable Duptags\n");
if (dsisr & 0x800)
printk(KERN_ERR "Recoverable D-cache parity error count overflow\n");
if (dsisr & 0x400)
printk(KERN_ERR "TLB parity error count overflow\n");
}

if (srr1 & 0x80000)
printk(KERN_ERR "Bus Error\n");
if (srr1 & 0x40000)

if (srr1 & 0x40000) {
printk(KERN_ERR "I-side SLB multiple hit\n");
dump_slb = 1;
}

if (srr1 & 0x20000)
printk(KERN_ERR "I-cache parity error hit\n");

if (num_mce_regs == 0)
printk(KERN_ERR "No MCE registers mapped yet, can't dump\n");
else
printk(KERN_ERR "SoC debug registers:\n");

for (i = 0; i < num_mce_regs; i++)
printk(KERN_ERR "%s: 0x%08x\n", mce_regs[i].name,
in_le32(mce_regs[i].addr));

if (dump_slb) {
unsigned long e, v;
int i;

printk(KERN_ERR "slb contents:\n");
for (i = 0; i < SLB_NUM_ENTRIES; i++) {
asm volatile("slbmfee %0,%1" : "=r" (e) : "r" (i));
asm volatile("slbmfev %0,%1" : "=r" (v) : "r" (i));
printk(KERN_ERR "%02d %016lx %016lx\n", i, e, v);
}
}


/* SRR1[62] is from MSR[62] if recoverable, so pass that back */
return !!(srr1 & 0x2);
}
Expand Down

0 comments on commit 3240c76

Please sign in to comment.