#define DEBUG #include #include #include #include #include #include #include #include #include "ras.h" #include "cbe_regs.h" static void dump_fir(int cpu) { struct cbe_pmd_regs __iomem *pregs = cbe_get_cpu_pmd_regs(cpu); struct cbe_iic_regs __iomem *iregs = cbe_get_cpu_iic_regs(cpu); if (pregs == NULL) return; /* Todo: do some nicer parsing of bits and based on them go down * to other sub-units FIRs and not only IIC */ printk(KERN_ERR "Global Checkstop FIR : 0x%016lx\n", in_be64(&pregs->checkstop_fir)); printk(KERN_ERR "Global Recoverable FIR : 0x%016lx\n", in_be64(&pregs->checkstop_fir)); printk(KERN_ERR "Global MachineCheck FIR : 0x%016lx\n", in_be64(&pregs->spec_att_mchk_fir)); if (iregs == NULL) return; printk(KERN_ERR "IOC FIR : 0x%016lx\n", in_be64(&iregs->ioc_fir)); } void cbe_system_error_exception(struct pt_regs *regs) { int cpu = smp_processor_id(); printk(KERN_ERR "System Error Interrupt on CPU %d !\n", cpu); dump_fir(cpu); dump_stack(); } void cbe_maintenance_exception(struct pt_regs *regs) { int cpu = smp_processor_id(); /* * Nothing implemented for the maintenance interrupt at this point */ printk(KERN_ERR "Unhandled Maintenance interrupt on CPU %d !\n", cpu); dump_stack(); } void cbe_thermal_exception(struct pt_regs *regs) { int cpu = smp_processor_id(); /* * Nothing implemented for the thermal interrupt at this point */ printk(KERN_ERR "Unhandled Thermal interrupt on CPU %d !\n", cpu); dump_stack(); } static int cbe_machine_check_handler(struct pt_regs *regs) { int cpu = smp_processor_id(); printk(KERN_ERR "Machine Check Interrupt on CPU %d !\n", cpu); dump_fir(cpu); /* No recovery from this code now, lets continue */ return 0; } void __init cbe_ras_init(void) { unsigned long hid0; /* * Enable System Error & thermal interrupts and wakeup conditions */ hid0 = mfspr(SPRN_HID0); hid0 |= HID0_CBE_THERM_INT_EN | HID0_CBE_THERM_WAKEUP | HID0_CBE_SYSERR_INT_EN | HID0_CBE_SYSERR_WAKEUP; mtspr(SPRN_HID0, hid0); mb(); /* * Install machine check handler. Leave setting of precise mode to * what the firmware did for now */ ppc_md.machine_check_exception = cbe_machine_check_handler; mb(); /* * For now, we assume that IOC_FIR is already set to forward some * error conditions to the System Error handler. If that is not true * then it will have to be fixed up here. */ }