123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- #define DEBUG
- #include <linux/types.h>
- #include <linux/kernel.h>
- #include <linux/smp.h>
- #include <asm/reg.h>
- #include <asm/io.h>
- #include <asm/prom.h>
- #include <asm/machdep.h>
- #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.
- */
- }
|