For aarch64, unsigned long is 64-bit data. Memory commands should be fixed
with u32 for 32-bit address access. A double word data size is added to
support 64-bit data.

Signed-off-by: York Sun <[email protected]>
---
This patch fix this problem on aarch64

cp 30000004 80000000 1

This command causes alighment exception becuase "unsigned long" is 64-bit.

 common/cmd_mem.c      |  137 +++++++++++++++++++++++++++++++------------------
 common/command.c      |    2 +
 lib/display_options.c |    9 ++--
 3 files changed, 96 insertions(+), 52 deletions(-)

diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index c3aab3d..24658ca 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -187,12 +187,14 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int 
argc, char * const argv[])
        bytes = size * count;
        buf = map_sysmem(addr, bytes);
        while (count-- > 0) {
-               if (size == 4)
-                       *((ulong *)buf) = (ulong)writeval;
+               if (size == 8)
+                       *((u64 *)buf) = (u64)writeval;
+               else if (size == 4)
+                       *((u32 *)buf) = (u32)writeval;
                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);
@@ -270,7 +272,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;
@@ -298,23 +302,26 @@ 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;
+               u64 word1, word2;
+               if (size == 8) {
+                       word1 = *(u64 *)buf1;
+                       word2 = *(u64 *)buf2;
+               } else if (size == 4) {
+                       word1 = *(u32 *)buf1;
+                       word2 = *(u32 *)buf2;
                } 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;
 
-                       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);
+                       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);
                        rcode = 1;
                        break;
                }
