[PATCH 3/3] ARM: always call dcache_invalidate_stale before enabling D-Cache
Ahmad Fatoum <[email protected]> Tue, 7 Jul 2026 10:05:29 +0200
| Newsgroups | org.infradead.lists.barebox |
|---|---|
| Message-ID | <[email protected]> |
dcache_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 dcache_invalidate_stale() precede the code that depends on it having run. Signed-off-by: Ahmad Fatoum <[email protected]> --- 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..7f43d617c251 100644 --- a/arch/arm/cpu/armv7r-mpu.c +++ b/arch/arm/cpu/armv7r-mpu.c @@ -34,6 +34,7 @@ void armv7r_cache_enable(void) { + dcache_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 eb1793b54e66..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 dcache_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 3404f6d05802..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 dcache_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..e8c4ae2cc259 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); + dcache_invalidate_stale(); + if (get_cr() & CR_M) return; diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c index 8f0d0f55f862..13cfaff18350 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. + */ + dcache_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