[U-Boot] [PATCH] flread: new command for reading indirect mapped flashes

Mike Frysinger
2009-06-30T18:44:25Z

From: Harald Krapfenbauer <Harald.Krapfenbauer@bluetechnix.at>

The current flash framework generally assumes that the flash in question
is completely directly addressable. With the new weak accessor functions,
that is no longer always the case. These allow us to hook up flashes
whose pins are only partially directly addressable while the rest are
connected to GPIOs. Since all the erase/write commands go through the
weak accessor functions, those work transparently. But for reading from
the flash, the common memory function is still used and this does not go
through the weak accessor functions. So we need a dedicated command to
make sure the weak accessor functions are used to do the actual reading.

Signed-off-by: Harald Krapfenbauer <Harald.Krapfenbauer@bluetechnix.at>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
common/cmd_flash.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
include/flash.h | 7 +++++
2 files changed, 73 insertions(+), 0 deletions(-)

diff --git a/common/cmd_flash.c b/common/cmd_flash.c
index 9f27ab0..b8d305b 100644
--- a/common/cmd_flash.c
+++ b/common/cmd_flash.c
@@ -696,6 +696,72 @@ int flash_sect_protect (int p, ulong addr_first, ulong addr_last)
}
#endif /* CONFIG_SYS_NO_FLASH */

+#if defined(CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS) && !defined(CONFIG_SYS_NO_FLASH)
+int do_flread(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ ulong src, dst, size;
+ u8 *psrc, *pdst, *pend;
+ flash_info_t *info = &flash_info[0];
+
+ if (argc != 4) {
+ cmd_usage(cmdtp);
+ return 1;
+ }
+
+ src = simple_strtoul(argv[1], NULL, 16);
+ dst = simple_strtoul(argv[2], NULL, 16);
+ size = simple_strtoul(argv[3], NULL, 16);
+ if (src < info->start[0] ||
+ (src + size) > (info->start[0] + info->size)) {
+ printf("Error: memory area %#08lx to %#08lx is not in FLASH\n",
+ src, src + size);
+ return 1;
+ }
+ if (dst < CONFIG_SYS_SDRAM_BASE ||
+ (dst + size) > (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_MAX_RAM_SIZE)) {
+ printf("Error: memory area %#08lx to %#08lx is not in RAM\n",
+ dst, dst + size);
+ return 1;
+ }
+
+ psrc = (void *)src;
+ pend = psrc + size;
+ pdst = (void *)dst;
+ if ((src & 0x3) == (dst & 0x3)) {
+ /* copy byte-wise until we get a 32-bit-aligned address */
+ while ((u32)psrc & 0x3) {
+ *pdst = flash_read8(psrc);
+ ++pdst;
+ ++psrc;
+ }
+ /* copy 32-bit words */
+ while (psrc < pend - 3) {
+ u32 *pdst32 = (void *)pdst,
+ *psrc32 = (void *)psrc;
+ *pdst32 = flash_read32(psrc32);
+ pdst = (void *)++pdst32;
+ psrc = (void *)++psrc32;
+ }
+ }
+ /* copy remaining byte-wise */
+ while (psrc < pend) {
+ *pdst = flash_read8(psrc);
+ ++pdst;
+ ++psrc;
+ }
+
+ printf("Done.\n");
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ flread, 4, 0, do_flread,
+ "read from FLASH to RAM",
+ "src dest length\n"
+ " - copy 'length' bytes from FLASH addr 'src' to RAM addr 'dest'\n"
+);
+#endif

/**************************************************/
#if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_CMD_MTDPARTS)
diff --git a/include/flash.h b/include/flash.h
index b016162..c5e7bf4 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -104,6 +104,13 @@ extern int flash_write (char *, ulong, ulong);
extern flash_info_t *addr2info (ulong);
extern int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt);

+/* drivers/mtd/cfi_flash.c */
+#ifdef CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS
+extern u8 flash_read8(void *addr);
+extern u16 flash_read16(void *addr);
+extern u32 flash_read32(void *addr);
+#endif
+
/* drivers/mtd/cfi_mtd.c */
#ifdef CONFIG_FLASH_CFI_MTD
extern int cfi_mtd_init(void);
--
1.6.3.3