@@ -432,12 +439,14 @@ static int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int 
argc, char * const argv[])
        buf = map_sysmem(dest, bytes);
        src = map_sysmem(addr, bytes);
        while (count-- > 0) {
-               if (size == 4)
-                       *((ulong *)buf) = *((ulong  *)src);
+               if (size == 8)
+                       *((u64 *)buf) = *((u64 *)src);
+               else if (size == 4)
+                       *((u32 *)buf) = *((u32 *)src);
                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;
 
@@ -465,11 +474,12 @@ static int do_mem_base(cmd_tbl_t *cmdtp, int flag, int 
argc,
 static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,
                       char * const argv[])
 {
-       ulong   addr, length, i, bytes;
+       u64     addr, length, i, bytes;
        int     size;
-       volatile uint   *longp;
-       volatile ushort *shortp;
-       volatile u_char *cp;
+       volatile u64 *llp;
+       volatile u32 *longp;
+       volatile u16 *shortp;
+       volatile u8 *cp;
        const void *buf;
 
        if (argc < 3)
@@ -497,24 +507,36 @@ 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) {
-               if (size == 4) {
-                       longp = (uint *)buf;
+               if (size == 8) {
+                       llp = (u64 *)buf;
+                       for (;;)
+                               i = *llp;
+               } else if (size == 4) {
+                       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;
        }
 
+       if (size == 8) {
+               for (;;) {
+                       llp = (u64 *)buf;
+                       i = length;
+                       while (i-- > 0)
+                               *llp++;
+               }
+       }
        if (size == 4) {
                for (;;) {
-                       longp = (uint *)buf;
+                       longp = (u32 *)buf;
                        i = length;
                        while (i-- > 0)
                                *longp++;
@@ -542,11 +564,12 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int 
argc,
 #ifdef CONFIG_LOOPW
 int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       ulong   addr, length, i, data, bytes;
+       u64     addr, length, i, data, bytes;
        int     size;
-       volatile uint   *longp;
-       volatile ushort *shortp;
-       volatile u_char *cp;
+       volatile u64 *llp;
+       volatile u32 *longp;
+       volatile u16 *shortp;
+       volatile u8 *cp;
        void *buf;
 
        if (argc < 4)
@@ -577,24 +600,36 @@ 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) {
+               if (size == 8) {
+                       llp = (u64 *)buf;
+                       for (;;)
+                               *llp = data;
                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;
        }
 
+       if (size == 8) {
+               for (;;) {
+                       llp = (u64 *)buf;
+                       i = length;
+                       while (i-- > 0)
+                               *llp++ = data;
+               }
+       }
        if (size == 4) {
                for (;;) {
-                       longp = (uint *)buf;
+                       longp = (u32 *)buf;
                        i = length;
                        while (i-- > 0)
                                *longp++ = data;
@@ -602,14 +637,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;
@@ -1000,7 +1035,7 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int 
argc,
 static int
 mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const 
argv[])
 {
-       ulong   addr, i;
+       u64     addr, i;
        int     nbytes, size;
        void *ptr = NULL;
 
@@ -1048,13 +1083,15 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int 
argc, char * const argv[])
         */
        do {
                ptr = map_sysmem(addr, size);
-               printf("%08lx:", addr);
-               if (size == 4)
-                       printf(" %08x", *((uint *)ptr));
+               printf("%p:", (void *)addr);
+               if (size == 8)
+                       printf(" %08llx", *((u64 *)ptr));
+               else if (size == 4)
+                       printf(" %08x", *((u32 *)ptr));
                else if (size == 2)
-                       printf(" %04x", *((ushort *)ptr));
+                       printf(" %04x", *((u16 *)ptr));
                else
-                       printf(" %02x", *((u_char *)ptr));
+                       printf(" %02x", *((u8 *)ptr));
 
                nbytes = readline (" ? ");
                if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
@@ -1083,12 +1120,14 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int 
argc, char * const argv[])
                                 */
                                reset_cmd_timeout();
 #endif
-                               if (size == 4)
-                                       *((uint *)ptr) = i;
+                               if (size == 8)
+                                       *((u64 *)ptr) = i;
+                               else if (size == 4)
+                                       *((u32 *)ptr) = i;
                                else if (size == 2)
-                                       *((ushort *)ptr) = i;
+                                       *((u16 *)ptr) = i;
                                else
-                                       *((u_char *)ptr) = i;
+                                       *((u8 *)ptr) = i;
                                if (incrflag)
                                        addr += size;
                        }
diff --git a/common/command.c b/common/command.c
index 597ab4c..bdf5c2f 100644
--- a/common/command.c
+++ b/common/command.c
@@ -421,6 +421,8 @@ int cmd_get_data_size(char* arg, int default_size)
                        return 2;
                case 'l':
                        return 4;
+               case 'q':
+                       return 8;
                case 's':
                        return -2;
                default:
diff --git a/lib/display_options.c b/lib/display_options.c
index 4a972b0..7731cf0 100644
--- a/lib/display_options.c
+++ b/lib/display_options.c
@@ -87,6 +87,7 @@ int print_buffer(ulong addr, const void *data, uint width, 
uint count,
 {
        /* linebuf as a union causes proper alignment */
        union linebuf {
+               uint64_t uq[MAX_LINE_LENGTH_BYTES/sizeof(uint64_t) + 1];
                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];
@@ -108,14 +109,16 @@ int print_buffer(ulong addr, const void *data, uint 
width, uint count,
 
                /* Copy from memory into linebuf and print hex values */
                for (i = 0; i < thislinelen; i++) {
-                       uint32_t x;
-                       if (width == 4)
+                       uint64_t x;
+                       if (width == 8)
+                               x = lb.uq[i] = *(volatile uint64_t *)data;
+                       else if (width == 4)
                                x = lb.ui[i] = *(volatile uint32_t *)data;
                        else if (width == 2)
                                x = lb.us[i] = *(volatile uint16_t *)data;
                        else
                                x = lb.uc[i] = *(volatile uint8_t *)data;
-                       printf(" %0*x", width * 2, x);
+                       printf(" %0*llx", width * 2, x);
                        data += width;
                }
 
-- 
1.7.9.5


_______________________________________________
U-Boot mailing list
[email protected]
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to