]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/cmd_mem.c
karo: tx6ul: fix bogus GPIO numbers
[karo-tx-uboot.git] / common / cmd_mem.c
index 12dbc1609c38782cbd3a0ffcfbdab4997e5a5643..43c3fb62bffec59d3e36adab0b25535918be4b18 100644 (file)
@@ -2,23 +2,7 @@
  * (C) Copyright 2000
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 
 /*
  */
 
 #include <common.h>
+#include <bootretry.h>
+#include <cli.h>
 #include <command.h>
 #ifdef CONFIG_HAS_DATAFLASH
 #include <dataflash.h>
 #endif
+#include <hash.h>
+#include <inttypes.h>
+#include <mapmem.h>
 #include <watchdog.h>
 #include <asm/io.h>
 #include <linux/compiler.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifndef CONFIG_SYS_MEMTEST_SCRATCH
+#define CONFIG_SYS_MEMTEST_SCRATCH 0
+#endif
+
 static int mod_mem(cmd_tbl_t *, int, int, int, char * const []);
 
 /* Display values from last command.
  * Memory modify remembered values are different from display memory.
  */
-static uint    dp_last_addr, dp_last_size;
-static uint    dp_last_length = 0x40;
-static uint    mm_last_addr, mm_last_size;
+static ulong   dp_last_addr, dp_last_size;
+static ulong   dp_last_length = 0x40;
+static ulong   mm_last_addr, mm_last_size;
 
 static ulong   base_address = 0;
 
 /* Memory Display
  *
  * Syntax:
- *     md{.b, .w, .l} {addr} {len}
+ *     md{.b, .w, .l, .q} {addr} {len}
  */
 #define DISP_LINE_LEN  16
 static int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
@@ -166,9 +159,14 @@ static int do_mem_nm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
 static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       ulong   addr, writeval, count;
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       u64 writeval;
+#else
+       ulong writeval;
+#endif
+       ulong   addr, count;
        int     size;
-       void *buf;
+       void *buf, *start;
        ulong bytes;
 
        if ((argc < 3) || (argc > 4))
@@ -186,7 +184,11 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
        /* Get the value to write.
        */
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       writeval = simple_strtoull(argv[2], NULL, 16);
+#else
        writeval = simple_strtoul(argv[2], NULL, 16);
+#endif
 
        /* Count ? */
        if (argc == 4) {
@@ -196,22 +198,27 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        }
 
        bytes = size * count;
-       buf = map_sysmem(addr, bytes);
+       start = map_sysmem(addr, bytes);
+       buf = start;
        while (count-- > 0) {
                if (size == 4)
-                       *((ulong *)buf) = (ulong)writeval;
+                       *((u32 *)buf) = (u32)writeval;
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+               else if (size == 8)
+                       *((u64 *)buf) = (u64)writeval;
+#endif
                else if (size == 2)
-                       *((ushort *)buf) = (ushort)writeval;
+                       *((u16 *)buf) = (u16)writeval;
                else
-                       *((u_char *)buf) = (u_char)writeval;
+                       *((u8 *)buf) = (u8)writeval;
                buf += size;
        }
-       unmap_sysmem(buf);
+       unmap_sysmem(start);
        return 0;
 }
 
 #ifdef CONFIG_MX_CYCLIC
-int do_mem_mdc ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static int do_mem_mdc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        int i;
        ulong count;
@@ -238,7 +245,7 @@ int do_mem_mdc ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        return 0;
 }
 
-int do_mem_mwc ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static int do_mem_mwc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        int i;
        ulong count;
@@ -273,6 +280,11 @@ static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        int     rcode = 0;
        const char *type;
        const void *buf1, *buf2, *base;
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       u64 word1, word2;
+#else
+       ulong word1, word2;
+#endif
 
        if (argc != 4)
                return CMD_RET_USAGE;
@@ -281,7 +293,9 @@ static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        */
        if ((size = cmd_get_data_size(argv[0], 4)) < 0)
                return 1;
-       type = size == 4 ? "word" : size == 2 ? "halfword" : "byte";
+       type = size == 8 ? "double word" :
+              size == 4 ? "word" :
+              size == 2 ? "halfword" : "byte";
 
        addr1 = simple_strtoul(argv[1], NULL, 16);
        addr1 += base_address;
