summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2013-05-15 21:11:47 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2013-05-23 09:29:52 +0200
commit28278839116d9e29132a61c2c0c612900c244708 (patch)
tree9fc879b4a385d899515e908b007b96a214032b90
parent465950ee64f6fbeb0daf138c2d43ad71be159375 (diff)
downloadbarebox-28278839116d9e29132a61c2c0c612900c244708.tar.gz
barebox-28278839116d9e29132a61c2c0c612900c244708.tar.xz
ARM: invalidate data caches during early init
Some SoCs come up with invalid entries in the data cache. This can lead to memory corruption when we enable them later, so invalidate the caches early. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Reviewed-by: Lucas Stach <l.stach@pengutronix.de> Tested-by: Lucas Stach <l.stach@pengutronix.de>
-rw-r--r--arch/arm/cpu/cache.c21
-rw-r--r--arch/arm/cpu/start-pbl.c2
-rw-r--r--arch/arm/cpu/start.c2
-rw-r--r--arch/arm/include/asm/cache.h5
4 files changed, 30 insertions, 0 deletions
diff --git a/arch/arm/cpu/cache.c b/arch/arm/cpu/cache.c
index 95c8338250..7aab55b6bc 100644
--- a/arch/arm/cpu/cache.c
+++ b/arch/arm/cpu/cache.c
@@ -134,3 +134,24 @@ void arm_early_mmu_cache_flush(void)
#endif
}
}
+
+void v7_mmu_cache_invalidate(void);
+
+void arm_early_mmu_cache_invalidate(void)
+{
+ switch (arm_early_get_cpu_architecture()) {
+ case CPU_ARCH_ARMv4T:
+ case CPU_ARCH_ARMv5:
+ case CPU_ARCH_ARMv5T:
+ case CPU_ARCH_ARMv5TE:
+ case CPU_ARCH_ARMv5TEJ:
+ case CPU_ARCH_ARMv6:
+ asm volatile("mcr p15, 0, %0, c7, c6, 0\n" : : "r"(0));
+ return;
+#ifdef CONFIG_CPU_32v7
+ case CPU_ARCH_ARMv7:
+ v7_mmu_cache_invalidate();
+ return;
+#endif
+ }
+}
diff --git a/arch/arm/cpu/start-pbl.c b/arch/arm/cpu/start-pbl.c
index 6f03c4a7df..3ef0118521 100644
--- a/arch/arm/cpu/start-pbl.c
+++ b/arch/arm/cpu/start-pbl.c
@@ -59,6 +59,8 @@ static noinline __noreturn void __barebox_arm_entry(uint32_t membase,
endmem -= STACK_SIZE; /* stack */
+ arm_early_mmu_cache_invalidate();
+
if (IS_ENABLED(CONFIG_PBL_RELOCATABLE))
relocate_to_current_adr();
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index 580c1fed22..5a3c629c73 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -124,6 +124,8 @@ void __naked __noreturn barebox_arm_entry(uint32_t membase, uint32_t memsize,
{
arm_setup_stack(membase + memsize - 16);
+ arm_early_mmu_cache_invalidate();
+
__start(membase, memsize, boarddata);
}
#else
diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
index e5621ebbca..f5f8bf3879 100644
--- a/arch/arm/include/asm/cache.h
+++ b/arch/arm/include/asm/cache.h
@@ -10,10 +10,15 @@ int arm_set_cache_functions(void);
#ifdef CONFIG_MMU
void arm_early_mmu_cache_flush(void);
+void arm_early_mmu_cache_invalidate(void);
#else
static inline void arm_early_mmu_cache_flush(void)
{
}
+
+static inline void arm_early_mmu_cache_invalidate(void)
+{
+}
#endif
#endif