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 <yorksun@freescale.com>
This commit is contained in:
York Sun 2014-02-26 17:03:19 -08:00 committed by Tom Rini
parent f9aa6a1086
commit 4d1fd7f1ae
5 changed files with 174 additions and 11 deletions

3
README
View file

@ -3470,6 +3470,9 @@ typically in board_init_f() and board_init_r().
Configuration Settings: 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; - CONFIG_SYS_LONGHELP: Defined when you want long help messages included;
undefine this when you're short of memory. undefine this when you're short of memory.

View file

@ -41,7 +41,7 @@ static ulong base_address = 0;
/* Memory Display /* Memory Display
* *
* Syntax: * Syntax:
* md{.b, .w, .l} {addr} {len} * md{.b, .w, .l, .q} {addr} {len}
*/ */
#define DISP_LINE_LEN 16 #define DISP_LINE_LEN 16
static int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 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[]) 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; int size;
void *buf; void *buf;
ulong bytes; 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. /* 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); writeval = simple_strtoul(argv[2], NULL, 16);
#endif
/* Count ? */ /* Count ? */
if (argc == 4) { 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) { while (count-- > 0) {
if (size == 4) if (size == 4)
*((u32 *)buf) = (u32)writeval; *((u32 *)buf) = (u32)writeval;
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
else if (size == 8)
*((u64 *)buf) = (u64)writeval;
#endif
else if (size == 2) else if (size == 2)
*((u16 *)buf) = (u16)writeval; *((u16 *)buf) = (u16)writeval;
else else
@ -262,6 +275,11 @@ static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
int rcode = 0; int rcode = 0;
const char *type; const char *type;
const void *buf1, *buf2, *base; const void *buf1, *buf2, *base;
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
u64 word1, word2;
#else
ulong word1, word2;
#endif
if (argc != 4) if (argc != 4)
return CMD_RET_USAGE; 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) if ((size = cmd_get_data_size(argv[0], 4)) < 0)
return 1; 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 = simple_strtoul(argv[1], NULL, 16);
addr1 += base_address; 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); base = buf1 = map_sysmem(addr1, bytes);
buf2 = map_sysmem(addr2, bytes); buf2 = map_sysmem(addr2, bytes);
for (ngood = 0; ngood < count; ++ngood) { for (ngood = 0; ngood < count; ++ngood) {
ulong word1, word2;
if (size == 4) { if (size == 4) {
word1 = *(u32 *)buf1; word1 = *(u32 *)buf1;
word2 = *(u32 *)buf2; word2 = *(u32 *)buf2;
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
} else if (size == 8) {
word1 = *(u64 *)buf1;
word2 = *(u64 *)buf2;
#endif
} else if (size == 2) { } else if (size == 2) {
word1 = *(u16 *)buf1; word1 = *(u16 *)buf1;
word2 = *(u16 *)buf2; 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) { if (word1 != word2) {
ulong offset = buf1 - base; 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", printf("%s at 0x%08lx (%#0*lx) != %s at 0x%08lx (%#0*lx)\n",
type, (ulong)(addr1 + offset), size, word1, type, (ulong)(addr1 + offset), size, word1,
type, (ulong)(addr2 + offset), size, word2); type, (ulong)(addr2 + offset), size, word2);
#endif
rcode = 1; rcode = 1;
break; break;
} }
@ -434,6 +463,10 @@ static int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
while (count-- > 0) { while (count-- > 0) {
if (size == 4) if (size == 4)
*((u32 *)buf) = *((u32 *)src); *((u32 *)buf) = *((u32 *)src);
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
else if (size == 8)
*((u64 *)buf) = *((u64 *)src);
#endif
else if (size == 2) else if (size == 2)
*((u16 *)buf) = *((u16 *)src); *((u16 *)buf) = *((u16 *)src);
else else
@ -467,6 +500,9 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,
{ {
ulong addr, length, i, bytes; ulong addr, length, i, bytes;
int size; int size;
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
volatile u64 *llp;
#endif
volatile u32 *longp; volatile u32 *longp;
volatile u16 *shortp; volatile u16 *shortp;
volatile u8 *cp; 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 we have only one object, just run infinite loops.
*/ */
if (length == 1) { if (length == 1) {
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
if (size == 8) {
llp = (u64 *)buf;
for (;;)
i = *llp;
}
#endif
if (size == 4) { if (size == 4) {
longp = (u32 *)buf; longp = (u32 *)buf;
for (;;) for (;;)
@ -512,6 +555,16 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,
i = *cp; 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) { if (size == 4) {
for (;;) { for (;;) {
longp = (u32 *)buf; longp = (u32 *)buf;
@ -542,8 +595,14 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,
#ifdef CONFIG_LOOPW #ifdef CONFIG_LOOPW
int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 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; int size;
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
volatile u64 *llp;
u64 data;
#else
ulong data;
#endif
volatile u32 *longp; volatile u32 *longp;
volatile u16 *shortp; volatile u16 *shortp;
volatile u8 *cp; 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); length = simple_strtoul(argv[2], NULL, 16);
/* data to write */ /* data to write */
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
data = simple_strtoull(argv[3], NULL, 16);
#else
data = simple_strtoul(argv[3], NULL, 16); data = simple_strtoul(argv[3], NULL, 16);
#endif
bytes = size * length; bytes = size * length;
buf = map_sysmem(addr, bytes); 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 we have only one object, just run infinite loops.
*/ */
if (length == 1) { if (length == 1) {
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
if (size == 8) {
llp = (u64 *)buf;
for (;;)
*llp = data;
}
#endif
if (size == 4) { if (size == 4) {
longp = (u32 *)buf; longp = (u32 *)buf;
for (;;) for (;;)
*longp = data; *longp = data;
} }
if (size == 2) { if (size == 2) {
shortp = (u16 *)buf; shortp = (u16 *)buf;
for (;;) for (;;)
@ -592,6 +662,16 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
*cp = data; *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) { if (size == 4) {
for (;;) { for (;;) {
longp = (u32 *)buf; longp = (u32 *)buf;
@ -998,13 +1078,18 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
/* Modify memory. /* Modify memory.
* *
* Syntax: * Syntax:
* mm{.b, .w, .l} {addr} * mm{.b, .w, .l, .q} {addr}
* nm{.b, .w, .l} {addr} * nm{.b, .w, .l, .q} {addr}
*/ */
static int static int
mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) 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; int nbytes, size;
void *ptr = NULL; 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); printf("%08lx:", addr);
if (size == 4) if (size == 4)
printf(" %08x", *((u32 *)ptr)); printf(" %08x", *((u32 *)ptr));
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
else if (size == 8)
printf(" %016llx", *((u64 *)ptr));
#endif
else if (size == 2) else if (size == 2)
printf(" %04x", *((u16 *)ptr)); printf(" %04x", *((u16 *)ptr));
else else
@ -1079,7 +1168,11 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
#endif #endif
else { else {
char *endp; char *endp;
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
i = simple_strtoull(console_buffer, &endp, 16);
#else
i = simple_strtoul(console_buffer, &endp, 16); i = simple_strtoul(console_buffer, &endp, 16);
#endif
nbytes = endp - console_buffer; nbytes = endp - console_buffer;
if (nbytes) { if (nbytes) {
#ifdef CONFIG_BOOT_RETRY_TIME #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 #endif
if (size == 4) if (size == 4)
*((u32 *)ptr) = i; *((u32 *)ptr) = i;
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
else if (size == 8)
*((u64 *)ptr) = i;
#endif
else if (size == 2) else if (size == 2)
*((u16 *)ptr) = i; *((u16 *)ptr) = i;
else else
@ -1136,39 +1233,63 @@ static int do_mem_crc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
U_BOOT_CMD( U_BOOT_CMD(
md, 3, 1, do_mem_md, md, 3, 1, do_mem_md,
"memory display", "memory display",
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
"[.b, .w, .l, .q] address [# of objects]"
#else
"[.b, .w, .l] address [# of objects]" "[.b, .w, .l] address [# of objects]"
#endif
); );
U_BOOT_CMD( U_BOOT_CMD(
mm, 2, 1, do_mem_mm, mm, 2, 1, do_mem_mm,
"memory modify (auto-incrementing address)", "memory modify (auto-incrementing address)",
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
"[.b, .w, .l, .q] address"
#else
"[.b, .w, .l] address" "[.b, .w, .l] address"
#endif
); );
U_BOOT_CMD( U_BOOT_CMD(
nm, 2, 1, do_mem_nm, nm, 2, 1, do_mem_nm,
"memory modify (constant address)", "memory modify (constant address)",
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
"[.b, .w, .l, .q] address"
#else
"[.b, .w, .l] address" "[.b, .w, .l] address"
#endif
); );
U_BOOT_CMD( U_BOOT_CMD(
mw, 4, 1, do_mem_mw, mw, 4, 1, do_mem_mw,
"memory write (fill)", "memory write (fill)",
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
"[.b, .w, .l, .q] address value [count]"
#else
"[.b, .w, .l] address value [count]" "[.b, .w, .l] address value [count]"
#endif
); );
U_BOOT_CMD( U_BOOT_CMD(
cp, 4, 1, do_mem_cp, cp, 4, 1, do_mem_cp,
"memory copy", "memory copy",
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
"[.b, .w, .l, .q] source target count"
#else
"[.b, .w, .l] source target count" "[.b, .w, .l] source target count"
#endif
); );
U_BOOT_CMD( U_BOOT_CMD(
cmp, 4, 1, do_mem_cmp, cmp, 4, 1, do_mem_cmp,
"memory compare", "memory compare",
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
"[.b, .w, .l, .q] addr1 addr2 count"
#else
"[.b, .w, .l] addr1 addr2 count" "[.b, .w, .l] addr1 addr2 count"
#endif
); );
#ifdef CONFIG_CMD_CRC32 #ifdef CONFIG_CMD_CRC32
@ -1220,14 +1341,22 @@ U_BOOT_CMD(
U_BOOT_CMD( U_BOOT_CMD(
loop, 3, 1, do_mem_loop, loop, 3, 1, do_mem_loop,
"infinite loop on address range", "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" "[.b, .w, .l] address number_of_objects"
#endif
); );
#ifdef CONFIG_LOOPW #ifdef CONFIG_LOOPW
U_BOOT_CMD( U_BOOT_CMD(
loopw, 4, 1, do_mem_loopw, loopw, 4, 1, do_mem_loopw,
"infinite write loop on address range", "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" "[.b, .w, .l] address number_of_objects data_to_write"
#endif
); );
#endif /* CONFIG_LOOPW */ #endif /* CONFIG_LOOPW */
@ -1243,13 +1372,21 @@ U_BOOT_CMD(
U_BOOT_CMD( U_BOOT_CMD(
mdc, 4, 1, do_mem_mdc, mdc, 4, 1, do_mem_mdc,
"memory display cyclic", "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)" "[.b, .w, .l] address count delay(ms)"
#endif
); );
U_BOOT_CMD( U_BOOT_CMD(
mwc, 4, 1, do_mem_mwc, mwc, 4, 1, do_mem_mwc,
"memory write cyclic", "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)" "[.b, .w, .l] address value delay(ms)"
#endif
); );
#endif /* CONFIG_MX_CYCLIC */ #endif /* CONFIG_MX_CYCLIC */

View file

@ -421,6 +421,10 @@ int cmd_get_data_size(char* arg, int default_size)
return 2; return 2;
case 'l': case 'l':
return 4; return 4;
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
case 'q':
return 8;
#endif
case 's': case 's':
return -2; return -2;
default: default:

View file

@ -96,6 +96,10 @@ typedef volatile unsigned char vu_char;
#include <flash.h> #include <flash.h>
#include <image.h> #include <image.h>
#ifdef __LP64__
#define CONFIG_SYS_SUPPORT_64BIT_DATA
#endif
#ifdef DEBUG #ifdef DEBUG
#define _DEBUG 1 #define _DEBUG 1
#else #else

View file

@ -87,11 +87,19 @@ int print_buffer(ulong addr, const void *data, uint width, uint count,
{ {
/* linebuf as a union causes proper alignment */ /* linebuf as a union causes proper alignment */
union linebuf { 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]; uint32_t ui[MAX_LINE_LENGTH_BYTES/sizeof(uint32_t) + 1];
uint16_t us[MAX_LINE_LENGTH_BYTES/sizeof(uint16_t) + 1]; uint16_t us[MAX_LINE_LENGTH_BYTES/sizeof(uint16_t) + 1];
uint8_t uc[MAX_LINE_LENGTH_BYTES/sizeof(uint8_t) + 1]; uint8_t uc[MAX_LINE_LENGTH_BYTES/sizeof(uint8_t) + 1];
} lb; } lb;
int i; int i;
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
uint64_t x;
#else
uint32_t x;
#endif
if (linelen*width > MAX_LINE_LENGTH_BYTES) if (linelen*width > MAX_LINE_LENGTH_BYTES)
linelen = MAX_LINE_LENGTH_BYTES / width; 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 */ /* Copy from memory into linebuf and print hex values */
for (i = 0; i < thislinelen; i++) { for (i = 0; i < thislinelen; i++) {
uint32_t x;
if (width == 4) if (width == 4)
x = lb.ui[i] = *(volatile uint32_t *)data; 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) else if (width == 2)
x = lb.us[i] = *(volatile uint16_t *)data; x = lb.us[i] = *(volatile uint16_t *)data;
else else
x = lb.uc[i] = *(volatile uint8_t *)data; 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); printf(" %0*x", width * 2, x);
#endif
data += width; data += width;
} }