@@ -309,23 +323,33 @@ static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        base = buf1 = map_sysmem(addr1, bytes);
        buf2 = map_sysmem(addr2, bytes);
        for (ngood = 0; ngood < count; ++ngood) {
-               ulong word1, word2;
                if (size == 4) {
-                       word1 = *(ulong *)buf1;
-                       word2 = *(ulong *)buf2;
+                       word1 = *(u32 *)buf1;
+                       word2 = *(u32 *)buf2;
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+               } else if (size == 8) {
+                       word1 = *(u64 *)buf1;
+                       word2 = *(u64 *)buf2;
+#endif
                } else if (size == 2) {
-                       word1 = *(ushort *)buf1;
-                       word2 = *(ushort *)buf2;
+                       word1 = *(u16 *)buf1;
+                       word2 = *(u16 *)buf2;
                } else {
-                       word1 = *(u_char *)buf1;
-                       word2 = *(u_char *)buf2;
+                       word1 = *(u8 *)buf1;
+                       word2 = *(u8 *)buf2;
                }
                if (word1 != word2) {
                        ulong offset = buf1 - base;
-
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+                       printf("%s at 0x%p (%#0*"PRIx64") != %s at 0x%p (%#0*"
+                              PRIx64 ")\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;
                }
@@ -440,15 +464,19 @@ static int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 #endif
 
        bytes = size * count;
-       buf = map_sysmem(addr, bytes);
+       buf = map_sysmem(dest, bytes);
        src = map_sysmem(addr, bytes);
        while (count-- > 0) {
                if (size == 4)
-                       *((ulong *)buf) = *((ulong  *)src);
+                       *((u32 *)buf) = *((u32  *)src);
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+               else if (size == 8)
+                       *((u64 *)buf) = *((u64 *)src);
+#endif
                else if (size == 2)
-                       *((ushort *)buf) = *((ushort *)src);
+                       *((u16 *)buf) = *((u16 *)src);
                else
-                       *((u_char *)buf) = *((u_char *)src);
+                       *((u8 *)buf) = *((u8 *)src);
                src += size;
                buf += size;
 
@@ -456,6 +484,9 @@ static int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                if ((count % (64 << 10)) == 0)
                        WATCHDOG_RESET();
        }
+       unmap_sysmem(buf);
+       unmap_sysmem(src);
+
        return 0;
 }
 
@@ -478,9 +509,12 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,
 {
        ulong   addr, length, i, bytes;
        int     size;
-       volatile uint   *longp;
-       volatile ushort *shortp;
-       volatile u_char *cp;
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       volatile u64 *llp;
+#endif
+       volatile u32 *longp;
+       volatile u16 *shortp;
+       volatile u8 *cp;
        const void *buf;
 
        if (argc < 3)
@@ -508,24 +542,41 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,
         * If we have only one object, just run infinite loops.
         */
        if (length == 1) {
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+               if (size == 8) {
+                       llp = (u64 *)buf;
+                       for (;;)
+                               i = *llp;
+               }
+#endif
                if (size == 4) {
-                       longp = (uint *)buf;
+                       longp = (u32 *)buf;
                        for (;;)
                                i = *longp;
                }
                if (size == 2) {
-                       shortp = (ushort *)buf;
+                       shortp = (u16 *)buf;
                        for (;;)
                                i = *shortp;
                }
-               cp = (u_char *)buf;
+               cp = (u8 *)buf;
                for (;;)
                        i = *cp;
        }
 
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       if (size == 8) {
+               for (;;) {
+                       llp = (u64 *)buf;
+                       i = length;
+                       while (i-- > 0)
+                               *llp++;
+               }
+       }
+#endif
        if (size == 4) {
                for (;;) {
-                       longp = (uint *)buf;
+                       longp = (u32 *)buf;
                        i = length;
                        while (i-- > 0)
                                *longp++;
@@ -533,29 +584,38 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,
        }
        if (size == 2) {
                for (;;) {
-                       shortp = (ushort *)buf;
+                       shortp = (u16 *)buf;
                        i = length;
                        while (i-- > 0)
                                *shortp++;
                }
        }
        for (;;) {
-               cp = (u_char *)buf;
+               cp = (u8 *)buf;
                i = length;
                while (i-- > 0)
                        *cp++;
        }
        unmap_sysmem(buf);
+
+       return 0;
 }
 
 #ifdef CONFIG_LOOPW
-int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static int do_mem_loopw(cmd_tbl_t *cmdtp, int flag, int argc,
+                       char * const argv[])
 {
-       ulong   addr, length, i, data, bytes;
+       ulong   addr, length, i, bytes;
        int     size;
-       volatile uint   *longp;
-       volatile ushort *shortp;
-       volatile u_char *cp;
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       volatile u64 *llp;
+       u64 data;
+#else
+       ulong   data;
+#endif
+       volatile u32 *longp;
+       volatile u16 *shortp;
+       volatile u8 *cp;
        void *buf;
 
        if (argc < 4)
@@ -577,7 +637,11 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        length = simple_strtoul(argv[2], NULL, 16);
 
        /* data to write */
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       data = simple_strtoull(argv[3], NULL, 16);
+#else
        data = simple_strtoul(argv[3], NULL, 16);
+#endif
 
        bytes = size * length;
        buf = map_sysmem(addr, bytes);
@@ -586,24 +650,41 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
         * If we have only one object, just run infinite loops.
         */
        if (length == 1) {
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+               if (size == 8) {
+                       llp = (u64 *)buf;
+                       for (;;)
+                               *llp = data;
+               }
+#endif
                if (size == 4) {
-                       longp = (uint *)buf;
+                       longp = (u32 *)buf;
                        for (;;)
                                *longp = data;
-                                       }
+               }
                if (size == 2) {
-                       shortp = (ushort *)buf;
+                       shortp = (u16 *)buf;
                        for (;;)
                                *shortp = data;
                }
-               cp = (u_char *)buf;
+               cp = (u8 *)buf;
                for (;;)
                        *cp = data;
        }
 
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       if (size == 8) {
+               for (;;) {
+                       llp = (u64 *)buf;
+                       i = length;
+                       while (i-- > 0)
+                               *llp++ = data;
+               }
+       }
+#endif
        if (size == 4) {
                for (;;) {
-                       longp = (uint *)buf;
+                       longp = (u32 *)buf;
                        i = length;
                        while (i-- > 0)
                                *longp++ = data;
@@ -611,14 +692,14 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        }
        if (size == 2) {
                for (;;) {
-                       shortp = (ushort *)buf;
+                       shortp = (u16 *)buf;
                        i = length;
                        while (i-- > 0)
                                *shortp++ = data;
                }
        }
        for (;;) {
-               cp = (u_char *)buf;
+               cp = (u8 *)buf;
                i = length;
                while (i-- > 0)
                        *cp++ = data;
@@ -626,25 +707,20 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 }
 #endif /* CONFIG_LOOPW */
 
-static ulong mem_test_alt(ulong start_addr, ulong end_addr)
+#ifdef CONFIG_CMD_MEMTEST
+static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr,
+                         vu_long *dummy)
 {
-       vu_long *start, *end;
        vu_long *addr;
        ulong errs = 0;
        ulong val, readback;
        int j;
-       vu_long len;
        vu_long offset;
        vu_long test_offset;
        vu_long pattern;
        vu_long temp;
        vu_long anti_pattern;
        vu_long num_words;
-#if defined(CONFIG_SYS_MEMTEST_SCRATCH)
-       vu_long *dummy = (vu_long *)CONFIG_SYS_MEMTEST_SCRATCH;
-#else
-       vu_long *dummy = NULL;  /* yes, this is address 0x0, not NULL */
-#endif
        static const ulong bitpattern[] = {
                0x00000001,     /* single bit */
                0x00000003,     /* two adjacent bits */
@@ -656,8 +732,7 @@ static ulong mem_test_alt(ulong start_addr, ulong end_addr)
                0xaaaaaaaa,     /* alternating 1/0 */
        };
 
-       start = (vu_long *)start_addr;
-       end = (vu_long *)end_addr;
+       num_words = (end_addr - start_addr) / sizeof(vu_long);
 
        /*
         * Data line test: write a pattern to the first
@@ -676,11 +751,11 @@ static ulong mem_test_alt(ulong start_addr, ulong end_addr)
         * '0's and '0' bits through a field of '1's (i.e.
         * pattern and ~pattern).
         */
-       addr = start;
+       addr = buf;
        for (j = 0; j < sizeof(bitpattern) / sizeof(bitpattern[0]); j++) {
                val = bitpattern[j];
                for (; val != 0; val <<= 1) {
-                       *addr  = val;
+                       *addr = val;
                        *dummy  = ~val; /* clear the test data off the bus */
                        readback = *addr;
                        if (readback != val) {
@@ -739,58 +814,58 @@ static ulong mem_test_alt(ulong start_addr, ulong end_addr)
         *
         * Returns:     0 if the test succeeds, 1 if the test fails.
         */
-       len = (end_addr - start_addr) / sizeof(vu_long);
        pattern = (vu_long) 0xaaaaaaaa;
        anti_pattern = (vu_long) 0x55555555;
 
-       debug("%s:%d: length = 0x%.8lx\n",
-               __func__, __LINE__, len);
+       debug("%s:%d: length = 0x%.8lx\n", __func__, __LINE__, num_words);
        /*
         * Write the default pattern at each of the
         * power-of-two offsets.
         */
-       for (offset = 1; offset < len; offset <<= 1)
-               start[offset] = pattern;
+       for (offset = 1; offset < num_words; offset <<= 1)
+               addr[offset] = pattern;
 
        /*
         * Check for address bits stuck high.
         */
        test_offset = 0;
-       start[test_offset] = anti_pattern;
+       addr[test_offset] = anti_pattern;
 
-       for (offset = 1; offset < len; offset <<= 1) {
-               temp = start[offset];
+       for (offset = 1; offset < num_words; offset <<= 1) {
+               temp = addr[offset];
                if (temp != pattern) {
                        printf("\nFAILURE: Address bit stuck high @ 0x%.8lx:"
                                " expected 0x%.8lx, actual 0x%.8lx\n",
-                               (ulong)&start[offset], pattern, temp);
+                               start_addr + offset*sizeof(vu_long),
+                               pattern, temp);
                        errs++;
                        if (ctrlc())
                                return -1;
                }
        }
-       start[test_offset] = pattern;
+       addr[test_offset] = pattern;
        WATCHDOG_RESET();
 
        /*
         * Check for addr bits stuck low or shorted.
         */
-       for (test_offset = 1; test_offset < len; test_offset <<= 1) {
-               start[test_offset] = anti_pattern;
+       for (test_offset = 1; test_offset < num_words; test_offset <<= 1) {
+               addr[test_offset] = anti_pattern;
 
-               for (offset = 1; offset < len; offset <<= 1) {
-                       temp = start[offset];
+               for (offset = 1; offset < num_words; offset <<= 1) {
+                       temp = addr[offset];
                        if ((temp != pattern) && (offset != test_offset)) {
                                printf("\nFAILURE: Address bit stuck low or"
                                        " shorted @ 0x%.8lx: expected 0x%.8lx,"
                                        " actual 0x%.8lx\n",
-                                       (ulong)&start[offset], pattern, temp);
+                                       start_addr + offset*sizeof(vu_long),
+                                       pattern, temp);
                                errs++;
                                if (ctrlc())
                                        return -1;
                        }
                }
-               start[test_offset] = pattern;
+               addr[test_offset] = pattern;
        }
 
        /*
@@ -805,14 +880,14 @@ static ulong mem_test_alt(ulong start_addr, ulong end_addr)
         *
         * Returns:     0 if the test succeeds, 1 if the test fails.
         */
-       num_words = ((ulong)end - (ulong)start)/sizeof(vu_long) + 1;
+       num_words++;
 
        /*
         * Fill memory with a known pattern.
         */
        for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
                WATCHDOG_RESET();
-               start[offset] = pattern;
+               addr[offset] = pattern;
        }
 
        /*
@@ -820,18 +895,19 @@ static ulong mem_test_alt(ulong start_addr, ulong end_addr)
         */
        for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
                WATCHDOG_RESET();
-               temp = start[offset];
+               temp = addr[offset];
                if (temp != pattern) {
                        printf("\nFAILURE (read/write) @ 0x%.8lx:"
                                " expected 0x%.8lx, actual 0x%.8lx)\n",
-                               (ulong)&start[offset], pattern, temp);
+                               start_addr + offset*sizeof(vu_long),
+                               pattern, temp);
                        errs++;
                        if (ctrlc())
                                return -1;
                }
 
                anti_pattern = ~pattern;
-               start[offset] = anti_pattern;
+               addr[offset] = anti_pattern;
        }
 
        /*
@@ -840,28 +916,29 @@ static ulong mem_test_alt(ulong start_addr, ulong end_addr)
        for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
                WATCHDOG_RESET();
                anti_pattern = ~pattern;
-               temp = start[offset];
+               temp = addr[offset];
                if (temp != anti_pattern) {
                        printf("\nFAILURE (read/write): @ 0x%.8lx:"
                                " expected 0x%.8lx, actual 0x%.8lx)\n",
-                               (ulong)&start[offset], anti_pattern, temp);
+                               start_addr + offset*sizeof(vu_long),
+                               anti_pattern, temp);
                        errs++;
                        if (ctrlc())
                                return -1;
                }
-               start[offset] = 0;
+               addr[offset] = 0;
        }
 
        return 0;
 }
 
-static ulong mem_test_quick(ulong start_addr, ulong end_addr, vu_long pattern,
-                           int iteration)
+static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr,
+                           vu_long pattern, int iteration)
 {
-       vu_long *start, *end;
+       vu_long *end;
        vu_long *addr;
        ulong errs = 0;
-       ulong incr;
+       ulong incr, length;
        ulong val, readback;
 
        /* Alternate the pattern */
@@ -879,14 +956,14 @@ static ulong mem_test_quick(ulong start_addr, ulong end_addr, vu_long pattern,
                else
                        pattern = ~pattern;
        }
-       start = (vu_long *)start_addr;
-       end = (vu_long *)end_addr;
+       length = (end_addr - start_addr) / sizeof(ulong);
+       end = buf + length;
        printf("\rPattern %08lX  Writing..."
                "%12s"
                "\b\b\b\b\b\b\b\b\b\b",
                pattern, "");
 
-       for (addr = start, val = pattern; addr < end; addr++) {
+       for (addr = buf, val = pattern; addr < end; addr++) {
                WATCHDOG_RESET();
                *addr = val;
                val += incr;
@@ -894,13 +971,16 @@ static ulong mem_test_quick(ulong start_addr, ulong end_addr, vu_long pattern,
 
        puts("Reading...");
 
-       for (addr = start, val = pattern; addr < end; addr++) {
+       for (addr = buf, val = pattern; addr < end; addr++) {
                WATCHDOG_RESET();
                readback = *addr;
                if (readback != val) {
+                       ulong offset = addr - buf;
+
                        printf("\nMem error @ 0x%08X: "
                                "found %08lX, expected %08lX\n",
-                               (uint)(uintptr_t)addr, readback, val);
+                               (uint)(uintptr_t)(start_addr + offset*sizeof(vu_long)),
+                               readback, val);
                        errs++;
                        if (ctrlc())
                                return -1;
@@ -920,10 +1000,11 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
                        char * const argv[])
 {
        ulong start, end;
-       int iteration_limit;
+       vu_long *buf, *dummy;
+       ulong iteration_limit = 0;
        int ret;
        ulong errs = 0; /* number of errors, or -1 if interrupted */
-       ulong pattern;
+       ulong pattern = 0;
        int iteration;
 #if defined(CONFIG_SYS_ALT_MEMTEST)
        const int alt_test = 1;
@@ -931,30 +1012,36 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
        const int alt_test = 0;
 #endif
 
+       start = CONFIG_SYS_MEMTEST_START;
+       end = CONFIG_SYS_MEMTEST_END;
+
        if (argc > 1)
-               start = simple_strtoul(argv[1], NULL, 16);
-       else
-               start = CONFIG_SYS_MEMTEST_START;
+               if (strict_strtoul(argv[1], 16, &start) < 0)
+                       return CMD_RET_USAGE;
 
        if (argc > 2)
-               end = simple_strtoul(argv[2], NULL, 16);
-       else
-               end = CONFIG_SYS_MEMTEST_END;
+               if (strict_strtoul(argv[2], 16, &end) < 0)
+                       return CMD_RET_USAGE;
 
        if (argc > 3)
-               pattern = (ulong)simple_strtoul(argv[3], NULL, 16);
-       else
-               pattern = 0;
+               if (strict_strtoul(argv[3], 16, &pattern) < 0)
+                       return CMD_RET_USAGE;
 
        if (argc > 4)
-               iteration_limit = (ulong)simple_strtoul(argv[4], NULL, 16);
-       else
-               iteration_limit = 0;
+               if (strict_strtoul(argv[4], 16, &iteration_limit) < 0)
+                       return CMD_RET_USAGE;
+
+       if (end < start) {
+               printf("Refusing to do empty test\n");
+               return -1;
+       }
 
        printf("Testing %08x ... %08x:\n", (uint)start, (uint)end);
        debug("%s:%d: start %#08lx end %#08lx\n", __func__, __LINE__,
              start, end);
 
+       buf = map_sysmem(start, end - start);
+       dummy = map_sysmem(CONFIG_SYS_MEMTEST_SCRATCH, sizeof(vu_long));
        for (iteration = 0;
                        !iteration_limit || iteration < iteration_limit;
                        iteration++) {
@@ -965,10 +1052,27 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
 
                printf("Iteration: %6d\r", iteration + 1);
                debug("\n");
-               if (alt_test)
-                       errs = mem_test_alt(start, end);
-               else
-                       errs = mem_test_quick(start, end, pattern, iteration);
+               if (alt_test) {
+                       errs = mem_test_alt(buf, start, end, dummy);
+               } else {
+                       errs = mem_test_quick(buf, start, end, pattern,
+                                             iteration);
+               }
+               if (errs == -1UL)
+                       break;
+       }
+
+       /*
+        * Work-around for eldk-4.2 which gives this warning if we try to
+        * case in the unmap_sysmem() call:
+        * warning: initialization discards qualifiers from pointer target type
+        */
+       {
+               void *vbuf = (void *)buf;
+               void *vdummy = (void *)dummy;
+
+               unmap_sysmem(vbuf);
+               unmap_sysmem(vdummy);
        }
 
        if (errs == -1UL) {
@@ -981,29 +1085,32 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
                ret = errs != 0;
        }
 
-       return ret;     /* not reached */
+       return ret;
 }
-
+#endif /* CONFIG_CMD_MEMTEST */
 
 /* Modify memory.
  *
  * Syntax:
- *     mm{.b, .w, .l} {addr}
- *     nm{.b, .w, .l} {addr}
+ *     mm{.b, .w, .l, .q} {addr}
+ *     nm{.b, .w, .l, .q} {addr}
  */
 static int
 mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
 {
-       ulong   addr, i;
+       ulong   addr;
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       u64 i;
+#else
+       ulong i;
+#endif
        int     nbytes, size;
        void *ptr = NULL;
 
        if (argc != 2)
                return CMD_RET_USAGE;
 
-#ifdef CONFIG_BOOT_RETRY_TIME
-       reset_cmd_timeout();    /* got a good command to get here */
-#endif
+       bootretry_reset_cmd_timeout();  /* got a good command to get here */
        /* We use the last specified parameters, unless new ones are
         * entered.
         */
@@ -1044,13 +1151,17 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
                ptr = map_sysmem(addr, size);
                printf("%08lx:", addr);
                if (size == 4)
-                       printf(" %08x", *((uint *)ptr));
+                       printf(" %08x", *((u32 *)ptr));
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+               else if (size == 8)
+                       printf(" %016" PRIx64, *((u64 *)ptr));
+#endif
                else if (size == 2)
-                       printf(" %04x", *((ushort *)ptr));
+                       printf(" %04x", *((u16 *)ptr));
                else
-                       printf(" %02x", *((u_char *)ptr));
+                       printf(" %02x", *((u8 *)ptr));
 
-               nbytes = readline (" ? ");
+               nbytes = cli_readline(" ? ");
                if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
                        /* <CR> pressed as only input, don't modify current
                         * location and move to next. "-" pressed will go back.
@@ -1058,9 +1169,8 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
                        if (incrflag)
                                addr += nbytes ? -size : size;
                        nbytes = 1;
-#ifdef CONFIG_BOOT_RETRY_TIME
-                       reset_cmd_timeout(); /* good enough to not time out */
-#endif
+                       /* good enough to not time out */
+                       bootretry_reset_cmd_timeout();
                }
 #ifdef CONFIG_BOOT_RETRY_TIME
                else if (nbytes == -2) {
@@ -1069,20 +1179,26 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
 #endif
                else {
                        char *endp;
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+                       i = simple_strtoull(console_buffer, &endp, 16);
+#else
                        i = simple_strtoul(console_buffer, &endp, 16);
+#endif
                        nbytes = endp - console_buffer;
                        if (nbytes) {
-#ifdef CONFIG_BOOT_RETRY_TIME
                                /* good enough to not time out
                                 */
-                               reset_cmd_timeout();
-#endif
+                               bootretry_reset_cmd_timeout();
                                if (size == 4)
-                                       *((uint *)ptr) = i;
+                                       *((u32 *)ptr) = i;
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+                               else if (size == 8)
+                                       *((u64 *)ptr) = i;
+#endif
                                else if (size == 2)
-                                       *((ushort *)ptr) = i;
+                                       *((u16 *)ptr) = i;
                                else
-                                       *((u_char *)ptr) = i;
+                                       *((u8 *)ptr) = i;
                                if (incrflag)
                                        addr += size;
                        }
@@ -1098,89 +1214,27 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
 
 #ifdef CONFIG_CMD_CRC32
 
-#ifndef CONFIG_CRC32_VERIFY
-
 static int do_mem_crc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       ulong addr, length;
-       ulong crc;
-       ulong *ptr;
-
-       if (argc < 3)
-               return CMD_RET_USAGE;
-
-       addr = simple_strtoul (argv[1], NULL, 16);
-       addr += base_address;
-
-       length = simple_strtoul (argv[2], NULL, 16);
-
-       crc = crc32_wd (0, (const uchar *) addr, length, CHUNKSZ_CRC32);
-
-       printf ("CRC32 for %08lx ... %08lx ==> %08lx\n",
-                       addr, addr + length - 1, crc);
-
-       if (argc > 3) {
-               ptr = (ulong *) simple_strtoul (argv[3], NULL, 16);
-               *ptr = crc;
-       }
-
-       return 0;
-}
-
-#else  /* CONFIG_CRC32_VERIFY */
-
-int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-       ulong addr, length;
-       ulong crc;
-       ulong *ptr;
-       ulong vcrc;
-       int verify;
+       int flags = 0;
        int ac;
        char * const *av;
 
-       if (argc < 3) {
-usage:
+       if (argc < 3)
                return CMD_RET_USAGE;
-       }
 
        av = argv + 1;
        ac = argc - 1;
+#ifdef CONFIG_HASH_VERIFY
        if (strcmp(*av, "-v") == 0) {
-               verify = 1;
+               flags |= HASH_FLAG_VERIFY | HASH_FLAG_ENV;
                av++;
                ac--;
-               if (ac < 3)
-                       goto usage;
-       } else
-               verify = 0;
-
-       addr = simple_strtoul(*av++, NULL, 16);
-       addr += base_address;
-       length = simple_strtoul(*av++, NULL, 16);
-
-       crc = crc32_wd (0, (const uchar *) addr, length, CHUNKSZ_CRC32);
-
-       if (!verify) {
-               printf ("CRC32 for %08lx ... %08lx ==> %08lx\n",
-                               addr, addr + length - 1, crc);
-               if (ac > 2) {
-                       ptr = (ulong *) simple_strtoul (*av++, NULL, 16);
-                       *ptr = crc;
-               }
-       } else {
-               vcrc = simple_strtoul(*av++, NULL, 16);
-               if (vcrc != crc) {
-                       printf ("CRC32 for %08lx ... %08lx ==> %08lx != %08lx ** ERROR **\n",
-                                       addr, addr + length - 1, crc, vcrc);
-                       return 1;
-               }
        }
+#endif
 
-       return 0;
-
+       return hash_command("crc32", flags, cmdtp, flag, ac, av);
 }
-#endif /* CONFIG_CRC32_VERIFY */
 
 #endif
 
@@ -1188,44 +1242,68 @@ usage:
 U_BOOT_CMD(
        md,     3,      1,      do_mem_md,
        "memory display",
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       "[.b, .w, .l, .q] address [# of objects]"
+#else
        "[.b, .w, .l] address [# of objects]"
+#endif
 );
 
 
 U_BOOT_CMD(
        mm,     2,      1,      do_mem_mm,
        "memory modify (auto-incrementing address)",
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       "[.b, .w, .l, .q] address"
+#else
        "[.b, .w, .l] address"
+#endif
 );
 
 
 U_BOOT_CMD(
        nm,     2,      1,      do_mem_nm,
        "memory modify (constant address)",
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       "[.b, .w, .l, .q] address"
+#else
        "[.b, .w, .l] address"
+#endif
 );
 
 U_BOOT_CMD(
        mw,     4,      1,      do_mem_mw,
        "memory write (fill)",
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       "[.b, .w, .l, .q] address value [count]"
+#else
        "[.b, .w, .l] address value [count]"
+#endif
 );
 
 U_BOOT_CMD(
        cp,     4,      1,      do_mem_cp,
        "memory copy",
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       "[.b, .w, .l, .q] source target count"
+#else
        "[.b, .w, .l] source target count"
+#endif
 );
 
 U_BOOT_CMD(
        cmp,    4,      1,      do_mem_cmp,
        "memory compare",
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       "[.b, .w, .l, .q] addr1 addr2 count"
+#else
        "[.b, .w, .l] addr1 addr2 count"
+#endif
 );
 
 #ifdef CONFIG_CMD_CRC32
 
-#ifndef CONFIG_CRC32_VERIFY
+#ifndef CONFIG_HASH_VERIFY
 
 U_BOOT_CMD(
        crc32,  4,      1,      do_mem_crc,
@@ -1233,7 +1311,7 @@ U_BOOT_CMD(
        "address count [addr]\n    - compute CRC32 checksum [save at addr]"
 );
 
-#else  /* CONFIG_CRC32_VERIFY */
+#else  /* CONFIG_HASH_VERIFY */
 
 U_BOOT_CMD(
        crc32,  5,      1,      do_mem_crc,
@@ -1242,12 +1320,12 @@ U_BOOT_CMD(
        "-v address count crc\n    - verify crc of memory area"
 );
 
-#endif /* CONFIG_CRC32_VERIFY */
+#endif /* CONFIG_HASH_VERIFY */
 
 #endif
 
 #ifdef CONFIG_CMD_MEMINFO
-__weak void board_show_dram(ulong size)
+__weak void board_show_dram(phys_size_t size)
 {
        puts("DRAM:  ");
        print_size(size, "\n");
@@ -1272,34 +1350,52 @@ U_BOOT_CMD(
 U_BOOT_CMD(
        loop,   3,      1,      do_mem_loop,
        "infinite loop on address range",
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       "[.b, .w, .l, .q] address number_of_objects"
+#else
        "[.b, .w, .l] address number_of_objects"
+#endif
 );
 
 #ifdef CONFIG_LOOPW
 U_BOOT_CMD(
        loopw,  4,      1,      do_mem_loopw,
        "infinite write loop on address range",
+#ifdef CONFIG_SYS_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
 );
 #endif /* CONFIG_LOOPW */
 
+#ifdef CONFIG_CMD_MEMTEST
 U_BOOT_CMD(
        mtest,  5,      1,      do_mem_mtest,
        "simple RAM read/write test",
        "[start [end [pattern [iterations]]]]"
 );
+#endif /* CONFIG_CMD_MEMTEST */
 
 #ifdef CONFIG_MX_CYCLIC
 U_BOOT_CMD(
        mdc,    4,      1,      do_mem_mdc,
        "memory display cyclic",
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       "[.b, .w, .l, .q] address count delay(ms)"
+#else
        "[.b, .w, .l] address count delay(ms)"
+#endif
 );
 
 U_BOOT_CMD(
        mwc,    4,      1,      do_mem_mwc,
        "memory write cyclic",
+#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
+       "[.b, .w, .l, .q] address value delay(ms)"
+#else
        "[.b, .w, .l] address value delay(ms)"
+#endif
 );
 #endif /* CONFIG_MX_CYCLIC */