void nautilus_machine_check(unsigned long vector, unsigned long la_ptr, struct pt_regs *regs) { char *mchk_class; /* Now for some analysis. Machine checks fall into two classes -- those picked up by the system, and those picked up by the CPU. Add to that the two levels of severity - correctable or not. */ if (vector == SCB_Q_SYSMCHK && ((IRONGATE0->dramms & 0x300) == 0x300)) { unsigned long nmi_ctl; /* Clear ALI NMI */ nmi_ctl = inb(0x61); nmi_ctl |= 0x0c; outb(nmi_ctl, 0x61); nmi_ctl &= ~0x0c; outb(nmi_ctl, 0x61); /* Write again clears error bits. */ IRONGATE0->stat_cmd = IRONGATE0->stat_cmd & ~0x100; mb(); IRONGATE0->stat_cmd; /* Write again clears error bits. */ IRONGATE0->dramms = IRONGATE0->dramms; mb(); IRONGATE0->dramms; draina(); wrmces(0x7); mb(); return; } if (vector == SCB_Q_SYSERR) mchk_class = "Correctable"; else if (vector == SCB_Q_SYSMCHK) mchk_class = "Fatal"; else { ev6_machine_check(vector, la_ptr, regs); return; } printk(KERN_CRIT "NAUTILUS Machine check 0x%lx " "[%s System Machine Check (NMI)]\n", vector, mchk_class); naut_sys_machine_check(vector, la_ptr, regs); /* Tell the PALcode to clear the machine check */ draina(); wrmces(0x7); mb(); }
void nautilus_machine_check(unsigned long vector, unsigned long la_ptr) { char *mchk_class; /* */ if (vector == SCB_Q_SYSMCHK && ((IRONGATE0->dramms & 0x300) == 0x300)) { unsigned long nmi_ctl; /* */ nmi_ctl = inb(0x61); nmi_ctl |= 0x0c; outb(nmi_ctl, 0x61); nmi_ctl &= ~0x0c; outb(nmi_ctl, 0x61); /* */ IRONGATE0->stat_cmd = IRONGATE0->stat_cmd & ~0x100; mb(); IRONGATE0->stat_cmd; /* */ IRONGATE0->dramms = IRONGATE0->dramms; mb(); IRONGATE0->dramms; draina(); wrmces(0x7); mb(); return; } if (vector == SCB_Q_SYSERR) mchk_class = "Correctable"; else if (vector == SCB_Q_SYSMCHK) mchk_class = "Fatal"; else { ev6_machine_check(vector, la_ptr); return; } printk(KERN_CRIT "NAUTILUS Machine check 0x%lx " "[%s System Machine Check (NMI)]\n", vector, mchk_class); naut_sys_machine_check(vector, la_ptr, get_irq_regs()); /* */ draina(); wrmces(0x7); mb(); }