
we load the secondary stage u-boot image from NAND to system memory by nand_load, we have not flush data cache to memory, not invalidate instruction cache before we jump to RAM. when the system is cache enable and the TLB/page attribute of system memory is cacheable, it will cause issue.
- 83xx family is using the dcache lock, so all of dcache access is cache-inhibited. so you can't see the issue. - 85xx family is using dcache, icache enable, partial cache lock. you will see the issue.
The patch fix the cache issue.
Signed-off-by: Dave Liu daveliu@freescale.com --- nand_spl/nand_boot_fsl_elbc.c | 35 +++++++++++++++++++++++++++++++++++ 1 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/nand_spl/nand_boot_fsl_elbc.c b/nand_spl/nand_boot_fsl_elbc.c index 4a961ea..b0ab734 100644 --- a/nand_spl/nand_boot_fsl_elbc.c +++ b/nand_spl/nand_boot_fsl_elbc.c @@ -27,6 +27,7 @@ #include <asm/io.h> #include <asm/immap_83xx.h> #include <asm/fsl_lbc.h> +#include <asm/cache.h> #include <linux/mtd/nand.h>
#define WINDOW_SIZE 8192 @@ -125,6 +126,33 @@ static void nand_load(unsigned int offs, int uboot_size, uchar *dst) }
/* + * clean the dcache, invalidate the icache + * for powerpc architecture + */ +static void __flush_cache(ulong start, ulong size) +{ + ulong addr, end; + ulong cache_line = CONFIG_SYS_CACHELINE_SIZE; + + end = start + size; + + /* clean the dcache, make sure all of data to memory */ + for (addr = start; addr < end; addr += cache_line) + asm ("dcbst 0,%0": :"r" (addr)); + + /* wait for all dcbst to complete on bus */ + asm ("sync"); + + /* invalidate icache */ + for (addr = start; addr < end; addr += cache_line) + asm ("icbi 0,%0": :"r" (addr)); + + asm ("sync"); + /* flush prefetch queue in any case */ + asm ("isync"); +} + +/* * The main entry for NAND booting. It's necessary that SDRAM is already * configured and available since this code loads the main U-Boot image * from NAND into SDRAM and starts it from there. @@ -143,6 +171,13 @@ void nand_boot(void) * Jump to U-Boot image */ puts("transfering control\n"); + /* + * We need clean dcache and invalidate + * to sync between icache and dcache + * before jump to RAM. make sure all of + * NAND data write to memory. + */ + __flush_cache(CONFIG_SYS_NAND_U_BOOT_DST, CONFIG_SYS_NAND_U_BOOT_SIZE); uboot = (void *)CONFIG_SYS_NAND_U_BOOT_START; uboot(); }