We have several places in the code which which prepares just modified code for execution. This is done differently in all the places, so add a common function to be used by all. Most places called arm_early_mmu_cache_flush(). This function includes invalidating the instruction cache, so doing it again is unnecessary. Sometimes we had arm_early_mmu_cache_flush() inside #ifdef CONFIG_MMU. The ifdef seems unnecessary since we do not have it consistently, so remove the ifdef. Some early i.MX xload code had icache_invalidate() but forgot to flush the caches. Replace the instruction cache invalidation with sync_caches_for_execution(). Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx> --- arch/arm/cpu/common.c | 19 +++++++++++++++++-- arch/arm/cpu/setupc.S | 12 ++---------- arch/arm/cpu/setupc_64.S | 5 ++--- arch/arm/cpu/start-pbl.c | 3 +-- arch/arm/cpu/uncompress.c | 3 +-- arch/arm/include/asm/cache.h | 2 ++ arch/arm/mach-layerscape/xload-qspi.c | 3 ++- drivers/mci/imx-esdhc-pbl.c | 4 +++- 8 files changed, 30 insertions(+), 21 deletions(-) diff --git a/arch/arm/cpu/common.c b/arch/arm/cpu/common.c index 51fe7ed988..821cafbf26 100644 --- a/arch/arm/cpu/common.c +++ b/arch/arm/cpu/common.c @@ -27,6 +27,22 @@ #include <asm/cache.h> #include <debug_ll.h> +/** + * sync_caches_for_execution - synchronize caches for code execution + * + * Code has been modified in memory, call this before executing it. + * This function flushes the data cache up to the point of unification + * and invalidates the instruction cache. + */ +void sync_caches_for_execution(void) +{ + /* + * Despite the name arm_early_mmu_cache_flush not only flushes the + * data cache, but also invalidates the instruction cache. + */ + arm_early_mmu_cache_flush(); +} + #define R_ARM_RELATIVE 23 #define R_AARCH64_RELATIVE 1027 @@ -103,8 +119,7 @@ void relocate_to_current_adr(void) #error "Architecture not specified" #endif - arm_early_mmu_cache_flush(); - icache_invalidate(); + sync_caches_for_execution(); } #ifdef ARM_MULTIARCH diff --git a/arch/arm/cpu/setupc.S b/arch/arm/cpu/setupc.S index a5f311b8ec..8ae7c89a2c 100644 --- a/arch/arm/cpu/setupc.S +++ b/arch/arm/cpu/setupc.S @@ -27,11 +27,7 @@ ENTRY(setup_c) ldr r2, =__bss_stop sub r2, r2, r0 bl memset /* clear bss */ -#ifdef CONFIG_MMU - bl arm_early_mmu_cache_flush -#endif - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 /* flush icache */ + bl sync_caches_for_execution sub lr, r5, r4 /* adjust return address to new location */ pop {r4, r5} mov pc, lr @@ -73,11 +69,7 @@ ENTRY(relocate_to_adr) bl memcpy /* copy binary */ -#ifdef CONFIG_MMU - bl arm_early_mmu_cache_flush -#endif - mov r0,#0 - mcr p15, 0, r0, c7, c5, 0 /* flush icache */ + bl sync_caches_for_execution ldr r0,=1f sub r0, r0, r8 diff --git a/arch/arm/cpu/setupc_64.S b/arch/arm/cpu/setupc_64.S index 61e70850d7..ee9ea6cfc0 100644 --- a/arch/arm/cpu/setupc_64.S +++ b/arch/arm/cpu/setupc_64.S @@ -56,9 +56,8 @@ ENTRY(relocate_to_adr) bl memcpy /* copy binary */ -#ifdef CONFIG_MMU - bl arm_early_mmu_cache_flush -#endif + bl sync_caches_for_execution + mov x0,#0 ic ivau, x0 /* flush icache */ diff --git a/arch/arm/cpu/start-pbl.c b/arch/arm/cpu/start-pbl.c index 25ef0d3d82..f5c7cfec19 100644 --- a/arch/arm/cpu/start-pbl.c +++ b/arch/arm/cpu/start-pbl.c @@ -95,8 +95,7 @@ __noreturn void barebox_single_pbl_start(unsigned long membase, pbl_barebox_uncompress((void*)barebox_base, (void *)pg_start, pg_len); - arm_early_mmu_cache_flush(); - icache_invalidate(); + sync_caches_for_execution(); if (IS_ENABLED(CONFIG_THUMB2_BAREBOX)) barebox = (void *)(barebox_base + 1); diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c index e52716557b..c7851c5c75 100644 --- a/arch/arm/cpu/uncompress.c +++ b/arch/arm/cpu/uncompress.c @@ -94,8 +94,7 @@ void __noreturn barebox_multi_pbl_start(unsigned long membase, pbl_barebox_uncompress((void*)barebox_base, pg_start, pg_len); - arm_early_mmu_cache_flush(); - icache_invalidate(); + sync_caches_for_execution(); if (IS_ENABLED(CONFIG_THUMB2_BAREBOX)) barebox = (void *)(barebox_base + 1); diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h index 0822cb78c3..bf3a1a0ed2 100644 --- a/arch/arm/include/asm/cache.h +++ b/arch/arm/include/asm/cache.h @@ -21,4 +21,6 @@ int arm_set_cache_functions(void); void arm_early_mmu_cache_flush(void); void arm_early_mmu_cache_invalidate(void); +void sync_caches_for_execution(void); + #endif diff --git a/arch/arm/mach-layerscape/xload-qspi.c b/arch/arm/mach-layerscape/xload-qspi.c index c76780a0e8..192aea64b4 100644 --- a/arch/arm/mach-layerscape/xload-qspi.c +++ b/arch/arm/mach-layerscape/xload-qspi.c @@ -25,7 +25,8 @@ int ls1046a_qspi_start_image(unsigned long r0, unsigned long r1, out_be32(qspi_reg_base, 0x000f400c); memcpy(membase, qspi_mem_base + BAREBOX_START, barebox_image_size); - icache_invalidate(); + + sync_caches_for_execution(); printf("Starting barebox\n"); diff --git a/drivers/mci/imx-esdhc-pbl.c b/drivers/mci/imx-esdhc-pbl.c index 0251757a2a..367daa85a6 100644 --- a/drivers/mci/imx-esdhc-pbl.c +++ b/drivers/mci/imx-esdhc-pbl.c @@ -332,6 +332,8 @@ esdhc_start_image(struct esdhc *esdhc, ptrdiff_t address, ptrdiff_t entry, u32 o bb = buf + ofs; + sync_caches_for_execution(); + bb(); } @@ -458,7 +460,7 @@ int ls1046a_esdhc_start_image(unsigned long r0, unsigned long r1, unsigned long return ret; } - icache_invalidate(); + sync_caches_for_execution(); printf("Starting barebox\n"); -- 2.20.1 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox