Merge tag 'tpm-030822' of https://source.denx.de/u-boot/custodians/u-boot-tpm
[platform/kernel/u-boot.git] / cmd / mem.c
index 575893c..1f4e3fc 100644 (file)
--- a/cmd/mem.c
+++ b/cmd/mem.c
 #include <cli.h>
 #include <command.h>
 #include <console.h>
+#ifdef CONFIG_MTD_NOR_FLASH
 #include <flash.h>
+#endif
 #include <hash.h>
 #include <log.h>
 #include <mapmem.h>
 #include <rand.h>
 #include <watchdog.h>
+#include <asm/global_data.h>
 #include <asm/io.h>
 #include <linux/bitops.h>
 #include <linux/compiler.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#ifndef CONFIG_SYS_MEMTEST_SCRATCH
-#define CONFIG_SYS_MEMTEST_SCRATCH 0
-#endif
-
 /* Create a compile-time value */
 #ifdef MEM_SUPPORT_64BIT_DATA
 #define SUPPORT_64BIT_DATA 1
@@ -53,7 +52,8 @@ static ulong  dp_last_length = 0x40;
 static ulong   mm_last_addr, mm_last_size;
 
 static ulong   base_address = 0;
-#ifdef CONFIG_MEM_SEARCH
+#ifdef CONFIG_CMD_MEM_SEARCH
+static ulong dp_last_ms_length;
 static u8 search_buf[64];
 static uint search_len;
 #endif
@@ -91,14 +91,14 @@ static int do_mem_md(struct cmd_tbl *cmdtp, int flag, int argc,
 
                /* Address is specified since argc > 1
                */
-               addr = simple_strtoul(argv[1], NULL, 16);
+               addr = hextoul(argv[1], NULL);
                addr += base_address;
 
                /* If another parameter, it is the length to display.
                 * Length is the number of objects, not number of bytes.
                 */
                if (argc > 2)
-                       length = simple_strtoul(argv[2], NULL, 16);
+                       length = hextoul(argv[2], NULL);
        }
 
        bytes = size * length;
@@ -146,7 +146,7 @@ static int do_mem_mw(struct cmd_tbl *cmdtp, int flag, int argc,
 
        /* Address is specified since argc > 1
        */
-       addr = simple_strtoul(argv[1], NULL, 16);
+       addr = hextoul(argv[1], NULL);
        addr += base_address;
 
        /* Get the value to write.
@@ -154,11 +154,11 @@ static int do_mem_mw(struct cmd_tbl *cmdtp, int flag, int argc,
        if (SUPPORT_64BIT_DATA)
                writeval = simple_strtoull(argv[2], NULL, 16);
        else
-               writeval = simple_strtoul(argv[2], NULL, 16);
+               writeval = hextoul(argv[2], NULL);
 
        /* Count ? */
        if (argc == 4) {
-               count = simple_strtoul(argv[3], NULL, 16);
+               count = hextoul(argv[3], NULL);
        } else {
                count = 1;
        }
@@ -191,7 +191,7 @@ static int do_mem_mdc(struct cmd_tbl *cmdtp, int flag, int argc,
        if (argc < 4)
                return CMD_RET_USAGE;
 
-       count = simple_strtoul(argv[3], NULL, 10);
+       count = dectoul(argv[3], NULL);
 
        for (;;) {
                do_mem_md (NULL, 0, 3, argv);
@@ -219,7 +219,7 @@ static int do_mem_mwc(struct cmd_tbl *cmdtp, int flag, int argc,
        if (argc < 4)
                return CMD_RET_USAGE;
 
-       count = simple_strtoul(argv[3], NULL, 10);
+       count = dectoul(argv[3], NULL);
 
        for (;;) {
                do_mem_mw (NULL, 0, 3, argv);
@@ -260,13 +260,13 @@ static int do_mem_cmp(struct cmd_tbl *cmdtp, int flag, int argc,
               size == 4 ? "word" :
               size == 2 ? "halfword" : "byte";
 
-       addr1 = simple_strtoul(argv[1], NULL, 16);
+       addr1 = hextoul(argv[1], NULL);
        addr1 += base_address;
 
-       addr2 = simple_strtoul(argv[2], NULL, 16);
+       addr2 = hextoul(argv[2], NULL);
        addr2 += base_address;
 
-       count = simple_strtoul(argv[3], NULL, 16);
+       count = hextoul(argv[3], NULL);
 
        bytes = size * count;
        base = buf1 = map_sysmem(addr1, bytes);
@@ -323,13 +323,13 @@ static int do_mem_cp(struct cmd_tbl *cmdtp, int flag, int argc,
        if ((size = cmd_get_data_size(argv[0], 4)) < 0)
                return 1;
 
-       addr = simple_strtoul(argv[1], NULL, 16);
+       addr = hextoul(argv[1], NULL);
        addr += base_address;
 
-       dest = simple_strtoul(argv[2], NULL, 16);
+       dest = hextoul(argv[2], NULL);
        dest += base_address;
 
-       count = simple_strtoul(argv[3], NULL, 16);
+       count = hextoul(argv[3], NULL);
 
        if (count == 0) {
                puts ("Zero length ???\n");
@@ -367,7 +367,7 @@ static int do_mem_cp(struct cmd_tbl *cmdtp, int flag, int argc,
        return 0;
 }
 
-#ifdef CONFIG_MEM_SEARCH
+#ifdef CONFIG_CMD_MEM_SEARCH
 static int do_mem_search(struct cmd_tbl *cmdtp, int flag, int argc,
                         char *const argv[])
 {
@@ -377,6 +377,7 @@ static int do_mem_search(struct cmd_tbl *cmdtp, int flag, int argc,
        ulong last_pos;         /* Offset of last match in 'size' units*/
        ulong last_addr;        /* Address of last displayed line */
        int limit = 10;
+       int used_len;
        int count;
        int size;
        int i;
@@ -384,44 +385,46 @@ static int do_mem_search(struct cmd_tbl *cmdtp, int flag, int argc,
        /* We use the last specified parameters, unless new ones are entered */
        addr = dp_last_addr;
        size = dp_last_size;
-       length = dp_last_length;
+       length = dp_last_ms_length;
 
        if (argc < 3)
                return CMD_RET_USAGE;
 
-       if ((!flag & CMD_FLAG_REPEAT)) {
+       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 */)
+               if (size < 0 && size != CMD_DATA_SIZE_STR)
                        return 1;
 
-               argc--; argv++;
+               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);
+                               limit = hextoul(argv[0] + 2, NULL);
                        else
                                return CMD_RET_USAGE;
-                       argc--; argv++;
+                       argc--;
+                       argv++;
                }
 
                /* Address is specified since argc > 1 */
-               addr = simple_strtoul(argv[0], NULL, 16);
+               addr = hextoul(argv[0], NULL);
                addr += base_address;
 
                /* Length is the number of objects, not number of bytes */
-               length = simple_strtoul(argv[1], NULL, 16);
+               length = hextoul(argv[1], NULL);
 
                /* 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) {
+                       if (MEM_SUPPORT_64BIT_DATA && size == 8) {
                                u64 val = simple_strtoull(argv[i], NULL, 16);
 
                                *(u64 *)ptr = val;
@@ -433,7 +436,7 @@ static int do_mem_search(struct cmd_tbl *cmdtp, int flag, int argc,
                                ptr += len;
                                continue;
                        } else {
-                               u32 val = simple_strtoul(argv[i], NULL, 16);
+                               u32 val = hextoul(argv[i], NULL);
 
                                switch (size) {
                                case 1:
@@ -460,7 +463,8 @@ static int do_mem_search(struct cmd_tbl *cmdtp, int flag, int argc,
        last_pos = 0;
        last_addr = 0;
        count = 0;
-       for (offset = 0; offset <= bytes - search_len && count < limit;
+       for (offset = 0;
+            offset < bytes && offset <= bytes - search_len && count < limit;
             offset += size) {
                void *ptr = buf + offset;
 
@@ -495,9 +499,10 @@ static int do_mem_search(struct cmd_tbl *cmdtp, int flag, int argc,
 
        unmap_sysmem(buf);
 
-       dp_last_addr = addr + offset / size;
+       used_len = offset / size;
+       dp_last_addr = addr + used_len;
        dp_last_size = size;
-       dp_last_length = length - offset / size;
+       dp_last_ms_length = length < used_len ? 0 : length - used_len;
 
        return count ? 0 : CMD_RET_FAILURE;
 }
@@ -509,7 +514,7 @@ static int do_mem_base(struct cmd_tbl *cmdtp, int flag, int argc,
        if (argc > 1) {
                /* Set new base address.
                */
-               base_address = simple_strtoul(argv[1], NULL, 16);
+               base_address = hextoul(argv[1], NULL);
        }
        /* Print the current base address.
        */
@@ -540,11 +545,11 @@ static int do_mem_loop(struct cmd_tbl *cmdtp, int flag, int argc,
 
        /* Address is always specified.
        */
-       addr = simple_strtoul(argv[1], NULL, 16);
+       addr = hextoul(argv[1], NULL);
 
        /* Length is the number of objects, not number of bytes.
        */
-       length = simple_strtoul(argv[2], NULL, 16);
+       length = hextoul(argv[2], NULL);
 
        bytes = size * length;
        buf = map_sysmem(addr, bytes);
@@ -633,17 +638,17 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc,
 
        /* Address is always specified.
        */
-       addr = simple_strtoul(argv[1], NULL, 16);
+       addr = hextoul(argv[1], NULL);
 
        /* Length is the number of objects, not number of bytes.
        */
-       length = simple_strtoul(argv[2], NULL, 16);
+       length = hextoul(argv[2], NULL);
 
        /* data to write */
        if (SUPPORT_64BIT_DATA)
                data = simple_strtoull(argv[3], NULL, 16);
        else
-               data = simple_strtoul(argv[3], NULL, 16);
+               data = hextoul(argv[3], NULL);
 
        bytes = size * length;
        buf = map_sysmem(addr, bytes);
@@ -983,6 +988,18 @@ static ulong test_bitflip_comparison(volatile unsigned long *bufa,
        return errs;
 }
 
+static ulong mem_test_bitflip(vu_long *buf, ulong start, ulong end)
+{
+       /*
+        * Split the specified range into two halves.
+        * Note that mtest range is inclusive of start,end.
+        * Bitflip test instead uses a count (of 32-bit words).
+        */
+       ulong half_size = (end - start + 1) / 2 / sizeof(unsigned long);
+
+       return test_bitflip_comparison(buf, buf + half_size, half_size);
+}
+
 static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr,
                            vu_long pattern, int iteration)
 {
@@ -1102,11 +1119,10 @@ static int do_mem_mtest(struct cmd_tbl *cmdtp, int flag, int argc,
                        errs = mem_test_alt(buf, start, end, dummy);
                        if (errs == -1UL)
                                break;
-                       count += errs;
-                       errs = test_bitflip_comparison(buf,
-                                                      buf + (end - start) / 2,
-                                                      (end - start) /
-                                                      sizeof(unsigned long));
+                       if (IS_ENABLED(CONFIG_SYS_ALT_MEMTEST_BITFLIP)) {
+                               count += errs;
+                               errs = mem_test_bitflip(buf, start, end);
+                       }
                } else {
                        errs = mem_test_quick(buf, start, end, pattern,
                                              iteration);
@@ -1161,7 +1177,7 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc,
 
                /* Address is specified since argc > 1
                */
-               addr = simple_strtoul(argv[1], NULL, 16);
+               addr = hextoul(argv[1], NULL);
                addr += base_address;
        }
 
@@ -1201,7 +1217,7 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc,
                        if (SUPPORT_64BIT_DATA)
                                i = simple_strtoull(console_buffer, &endp, 16);
                        else
-                               i = simple_strtoul(console_buffer, &endp, 16);
+                               i = hextoul(console_buffer, &endp);
                        nbytes = endp - console_buffer;
                        if (nbytes) {
                                /* good enough to not time out
@@ -1268,11 +1284,11 @@ static int do_random(struct cmd_tbl *cmdtp, int flag, int argc,
        if (argc < 3 || argc > 4)
                return CMD_RET_USAGE;
 
-       len = simple_strtoul(argv[2], NULL, 16);
-       addr = simple_strtoul(argv[1], NULL, 16);
+       len = hextoul(argv[2], NULL);
+       addr = hextoul(argv[1], NULL);
 
        if (argc == 4) {
-               seed = simple_strtoul(argv[3], NULL, 16);
+               seed = hextoul(argv[3], NULL);
                if (seed == 0) {
                        printf("The seed cannot be 0. Using 0xDEADBEEF.\n");
                        seed = 0xDEADBEEF;
@@ -1337,13 +1353,13 @@ U_BOOT_CMD(
        "[.b, .w, .l" HELP_Q "] addr1 addr2 count"
 );
 
-#ifdef CONFIG_MEM_SEARCH
+#ifdef CONFIG_CMD_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" :
+       "  -q = quiet, -l<val> = match limit"
 );
 #endif