[U-Boot] [PATCH] Add the "mfill" and "mcheck" memory commands.

The mfill command writes the value of a counter to a memory area. The mcheck command verifies the memory area against the counter value. Those commands are useful for debugging memory/framebuffer controller.
The configuration option is CONFIG_MFILL and this only takes effect if the memory commands are activated globally (CONFIG_CMD_MEM).
Signed-off-by: Benoît Monin <bmonin <at> adeneo.eu> --- README | 17 +++++++- common/cmd_mem.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 1 deletions(-)
diff --git a/README b/README index 43fb1c0..d0a636e 100644 --- a/README +++ b/README @@ -627,7 +627,7 @@ The following options need to be configured: CONFIG_CMD_LOADB loadb CONFIG_CMD_LOADS loads CONFIG_CMD_MEMORY md, mm, nm, mw, cp, cmp, crc, base, - loop, loopw, mtest + loop, loopw, mtest, mfill, mcheck CONFIG_CMD_MISC Misc functions like sleep etc CONFIG_CMD_MMC * MMC memory mapped support CONFIG_CMD_MII * MII utility commands @@ -2678,6 +2678,21 @@ Low Level (hardware related) configuration options: This only takes effect if the memory commands are activated globally (CONFIG_CMD_MEM).
+- CONFIG_MFILL + Add the "mfill" and "mcheck" memory commands. "mfill" writes + a memory area with the value of a counter. "mcheck" checks + a memory area against the value of a counter and can be run + after mfill. + + (mfill/mcheck)[.b, .w, .l] address count [init] + [.b, .w, .l] : Access size (default to l). + address : Address in hexadecimal. + count : Number of elements to write in hex. + [init] : Initial value of the counter (default to 0). + + This only takes effect if the memory commands are activated + globally (CONFIG_CMD_MEM). + - CONFIG_SKIP_LOWLEVEL_INIT - CONFIG_SKIP_RELOCATE_UBOOT
diff --git a/common/cmd_mem.c b/common/cmd_mem.c index 2d4fc2a..0191687 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -943,6 +943,117 @@ int do_mem_mtest (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return rcode; }
+#ifdef CONFIG_MFILL +/* Memory fill + * + * Write a memory area with the value of a counter + * + * mfill{.b, .w, .l} {address} {count} {init} + */ +static int do_mem_mfill(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + volatile void* addr; + ulong count; + ulong val; + int size; + + if (argc < 3) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + /* Scan for data size */ + if ((size = cmd_get_data_size(argv[0], 4)) < 0) + return 1; + addr = (void*)simple_strtoul(argv[1], NULL, 16); + addr += base_address; + count = simple_strtoul(argv[2], NULL, 16); + if (argc == 4) { + val = simple_strtoul(argv[3], NULL, 16); + } else { + val = 0; + } + if (size == 4) { + while (count-- > 0) { + *((ulong*)addr) = (ulong)val++; + addr += size; + } + } else if (size == 2) { + while (count-- > 0) { + *((ushort*)addr) = (ushort)val++; + addr += size; + } + } else { + while (count-- > 0) { + *((uchar*)addr) = (uchar)val++; + addr += size; + } + } + return 0; +} + +/* Memory check + * + * Check a memory area against the value of a counter + * Run this after mfill. + * + * mcheck{.b, .w, .l} {address} {count} {init} + */ +static int do_mem_mcheck(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + volatile void* addr; + ulong count; + ulong val; + int size; + + if (argc < 3) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + /* Scan for data size */ + if ((size = cmd_get_data_size(argv[0], 4)) < 0) + return 1; + addr = (void*)simple_strtoul(argv[1], NULL, 16); + addr += base_address; + count = simple_strtoul(argv[2], NULL, 16); + if (argc == 4) { + val = simple_strtoul(argv[3], NULL, 16); + } else { + val = 0; + } + if (size == 4) { + while (count-- > 0) { + if (*((ulong*)addr) != (ulong)val) { + printf ("Mem error @ 0x%p: found 0x%08lx, expected 0x%08lx\n", + addr, *((ulong*)addr), (ulong)val); + if (ctrlc()) return 1; + } + addr += size; + val++; + } + } else if (size == 2) { + while (count-- > 0) { + if (*((ushort*)addr) != (ushort)val) { + printf ("Mem error @ 0x%p: found 0x%04x, expected 0x%04x\n", + addr, *((ushort*)addr), (ushort)val); + if (ctrlc()) return 1; + } + addr += size; + val++; + } + } else { + while (count-- > 0) { + if (*((uchar*)addr) != (uchar)val) { + printf ("Mem error @ 0x%p: found 0x%02x, expected 0x%02x\n", + addr, *((uchar*)addr), (uchar)val); + if (ctrlc()) return 1; + } + addr += size; + val++; + } + } + return 0; +} +#endif /* CONFIG_MFILL */
/* Modify memory. * @@ -1256,6 +1367,22 @@ U_BOOT_CMD( " - simple RAM read/write test\n" );
+#ifdef CONFIG_MFILL +U_BOOT_CMD( + mfill, 4, 1, do_mem_mfill, + "mfill - Fill memory with the value of a counter\n", + "[.b, .w, .l] address count [init]\n" + " - Fill memory range with the value of a counter\n" +); + +U_BOOT_CMD( + mcheck, 4, 1, do_mem_mcheck, + "mcheck - Check memory after mfill\n", + "[.b, .w, .l] address count [init]\n" + " - Check memory range after mfill\n" +); +#endif /* CONFIG_MFILL */ + #ifdef CONFIG_MX_CYCLIC U_BOOT_CMD( mdc, 4, 1, do_mem_mdc,

Dear Benoit Monin,
In message 28907262.11403.1236090567026.JavaMail.www@wwinf8303 you wrote:
The mfill command writes the value of a counter to a memory area. The mcheck command verifies the memory area against the counter value. Those commands are useful for debugging memory/framebuffer controller.
The configuration option is CONFIG_MFILL and this only takes effect if the memory commands are activated globally (CONFIG_CMD_MEM).
What exactly is the purpose of this patch? Looks like an extremely simple memory test to me. Don't we have already a rich selection of better ones available yet?
Best regards,
Wolfgang Denk
participants (2)
-
Benoit Monin
-
Wolfgang Denk