[U-Boot] [RFC] Add 64-bit data support for memory commands

York Sun yorksun at freescale.com
Wed Feb 12 22:20:23 CET 2014


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 <yorksun at freescale.com>
---
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




More information about the U-Boot mailing list