arm: adjust PC displayed in exception handlers to point to the failing instruction
authorLothar Waßmann <LW@KARO-electronics.de>
Wed, 2 Jul 2014 12:23:56 +0000 (14:23 +0200)
committerLothar Waßmann <LW@KARO-electronics.de>
Wed, 2 Jul 2014 12:23:56 +0000 (14:23 +0200)
arch/arm/lib/interrupts.c

index 787dceb..a122e74 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 #include <common.h>
-#include <asm/proc-armv/ptrace.h>
+#include <asm/ptrace.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -131,9 +131,17 @@ void show_regs (struct pt_regs *regs)
                thumb_mode (regs) ? " (T)" : "");
 }
 
+/* fixup PC to point to instruction leading to exception */
+static inline void fixup_pc(struct pt_regs *regs, int offset)
+{
+       uint32_t pc = instruction_pointer(regs) + offset;
+       regs->ARM_pc = pc | (regs->ARM_pc & PCMASK);
+}
+
 void do_undefined_instruction (struct pt_regs *pt_regs)
 {
        printf ("undefined instruction\n");
+       fixup_pc(pt_regs, -4);
        show_regs (pt_regs);
        bad_mode ();
 }
@@ -141,6 +149,7 @@ void do_undefined_instruction (struct pt_regs *pt_regs)
 void do_software_interrupt (struct pt_regs *pt_regs)
 {
        printf ("software interrupt\n");
+       fixup_pc(pt_regs, -4);
        show_regs (pt_regs);
        bad_mode ();
 }
@@ -148,6 +157,7 @@ void do_software_interrupt (struct pt_regs *pt_regs)
 void do_prefetch_abort (struct pt_regs *pt_regs)
 {
        printf ("prefetch abort\n");
+       fixup_pc(pt_regs, -8);
        show_regs (pt_regs);
        bad_mode ();
 }
@@ -162,6 +172,7 @@ void do_data_abort (struct pt_regs *pt_regs)
        printf ("data abort\n\n");
        if (fsr & 1)
                printf ("MAYBE you should read doc/README.arm-unaligned-accesses\n\n");
+       fixup_pc(pt_regs, -8);
        show_regs (pt_regs);
        bad_mode ();
 }
@@ -169,6 +180,7 @@ void do_data_abort (struct pt_regs *pt_regs)
 void do_not_used (struct pt_regs *pt_regs)
 {
        printf ("not used\n");
+       fixup_pc(pt_regs, -8);
        show_regs (pt_regs);
        bad_mode ();
 }
@@ -176,6 +188,7 @@ void do_not_used (struct pt_regs *pt_regs)
 void do_fiq (struct pt_regs *pt_regs)
 {
        printf ("fast interrupt request\n");
+       fixup_pc(pt_regs, -8);
        show_regs (pt_regs);
        bad_mode ();
 }
@@ -184,6 +197,7 @@ void do_fiq (struct pt_regs *pt_regs)
 void do_irq (struct pt_regs *pt_regs)
 {
        printf ("interrupt request\n");
+       fixup_pc(pt_regs, -8);
        show_regs (pt_regs);
        bad_mode ();
 }