X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=arch%2Farm%2Flib%2Finterrupts.c;h=80869adb6107a71dc7a7ba1a74471be1444cd456;hb=c1c597e8a8abfe16938ce8a1d792c703c1a6c79b;hp=066c172bb32420ed51553fee64e9845984bcdbad;hpb=01abae4d04868dede60947867699bf096a1831ff;p=oweals%2Fu-boot.git diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c index 066c172bb3..80869adb61 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 (); }