
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);