bf60x: Add double fault, hardware error and NMI SEC handler
authorSonic Zhang <sonic.zhang@analog.com>
Wed, 4 Jul 2012 11:22:55 +0000 (19:22 +0800)
committerBob Liu <lliubbo@gmail.com>
Tue, 24 Jul 2012 05:39:52 +0000 (13:39 +0800)
Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
Signed-off-by: Bob Liu <lliubbo@gmail.com>
arch/blackfin/include/asm/traps.h
arch/blackfin/mach-common/ints-priority.c

index 70c4e511cae648c4dfbbf0fc2dcf0ac04ddb37af..cec771b8100c7c7e55f4ca242cf4741dc5546166 100644 (file)
        level "   for Supervisor use: Supervisor only registers, all MMRs, and Supervisor\n" \
        level "   only instructions.\n"
 
+extern void double_fault_c(struct pt_regs *fp);
+
 #endif                         /* __ASSEMBLY__ */
 #endif                         /* _BFIN_TRAPS_H */
index 5a109a184021e3145c8aa2cbbb2d94b88c44a72a..9660d5fdbed4786f51b64e5216bfc13b09efc48e 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/gpio.h>
 #include <asm/irq_handler.h>
 #include <asm/dpmc.h>
+#include <asm/traps.h>
 
 #ifndef SEC_GCTL
 # define SIC_SYSIRQ(irq)       (irq - (IRQ_CORETMR + 1))
@@ -413,6 +414,34 @@ void handle_sec_fault(unsigned int irq, struct irq_desc *desc)
        raw_spin_unlock(&desc->lock);
 }
 
+void handle_core_fault(unsigned int irq, struct irq_desc *desc)
+{
+       struct pt_regs *fp = get_irq_regs();
+
+       raw_spin_lock(&desc->lock);
+
+       switch (irq) {
+       case IRQ_C0_DBL_FAULT:
+               double_fault_c(fp);
+               break;
+       case IRQ_C0_HW_ERR:
+               dump_bfin_process(fp);
+               dump_bfin_mem(fp);
+               show_regs(fp);
+               printk(KERN_NOTICE "Kernel Stack\n");
+               show_stack(current, NULL);
+               print_modules();
+               panic("Kernel core hardware error");
+               break;
+       case IRQ_C0_NMI_L1_PARITY_ERR:
+               panic("NMI %d occurs unexpectedly");
+               break;
+       default:
+               panic("Core 1 fault %d occurs unexpectedly");
+       }
+
+       raw_spin_unlock(&desc->lock);
+}
 #endif
 
 #ifdef CONFIG_SMP
@@ -1522,9 +1551,12 @@ int __init init_arch_irq(void)
                } else if (irq < BFIN_IRQ(0)) {
                        irq_set_chip_and_handler(irq, &bfin_internal_irqchip,
                                        handle_simple_irq);
-               } else if (irq < CORE_IRQS && irq != IRQ_CGU_EVT) {
+               } else if (irq == IRQ_SEC_ERR) {
                        irq_set_chip_and_handler(irq, &bfin_sec_irqchip,
                                        handle_sec_fault);
+               } else if (irq < CORE_IRQS && irq >= IRQ_C0_DBL_FAULT) {
+                       irq_set_chip_and_handler(irq, &bfin_sec_irqchip,
+                                       handle_core_fault);
                } else if (irq >= BFIN_IRQ(21) && irq <= BFIN_IRQ(26)) {
                        irq_set_chip(irq, &bfin_sec_irqchip);
                        irq_set_chained_handler(irq, bfin_demux_gpio_irq);