diff options
Diffstat (limited to 'arch/arm/lib')
-rw-r--r-- | arch/arm/lib/bootm.c | 1 | ||||
-rw-r--r-- | arch/arm/lib/cache-cp15.c | 28 | ||||
-rw-r--r-- | arch/arm/lib/interrupts.c | 14 | ||||
-rw-r--r-- | arch/arm/lib/vectors.S | 5 |
4 files changed, 31 insertions, 17 deletions
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 704849bd0c7..b3e5d24a322 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -360,6 +360,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) #ifdef CONFIG_CPU_V7M ulong addr = (ulong)kernel_entry | 1; kernel_entry = (void *)addr; + dcache_disable(); #endif s = getenv("machid"); if (s) { diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c index e9bbcf51220..f0c1b03728b 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 @@ -129,7 +119,7 @@ static inline void mmu_setup(void) dram_bank_mmu_setup(i); } -#ifdef CONFIG_ARMV7_LPAE +#if defined(CONFIG_ARMV7_LPAE) && __LINUX_ARM_ARCH__ != 4 /* Set up 4 PTE entries pointing to our 4 1GB page tables */ for (i = 0; i < 4; i++) { u64 *page_table = (u64 *)(gd->arch.tlb_addr + (4096 * 4)); @@ -147,7 +137,7 @@ static inline void mmu_setup(void) #endif if (is_hyp()) { - /* Set HCTR to enable LPAE */ + /* Set HTCR to enable LPAE */ asm volatile("mcr p15, 4, %0, c2, c0, 2" : : "r" (reg) : "memory"); /* Set HTTBR0 */ @@ -172,6 +162,15 @@ static inline void mmu_setup(void) : : "r" (MEMORY_ATTRIBUTES) : "memory"); } #elif defined(CONFIG_CPU_V7) + if (is_hyp()) { + /* Set HTCR to disable LPAE */ + asm volatile("mcr p15, 4, %0, c2, c0, 2" + : : "r" (0) : "memory"); + } else { + /* Set TTBCR to disable LPAE */ + asm volatile("mcr p15, 0, %0, c2, c0, 2" + : : "r" (0) : "memory"); + } /* Set TTBR0 */ reg = gd->arch.tlb_addr & TTBR0_BASE_ADDR_MASK; #if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) @@ -196,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); } @@ -214,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); } @@ -224,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 */ @@ -234,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 066c172bb32..80869adb610 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 f53b1e9a2bc..101909103e4 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. |