cache_invalidate_stale() needs to be executed prior to enabling the
MMU. This was so far guaranteed by __barebox_arm_entry() invoking it
prior to barebox_pbl_start(), which does mmu_early_enable().

As there's more boot time to be saved by calling mmu_early_enable()
earlier, some SoC support has already started calling mmu_early_enable()
prior to barebox_pbl_start(). Should this be extended to older CPUs like
Cortex-A9, we would introduce a regression as the data cache would not be
discarded prior to enabling it.

Avoid this failure mode altogether by having cache_invalidate_stale()
precede the code that depends on it having run.

This function invalidates both I-Cache and D-Cache, but only D-Cache is
interesting to us here as I-Cache has already been invalidated in
arm_cpu_lowlevel_init().

Signed-off-by: Ahmad Fatoum <[email protected]>
---
v1 -> v2:
  - point out that arm_cpu_lowlevel_init() invalidates (Lucas)
---
 arch/arm/cpu/armv7r-mpu.c  |  1 +
 arch/arm/cpu/entry_ll_32.S |  7 -------
 arch/arm/cpu/entry_ll_64.S |  7 -------
 arch/arm/cpu/mmu_32.c      |  2 ++
 arch/arm/cpu/uncompress.c  | 12 ++++++++++--
 5 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/arch/arm/cpu/armv7r-mpu.c b/arch/arm/cpu/armv7r-mpu.c
index d494aec583ef..47e108133178 100644
--- a/arch/arm/cpu/armv7r-mpu.c
+++ b/arch/arm/cpu/armv7r-mpu.c
@@ -34,6 +34,7 @@
 
 void armv7r_cache_enable(void)
 {
+       cache_invalidate_stale();
        set_cr(get_cr() | CR_C);
 }
 
diff --git a/arch/arm/cpu/entry_ll_32.S b/arch/arm/cpu/entry_ll_32.S
index 0763581fded4..981722ab7b05 100644
--- a/arch/arm/cpu/entry_ll_32.S
+++ b/arch/arm/cpu/entry_ll_32.S
@@ -12,12 +12,5 @@
 .section .text.__barebox_arm_entry
 ENTRY(__barebox_arm_entry)
        mov     sp, r3
-       mov     r4, r0
-       mov     r5, r1
-       mov     r6, r2
-       bl      cache_invalidate_stale
-       mov     r0, r4
-       mov     r1, r5
-       mov     r2, r6
        b       barebox_pbl_start
 ENDPROC(__barebox_arm_entry)
diff --git a/arch/arm/cpu/entry_ll_64.S b/arch/arm/cpu/entry_ll_64.S
index c80a23c6506d..71fb74b48f7e 100644
--- a/arch/arm/cpu/entry_ll_64.S
+++ b/arch/arm/cpu/entry_ll_64.S
@@ -12,12 +12,5 @@
 .section .text.__barebox_arm_entry
 ENTRY(__barebox_arm_entry)
        mov     sp, x3
-       mov     x19, x0
-       mov     x20, x1
-       mov     x21, x2
-       bl      cache_invalidate_stale
-       mov     x0, x19
-       mov     x1, x20
-       mov     x2, x21
        b       barebox_pbl_start
 ENDPROC(__barebox_arm_entry)
diff --git a/arch/arm/cpu/mmu_32.c b/arch/arm/cpu/mmu_32.c
index efdb867532f9..7b49643fd79b 100644
--- a/arch/arm/cpu/mmu_32.c
+++ b/arch/arm/cpu/mmu_32.c
@@ -613,6 +613,8 @@ void mmu_early_enable(unsigned long membase, unsigned long 
memsize)
 
        pr_debug("enabling MMU, ttb @ 0x%p\n", ttb);
 
+       cache_invalidate_stale();
+
        if (get_cr() & CR_M)
                return;
 
diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c
index 8f0d0f55f862..4d954b3eaaae 100644
--- a/arch/arm/cpu/uncompress.c
+++ b/arch/arm/cpu/uncompress.c
@@ -85,10 +85,18 @@ void __noreturn barebox_pbl_start(unsigned long membase, 
unsigned long memsize,
 #ifdef DEBUG
        print_pbl_mem_layout(membase, endmem, barebox_base);
 #endif
-       if (IS_ENABLED(CONFIG_MMU))
+
+       /* Enable Caches to speed up the decompression below. */
+       if (IS_ENABLED(CONFIG_MMU)) {
                mmu_early_enable(membase, memsize);
-       else if (IS_ENABLED(CONFIG_ARMV7R_MPU))
+       } else if (IS_ENABLED(CONFIG_ARMV7R_MPU)) {
                armv7r_cache_enable();
+       } else {
+               /* Even if we don't use the cache right now, it may be used 
later.
+                * Some CPUs may boot up with dirty cache lines, get rid of 
them.
+                */
+               cache_invalidate_stale();
+       }
 
        pr_debug("uncompressing barebox ELF at 0x%p (size 0x%08x) to 0x%08lx 
(uncompressed size: 0x%08x)\n",
                        pg_start, pg_len, barebox_base, uncompressed_len);
-- 
2.47.3


Reply via email to