[U-Boot] [PATCH v2] nand: Fix cache and memory inconsistent issue

Dave Liu daveliu at freescale.com
Fri Nov 28 13:16:28 CET 2008


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 at 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();
 }
-- 
1.5.4



More information about the U-Boot mailing list