[U-Boot] [PATCH] arm: adjust PC displayed in exception handlers to point to the failing instruction

Lothar Waßmann LW at KARO-electronics.de
Thu Jun 8 07:52:33 UTC 2017


Adjust the program counter register to point to the failing
instruction depending on the exeption type.
This makes it easier to localize the offending instruction leading to
a fatal exception.

Signed-off-by: Lothar Waßmann <LW at KARO-electronics.de>
---
 arch/arm/lib/interrupts.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c
index 066c172..5d06196 100644
--- a/arch/arm/lib/interrupts.c
+++ b/arch/arm/lib/interrupts.c
@@ -93,10 +93,18 @@ void show_regs (struct pt_regs *regs)
 		thumb_mode (regs) ? " (T)" : "");
 }
 
+/* fixup PC to point to the instruction leading to the 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)
 {
 	efi_restore_gd();
 	printf ("undefined instruction\n");
+	fixup_pc(pt_regs, -4);
 	show_regs (pt_regs);
 	bad_mode ();
 }
@@ -105,6 +113,7 @@ void do_software_interrupt (struct pt_regs *pt_regs)
 {
 	efi_restore_gd();
 	printf ("software interrupt\n");
+	fixup_pc(pt_regs, -4);
 	show_regs (pt_regs);
 	bad_mode ();
 }
@@ -113,6 +122,7 @@ void do_prefetch_abort (struct pt_regs *pt_regs)
 {
 	efi_restore_gd();
 	printf ("prefetch abort\n");
+	fixup_pc(pt_regs, -8);
 	show_regs (pt_regs);
 	bad_mode ();
 }
@@ -121,6 +131,7 @@ void do_data_abort (struct pt_regs *pt_regs)
 {
 	efi_restore_gd();
 	printf ("data abort\n");
+	fixup_pc(pt_regs, -8);
 	show_regs (pt_regs);
 	bad_mode ();
 }
@@ -129,6 +140,7 @@ void do_not_used (struct pt_regs *pt_regs)
 {
 	efi_restore_gd();
 	printf ("not used\n");
+	fixup_pc(pt_regs, -8);
 	show_regs (pt_regs);
 	bad_mode ();
 }
@@ -137,6 +149,7 @@ void do_fiq (struct pt_regs *pt_regs)
 {
 	efi_restore_gd();
 	printf ("fast interrupt request\n");
+	fixup_pc(pt_regs, -8);
 	show_regs (pt_regs);
 	bad_mode ();
 }
@@ -145,6 +158,7 @@ void do_irq (struct pt_regs *pt_regs)
 {
 	efi_restore_gd();
 	printf ("interrupt request\n");
+	fixup_pc(pt_regs, -8);
 	show_regs (pt_regs);
 	bad_mode ();
 }
-- 
2.1.4



More information about the U-Boot mailing list