diff options
author | Tom Rini <trini@konsulko.com> | 2020-07-08 20:20:24 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2020-07-08 20:20:24 -0400 |
commit | 61608f395e7dcb2be6060407a72a1149b046430a (patch) | |
tree | 387269e837a47126d5a7ccdef2b4d5af60598e16 /cmd/mem.c | |
parent | 186529953fd10a97e6343418095edd1c535aaeb2 (diff) | |
parent | c89b41b4db4a746647c4f0e6d33c6f4edfe96e38 (diff) |
Merge branch '2020-07-08-misc-features-and-fixes'
- mem cmd improvements
- TPM fixes
- SPL/NAND/FIT fixes
- RSA improvements
Diffstat (limited to 'cmd/mem.c')
-rw-r--r-- | cmd/mem.c | 334 |
1 files changed, 205 insertions, 129 deletions
@@ -25,6 +25,7 @@ #include <asm/io.h> #include <linux/bitops.h> #include <linux/compiler.h> +#include <linux/ctype.h> #include <linux/delay.h> DECLARE_GLOBAL_DATA_PTR; @@ -33,6 +34,15 @@ DECLARE_GLOBAL_DATA_PTR; #define CONFIG_SYS_MEMTEST_SCRATCH 0 #endif +/* Create a compile-time value */ +#ifdef MEM_SUPPORT_64BIT_DATA +#define SUPPORT_64BIT_DATA 1 +#define HELP_Q ", .q" +#else +#define SUPPORT_64BIT_DATA 0 +#define HELP_Q "" +#endif + static int mod_mem(struct cmd_tbl *, int, int, int, char * const []); /* Display values from last command. @@ -43,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 * @@ -116,11 +130,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 - u64 writeval; -#else - ulong writeval; -#endif + ulong writeval; /* 64-bit if SUPPORT_64BIT_DATA */ ulong addr, count; int size; void *buf, *start; @@ -141,11 +151,10 @@ static int do_mem_mw(struct cmd_tbl *cmdtp, int flag, int argc, /* Get the value to write. */ -#ifdef 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) { @@ -160,10 +169,8 @@ 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 - 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 @@ -240,11 +247,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 - u64 word1, word2; -#else - ulong word1, word2; -#endif + ulong word1, word2; /* 64-bit if SUPPORT_64BIT_DATA */ if (argc != 4) return CMD_RET_USAGE; @@ -272,11 +275,9 @@ 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 - } 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; @@ -286,15 +287,9 @@ 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 - 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; } @@ -372,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[]) { @@ -391,9 +522,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 - volatile u64 *llp; -#endif + volatile ulong *llp; /* 64-bit if SUPPORT_64BIT_DATA */ volatile u32 *longp; volatile u16 *shortp; volatile u8 *cp; @@ -424,13 +553,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) { -#ifdef 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 (;;) @@ -446,16 +573,14 @@ static int do_mem_loop(struct cmd_tbl *cmdtp, int flag, int argc, i = *cp; } -#ifdef 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; @@ -489,12 +614,8 @@ 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 - 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; @@ -519,11 +640,10 @@ 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 - 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); @@ -532,13 +652,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) { -#ifdef 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 (;;) @@ -554,16 +672,14 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc, *cp = data; } -#ifdef 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; @@ -1016,18 +1132,13 @@ 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, char *const argv[]) { ulong addr; -#ifdef MEM_SUPPORT_64BIT_DATA - u64 i; -#else - ulong i; -#endif + ulong i; /* 64-bit if SUPPORT_64BIT_DATA */ int nbytes, size; void *ptr = NULL; @@ -1062,10 +1173,8 @@ 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 - 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 @@ -1089,11 +1198,10 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc, #endif else { char *endp; -#ifdef 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 @@ -1101,10 +1209,8 @@ 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 - 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 @@ -1196,65 +1302,51 @@ 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 - "[.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)", -#ifdef 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)", -#ifdef 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)", -#ifdef 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", -#ifdef 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", -#ifdef 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_MEM_SEARCH +/**************************************************/ +U_BOOT_CMD( + ms, 255, 1, do_mem_search, + "memory search", + "[.b, .w, .l" HELP_Q ", .s] [-q | -<n>] address #-of-objects <value>..." + " -q = quiet, -l<val> = match limit" : +); +#endif + #ifdef CONFIG_CMD_CRC32 #ifndef CONFIG_CRC32_VERIFY @@ -1299,22 +1391,14 @@ U_BOOT_CMD( U_BOOT_CMD( loop, 3, 1, do_mem_loop, "infinite loop on address range", -#ifdef 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", -#ifdef 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 +1414,13 @@ U_BOOT_CMD( U_BOOT_CMD( mdc, 4, 1, do_mem_mdc, "memory display cyclic", -#ifdef 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", -#ifdef 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 */ |