summaryrefslogtreecommitdiff
path: root/arch/arm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/lib')
-rw-r--r--arch/arm/lib/bootm.c1
-rw-r--r--arch/arm/lib/cache-cp15.c28
-rw-r--r--arch/arm/lib/interrupts.c14
-rw-r--r--arch/arm/lib/vectors.S5
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.