diff options
Diffstat (limited to 'arch/arm/lib')
-rw-r--r-- | arch/arm/lib/cache-cp15.c | 15 | ||||
-rw-r--r-- | arch/arm/lib/interrupts.c | 14 | ||||
-rw-r--r-- | arch/arm/lib/vectors.S | 5 |
3 files changed, 19 insertions, 15 deletions
diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c index cf852c061b..f0c1b03728 100644 --- a/arch/arm/lib/cache-cp15.c +++ b/arch/arm/lib/cache-cp15.c @@ -22,16 +22,6 @@ __weak void arm_init_domains(void) { } -static void cp_delay (void) -{ - volatile int i; - - /* copro seems to need some delay between reading and writing */ - for (i = 0; i < 100; i++) - nop(); - asm volatile("" : : : "memory"); -} - void set_section_dcache(int section, enum dcache_option option) { #ifdef CONFIG_ARMV7_LPAE @@ -205,7 +195,6 @@ static inline void mmu_setup(void) /* and enable the mmu */ reg = get_cr(); /* get control reg. */ - cp_delay(); set_cr(reg | CR_M); } @@ -223,7 +212,6 @@ static void cache_enable(uint32_t cache_bit) if ((cache_bit == CR_C) && !mmu_enabled()) mmu_setup(); reg = get_cr(); /* get control reg. */ - cp_delay(); set_cr(reg | cache_bit); } @@ -233,7 +221,6 @@ static void cache_disable(uint32_t cache_bit) uint32_t reg; reg = get_cr(); - cp_delay(); if (cache_bit == CR_C) { /* if cache isn;t enabled no need to disable */ @@ -243,7 +230,7 @@ static void cache_disable(uint32_t cache_bit) cache_bit |= CR_M; } reg = get_cr(); - cp_delay(); + if (cache_bit == (CR_C | CR_M)) flush_dcache_all(); set_cr(reg & ~cache_bit); 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 (); } diff --git a/arch/arm/lib/vectors.S b/arch/arm/lib/vectors.S index f53b1e9a2b..101909103e 100644 --- a/arch/arm/lib/vectors.S +++ b/arch/arm/lib/vectors.S @@ -117,7 +117,6 @@ data_abort: not_used: irq: fiq: - 1: bl 1b /* hang and never return */ @@ -126,7 +125,11 @@ fiq: /* IRQ stack memory (calculated at run-time) + 8 bytes */ .globl IRQ_STACK_START_IN IRQ_STACK_START_IN: +#ifdef IRAM_BASE_ADDR + .word IRAM_BASE_ADDR + 0x20 +#else .word 0x0badc0de +#endif @ @ IRQ stack frame. |