From patchwork Wed Jun 3 01:26:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 241591 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Tue, 2 Jun 2020 19:26:44 -0600 Subject: [PATCH 1/6] Update MEM_SUPPORT_64BIT_DATA to be always defined Message-ID: <20200602192642.1.Ibc067a3d1c5425aa60dfb9314a23d6dc5c2e480d@changeid> Define this macro always so we don't need the preprocessor to check it. Convert the users to #if instead of #ifdef. Note that '#if MEM_SUPPORT_64BIT_DATA' does not give an error if the macro is not define. It just assumes zero. Signed-off-by: Simon Glass Reviewed-by: Stefan Roese --- cmd/mem.c | 54 +++++++++++++++++++++---------------------- common/command.c | 2 +- include/compiler.h | 4 +++- lib/display_options.c | 6 ++--- 4 files changed, 34 insertions(+), 32 deletions(-) diff --git a/cmd/mem.c b/cmd/mem.c index 9b97f7bf69..fe43427d3c 100644 --- a/cmd/mem.c +++ b/cmd/mem.c @@ -116,7 +116,7 @@ static int do_mem_nm(struct cmd_tbl *cmdtp, int flag, int argc, static int do_mem_mw(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA u64 writeval; #else ulong writeval; @@ -141,7 +141,7 @@ static int do_mem_mw(struct cmd_tbl *cmdtp, int flag, int argc, /* Get the value to write. */ -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA writeval = simple_strtoull(argv[2], NULL, 16); #else writeval = simple_strtoul(argv[2], NULL, 16); @@ -160,7 +160,7 @@ static int do_mem_mw(struct cmd_tbl *cmdtp, int flag, int argc, while (count-- > 0) { if (size == 4) *((u32 *)buf) = (u32)writeval; -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA else if (size == 8) *((u64 *)buf) = (u64)writeval; #endif @@ -240,7 +240,7 @@ static int do_mem_cmp(struct cmd_tbl *cmdtp, int flag, int argc, int rcode = 0; const char *type; const void *buf1, *buf2, *base; -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA u64 word1, word2; #else ulong word1, word2; @@ -272,7 +272,7 @@ static int do_mem_cmp(struct cmd_tbl *cmdtp, int flag, int argc, if (size == 4) { word1 = *(u32 *)buf1; word2 = *(u32 *)buf2; -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA } else if (size == 8) { word1 = *(u64 *)buf1; word2 = *(u64 *)buf2; @@ -286,7 +286,7 @@ static int do_mem_cmp(struct cmd_tbl *cmdtp, int flag, int argc, } if (word1 != word2) { ulong offset = buf1 - base; -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA printf("%s at 0x%p (%#0*llx) != %s at 0x%p (%#0*llx)\n", type, (void *)(addr1 + offset), size, word1, type, (void *)(addr2 + offset), size, word2); @@ -391,7 +391,7 @@ static int do_mem_loop(struct cmd_tbl *cmdtp, int flag, int argc, { ulong addr, length, i, bytes; int size; -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA volatile u64 *llp; #endif volatile u32 *longp; @@ -424,7 +424,7 @@ static int do_mem_loop(struct cmd_tbl *cmdtp, int flag, int argc, * If we have only one object, just run infinite loops. */ if (length == 1) { -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA if (size == 8) { llp = (u64 *)buf; for (;;) @@ -446,7 +446,7 @@ static int do_mem_loop(struct cmd_tbl *cmdtp, int flag, int argc, i = *cp; } -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA if (size == 8) { for (;;) { llp = (u64 *)buf; @@ -489,7 +489,7 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc, { ulong addr, length, i, bytes; int size; -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA volatile u64 *llp; u64 data; #else @@ -519,7 +519,7 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc, length = simple_strtoul(argv[2], NULL, 16); /* data to write */ -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA data = simple_strtoull(argv[3], NULL, 16); #else data = simple_strtoul(argv[3], NULL, 16); @@ -532,7 +532,7 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc, * If we have only one object, just run infinite loops. */ if (length == 1) { -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA if (size == 8) { llp = (u64 *)buf; for (;;) @@ -554,7 +554,7 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc, *cp = data; } -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA if (size == 8) { for (;;) { llp = (u64 *)buf; @@ -1023,7 +1023,7 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc, char *const argv[]) { ulong addr; -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA u64 i; #else ulong i; @@ -1062,7 +1062,7 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc, printf("%08lx:", addr); if (size == 4) printf(" %08x", *((u32 *)ptr)); -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA else if (size == 8) printf(" %016llx", *((u64 *)ptr)); #endif @@ -1089,7 +1089,7 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc, #endif else { char *endp; -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA i = simple_strtoull(console_buffer, &endp, 16); #else i = simple_strtoul(console_buffer, &endp, 16); @@ -1101,7 +1101,7 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc, bootretry_reset_cmd_timeout(); if (size == 4) *((u32 *)ptr) = i; -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA else if (size == 8) *((u64 *)ptr) = i; #endif @@ -1196,7 +1196,7 @@ static int do_random(struct cmd_tbl *cmdtp, int flag, int argc, U_BOOT_CMD( md, 3, 1, do_mem_md, "memory display", -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] address [# of objects]" #else "[.b, .w, .l] address [# of objects]" @@ -1207,7 +1207,7 @@ U_BOOT_CMD( U_BOOT_CMD( mm, 2, 1, do_mem_mm, "memory modify (auto-incrementing address)", -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] address" #else "[.b, .w, .l] address" @@ -1218,7 +1218,7 @@ U_BOOT_CMD( U_BOOT_CMD( nm, 2, 1, do_mem_nm, "memory modify (constant address)", -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] address" #else "[.b, .w, .l] address" @@ -1228,7 +1228,7 @@ U_BOOT_CMD( U_BOOT_CMD( mw, 4, 1, do_mem_mw, "memory write (fill)", -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] address value [count]" #else "[.b, .w, .l] address value [count]" @@ -1238,7 +1238,7 @@ U_BOOT_CMD( U_BOOT_CMD( cp, 4, 1, do_mem_cp, "memory copy", -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] source target count" #else "[.b, .w, .l] source target count" @@ -1248,7 +1248,7 @@ U_BOOT_CMD( U_BOOT_CMD( cmp, 4, 1, do_mem_cmp, "memory compare", -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] addr1 addr2 count" #else "[.b, .w, .l] addr1 addr2 count" @@ -1299,7 +1299,7 @@ U_BOOT_CMD( U_BOOT_CMD( loop, 3, 1, do_mem_loop, "infinite loop on address range", -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] address number_of_objects" #else "[.b, .w, .l] address number_of_objects" @@ -1310,7 +1310,7 @@ U_BOOT_CMD( U_BOOT_CMD( loopw, 4, 1, do_mem_loopw, "infinite write loop on address range", -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] address number_of_objects data_to_write" #else "[.b, .w, .l] address number_of_objects data_to_write" @@ -1330,7 +1330,7 @@ U_BOOT_CMD( U_BOOT_CMD( mdc, 4, 1, do_mem_mdc, "memory display cyclic", -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] address count delay(ms)" #else "[.b, .w, .l] address count delay(ms)" @@ -1340,7 +1340,7 @@ U_BOOT_CMD( U_BOOT_CMD( mwc, 4, 1, do_mem_mwc, "memory write cyclic", -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA "[.b, .w, .l, .q] address value delay(ms)" #else "[.b, .w, .l] address value delay(ms)" diff --git a/common/command.c b/common/command.c index 4f49f15bfd..fc37ed4d7c 100644 --- a/common/command.c +++ b/common/command.c @@ -473,7 +473,7 @@ int cmd_get_data_size(char* arg, int default_size) return 2; case 'l': return 4; -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA case 'q': return 8; #endif diff --git a/include/compiler.h b/include/compiler.h index ed74c272b8..90b7afae53 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -145,7 +145,9 @@ typedef unsigned long int uintptr_t; #define unlikely(x) __builtin_expect(!!(x), 0) #ifdef __LP64__ -#define MEM_SUPPORT_64BIT_DATA +#define MEM_SUPPORT_64BIT_DATA 1 +#else +#define MEM_SUPPORT_64BIT_DATA 0 #endif #endif diff --git a/lib/display_options.c b/lib/display_options.c index 74f769d9ff..dadfc60560 100644 --- a/lib/display_options.c +++ b/lib/display_options.c @@ -137,7 +137,7 @@ int print_buffer(ulong addr, const void *data, uint width, uint count, { /* linebuf as a union causes proper alignment */ union linebuf { -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA uint64_t uq[MAX_LINE_LENGTH_BYTES/sizeof(uint64_t) + 1]; #endif uint32_t ui[MAX_LINE_LENGTH_BYTES/sizeof(uint32_t) + 1]; @@ -145,7 +145,7 @@ int print_buffer(ulong addr, const void *data, uint width, uint count, uint8_t uc[MAX_LINE_LENGTH_BYTES/sizeof(uint8_t) + 1]; } lb; int i; -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA uint64_t __maybe_unused x; #else uint32_t __maybe_unused x; @@ -168,7 +168,7 @@ int print_buffer(ulong addr, const void *data, uint width, uint count, for (i = 0; i < thislinelen; i++) { if (width == 4) x = lb.ui[i] = *(volatile uint32_t *)data; -#ifdef MEM_SUPPORT_64BIT_DATA +#if MEM_SUPPORT_64BIT_DATA else if (width == 8) x = lb.uq[i] = *(volatile uint64_t *)data; #endif From patchwork Wed Jun 3 01:26:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 241590 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Tue, 2 Jun 2020 19:26:45 -0600 Subject: [PATCH 2/6] cmd: mem: Use a macro to avoid #ifdef in help In-Reply-To: <20200602192642.1.Ibc067a3d1c5425aa60dfb9314a23d6dc5c2e480d@changeid> References: <20200602192642.1.Ibc067a3d1c5425aa60dfb9314a23d6dc5c2e480d@changeid> Message-ID: <20200602192642.2.I20e53b990f01eec7de8a443fdf410d109ca0f159@changeid> It is a bit painful to have #ifdefs in the middle of the help for each command. Add a macro to avoid this. Signed-off-by: Simon Glass Reviewed-by: Stefan Roese --- cmd/mem.c | 68 ++++++++++++++----------------------------------------- 1 file changed, 17 insertions(+), 51 deletions(-) diff --git a/cmd/mem.c b/cmd/mem.c index fe43427d3c..da02bbce95 100644 --- a/cmd/mem.c +++ b/cmd/mem.c @@ -33,6 +33,13 @@ DECLARE_GLOBAL_DATA_PTR; #define CONFIG_SYS_MEMTEST_SCRATCH 0 #endif +/* Create a compile-time value */ +#if MEM_SUPPORT_64BIT_DATA +#define HELP_Q ", .q" +#else +#define HELP_Q "" +#endif + static int mod_mem(struct cmd_tbl *, int, int, int, char * const []); /* Display values from last command. @@ -1016,7 +1023,6 @@ static int do_mem_mtest(struct cmd_tbl *cmdtp, int flag, int argc, * * Syntax: * mm{.b, .w, .l, .q} {addr} - * nm{.b, .w, .l, .q} {addr} */ static int mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc, @@ -1196,63 +1202,39 @@ static int do_random(struct cmd_tbl *cmdtp, int flag, int argc, U_BOOT_CMD( md, 3, 1, do_mem_md, "memory display", -#if MEM_SUPPORT_64BIT_DATA - "[.b, .w, .l, .q] address [# of objects]" -#else - "[.b, .w, .l] address [# of objects]" -#endif + "[.b, .w, .l" HELP_Q "] address [# of objects]" ); U_BOOT_CMD( mm, 2, 1, do_mem_mm, "memory modify (auto-incrementing address)", -#if MEM_SUPPORT_64BIT_DATA - "[.b, .w, .l, .q] address" -#else - "[.b, .w, .l] address" -#endif + "[.b, .w, .l" HELP_Q "] address" ); U_BOOT_CMD( nm, 2, 1, do_mem_nm, "memory modify (constant address)", -#if MEM_SUPPORT_64BIT_DATA - "[.b, .w, .l, .q] address" -#else - "[.b, .w, .l] address" -#endif + "[.b, .w, .l" HELP_Q "] address" ); U_BOOT_CMD( mw, 4, 1, do_mem_mw, "memory write (fill)", -#if MEM_SUPPORT_64BIT_DATA - "[.b, .w, .l, .q] address value [count]" -#else - "[.b, .w, .l] address value [count]" -#endif + "[.b, .w, .l" HELP_Q "] address value [count]" ); U_BOOT_CMD( cp, 4, 1, do_mem_cp, "memory copy", -#if MEM_SUPPORT_64BIT_DATA - "[.b, .w, .l, .q] source target count" -#else - "[.b, .w, .l] source target count" -#endif + "[.b, .w, .l" HELP_Q "] source target count" ); U_BOOT_CMD( cmp, 4, 1, do_mem_cmp, "memory compare", -#if MEM_SUPPORT_64BIT_DATA - "[.b, .w, .l, .q] addr1 addr2 count" -#else - "[.b, .w, .l] addr1 addr2 count" -#endif + "[.b, .w, .l" HELP_Q "] addr1 addr2 count" ); #ifdef CONFIG_CMD_CRC32 @@ -1299,22 +1281,14 @@ U_BOOT_CMD( U_BOOT_CMD( loop, 3, 1, do_mem_loop, "infinite loop on address range", -#if MEM_SUPPORT_64BIT_DATA - "[.b, .w, .l, .q] address number_of_objects" -#else - "[.b, .w, .l] address number_of_objects" -#endif + "[.b, .w, .l" HELP_Q "] address number_of_objects" ); #ifdef CONFIG_LOOPW U_BOOT_CMD( loopw, 4, 1, do_mem_loopw, "infinite write loop on address range", -#if MEM_SUPPORT_64BIT_DATA - "[.b, .w, .l, .q] address number_of_objects data_to_write" -#else - "[.b, .w, .l] address number_of_objects data_to_write" -#endif + "[.b, .w, .l" HELP_Q "] address number_of_objects data_to_write" ); #endif /* CONFIG_LOOPW */ @@ -1330,21 +1304,13 @@ U_BOOT_CMD( U_BOOT_CMD( mdc, 4, 1, do_mem_mdc, "memory display cyclic", -#if MEM_SUPPORT_64BIT_DATA - "[.b, .w, .l, .q] address count delay(ms)" -#else - "[.b, .w, .l] address count delay(ms)" -#endif + "[.b, .w, .l" HELP_Q "] address count delay(ms)" ); U_BOOT_CMD( mwc, 4, 1, do_mem_mwc, "memory write cyclic", -#if MEM_SUPPORT_64BIT_DATA - "[.b, .w, .l, .q] address value delay(ms)" -#else - "[.b, .w, .l] address value delay(ms)" -#endif + "[.b, .w, .l" HELP_Q "] address value delay(ms)" ); #endif /* CONFIG_CMD_MX_CYCLIC */ From patchwork Wed Jun 3 01:26:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 241594 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Tue, 2 Jun 2020 19:26:46 -0600 Subject: [PATCH 3/6] cmd: mem: Drop #ifdef for MEM_SUPPORT_64BIT_DATA In-Reply-To: <20200602192642.1.Ibc067a3d1c5425aa60dfb9314a23d6dc5c2e480d@changeid> References: <20200602192642.1.Ibc067a3d1c5425aa60dfb9314a23d6dc5c2e480d@changeid> Message-ID: <20200602192642.3.I47d7286dc9fe42c0ccfe4fb078bf85a87783b0eb@changeid> This is defined only when __lp64__ is defined. That means that ulong is 64 bits long. Therefore we don't need to use a separate u64 type on those architectures. Fix up the code to take advantage of that, removing the preprocessor conditions. Signed-off-by: Simon Glass Reviewed-by: Stefan Roese --- cmd/mem.c | 117 ++++++++++++++++++------------------------------------ 1 file changed, 38 insertions(+), 79 deletions(-) diff --git a/cmd/mem.c b/cmd/mem.c index da02bbce95..9ab6b1dd08 100644 --- a/cmd/mem.c +++ b/cmd/mem.c @@ -34,9 +34,11 @@ DECLARE_GLOBAL_DATA_PTR; #endif /* Create a compile-time value */ -#if MEM_SUPPORT_64BIT_DATA +#ifdef MEM_SUPPORT_64BIT_DATA +#define SUPPORT_64BIT_DATA 1 #define HELP_Q ", .q" #else +#define SUPPORT_64BIT_DATA 0 #define HELP_Q "" #endif @@ -123,11 +125,7 @@ static int do_mem_nm(struct cmd_tbl *cmdtp, int flag, int argc, static int do_mem_mw(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { -#if MEM_SUPPORT_64BIT_DATA - u64 writeval; -#else - ulong writeval; -#endif + ulong writeval; /* 64-bit if SUPPORT_64BIT_DATA */ ulong addr, count; int size; void *buf, *start; @@ -148,11 +146,10 @@ static int do_mem_mw(struct cmd_tbl *cmdtp, int flag, int argc, /* Get the value to write. */ -#if MEM_SUPPORT_64BIT_DATA - writeval = simple_strtoull(argv[2], NULL, 16); -#else - writeval = simple_strtoul(argv[2], NULL, 16); -#endif + if (SUPPORT_64BIT_DATA) + writeval = simple_strtoull(argv[2], NULL, 16); + else + writeval = simple_strtoul(argv[2], NULL, 16); /* Count ? */ if (argc == 4) { @@ -167,10 +164,8 @@ static int do_mem_mw(struct cmd_tbl *cmdtp, int flag, int argc, while (count-- > 0) { if (size == 4) *((u32 *)buf) = (u32)writeval; -#if MEM_SUPPORT_64BIT_DATA - else if (size == 8) - *((u64 *)buf) = (u64)writeval; -#endif + else if (SUPPORT_64BIT_DATA && size == 8) + *((ulong *)buf) = writeval; else if (size == 2) *((u16 *)buf) = (u16)writeval; else @@ -247,11 +242,7 @@ static int do_mem_cmp(struct cmd_tbl *cmdtp, int flag, int argc, int rcode = 0; const char *type; const void *buf1, *buf2, *base; -#if MEM_SUPPORT_64BIT_DATA - u64 word1, word2; -#else - ulong word1, word2; -#endif + ulong word1, word2; /* 64-bit if SUPPORT_64BIT_DATA */ if (argc != 4) return CMD_RET_USAGE; @@ -279,11 +270,9 @@ static int do_mem_cmp(struct cmd_tbl *cmdtp, int flag, int argc, if (size == 4) { word1 = *(u32 *)buf1; word2 = *(u32 *)buf2; -#if MEM_SUPPORT_64BIT_DATA - } else if (size == 8) { - word1 = *(u64 *)buf1; - word2 = *(u64 *)buf2; -#endif + } else if (SUPPORT_64BIT_DATA && size == 8) { + word1 = *(ulong *)buf1; + word2 = *(ulong *)buf2; } else if (size == 2) { word1 = *(u16 *)buf1; word2 = *(u16 *)buf2; @@ -293,15 +282,9 @@ static int do_mem_cmp(struct cmd_tbl *cmdtp, int flag, int argc, } if (word1 != word2) { ulong offset = buf1 - base; -#if MEM_SUPPORT_64BIT_DATA - printf("%s at 0x%p (%#0*llx) != %s at 0x%p (%#0*llx)\n", - type, (void *)(addr1 + offset), size, word1, - type, (void *)(addr2 + offset), size, word2); -#else printf("%s at 0x%08lx (%#0*lx) != %s at 0x%08lx (%#0*lx)\n", type, (ulong)(addr1 + offset), size, word1, type, (ulong)(addr2 + offset), size, word2); -#endif rcode = 1; break; } @@ -398,9 +381,7 @@ static int do_mem_loop(struct cmd_tbl *cmdtp, int flag, int argc, { ulong addr, length, i, bytes; int size; -#if MEM_SUPPORT_64BIT_DATA - volatile u64 *llp; -#endif + volatile ulong *llp; /* 64-bit if SUPPORT_64BIT_DATA */ volatile u32 *longp; volatile u16 *shortp; volatile u8 *cp; @@ -431,13 +412,11 @@ static int do_mem_loop(struct cmd_tbl *cmdtp, int flag, int argc, * If we have only one object, just run infinite loops. */ if (length == 1) { -#if MEM_SUPPORT_64BIT_DATA - if (size == 8) { - llp = (u64 *)buf; + if (SUPPORT_64BIT_DATA && size == 8) { + llp = (ulong *)buf; for (;;) i = *llp; } -#endif if (size == 4) { longp = (u32 *)buf; for (;;) @@ -453,16 +432,14 @@ static int do_mem_loop(struct cmd_tbl *cmdtp, int flag, int argc, i = *cp; } -#if MEM_SUPPORT_64BIT_DATA - if (size == 8) { + if (SUPPORT_64BIT_DATA && size == 8) { for (;;) { - llp = (u64 *)buf; + llp = (ulong *)buf; i = length; while (i-- > 0) *llp++; } } -#endif if (size == 4) { for (;;) { longp = (u32 *)buf; @@ -496,12 +473,8 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc, { ulong addr, length, i, bytes; int size; -#if MEM_SUPPORT_64BIT_DATA - volatile u64 *llp; - u64 data; -#else - ulong data; -#endif + volatile ulong *llp; /* 64-bit if SUPPORT_64BIT_DATA */ + ulong data; /* 64-bit if SUPPORT_64BIT_DATA */ volatile u32 *longp; volatile u16 *shortp; volatile u8 *cp; @@ -526,11 +499,10 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc, length = simple_strtoul(argv[2], NULL, 16); /* data to write */ -#if MEM_SUPPORT_64BIT_DATA - data = simple_strtoull(argv[3], NULL, 16); -#else - data = simple_strtoul(argv[3], NULL, 16); -#endif + if (SUPPORT_64BIT_DATA) + data = simple_strtoull(argv[3], NULL, 16); + else + data = simple_strtoul(argv[3], NULL, 16); bytes = size * length; buf = map_sysmem(addr, bytes); @@ -539,13 +511,11 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc, * If we have only one object, just run infinite loops. */ if (length == 1) { -#if MEM_SUPPORT_64BIT_DATA - if (size == 8) { - llp = (u64 *)buf; + if (SUPPORT_64BIT_DATA && size == 8) { + llp = (ulong *)buf; for (;;) *llp = data; } -#endif if (size == 4) { longp = (u32 *)buf; for (;;) @@ -561,16 +531,14 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc, *cp = data; } -#if MEM_SUPPORT_64BIT_DATA - if (size == 8) { + if (SUPPORT_64BIT_DATA && size == 8) { for (;;) { - llp = (u64 *)buf; + llp = (ulong *)buf; i = length; while (i-- > 0) *llp++ = data; } } -#endif if (size == 4) { for (;;) { longp = (u32 *)buf; @@ -1029,11 +997,7 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc, char *const argv[]) { ulong addr; -#if MEM_SUPPORT_64BIT_DATA - u64 i; -#else - ulong i; -#endif + ulong i; /* 64-bit if SUPPORT_64BIT_DATA */ int nbytes, size; void *ptr = NULL; @@ -1068,10 +1032,8 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc, printf("%08lx:", addr); if (size == 4) printf(" %08x", *((u32 *)ptr)); -#if MEM_SUPPORT_64BIT_DATA - else if (size == 8) - printf(" %016llx", *((u64 *)ptr)); -#endif + else if (SUPPORT_64BIT_DATA && size == 8) + printf(" %0lx", *((ulong *)ptr)); else if (size == 2) printf(" %04x", *((u16 *)ptr)); else @@ -1095,11 +1057,10 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc, #endif else { char *endp; -#if MEM_SUPPORT_64BIT_DATA - i = simple_strtoull(console_buffer, &endp, 16); -#else - i = simple_strtoul(console_buffer, &endp, 16); -#endif + if (SUPPORT_64BIT_DATA) + i = simple_strtoull(console_buffer, &endp, 16); + else + i = simple_strtoul(console_buffer, &endp, 16); nbytes = endp - console_buffer; if (nbytes) { /* good enough to not time out @@ -1107,10 +1068,8 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc, bootretry_reset_cmd_timeout(); if (size == 4) *((u32 *)ptr) = i; -#if MEM_SUPPORT_64BIT_DATA - else if (size == 8) - *((u64 *)ptr) = i; -#endif + else if (SUPPORT_64BIT_DATA && size == 8) + *((ulong *)ptr) = i; else if (size == 2) *((u16 *)ptr) = i; else From patchwork Wed Jun 3 01:26:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 241592 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Tue, 2 Jun 2020 19:26:47 -0600 Subject: [PATCH 4/6] display_options: Drop #ifdef for MEM_SUPPORT_64BIT_DATA In-Reply-To: <20200602192642.1.Ibc067a3d1c5425aa60dfb9314a23d6dc5c2e480d@changeid> References: <20200602192642.1.Ibc067a3d1c5425aa60dfb9314a23d6dc5c2e480d@changeid> Message-ID: <20200602192642.4.I47d7286dc9fe42c0ccfe4fb078bf85a87783b0eb@changeid> This is defined only when __lp64__ is defined. That means that ulong is 64 bits long. Therefore we don't need to use a separate u64 type on those architectures. Fix up the code to take advantage of that, removing the preprocessor conditions. Also include the missing header file that defines MEM_SUPPORT_64BIT_DATA Fixes: 09140113108 ("command: Remove the cmd_tbl_t typedef") Signed-off-by: Simon Glass --- lib/display_options.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/lib/display_options.c b/lib/display_options.c index dadfc60560..ea9977cc18 100644 --- a/lib/display_options.c +++ b/lib/display_options.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -137,19 +138,13 @@ int print_buffer(ulong addr, const void *data, uint width, uint count, { /* linebuf as a union causes proper alignment */ union linebuf { -#if MEM_SUPPORT_64BIT_DATA uint64_t uq[MAX_LINE_LENGTH_BYTES/sizeof(uint64_t) + 1]; -#endif uint32_t ui[MAX_LINE_LENGTH_BYTES/sizeof(uint32_t) + 1]; uint16_t us[MAX_LINE_LENGTH_BYTES/sizeof(uint16_t) + 1]; uint8_t uc[MAX_LINE_LENGTH_BYTES/sizeof(uint8_t) + 1]; } lb; int i; -#if MEM_SUPPORT_64BIT_DATA - uint64_t __maybe_unused x; -#else - uint32_t __maybe_unused x; -#endif + ulong x; if (linelen*width > MAX_LINE_LENGTH_BYTES) linelen = MAX_LINE_LENGTH_BYTES / width; @@ -168,20 +163,16 @@ int print_buffer(ulong addr, const void *data, uint width, uint count, for (i = 0; i < thislinelen; i++) { if (width == 4) x = lb.ui[i] = *(volatile uint32_t *)data; -#if MEM_SUPPORT_64BIT_DATA - else if (width == 8) - x = lb.uq[i] = *(volatile uint64_t *)data; -#endif + else if (MEM_SUPPORT_64BIT_DATA && width == 8) + x = lb.uq[i] = *(volatile ulong *)data; else if (width == 2) x = lb.us[i] = *(volatile uint16_t *)data; else x = lb.uc[i] = *(volatile uint8_t *)data; #if defined(CONFIG_SPL_BUILD) printf(" %x", (uint)x); -#elif defined(MEM_SUPPORT_64BIT_DATA) - printf(" %0*llx", width * 2, (long long)x); #else - printf(" %0*x", width * 2, x); + printf(" %0*lx", width * 2, x); #endif data += width; } From patchwork Wed Jun 3 01:26:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 241593 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Tue, 2 Jun 2020 19:26:48 -0600 Subject: [PATCH 5/6] command: Drop #ifdef for MEM_SUPPORT_64BIT_DATA In-Reply-To: <20200602192642.1.Ibc067a3d1c5425aa60dfb9314a23d6dc5c2e480d@changeid> References: <20200602192642.1.Ibc067a3d1c5425aa60dfb9314a23d6dc5c2e480d@changeid> Message-ID: <20200602192642.5.Id801bb27e51c631b4d06e973d233e950e25fc8a3@changeid> This is defined only when __lp64__ is defined. That means that ulong is 64 bits long. Therefore we don't need to use a separate u64 type on those architectures. Fix up the code to take advantage of that, removing the preprocessor conditions. Also include the header file that defines MEM_SUPPORT_64BIT_DATA. It is included by env.h in this file, but that might not last forever. Signed-off-by: Simon Glass --- common/command.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/common/command.c b/common/command.c index fc37ed4d7c..2c491e20a7 100644 --- a/common/command.c +++ b/common/command.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -473,12 +474,12 @@ int cmd_get_data_size(char* arg, int default_size) return 2; case 'l': return 4; -#if MEM_SUPPORT_64BIT_DATA - case 'q': - return 8; -#endif case 's': return -2; + case 'q': + if (MEM_SUPPORT_64BIT_DATA) + return 8; + /* no break */ default: return -1; } From patchwork Wed Jun 3 01:26:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 241595 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Tue, 2 Jun 2020 19:26:49 -0600 Subject: [PATCH 6/6] cmd: Add a memory-search command In-Reply-To: <20200602192642.1.Ibc067a3d1c5425aa60dfb9314a23d6dc5c2e480d@changeid> References: <20200602192642.1.Ibc067a3d1c5425aa60dfb9314a23d6dc5c2e480d@changeid> Message-ID: <20200602192642.6.Iaf24bd607de3836b8cd474fd0ae88452396ccb62@changeid> It is useful to be able to find hex values and strings in a memory range. Add a command to support this. cmd: Fix 'md' and add a memory-search command At present 'md.q' is broken. This series provides a fix for this. It also implements a new memory-search command called 'ms'. It allows searching memory for hex and string data. END Signed-off-by: Simon Glass --- README | 10 ++ cmd/Kconfig | 14 +++ cmd/mem.c | 151 +++++++++++++++++++++++ test/Makefile | 1 + test/cmd/Makefile | 5 + test/cmd/mem_search.c | 275 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 456 insertions(+) create mode 100644 test/cmd/Makefile create mode 100644 test/cmd/mem_search.c diff --git a/README b/README index 17dc0ee33b..8abcff0783 100644 --- a/README +++ b/README @@ -3283,6 +3283,7 @@ md - memory display mm - memory modify (auto-incrementing) nm - memory modify (constant address) mw - memory write (fill) +ms - memory search cp - memory copy cmp - memory compare crc32 - checksum calculation @@ -3528,6 +3529,15 @@ List of environment variables (most likely not complete): CONFIG_NET_RETRY_COUNT, if defined. This value has precedence over the valu based on CONFIG_NET_RETRY_COUNT. + memmatches - Number of matches found by the last 'ms' command, in hex + + memaddr - Address of the last match found by the 'ms' command, in hex, + or 0 if none + + mempos - Index position of the last match found by the 'ms' command, + in units of the size (.b, .w, .l) of the search + + The following image location variables contain the location of images used in booting. The "Image" column gives the role of the image and is not an environment variable name. The other columns are environment diff --git a/cmd/Kconfig b/cmd/Kconfig index 153864c587..a02a376d49 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -717,6 +717,20 @@ config CMD_MEMORY base - print or set address offset loop - initialize loop on address range +config MEM_SEARCH + bool "ms - Memory search" + help + Memory-search command + + This allows searching through a region of memory looking for hex + data (byte, 16-bit word, 32-bit long, also 64-bit on machines that + support it). It is also possible to search for a string. The + command accepts a memory range and a list of values to search for. + The values need to appear in memory in the same order they are given + in the command. At most 10 matches can be returned at a time, but + pressing return will show the next 10 matches. Environment variables + are set for use with scripting (memmatches, memaddr, mempos). + config CMD_MX_CYCLIC bool "Enable cyclic md/mw commands" depends on CMD_MEMORY diff --git a/cmd/mem.c b/cmd/mem.c index 9ab6b1dd08..575893c18d 100644 --- a/cmd/mem.c +++ b/cmd/mem.c @@ -25,6 +25,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -52,6 +53,10 @@ static ulong dp_last_length = 0x40; static ulong mm_last_addr, mm_last_size; static ulong base_address = 0; +#ifdef CONFIG_MEM_SEARCH +static u8 search_buf[64]; +static uint search_len; +#endif /* Memory Display * @@ -362,6 +367,142 @@ static int do_mem_cp(struct cmd_tbl *cmdtp, int flag, int argc, return 0; } +#ifdef CONFIG_MEM_SEARCH +static int do_mem_search(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + ulong addr, length, bytes, offset; + u8 *ptr, *end, *buf; + bool quiet = false; + ulong last_pos; /* Offset of last match in 'size' units*/ + ulong last_addr; /* Address of last displayed line */ + int limit = 10; + int count; + int size; + int i; + + /* We use the last specified parameters, unless new ones are entered */ + addr = dp_last_addr; + size = dp_last_size; + length = dp_last_length; + + if (argc < 3) + return CMD_RET_USAGE; + + if ((!flag & CMD_FLAG_REPEAT)) { + /* + * Check for a size specification. + * Defaults to long if no or incorrect specification. + */ + size = cmd_get_data_size(argv[0], 4); + if (size < 0 && size != -2 /* string */) + return 1; + + argc--; argv++; + while (argc && *argv[0] == '-') { + int ch = argv[0][1]; + + if (ch == 'q') + quiet = true; + else if (ch == 'l' && isxdigit(argv[0][2])) + limit = simple_strtoul(argv[0] + 2, NULL, 16); + else + return CMD_RET_USAGE; + argc--; argv++; + } + + /* Address is specified since argc > 1 */ + addr = simple_strtoul(argv[0], NULL, 16); + addr += base_address; + + /* Length is the number of objects, not number of bytes */ + length = simple_strtoul(argv[1], NULL, 16); + + /* Read the bytes to search for */ + end = search_buf + sizeof(search_buf); + for (i = 2, ptr = search_buf; i < argc && ptr < end; i++) { + if (SUPPORT_64BIT_DATA && size == 8) { + u64 val = simple_strtoull(argv[i], NULL, 16); + + *(u64 *)ptr = val; + } else if (size == -2) { /* string */ + int len = min(strlen(argv[i]), + (size_t)(end - ptr)); + + memcpy(ptr, argv[i], len); + ptr += len; + continue; + } else { + u32 val = simple_strtoul(argv[i], NULL, 16); + + switch (size) { + case 1: + *ptr = val; + break; + case 2: + *(u16 *)ptr = val; + break; + case 4: + *(u32 *)ptr = val; + break; + } + } + ptr += size; + } + search_len = ptr - search_buf; + } + + /* Do the search */ + if (size == -2) + size = 1; + bytes = size * length; + buf = map_sysmem(addr, bytes); + last_pos = 0; + last_addr = 0; + count = 0; + for (offset = 0; offset <= bytes - search_len && count < limit; + offset += size) { + void *ptr = buf + offset; + + if (!memcmp(ptr, search_buf, search_len)) { + uint align = (addr + offset) & 0xf; + ulong match = addr + offset; + + if (!count || (last_addr & ~0xf) != (match & ~0xf)) { + if (!quiet) { + if (count) + printf("--\n"); + print_buffer(match - align, ptr - align, + size, + ALIGN(search_len + align, + 16) / size, 0); + } + last_addr = match; + last_pos = offset / size; + } + count++; + } + } + if (!quiet) { + printf("%d match%s", count, count == 1 ? "" : "es"); + if (count == limit) + printf(" (repeat command to check for more)"); + printf("\n"); + } + env_set_hex("memmatches", count); + env_set_hex("memaddr", last_addr); + env_set_hex("mempos", last_pos); + + unmap_sysmem(buf); + + dp_last_addr = addr + offset / size; + dp_last_size = size; + dp_last_length = length - offset / size; + + return count ? 0 : CMD_RET_FAILURE; +} +#endif + static int do_mem_base(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { @@ -1196,6 +1337,16 @@ U_BOOT_CMD( "[.b, .w, .l" HELP_Q "] addr1 addr2 count" ); +#ifdef CONFIG_MEM_SEARCH +/**************************************************/ +U_BOOT_CMD( + ms, 255, 1, do_mem_search, + "memory search", + "[.b, .w, .l" HELP_Q ", .s] [-q | -] address #-of-objects ..." + " -q = quiet, -l = match limit" : +); +#endif + #ifdef CONFIG_CMD_CRC32 #ifndef CONFIG_CRC32_VERIFY diff --git a/test/Makefile b/test/Makefile index bab8f1a5c2..7c4039964e 100644 --- a/test/Makefile +++ b/test/Makefile @@ -3,6 +3,7 @@ # (C) Copyright 2012 The Chromium Authors obj-$(CONFIG_SANDBOX) += bloblist.o +obj-$(CONFIG_CMDLINE) += cmd/ obj-$(CONFIG_UNIT_TEST) += cmd_ut.o obj-$(CONFIG_UNIT_TEST) += ut.o obj-$(CONFIG_SANDBOX) += command_ut.o diff --git a/test/cmd/Makefile b/test/cmd/Makefile new file mode 100644 index 0000000000..85d38f09e8 --- /dev/null +++ b/test/cmd/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (c) 2013 Google, Inc + +obj-$(CONFIG_MEM_SEARCH) += mem_search.o diff --git a/test/cmd/mem_search.c b/test/cmd/mem_search.c new file mode 100644 index 0000000000..d57bfad398 --- /dev/null +++ b/test/cmd/mem_search.c @@ -0,0 +1,275 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Tests for memory commands + * + * Copyright 2020 Google LLC + * Written by Simon Glass + */ + +#include +#include +#include +#include +#include + +#define BUF_SIZE 0x100 + +/* Test 'ms' command with bytes */ +static int dm_test_ms_b(struct unit_test_state *uts) +{ + u8 *buf; + + buf = map_sysmem(0, BUF_SIZE + 1); + memset(buf, '\0', BUF_SIZE); + buf[0x0] = 0x12; + buf[0x31] = 0x12; + buf[0xff] = 0x12; + buf[0x100] = 0x12; + console_record_reset(); + run_command("ms.b 1 ff 12", 0); + ut_assert_nextline("00000030: 00 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................"); + ut_assert_nextline("--"); + ut_assert_nextline("000000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12 ................"); + ut_assert_nextline("2 matches"); + ut_assert_console_end(); + + ut_asserteq(2, env_get_hex("memmatches", 0)); + ut_asserteq(0xff, env_get_hex("memaddr", 0)); + ut_asserteq(0xfe, env_get_hex("mempos", 0)); + + unmap_sysmem(buf); + + return 0; +} +DM_TEST(dm_test_ms_b, 0); + +/* Test 'ms' command with 16-bit values */ +static int dm_test_ms_w(struct unit_test_state *uts) +{ + u16 *buf; + + buf = map_sysmem(0, BUF_SIZE + 2); + memset(buf, '\0', BUF_SIZE); + buf[0x34 / 2] = 0x1234; + buf[BUF_SIZE / 2] = 0x1234; + console_record_reset(); + run_command("ms.w 0 80 1234", 0); + ut_assert_nextline("00000030: 0000 0000 1234 0000 0000 0000 0000 0000 ....4..........."); + ut_assert_nextline("1 match"); + ut_assert_console_end(); + + ut_asserteq(1, env_get_hex("memmatches", 0)); + ut_asserteq(0x34, env_get_hex("memaddr", 0)); + ut_asserteq(0x34 / 2, env_get_hex("mempos", 0)); + + unmap_sysmem(buf); + + return 0; +} +DM_TEST(dm_test_ms_w, 0); + +/* Test 'ms' command with 32-bit values */ +static int dm_test_ms_l(struct unit_test_state *uts) +{ + u32 *buf; + + buf = map_sysmem(0, BUF_SIZE + 4); + memset(buf, '\0', BUF_SIZE); + buf[0x38 / 4] = 0x12345678; + buf[BUF_SIZE / 4] = 0x12345678; + console_record_reset(); + run_command("ms 0 40 12345678", 0); + ut_assert_nextline("00000030: 00000000 00000000 12345678 00000000 ........xV4....."); + ut_assert_nextline("1 match"); + ut_assert_console_end(); + + ut_asserteq(1, env_get_hex("memmatches", 0)); + ut_asserteq(0x38, env_get_hex("memaddr", 0)); + ut_asserteq(0x38 / 4, env_get_hex("mempos", 0)); + + console_record_reset(); + run_command("ms 0 80 12345679", 0); + ut_assert_nextline("0 matches"); + ut_assert_console_end(); + + ut_asserteq(0, env_get_hex("memmatches", 0)); + ut_asserteq(0, env_get_hex("memaddr", 0)); + ut_asserteq(0 / 4, env_get_hex("mempos", 0)); + + unmap_sysmem(buf); + + return 0; +} +DM_TEST(dm_test_ms_l, 0); + +/* Test 'ms' command with continuation */ +static int dm_test_ms_cont(struct unit_test_state *uts) +{ + char *const args[] = {"ms.b", "0", "100", "34"}; + int repeatable; + u8 *buf; + int i; + + buf = map_sysmem(0, BUF_SIZE); + memset(buf, '\0', BUF_SIZE); + for (i = 5; i < 0x33; i += 3) + buf[i] = 0x34; + console_record_reset(); + run_command("ms.b 0 100 34", 0); + ut_assert_nextlinen("00000000: 00 00 00 00 00 34 00 00 34 00 00 34 00 00 34 00"); + ut_assert_nextline("--"); + ut_assert_nextlinen("00000010: 00 34 00 00 34 00 00 34 00 00 34 00 00 34 00 00"); + ut_assert_nextline("--"); + ut_assert_nextlinen("00000020: 34 00 00 34 00 00 34 00 00 34 00 00 34 00 00 34"); + ut_assert_nextlinen("10 matches (repeat command to check for more)"); + ut_assert_console_end(); + + ut_asserteq(10, env_get_hex("memmatches", 0)); + ut_asserteq(0x20, env_get_hex("memaddr", 0)); + ut_asserteq(0x20, env_get_hex("mempos", 0)); + + /* + * run_command() ignoes the repeatable flag when using hush, so call + * cmd_process() directly + */ + console_record_reset(); + cmd_process(CMD_FLAG_REPEAT, 4, args, &repeatable, NULL); + ut_assert_nextlinen("00000020: 34 00 00 34 00 00 34 00 00 34 00 00 34 00 00 34"); + ut_assert_nextline("--"); + ut_assert_nextlinen("00000030: 00 00 34 00 00 00 00 00"); + ut_assert_nextlinen("6 matches"); + ut_assert_console_end(); + + ut_asserteq(6, env_get_hex("memmatches", 0)); + ut_asserteq(0x32, env_get_hex("memaddr", 0)); + + /* 0x32 less 0x21, where the second search started */ + ut_asserteq(0x11, env_get_hex("mempos", 0)); + + unmap_sysmem(buf); + + return 0; +} +DM_TEST(dm_test_ms_cont, 0); + +/* Test 'ms' command with multiple values */ +static int dm_test_ms_mult(struct unit_test_state *uts) +{ + static const char str[] = "hello"; + char *buf; + + buf = map_sysmem(0, BUF_SIZE + 5); + memset(buf, '\0', BUF_SIZE); + strcpy(buf + 0x1e, str); + strcpy(buf + 0x63, str); + strcpy(buf + BUF_SIZE - strlen(str) + 1, str); + console_record_reset(); + run_command("ms.b 0 100 68 65 6c 6c 6f", 0); + ut_assert_nextline("00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 68 65 ..............he"); + ut_assert_nextline("00000020: 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 00 00 00 llo............."); + ut_assert_nextline("--"); + ut_assert_nextline("00000060: 00 00 00 68 65 6c 6c 6f 00 00 00 00 00 00 00 00 ...hello........"); + ut_assert_nextline("2 matches"); + ut_assert_console_end(); + unmap_sysmem(buf); + + ut_asserteq(2, env_get_hex("memmatches", 0)); + ut_asserteq(0x63, env_get_hex("memaddr", 0)); + ut_asserteq(0x63, env_get_hex("mempos", 0)); + + return 0; +} +DM_TEST(dm_test_ms_mult, 0); + +/* Test 'ms' command with string */ +static int dm_test_ms_s(struct unit_test_state *uts) +{ + static const char str[] = "hello"; + static const char str2[] = "hellothere"; + char *buf; + + buf = map_sysmem(0, BUF_SIZE); + memset(buf, '\0', BUF_SIZE); + strcpy(buf + 0x1e, str); + strcpy(buf + 0x63, str); + strcpy(buf + 0xa1, str2); + console_record_reset(); + run_command("ms.s 0 100 hello", 0); + ut_assert_nextline("00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 68 65 ..............he"); + ut_assert_nextline("00000020: 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 00 00 00 llo............."); + ut_assert_nextline("--"); + ut_assert_nextline("00000060: 00 00 00 68 65 6c 6c 6f 00 00 00 00 00 00 00 00 ...hello........"); + ut_assert_nextline("--"); + ut_assert_nextline("000000a0: 00 68 65 6c 6c 6f 74 68 65 72 65 00 00 00 00 00 .hellothere....."); + ut_assert_nextline("3 matches"); + ut_assert_console_end(); + + ut_asserteq(3, env_get_hex("memmatches", 0)); + ut_asserteq(0xa1, env_get_hex("memaddr", 0)); + ut_asserteq(0xa1, env_get_hex("mempos", 0)); + + console_record_reset(); + run_command("ms.s 0 100 hello there", 0); + ut_assert_nextline("000000a0: 00 68 65 6c 6c 6f 74 68 65 72 65 00 00 00 00 00 .hellothere....."); + ut_assert_nextline("1 match"); + ut_assert_console_end(); + + ut_asserteq(1, env_get_hex("memmatches", 0)); + ut_asserteq(0xa1, env_get_hex("memaddr", 0)); + ut_asserteq(0xa1, env_get_hex("mempos", 0)); + + unmap_sysmem(buf); + + return 0; +} +DM_TEST(dm_test_ms_s, 0); + +/* Test 'ms' command with limit */ +static int dm_test_ms_limit(struct unit_test_state *uts) +{ + u8 *buf; + + buf = map_sysmem(0, BUF_SIZE + 1); + memset(buf, '\0', BUF_SIZE); + buf[0x0] = 0x12; + buf[0x31] = 0x12; + buf[0x62] = 0x12; + buf[0x76] = 0x12; + console_record_reset(); + run_command("ms.b -l2 1 ff 12", 0); + ut_assert_nextline("00000030: 00 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................"); + ut_assert_nextline("--"); + ut_assert_nextlinen("00000060: 00 00 12 00 00 00 00 00 00 00 00 00 00 00 00 00"); + ut_assert_nextline("2 matches (repeat command to check for more)"); + ut_assert_console_end(); + + ut_asserteq(2, env_get_hex("memmatches", 0)); + ut_asserteq(0x62, env_get_hex("memaddr", 0)); + ut_asserteq(0x61, env_get_hex("mempos", 0)); + + unmap_sysmem(buf); + + return 0; +} +DM_TEST(dm_test_ms_limit, 0); + +/* Test 'ms' command in quiet mode */ +static int dm_test_ms_quiet(struct unit_test_state *uts) +{ + u8 *buf; + + buf = map_sysmem(0, BUF_SIZE + 1); + memset(buf, '\0', BUF_SIZE); + buf[0x0] = 0x12; + buf[0x31] = 0x12; + buf[0x62] = 0x12; + buf[0x76] = 0x12; + console_record_reset(); + run_command("ms.b -l2 1 ff 12", 0); + ut_assert_console_end(); + unmap_sysmem(buf); + + return 0; +} +DM_TEST(dm_test_ms_quiet, 0); +