From 4d1fd7f1ae6cf4e6e4e1cad975f1dcdea62b6d83 Mon Sep 17 00:00:00 2001 From: York Sun Date: Wed, 26 Feb 2014 17:03:19 -0800 Subject: [PATCH] Add 64-bit data support for memory commands Add 64-bit data for memory commands, such as md, mw, mm, cmp. The new size ".q " is introduced. For 64-bit architecture, 64-bit data is enabled by default, by detecting compiler __LP64__. It is optional for other architectures. Signed-off-by: York Sun --- README | 3 + common/cmd_mem.c | 157 +++++++++++++++++++++++++++++++++++++++--- common/command.c | 4 ++ include/common.h | 4 ++ lib/display_options.c | 17 ++++- 5 files changed, 174 insertions(+), 11 deletions(-) diff --git a/README b/README index ff4926040b..216f0c70aa 100644 --- a/README +++ b/README @@ -3470,6 +3470,9 @@ typically in board_init_f() and board_init_r(). Configuration Settings: ----------------------- +- CONFIG_SYS_SUPPORT_64BIT_DATA: Defined automatically if compiled as 64-bit. + Optionally it can be defined to support 64-bit memory commands. + - CONFIG_SYS_LONGHELP: Defined when you want long help messages included; undefine this when you're short of memory. diff --git a/common/cmd_mem.c b/common/cmd_mem.c index 6d75d025bd..5b03c2d5b1 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -41,7 +41,7 @@ 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[]) @@ -155,7 +155,12 @@ 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; ulong bytes; @@ -175,7 +180,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) { @@ -189,6 +198,10 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) while (count-- > 0) { if (size == 4) *((u32 *)buf) = (u32)writeval; +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA + else if (size == 8) + *((u64 *)buf) = (u64)writeval; +#endif else if (size == 2) *((u16 *)buf) = (u16)writeval; else @@ -262,6 +275,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; @@ -270,7 +288,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,10 +318,14 @@ 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 = *(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 = *(u16 *)buf1; word2 = *(u16 *)buf2; @@ -311,10 +335,15 @@ static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } if (word1 != word2) { ulong offset = buf1 - base; - +#ifdef CONFIG_SYS_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; } @@ -434,6 +463,10 @@ static int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) while (count-- > 0) { if (size == 4) *((u32 *)buf) = *((u32 *)src); +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA + else if (size == 8) + *((u64 *)buf) = *((u64 *)src); +#endif else if (size == 2) *((u16 *)buf) = *((u16 *)src); else @@ -467,6 +500,9 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc, { ulong addr, length, i, bytes; int size; +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA + volatile u64 *llp; +#endif volatile u32 *longp; volatile u16 *shortp; volatile u8 *cp; @@ -497,6 +533,13 @@ 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 = (u32 *)buf; for (;;) @@ -512,6 +555,16 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc, 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 = (u32 *)buf; @@ -542,8 +595,14 @@ 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; + ulong addr, length, i, bytes; int size; +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA + volatile u64 *llp; + u64 data; +#else + ulong data; +#endif volatile u32 *longp; volatile u16 *shortp; volatile u8 *cp; @@ -568,7 +627,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); @@ -577,11 +640,18 @@ 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 = (u32 *)buf; for (;;) *longp = data; - } + } if (size == 2) { shortp = (u16 *)buf; for (;;) @@ -592,6 +662,16 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) *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 = (u32 *)buf; @@ -998,13 +1078,18 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, /* 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; @@ -1055,6 +1140,10 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) printf("%08lx:", addr); if (size == 4) printf(" %08x", *((u32 *)ptr)); +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA + else if (size == 8) + printf(" %016llx", *((u64 *)ptr)); +#endif else if (size == 2) printf(" %04x", *((u16 *)ptr)); else @@ -1079,7 +1168,11 @@ 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 @@ -1089,6 +1182,10 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) #endif if (size == 4) *((u32 *)ptr) = i; +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA + else if (size == 8) + *((u64 *)ptr) = i; +#endif else if (size == 2) *((u16 *)ptr) = i; else @@ -1136,39 +1233,63 @@ static int do_mem_crc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 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 @@ -1220,14 +1341,22 @@ 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 */ @@ -1243,13 +1372,21 @@ U_BOOT_CMD( 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 */ diff --git a/common/command.c b/common/command.c index 26c37f2b9d..746b7e3f0e 100644 --- a/common/command.c +++ b/common/command.c @@ -421,6 +421,10 @@ int cmd_get_data_size(char* arg, int default_size) return 2; case 'l': return 4; +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA + case 'q': + return 8; +#endif case 's': return -2; default: diff --git a/include/common.h b/include/common.h index 96a45a6cf7..15f5834474 100644 --- a/include/common.h +++ b/include/common.h @@ -96,6 +96,10 @@ typedef volatile unsigned char vu_char; #include #include +#ifdef __LP64__ +#define CONFIG_SYS_SUPPORT_64BIT_DATA +#endif + #ifdef DEBUG #define _DEBUG 1 #else diff --git a/lib/display_options.c b/lib/display_options.c index 4a972b08a4..4c0c886d61 100644 --- a/lib/display_options.c +++ b/lib/display_options.c @@ -87,11 +87,19 @@ int print_buffer(ulong addr, const void *data, uint width, uint count, { /* linebuf as a union causes proper alignment */ union linebuf { +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA + uint64_t uq[MAX_LINE_LENGTH_BYTES/sizeof(uint64_t) + 1]; +#endif 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]; } lb; int i; +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA + uint64_t x; +#else + uint32_t x; +#endif if (linelen*width > MAX_LINE_LENGTH_BYTES) linelen = MAX_LINE_LENGTH_BYTES / width; @@ -108,14 +116,21 @@ 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) x = lb.ui[i] = *(volatile uint32_t *)data; +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA + else if (width == 8) + x = lb.uq[i] = *(volatile uint64_t *)data; +#endif else if (width == 2) x = lb.us[i] = *(volatile uint16_t *)data; else x = lb.uc[i] = *(volatile uint8_t *)data; +#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA + printf(" %0*llx", width * 2, x); +#else printf(" %0*x", width * 2, x); +#endif data += width; } -- 2.30.2