summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorTom Rini <trini@ti.com>2013-03-04 11:14:27 -0500
committerTom Rini <trini@ti.com>2013-03-04 11:14:27 -0500
commit1c9f47ab2a2e9b62d08d39bfb9c4adc8f8edc5da (patch)
treefa4ee32d67f02d1c8fa80a55b9d85982cedac062 /common
parentc259188b203d95e4a854e7e29b9e4472cc982f65 (diff)
parent218da0f35f4b5e5bf13d3dba6d975d4d5d65516f (diff)
downloadu-boot-imx-1c9f47ab2a2e9b62d08d39bfb9c4adc8f8edc5da.zip
u-boot-imx-1c9f47ab2a2e9b62d08d39bfb9c4adc8f8edc5da.tar.gz
u-boot-imx-1c9f47ab2a2e9b62d08d39bfb9c4adc8f8edc5da.tar.bz2
Merge branch 'mem' of git://git.denx.de/u-boot-x86
Diffstat (limited to 'common')
-rw-r--r--common/cmd_bootm.c11
-rw-r--r--common/cmd_cbfs.c4
-rw-r--r--common/cmd_cramfs.c4
-rw-r--r--common/cmd_fdos.c4
-rw-r--r--common/cmd_fdt.c11
-rw-r--r--common/cmd_hash.c14
-rw-r--r--common/cmd_jffs2.c4
-rw-r--r--common/cmd_load.c12
-rw-r--r--common/cmd_mem.c809
-rw-r--r--common/cmd_mtdparts.c4
-rw-r--r--common/cmd_nand.c12
-rw-r--r--common/cmd_nvedit.c11
-rw-r--r--common/cmd_reiser.c4
-rw-r--r--common/cmd_setexpr.c39
-rw-r--r--common/cmd_sha1sum.c6
-rw-r--r--common/cmd_unzip.c4
-rw-r--r--common/cmd_ximg.c7
-rw-r--r--common/cmd_zfs.c3
-rw-r--r--common/cmd_zip.c4
-rw-r--r--common/hash.c194
-rw-r--r--common/image.c4
21 files changed, 612 insertions, 553 deletions
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 1312a0d..b32991d 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -452,9 +452,7 @@ static int bootm_start_standalone(ulong iflag, int argc, char * const argv[])
/* Don't start if "autostart" is set to "no" */
if (((s = getenv("autostart")) != NULL) && (strcmp(s, "no") == 0)) {
- char buf[32];
- sprintf(buf, "%lX", images.os.image_len);
- setenv("filesize", buf);
+ setenv_hex("filesize", images.os.image_len);
return 0;
}
appl = (int (*)(int, char * const []))(ulong)ntohl(images.ep);
@@ -529,17 +527,14 @@ static int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int argc,
case BOOTM_STATE_RAMDISK:
{
ulong rd_len = images.rd_end - images.rd_start;
- char str[17];
ret = boot_ramdisk_high(&images.lmb, images.rd_start,
rd_len, &images.initrd_start, &images.initrd_end);
if (ret)
return ret;
- sprintf(str, "%lx", images.initrd_start);
- setenv("initrd_start", str);
- sprintf(str, "%lx", images.initrd_end);
- setenv("initrd_end", str);
+ setenv_hex("initrd_start", images.initrd_start);
+ setenv_hex("initrd_end", images.initrd_end);
}
break;
#endif
diff --git a/common/cmd_cbfs.c b/common/cmd_cbfs.c
index 3b6cfd8..f51534b 100644
--- a/common/cmd_cbfs.c
+++ b/common/cmd_cbfs.c
@@ -65,7 +65,6 @@ int do_cbfs_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
const struct cbfs_cachenode *file;
unsigned long offset;
unsigned long count;
- char buf[12];
long size;
if (argc < 3) {
@@ -95,8 +94,7 @@ int do_cbfs_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
printf("\n%ld bytes read\n", size);
- sprintf(buf, "%lX", size);
- setenv("filesize", buf);
+ setenv_hex("filesize", size);
return 0;
}
diff --git a/common/cmd_cramfs.c b/common/cmd_cramfs.c
index e7f496e..0e43ab6 100644
--- a/common/cmd_cramfs.c
+++ b/common/cmd_cramfs.c
@@ -146,11 +146,9 @@ int do_cramfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
size = cramfs_load ((char *) offset, &part, filename);
if (size > 0) {
- char buf[10];
printf("### CRAMFS load complete: %d bytes loaded to 0x%lx\n",
size, offset);
- sprintf(buf, "%x", size);
- setenv("filesize", buf);
+ setenv_hex("filesize", size);
} else {
printf("### CRAMFS LOAD ERROR<%x> for %s!\n", size, filename);
}
diff --git a/common/cmd_fdos.c b/common/cmd_fdos.c
index fbee861..8ea1140 100644
--- a/common/cmd_fdos.c
+++ b/common/cmd_fdos.c
@@ -40,7 +40,6 @@ int do_fdosboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
char *name;
char *ep;
int size;
- char buf [12];
int drive = CONFIG_SYS_FDC_DRIVE_NUMBER;
/* pre-set load_addr */
@@ -91,8 +90,7 @@ int do_fdosboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
flush_cache (load_addr, size);
- sprintf(buf, "%x", size);
- setenv("filesize", buf);
+ setenv_hex("filesize", size);
printf("Floppy DOS load complete: %d bytes loaded to 0x%lx\n",
size, load_addr);
diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c
index 6eec947..ac77a08 100644
--- a/common/cmd_fdt.c
+++ b/common/cmd_fdt.c
@@ -55,12 +55,8 @@ struct fdt_header *working_fdt;
void set_working_fdt_addr(void *addr)
{
- char buf[17];
-
working_fdt = addr;
-
- sprintf(buf, "%lx", (unsigned long)addr);
- setenv("fdtaddr", buf);
+ setenv_addr("fdtaddr", addr);
}
/*
@@ -347,10 +343,7 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
if (subcmd[0] == 's') {
/* get the num nodes at this level */
- char buf[11];
-
- sprintf(buf, "%d", curIndex + 1);
- setenv(var, buf);
+ setenv_ulong(var, curIndex + 1);
} else {
/* node index not found */
printf("libfdt node not found\n");
diff --git a/common/cmd_hash.c b/common/cmd_hash.c
index 689c608..4fe0e78 100644
--- a/common/cmd_hash.c
+++ b/common/cmd_hash.c
@@ -26,22 +26,30 @@
#include <common.h>
#include <command.h>
#include <hash.h>
+#include <linux/ctype.h>
static int do_hash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
+ char *s;
#ifdef CONFIG_HASH_VERIFY
- int verify = 0;
+ int flags = HASH_FLAG_ENV;
+ if (argc < 4)
+ return CMD_RET_USAGE;
if (!strcmp(argv[1], "-v")) {
- verify = 1;
+ flags |= HASH_FLAG_VERIFY;
argc--;
argv++;
}
+#else
+ const int flags = HASH_FLAG_ENV;
#endif
/* Move forward to 'algorithm' parameter */
argc--;
argv++;
- return hash_command(*argv, verify, cmdtp, flag, argc - 1, argv + 1);
+ for (s = *argv; *s; s++)
+ *s = tolower(*s);
+ return hash_command(*argv, flags, cmdtp, flag, argc - 1, argv + 1);
}
#ifdef CONFIG_HASH_VERIFY
diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c
index 27296dd..4a4a000 100644
--- a/common/cmd_jffs2.c
+++ b/common/cmd_jffs2.c
@@ -525,11 +525,9 @@ int do_jffs2_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
if (size > 0) {
- char buf[10];
printf("### %s load complete: %d bytes loaded to 0x%lx\n",
fsname, size, offset);
- sprintf(buf, "%x", size);
- setenv("filesize", buf);
+ setenv_hex("filesize", size);
} else {
printf("### %s LOAD ERROR<%x> for %s!\n", fsname, size, filename);
}
diff --git a/common/cmd_load.c b/common/cmd_load.c
index 46db962..0832e92 100644
--- a/common/cmd_load.c
+++ b/common/cmd_load.c
@@ -149,7 +149,6 @@ static ulong load_serial(long offset)
int type; /* return code for record type */
ulong addr; /* load address from S-Record */
ulong size; /* number of bytes transferred */
- char buf[32];
ulong store_addr;
ulong start_addr = ~0;
ulong end_addr = 0;
@@ -198,8 +197,7 @@ static ulong load_serial(long offset)
start_addr, end_addr, size, size
);
flush_cache(start_addr, size);
- sprintf(buf, "%lX", size);
- setenv("filesize", buf);
+ setenv_hex("filesize", size);
return (addr);
case SREC_START:
break;
@@ -519,7 +517,6 @@ static int do_load_serial_bin(cmd_tbl_t *cmdtp, int flag, int argc,
static ulong load_serial_bin(ulong offset)
{
int size, i;
- char buf[32];
set_kerm_bin_mode((ulong *) offset);
size = k_recv();
@@ -539,8 +536,7 @@ static ulong load_serial_bin(ulong offset)
flush_cache(offset, size);
printf("## Total Size = 0x%08x = %d Bytes\n", size, size);
- sprintf(buf, "%X", size);
- setenv("filesize", buf);
+ setenv_hex("filesize", size);
return offset;
}
@@ -965,7 +961,6 @@ static int getcxmodem(void) {
static ulong load_serial_ymodem(ulong offset)
{
int size;
- char buf[32];
int err;
int res;
connection_info_t info;
@@ -1012,8 +1007,7 @@ static ulong load_serial_ymodem(ulong offset)
flush_cache(offset, size);
printf("## Total Size = 0x%08x = %d Bytes\n", size, size);
- sprintf(buf, "%X", size);
- setenv("filesize", buf);
+ setenv_hex("filesize", size);
return offset;
}
diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index d44aa1d..042c994 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -32,11 +32,17 @@
#ifdef CONFIG_HAS_DATAFLASH
#include <dataflash.h>
#endif
+#include <hash.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.
@@ -138,9 +144,13 @@ static int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
# endif
{
+ ulong bytes = size * length;
+ const void *buf = map_sysmem(addr, bytes);
+
/* Print the lines. */
- print_buffer(addr, (void*)addr, size, length, DISP_LINE_LEN/size);
- addr += size*length;
+ print_buffer(addr, buf, size, length, DISP_LINE_LEN / size);
+ addr += bytes;
+ unmap_sysmem(buf);
}
#endif
@@ -163,6 +173,8 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
ulong addr, writeval, count;
int size;
+ void *buf;
+ ulong bytes;
if ((argc < 3) || (argc > 4))
return CMD_RET_USAGE;
@@ -188,15 +200,18 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
count = 1;
}
+ bytes = size * count;
+ buf = map_sysmem(addr, bytes);
while (count-- > 0) {
if (size == 4)
- *((ulong *)addr) = (ulong )writeval;
+ *((ulong *)buf) = (ulong)writeval;
else if (size == 2)
- *((ushort *)addr) = (ushort)writeval;
+ *((ushort *)buf) = (ushort)writeval;
else
- *((u_char *)addr) = (u_char)writeval;
- addr += size;
+ *((u_char *)buf) = (u_char)writeval;
+ buf += size;
}
+ unmap_sysmem(buf);
return 0;
}
@@ -258,10 +273,11 @@ int do_mem_mwc ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
- ulong addr1, addr2, count, ngood;
+ ulong addr1, addr2, count, ngood, bytes;
int size;
int rcode = 0;
const char *type;
+ const void *buf1, *buf2, *base;
if (argc != 4)
return CMD_RET_USAGE;
@@ -294,33 +310,40 @@ static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
#endif
+ bytes = size * count;
+ 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 *)addr1;
- word2 = *(ulong *)addr2;
+ word1 = *(ulong *)buf1;
+ word2 = *(ulong *)buf2;
} else if (size == 2) {
- word1 = *(ushort *)addr1;
- word2 = *(ushort *)addr2;
+ word1 = *(ushort *)buf1;
+ word2 = *(ushort *)buf2;
} else {
- word1 = *(u_char *)addr1;
- word2 = *(u_char *)addr2;
+ word1 = *(u_char *)buf1;
+ word2 = *(u_char *)buf2;
}
if (word1 != word2) {
+ ulong offset = buf1 - base;
+
printf("%s at 0x%08lx (%#0*lx) != %s at 0x%08lx (%#0*lx)\n",
- type, addr1, size, word1,
- type, addr2, size, word2);
+ type, (ulong)(addr1 + offset), size, word1,
+ type, (ulong)(addr2 + offset), size, word2);
rcode = 1;
break;
}
- addr1 += size;
- addr2 += size;
+ buf1 += size;
+ buf2 += size;
/* reset watchdog from time to time */
if ((ngood % (64 << 10)) == 0)
WATCHDOG_RESET();
}
+ unmap_sysmem(buf1);
+ unmap_sysmem(buf2);
printf("Total of %ld %s(s) were the same\n", ngood, type);
return rcode;
@@ -328,8 +351,10 @@ static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
static int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
- ulong addr, dest, count;
+ ulong addr, dest, count, bytes;
int size;
+ const void *src;
+ void *buf;
if (argc != 4)
return CMD_RET_USAGE;
@@ -419,15 +444,18 @@ 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);
+ src = map_sysmem(addr, bytes);
while (count-- > 0) {
if (size == 4)
- *((ulong *)dest) = *((ulong *)addr);
+ *((ulong *)buf) = *((ulong *)src);
else if (size == 2)
- *((ushort *)dest) = *((ushort *)addr);
+ *((ushort *)buf) = *((ushort *)src);
else
- *((u_char *)dest) = *((u_char *)addr);
- addr += size;
- dest += size;
+ *((u_char *)buf) = *((u_char *)src);
+ src += size;
+ buf += size;
/* reset watchdog from time to time */
if ((count % (64 << 10)) == 0)
@@ -453,11 +481,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;
+ ulong addr, length, i, bytes;
int size;
volatile uint *longp;
volatile ushort *shortp;
volatile u_char *cp;
+ const void *buf;
if (argc < 3)
return CMD_RET_USAGE;
@@ -477,28 +506,31 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,
*/
length = simple_strtoul(argv[2], NULL, 16);
+ bytes = size * length;
+ buf = map_sysmem(addr, bytes);
+
/* We want to optimize the loops to run as fast as possible.
* If we have only one object, just run infinite loops.
*/
if (length == 1) {
if (size == 4) {
- longp = (uint *)addr;
+ longp = (uint *)buf;
for (;;)
i = *longp;
}
if (size == 2) {
- shortp = (ushort *)addr;
+ shortp = (ushort *)buf;
for (;;)
i = *shortp;
}
- cp = (u_char *)addr;
+ cp = (u_char *)buf;
for (;;)
i = *cp;
}
if (size == 4) {
for (;;) {
- longp = (uint *)addr;
+ longp = (uint *)buf;
i = length;
while (i-- > 0)
*longp++;
@@ -506,28 +538,30 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,
}
if (size == 2) {
for (;;) {
- shortp = (ushort *)addr;
+ shortp = (ushort *)buf;
i = length;
while (i-- > 0)
*shortp++;
}
}
for (;;) {
- cp = (u_char *)addr;
+ cp = (u_char *)buf;
i = length;
while (i-- > 0)
*cp++;
}
+ unmap_sysmem(buf);
}
#ifdef CONFIG_LOOPW
int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
- ulong addr, length, i, data;
+ ulong addr, length, i, data, bytes;
int size;
volatile uint *longp;
volatile ushort *shortp;
volatile u_char *cp;
+ void *buf;
if (argc < 4)
return CMD_RET_USAGE;
@@ -550,28 +584,31 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
/* data to write */
data = simple_strtoul(argv[3], NULL, 16);
+ bytes = size * length;
+ buf = map_sysmem(addr, bytes);
+
/* We want to optimize the loops to run as fast as possible.
* If we have only one object, just run infinite loops.
*/
if (length == 1) {
if (size == 4) {
- longp = (uint *)addr;
+ longp = (uint *)buf;
for (;;)
*longp = data;
}
if (size == 2) {
- shortp = (ushort *)addr;
+ shortp = (ushort *)buf;
for (;;)
*shortp = data;
}
- cp = (u_char *)addr;
+ cp = (u_char *)buf;
for (;;)
*cp = data;
}
if (size == 4) {
for (;;) {
- longp = (uint *)addr;
+ longp = (uint *)buf;
i = length;
while (i-- > 0)
*longp++ = data;
@@ -579,14 +616,14 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
if (size == 2) {
for (;;) {
- shortp = (ushort *)addr;
+ shortp = (ushort *)buf;
i = length;
while (i-- > 0)
*shortp++ = data;
}
}
for (;;) {
- cp = (u_char *)addr;
+ cp = (u_char *)buf;
i = length;
while (i-- > 0)
*cp++ = data;
@@ -594,36 +631,19 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
#endif /* CONFIG_LOOPW */
-/*
- * Perform a memory test. A more complete alternative test can be
- * configured using CONFIG_SYS_ALT_MEMTEST. The complete test loops until
- * interrupted by ctrl-c or by a failure of one of the sub-tests.
- */
-static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
- char * const argv[])
+static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr,
+ vu_long *dummy)
{
- vu_long *addr, *start, *end;
- ulong val;
- ulong readback;
- ulong errs = 0;
- int iterations = 1;
- int iteration_limit;
-
-#if defined(CONFIG_SYS_ALT_MEMTEST)
- 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
- int j;
-
+ vu_long *addr;
+ ulong errs = 0;
+ ulong val, readback;
+ int j;
+ vu_long offset;
+ vu_long test_offset;
+ vu_long pattern;
+ vu_long temp;
+ vu_long anti_pattern;
+ vu_long num_words;
static const ulong bitpattern[] = {
0x00000001, /* single bit */
0x00000003, /* two adjacent bits */
@@ -634,320 +654,353 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
0x00000055, /* four non-adjacent bits */
0xaaaaaaaa, /* alternating 1/0 */
};
-#else
- ulong incr;
- ulong pattern;
-#endif
-
- if (argc > 1)
- start = (ulong *)simple_strtoul(argv[1], NULL, 16);
- else
- start = (ulong *)CONFIG_SYS_MEMTEST_START;
-
- if (argc > 2)
- end = (ulong *)simple_strtoul(argv[2], NULL, 16);
- else
- end = (ulong *)(CONFIG_SYS_MEMTEST_END);
-
- if (argc > 3)
- pattern = (ulong)simple_strtoul(argv[3], NULL, 16);
- else
- pattern = 0;
-
- if (argc > 4)
- iteration_limit = (ulong)simple_strtoul(argv[4], NULL, 16);
- else
- iteration_limit = 0;
-
-#if defined(CONFIG_SYS_ALT_MEMTEST)
- printf ("Testing %08x ... %08x:\n", (uint)start, (uint)end);
- debug("%s:%d: start 0x%p end 0x%p\n",
- __FUNCTION__, __LINE__, start, end);
-
- for (;;) {
- if (ctrlc()) {
- putc ('\n');
- return 1;
- }
-
- if (iteration_limit && iterations > iteration_limit) {
- printf("Tested %d iteration(s) with %lu errors.\n",
- iterations-1, errs);
- return errs != 0;
- }
-
- printf("Iteration: %6d\r", iterations);
- debug("\n");
- iterations++;
+ num_words = (end_addr - start_addr) / sizeof(vu_long);
- /*
- * Data line test: write a pattern to the first
- * location, write the 1's complement to a 'parking'
- * address (changes the state of the data bus so a
- * floating bus doesn't give a false OK), and then
- * read the value back. Note that we read it back
- * into a variable because the next time we read it,
- * it might be right (been there, tough to explain to
- * the quality guys why it prints a failure when the
- * "is" and "should be" are obviously the same in the
- * error message).
- *
- * Rather than exhaustively testing, we test some
- * patterns by shifting '1' bits through a field of
- * '0's and '0' bits through a field of '1's (i.e.
- * pattern and ~pattern).
- */
- addr = start;
- for (j = 0; j < sizeof(bitpattern)/sizeof(bitpattern[0]); j++) {
- val = bitpattern[j];
- for(; val != 0; val <<= 1) {
- *addr = val;
- *dummy = ~val; /* clear the test data off of the bus */
+ /*
+ * Data line test: write a pattern to the first
+ * location, write the 1's complement to a 'parking'
+ * address (changes the state of the data bus so a
+ * floating bus doesn't give a false OK), and then
+ * read the value back. Note that we read it back
+ * into a variable because the next time we read it,
+ * it might be right (been there, tough to explain to
+ * the quality guys why it prints a failure when the
+ * "is" and "should be" are obviously the same in the
+ * error message).
+ *
+ * Rather than exhaustively testing, we test some
+ * patterns by shifting '1' bits through a field of
+ * '0's and '0' bits through a field of '1's (i.e.
+ * pattern and ~pattern).
+ */
+ addr = buf;
+ for (j = 0; j < sizeof(bitpattern) / sizeof(bitpattern[0]); j++) {
+ val = bitpattern[j];
+ for (; val != 0; val <<= 1) {
+ *addr = val;
+ *dummy = ~val; /* clear the test data off the bus */
readback = *addr;
- if(readback != val) {
- printf ("FAILURE (data line): "
- "expected %08lx, actual %08lx\n",
- val, readback);
- errs++;
- if (ctrlc()) {
- putc ('\n');
- return 1;
- }
+ if (readback != val) {
+ printf("FAILURE (data line): "
+ "expected %08lx, actual %08lx\n",
+ val, readback);
+ errs++;
+ if (ctrlc())
+ return -1;
}
*addr = ~val;
*dummy = val;
readback = *addr;
- if(readback != ~val) {
- printf ("FAILURE (data line): "
- "Is %08lx, should be %08lx\n",
- readback, ~val);
- errs++;
- if (ctrlc()) {
- putc ('\n');
- return 1;
- }
+ if (readback != ~val) {
+ printf("FAILURE (data line): "
+ "Is %08lx, should be %08lx\n",
+ readback, ~val);
+ errs++;
+ if (ctrlc())
+ return -1;
}
- }
}
+ }
- /*
- * Based on code whose Original Author and Copyright
- * information follows: Copyright (c) 1998 by Michael
- * Barr. This software is placed into the public
- * domain and may be used for any purpose. However,
- * this notice must not be changed or removed and no
- * warranty is either expressed or implied by its
- * publication or distribution.
- */
+ /*
+ * Based on code whose Original Author and Copyright
+ * information follows: Copyright (c) 1998 by Michael
+ * Barr. This software is placed into the public
+ * domain and may be used for any purpose. However,
+ * this notice must not be changed or removed and no
+ * warranty is either expressed or implied by its
+ * publication or distribution.
+ */
- /*
- * Address line test
- *
- * Description: Test the address bus wiring in a
- * memory region by performing a walking
- * 1's test on the relevant bits of the
- * address and checking for aliasing.
- * This test will find single-bit
- * address failures such as stuck-high,
- * stuck-low, and shorted pins. The base
- * address and size of the region are
- * selected by the caller.
- *
- * Notes: For best results, the selected base
- * address should have enough LSB 0's to
- * guarantee single address bit changes.
- * For example, to test a 64-Kbyte
- * region, select a base address on a
- * 64-Kbyte boundary. Also, select the
- * region size as a power-of-two if at
- * all possible.
- *
- * Returns: 0 if the test succeeds, 1 if the test fails.
- */
- len = ((ulong)end - (ulong)start)/sizeof(vu_long);
- pattern = (vu_long) 0xaaaaaaaa;
- anti_pattern = (vu_long) 0x55555555;
+ /*
+ * Address line test
+
+ * Description: Test the address bus wiring in a
+ * memory region by performing a walking
+ * 1's test on the relevant bits of the
+ * address and checking for aliasing.
+ * This test will find single-bit
+ * address failures such as stuck-high,
+ * stuck-low, and shorted pins. The base
+ * address and size of the region are
+ * selected by the caller.
+
+ * Notes: For best results, the selected base
+ * address should have enough LSB 0's to
+ * guarantee single address bit changes.
+ * For example, to test a 64-Kbyte
+ * region, select a base address on a
+ * 64-Kbyte boundary. Also, select the
+ * region size as a power-of-two if at
+ * all possible.
+ *
+ * Returns: 0 if the test succeeds, 1 if the test fails.
+ */
+ pattern = (vu_long) 0xaaaaaaaa;
+ anti_pattern = (vu_long) 0x55555555;
- debug("%s:%d: length = 0x%.8lx\n",
- __FUNCTION__, __LINE__,
- len);
- /*
- * Write the default pattern at each of the
- * power-of-two offsets.
- */
- for (offset = 1; offset < len; offset <<= 1) {
- start[offset] = pattern;
- }
+ 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 < num_words; offset <<= 1)
+ addr[offset] = pattern;
- /*
- * Check for address bits stuck high.
- */
- test_offset = 0;
- start[test_offset] = anti_pattern;
+ /*
+ * Check for address bits stuck high.
+ */
+ test_offset = 0;
+ addr[test_offset] = anti_pattern;
- for (offset = 1; offset < len; offset <<= 1) {
- temp = start[offset];
- if (temp != pattern) {
- printf ("\nFAILURE: Address bit stuck high @ 0x%.8lx:"
+ 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, pattern, temp);
errs++;
- if (ctrlc()) {
- putc ('\n');
- return 1;
- }
- }
+ if (ctrlc())
+ return -1;
}
- start[test_offset] = pattern;
- WATCHDOG_RESET();
+ }
+ 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;
+ /*
+ * Check for addr bits stuck low or shorted.
+ */
+ 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);
- errs++;
- if (ctrlc()) {
- putc ('\n');
- return 1;
- }
+ printf("\nFAILURE: Address bit stuck low or"
+ " shorted @ 0x%.8lx: expected 0x%.8lx,"
+ " actual 0x%.8lx\n",
+ start_addr + offset, pattern, temp);
+ errs++;
+ if (ctrlc())
+ return -1;
}
- }
- start[test_offset] = pattern;
}
+ addr[test_offset] = pattern;
+ }
- /*
- * Description: Test the integrity of a physical
- * memory device by performing an
- * increment/decrement test over the
- * entire region. In the process every
- * storage bit in the device is tested
- * as a zero and a one. The base address
- * and the size of the region are
- * selected by the caller.
- *
- * Returns: 0 if the test succeeds, 1 if the test fails.
- */
- num_words = ((ulong)end - (ulong)start)/sizeof(vu_long) + 1;
+ /*
+ * Description: Test the integrity of a physical
+ * memory device by performing an
+ * increment/decrement test over the
+ * entire region. In the process every
+ * storage bit in the device is tested
+ * as a zero and a one. The base address
+ * and the size of the region are
+ * selected by the caller.
+ *
+ * Returns: 0 if the test succeeds, 1 if the test fails.
+ */
+ num_words++;
- /*
- * Fill memory with a known pattern.
- */
- for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
- WATCHDOG_RESET();
- start[offset] = pattern;
- }
+ /*
+ * Fill memory with a known pattern.
+ */
+ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
+ WATCHDOG_RESET();
+ addr[offset] = pattern;
+ }
- /*
- * Check each location and invert it for the second pass.
- */
- for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
- WATCHDOG_RESET();
- temp = start[offset];
- if (temp != pattern) {
- printf ("\nFAILURE (read/write) @ 0x%.8lx:"
+ /*
+ * Check each location and invert it for the second pass.
+ */
+ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
+ WATCHDOG_RESET();
+ 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, pattern, temp);
errs++;
- if (ctrlc()) {
- putc ('\n');
- return 1;
- }
- }
-
- anti_pattern = ~pattern;
- start[offset] = anti_pattern;
+ if (ctrlc())
+ return -1;
}
- /*
- * Check each location for the inverted pattern and zero it.
- */
- for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
- WATCHDOG_RESET();
- anti_pattern = ~pattern;
- temp = start[offset];
- if (temp != anti_pattern) {
- printf ("\nFAILURE (read/write): @ 0x%.8lx:"
+ anti_pattern = ~pattern;
+ addr[offset] = anti_pattern;
+ }
+
+ /*
+ * Check each location for the inverted pattern and zero it.
+ */
+ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
+ WATCHDOG_RESET();
+ anti_pattern = ~pattern;
+ 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, anti_pattern, temp);
errs++;
- if (ctrlc()) {
- putc ('\n');
- return 1;
- }
- }
- start[offset] = 0;
+ if (ctrlc())
+ return -1;
}
+ addr[offset] = 0;
}
-#else /* The original, quickie test */
- incr = 1;
- for (;;) {
- if (ctrlc()) {
- putc ('\n');
- return 1;
- }
-
- if (iteration_limit && iterations > iteration_limit) {
- printf("Tested %d iteration(s) with %lu errors.\n",
- iterations-1, errs);
- return errs != 0;
- }
- ++iterations;
-
- printf ("\rPattern %08lX Writing..."
- "%12s"
- "\b\b\b\b\b\b\b\b\b\b",
- pattern, "");
-
- for (addr=start,val=pattern; addr<end; addr++) {
- WATCHDOG_RESET();
- *addr = val;
- val += incr;
- }
-
- puts ("Reading...");
+ return 0;
+}
- for (addr=start,val=pattern; addr<end; addr++) {
- WATCHDOG_RESET();
- readback = *addr;
- if (readback != val) {
- printf ("\nMem error @ 0x%08X: "
- "found %08lX, expected %08lX\n",
- (uint)(uintptr_t)addr, readback, val);
- errs++;
- if (ctrlc()) {
- putc ('\n');
- return 1;
- }
- }
- val += incr;
- }
+static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr,
+ vu_long pattern, int iteration)
+{
+ vu_long *end;
+ vu_long *addr;
+ ulong errs = 0;
+ ulong incr, length;
+ ulong val, readback;
+ /* Alternate the pattern */
+ incr = 1;
+ if (iteration & 1) {
+ incr = -incr;
/*
* Flip the pattern each time to make lots of zeros and
* then, the next time, lots of ones. We decrement
* the "negative" patterns and increment the "positive"
* patterns to preserve this feature.
*/
- if(pattern & 0x80000000) {
+ if (pattern & 0x80000000)
pattern = -pattern; /* complement & increment */
- }
- else {
+ else
pattern = ~pattern;
+ }
+ 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 = buf, val = pattern; addr < end; addr++) {
+ WATCHDOG_RESET();
+ *addr = val;
+ val += incr;
+ }
+
+ puts("Reading...");
+
+ 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)(start_addr + offset),
+ readback, val);
+ errs++;
+ if (ctrlc())
+ return -1;
}
- incr = -incr;
+ val += incr;
}
+
+ return 0;
+}
+
+/*
+ * Perform a memory test. A more complete alternative test can be
+ * configured using CONFIG_SYS_ALT_MEMTEST. The complete test loops until
+ * interrupted by ctrl-c or by a failure of one of the sub-tests.
+ */
+static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ ulong start, end;
+ vu_long *buf, *dummy;
+ int iteration_limit;
+ int ret;
+ ulong errs = 0; /* number of errors, or -1 if interrupted */
+ ulong pattern;
+ int iteration;
+#if defined(CONFIG_SYS_ALT_MEMTEST)
+ const int alt_test = 1;
+#else
+ const int alt_test = 0;
#endif
- return 0; /* not reached */
+
+ if (argc > 1)
+ start = simple_strtoul(argv[1], NULL, 16);
+ else
+ start = CONFIG_SYS_MEMTEST_START;
+
+ if (argc > 2)
+ end = simple_strtoul(argv[2], NULL, 16);
+ else
+ end = CONFIG_SYS_MEMTEST_END;
+
+ if (argc > 3)
+ pattern = (ulong)simple_strtoul(argv[3], NULL, 16);
+ else
+ pattern = 0;
+
+ if (argc > 4)
+ iteration_limit = (ulong)simple_strtoul(argv[4], NULL, 16);
+ else
+ iteration_limit = 0;
+
+ 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++) {
+ if (ctrlc()) {
+ errs = -1UL;
+ break;
+ }
+
+ printf("Iteration: %6d\r", iteration + 1);
+ debug("\n");
+ 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) {
+ /* Memory test was aborted - write a newline to finish off */
+ putc('\n');
+ ret = 1;
+ } else {
+ printf("Tested %d iteration(s) with %lu errors.\n",
+ iteration, errs);
+ ret = errs != 0;
+ }
+
+ return ret; /* not reached */
}
@@ -962,6 +1015,7 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
{
ulong addr, i;
int nbytes, size;
+ void *ptr = NULL;
if (argc != 2)
return CMD_RET_USAGE;
@@ -1006,13 +1060,14 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
* the next value. A non-converted value exits.
*/
do {
+ ptr = map_sysmem(addr, size);
printf("%08lx:", addr);
if (size == 4)
- printf(" %08x", *((uint *)addr));
+ printf(" %08x", *((uint *)ptr));
else if (size == 2)
- printf(" %04x", *((ushort *)addr));
+ printf(" %04x", *((ushort *)ptr));
else
- printf(" %02x", *((u_char *)addr));
+ printf(" %02x", *((u_char *)ptr));
nbytes = readline (" ? ");
if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
@@ -1042,16 +1097,18 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
reset_cmd_timeout();
#endif
if (size == 4)
- *((uint *)addr) = i;
+ *((uint *)ptr) = i;
else if (size == 2)
- *((ushort *)addr) = i;
+ *((ushort *)ptr) = i;
else
- *((u_char *)addr) = i;
+ *((u_char *)ptr) = i;
if (incrflag)
addr += size;
}
}
} while (nbytes);
+ if (ptr)
+ unmap_sysmem(ptr);
mm_last_addr = addr;
mm_last_size = size;
@@ -1060,89 +1117,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;
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
diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c
index 06fc171..0cfca0c 100644
--- a/common/cmd_mtdparts.c
+++ b/common/cmd_mtdparts.c
@@ -230,7 +230,6 @@ static void memsize_format(char *buf, u32 size)
*/
static void index_partitions(void)
{
- char buf[16];
u16 mtddevnum;
struct part_info *part;
struct list_head *dentry;
@@ -244,8 +243,7 @@ static void index_partitions(void)
dev = list_entry(dentry, struct mtd_device, link);
if (dev == current_mtd_dev) {
mtddevnum += current_mtd_partnum;
- sprintf(buf, "%d", mtddevnum);
- setenv("mtddevnum", buf);
+ setenv_ulong("mtddevnum", mtddevnum);
break;
}
mtddevnum += dev->num_parts;
diff --git a/common/cmd_nand.c b/common/cmd_nand.c
index 495610c..32348f3 100644
--- a/common/cmd_nand.c
+++ b/common/cmd_nand.c
@@ -373,7 +373,6 @@ static void nand_print_and_set_info(int idx)
{
nand_info_t *nand = &nand_info[idx];
struct nand_chip *chip = nand->priv;
- char buf[32];
printf("Device %d: ", idx);
if (chip->numchips > 1)
@@ -385,14 +384,9 @@ static void nand_print_and_set_info(int idx)
printf(" Erase size %8d b\n", nand->erasesize);
/* Set geometry info */
- sprintf(buf, "%x", nand->writesize);
- setenv("nand_writesize", buf);
-
- sprintf(buf, "%x", nand->oobsize);
- setenv("nand_oobsize", buf);
-
- sprintf(buf, "%x", nand->erasesize);
- setenv("nand_erasesize", buf);
+ setenv_hex("nand_writesize", nand->writesize);
+ setenv_hex("nand_oobsize", nand->oobsize);
+ setenv_hex("nand_erasesize", nand->erasesize);
}
static int raw_access(nand_info_t *nand, ulong addr, loff_t off, ulong count,
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 7633f0c..d646d90 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -295,17 +295,17 @@ int setenv_ulong(const char *varname, ulong value)
}
/**
- * Set an environment variable to an address in hex
+ * Set an environment variable to an value in hex
*
* @param varname Environmet variable to set
- * @param addr Value to set it to
+ * @param value Value to set it to
* @return 0 if ok, 1 on error
*/
-int setenv_addr(const char *varname, const void *addr)
+int setenv_hex(const char *varname, ulong value)
{
char str[17];
- sprintf(str, "%lx", (uintptr_t)addr);
+ sprintf(str, "%lx", value);
return setenv(varname, str);
}
@@ -891,8 +891,7 @@ NXTARG: ;
envp->flags = ACTIVE_FLAG;
#endif
}
- sprintf(buf, "%zX", (size_t)(len + offsetof(env_t, data)));
- setenv("filesize", buf);
+ setenv_hex("filesize", len + offsetof(env_t, data));
return 0;
diff --git a/common/cmd_reiser.c b/common/cmd_reiser.c
index e658618..717c7f6 100644
--- a/common/cmd_reiser.c
+++ b/common/cmd_reiser.c
@@ -100,7 +100,6 @@ int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
ulong addr = 0, filelen;
disk_partition_t info;
block_dev_desc_t *dev_desc = NULL;
- char buf [12];
unsigned long count;
char *addr_str;
@@ -175,8 +174,7 @@ int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
load_addr = addr;
printf ("\n%ld bytes read\n", filelen);
- sprintf(buf, "%lX", filelen);
- setenv("filesize", buf);
+ setenv_hex("filesize", filelen);
return filelen;
}
diff --git a/common/cmd_setexpr.c b/common/cmd_setexpr.c
index 5a04295..7a38e94 100644
--- a/common/cmd_setexpr.c
+++ b/common/cmd_setexpr.c
@@ -53,7 +53,7 @@ static ulong get_arg(char *s, int w)
static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
ulong a, b;
- char buf[16];
+ ulong value;
int w;
/* Validate arguments */
@@ -67,8 +67,7 @@ static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
a = get_arg(argv[2], w);
if (argc == 3) {
- sprintf(buf, "%lx", a);
- setenv(argv[1], buf);
+ setenv_hex(argv[1], a);
return 0;
}
@@ -76,20 +75,36 @@ static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
b = get_arg(argv[4], w);
switch (argv[3][0]) {
- case '|': sprintf(buf, "%lx", (a | b)); break;
- case '&': sprintf(buf, "%lx", (a & b)); break;
- case '+': sprintf(buf, "%lx", (a + b)); break;
- case '^': sprintf(buf, "%lx", (a ^ b)); break;
- case '-': sprintf(buf, "%lx", (a - b)); break;
- case '*': sprintf(buf, "%lx", (a * b)); break;
- case '/': sprintf(buf, "%lx", (a / b)); break;
- case '%': sprintf(buf, "%lx", (a % b)); break;
+ case '|':
+ value = a | b;
+ break;
+ case '&':
+ value = a & b;
+ break;
+ case '+':
+ value = a + b;
+ break;
+ case '^':
+ value = a ^ b;
+ break;
+ case '-':
+ value = a - b;
+ break;
+ case '*':
+ value = a * b;
+ break;
+ case '/':
+ value = a / b;
+ break;
+ case '%':
+ value = a % b;
+ break;
default:
printf("invalid op\n");
return 1;
}
- setenv(argv[1], buf);
+ setenv_hex(argv[1], value);
return 0;
}
diff --git a/common/cmd_sha1sum.c b/common/cmd_sha1sum.c
index fe927ab..9f08629 100644
--- a/common/cmd_sha1sum.c
+++ b/common/cmd_sha1sum.c
@@ -31,7 +31,7 @@
int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
- int verify = 0;
+ int flags = HASH_FLAG_ENV;
int ac;
char * const *av;
@@ -42,13 +42,13 @@ int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
ac = argc - 1;
#ifdef CONFIG_SHA1SUM_VERIFY
if (strcmp(*av, "-v") == 0) {
- verify = 1;
+ flags |= HASH_FLAG_VERIFY;
av++;
ac--;
}
#endif
- return hash_command("sha1", verify, cmdtp, flag, ac, av);
+ return hash_command("sha1", flags, cmdtp, flag, ac, av);
}
#ifdef CONFIG_SHA1SUM_VERIFY
diff --git a/common/cmd_unzip.c b/common/cmd_unzip.c
index 43ed791..7470c2b 100644
--- a/common/cmd_unzip.c
+++ b/common/cmd_unzip.c
@@ -28,7 +28,6 @@ static int do_unzip(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
unsigned long src, dst;
unsigned long src_len = ~0UL, dst_len = ~0UL;
- char buf[32];
switch (argc) {
case 4:
@@ -46,8 +45,7 @@ static int do_unzip(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return 1;
printf("Uncompressed size: %ld = 0x%lX\n", src_len, src_len);
- sprintf(buf, "%lX", src_len);
- setenv("filesize", buf);
+ setenv_hex("filesize", src_len);
return 0;
}
diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c
index 42a7eba..ea0a26e 100644
--- a/common/cmd_ximg.c
+++ b/common/cmd_ximg.c
@@ -50,7 +50,6 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
ulong data, len, count;
int verify;
int part = 0;
- char pbuf[10];
image_header_t *hdr;
#if defined(CONFIG_FIT)
const char *uname = NULL;
@@ -256,10 +255,8 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
puts("OK\n");
}
- sprintf(pbuf, "%8lx", data);
- setenv("fileaddr", pbuf);
- sprintf(pbuf, "%8lx", len);
- setenv("filesize", pbuf);
+ setenv_hex("fileaddr", data);
+ setenv_hex("filesize", len);
return 0;
}
diff --git a/common/cmd_zfs.c b/common/cmd_zfs.c
index 1df0c4d..900e977 100644
--- a/common/cmd_zfs.c
+++ b/common/cmd_zfs.c
@@ -129,8 +129,7 @@ static int do_zfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
load_addr = addr;
printf("%llu bytes read\n", zfile.size);
- sprintf(buf, "%llX", zfile.size);
- setenv("filesize", buf);
+ setenv_hex("filesize", zfile.size);
return 0;
}
diff --git a/common/cmd_zip.c b/common/cmd_zip.c
index a73c86d..8607da8 100644
--- a/common/cmd_zip.c
+++ b/common/cmd_zip.c
@@ -28,7 +28,6 @@ static int do_zip(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
unsigned long src, dst;
unsigned long src_len, dst_len = ~0UL;
- char buf[32];
switch (argc) {
case 5:
@@ -47,8 +46,7 @@ static int do_zip(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return 1;
printf("Compressed size: %ld = 0x%lX\n", dst_len, dst_len);
- sprintf(buf, "%lX", dst_len);
- setenv("filesize", buf);
+ setenv_hex("filesize", dst_len);
return 0;
}
diff --git a/common/hash.c b/common/hash.c
index e3a6e43..f5badcb 100644
--- a/common/hash.c
+++ b/common/hash.c
@@ -28,49 +28,87 @@
#include <hash.h>
#include <sha1.h>
#include <sha256.h>
+#include <asm/io.h>
/*
* These are the hash algorithms we support. Chips which support accelerated
- * crypto could perhaps add named version of these algorithms here.
+ * crypto could perhaps add named version of these algorithms here. Note that
+ * algorithm names must be in lower case.
*/
static struct hash_algo hash_algo[] = {
-#ifdef CONFIG_SHA1
+ /*
+ * This is CONFIG_CMD_SHA1SUM instead of CONFIG_SHA1 since otherwise
+ * it bloats the code for boards which use SHA1 but not the 'hash'
+ * or 'sha1sum' commands.
+ */
+#ifdef CONFIG_CMD_SHA1SUM
{
- "SHA1",
+ "sha1",
SHA1_SUM_LEN,
sha1_csum_wd,
CHUNKSZ_SHA1,
},
+#define MULTI_HASH
#endif
#ifdef CONFIG_SHA256
{
- "SHA256",
+ "sha256",
SHA256_SUM_LEN,
sha256_csum_wd,
CHUNKSZ_SHA256,
},
+#define MULTI_HASH
#endif
+ {
+ "crc32",
+ 4,
+ crc32_wd_buf,
+ CHUNKSZ_CRC32,
+ },
};
+#if defined(CONFIG_HASH_VERIFY) || defined(CONFIG_CMD_HASH)
+#define MULTI_HASH
+#endif
+
+/* Try to minimize code size for boards that don't want much hashing */
+#ifdef MULTI_HASH
+#define multi_hash() 1
+#else
+#define multi_hash() 0
+#endif
+
/**
* store_result: Store the resulting sum to an address or variable
*
* @algo: Hash algorithm being used
* @sum: Hash digest (algo->digest_size bytes)
* @dest: Destination, interpreted as a hex address if it starts
- * with * or otherwise as an environment variable.
+ * with * (or allow_env_vars is 0) or otherwise as an
+ * environment variable.
+ * @allow_env_vars: non-zero to permit storing the result to an
+ * variable environment
*/
static void store_result(struct hash_algo *algo, const u8 *sum,
- const char *dest)
+ const char *dest, int allow_env_vars)
{
unsigned int i;
+ int env_var = 0;
- if (*dest == '*') {
- u8 *ptr;
+ /*
+ * If environment variables are allowed, then we assume that 'dest'
+ * is an environment variable, unless it starts with *, in which
+ * case we assume it is an address. If not allowed, it is always an
+ * address. This is to support the crc32 command.
+ */
+ if (allow_env_vars) {
+ if (*dest == '*')
+ dest++;
+ else
+ env_var = 1;
+ }
- ptr = (u8 *)simple_strtoul(dest + 1, NULL, 16);
- memcpy(ptr, sum, algo->digest_size);
- } else {
+ if (env_var) {
char str_output[HASH_MAX_DIGEST_SIZE * 2 + 1];
char *str_ptr = str_output;
@@ -80,6 +118,14 @@ static void store_result(struct hash_algo *algo, const u8 *sum,
}
str_ptr = '\0';
setenv(dest, str_output);
+ } else {
+ ulong addr;
+ void *buf;
+
+ addr = simple_strtoul(dest, NULL, 16);
+ buf = map_sysmem(addr, algo->digest_size);
+ memcpy(buf, sum, algo->digest_size);
+ unmap_sysmem(buf);
}
}
@@ -94,15 +140,31 @@ static void store_result(struct hash_algo *algo, const u8 *sum,
* Otherwise we assume it is an environment variable, and
* look up its value (it must contain a hex digest).
* @vsum: Returns binary digest value (algo->digest_size bytes)
+ * @allow_env_vars: non-zero to permit storing the result to an environment
+ * variable. If 0 then verify_str is assumed to be an
+ * address, and the * prefix is not expected.
* @return 0 if ok, non-zero on error
*/
-static int parse_verify_sum(struct hash_algo *algo, char *verify_str, u8 *vsum)
+static int parse_verify_sum(struct hash_algo *algo, char *verify_str, u8 *vsum,
+ int allow_env_vars)
{
- if (*verify_str == '*') {
- u8 *ptr;
+ int env_var = 0;
+
+ /* See comment above in store_result() */
+ if (allow_env_vars) {
+ if (*verify_str == '*')
+ verify_str++;
+ else
+ env_var = 1;
+ }
- ptr = (u8 *)simple_strtoul(verify_str + 1, NULL, 16);
- memcpy(vsum, ptr, algo->digest_size);
+ if (env_var) {
+ ulong addr;
+ void *buf;
+
+ addr = simple_strtoul(verify_str, NULL, 16);
+ buf = map_sysmem(addr, algo->digest_size);
+ memcpy(vsum, buf, algo->digest_size);
} else {
unsigned int i;
char *vsum_str;
@@ -141,7 +203,7 @@ static struct hash_algo *find_hash_algo(const char *name)
int i;
for (i = 0; i < ARRAY_SIZE(hash_algo); i++) {
- if (!strcasecmp(name, hash_algo[i].name))
+ if (!strcmp(name, hash_algo[i].name))
return &hash_algo[i];
}
@@ -158,63 +220,87 @@ static void show_hash(struct hash_algo *algo, ulong addr, ulong len,
printf("%02x", output[i]);
}
-int hash_command(const char *algo_name, int verify, cmd_tbl_t *cmdtp, int flag,
+int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
int argc, char * const argv[])
{
- struct hash_algo *algo;
ulong addr, len;
- u8 output[HASH_MAX_DIGEST_SIZE];
- u8 vsum[HASH_MAX_DIGEST_SIZE];
if (argc < 2)
return CMD_RET_USAGE;
- algo = find_hash_algo(algo_name);
- if (!algo) {
- printf("Unknown hash algorithm '%s'\n", algo_name);
- return CMD_RET_USAGE;
- }
addr = simple_strtoul(*argv++, NULL, 16);
len = simple_strtoul(*argv++, NULL, 16);
- argc -= 2;
- if (algo->digest_size > HASH_MAX_DIGEST_SIZE) {
- puts("HASH_MAX_DIGEST_SIZE exceeded\n");
- return 1;
- }
+ if (multi_hash()) {
+ struct hash_algo *algo;
+ u8 output[HASH_MAX_DIGEST_SIZE];
+ u8 vsum[HASH_MAX_DIGEST_SIZE];
+ void *buf;
- algo->hash_func_ws((const unsigned char *)addr, len, output,
- algo->chunk_size);
+ algo = find_hash_algo(algo_name);
+ if (!algo) {
+ printf("Unknown hash algorithm '%s'\n", algo_name);
+ return CMD_RET_USAGE;
+ }
+ argc -= 2;
- /* Try to avoid code bloat when verify is not needed */
+ if (algo->digest_size > HASH_MAX_DIGEST_SIZE) {
+ puts("HASH_MAX_DIGEST_SIZE exceeded\n");
+ return 1;
+ }
+
+ buf = map_sysmem(addr, len);
+ algo->hash_func_ws(buf, len, output, algo->chunk_size);
+ unmap_sysmem(buf);
+
+ /* Try to avoid code bloat when verify is not needed */
#ifdef CONFIG_HASH_VERIFY
- if (verify) {
+ if (flags & HASH_FLAG_VERIFY) {
#else
- if (0) {
+ if (0) {
#endif
- if (!argc)
- return CMD_RET_USAGE;
- if (parse_verify_sum(algo, *argv, vsum)) {
- printf("ERROR: %s does not contain a valid %s sum\n",
- *argv, algo->name);
- return 1;
- }
- if (memcmp(output, vsum, algo->digest_size) != 0) {
- int i;
+ if (!argc)
+ return CMD_RET_USAGE;
+ if (parse_verify_sum(algo, *argv, vsum,
+ flags & HASH_FLAG_ENV)) {
+ printf("ERROR: %s does not contain a valid "
+ "%s sum\n", *argv, algo->name);
+ return 1;
+ }
+ if (memcmp(output, vsum, algo->digest_size) != 0) {
+ int i;
+ show_hash(algo, addr, len, output);
+ printf(" != ");
+ for (i = 0; i < algo->digest_size; i++)
+ printf("%02x", vsum[i]);
+ puts(" ** ERROR **\n");
+ return 1;
+ }
+ } else {
show_hash(algo, addr, len, output);
- printf(" != ");
- for (i = 0; i < algo->digest_size; i++)
- printf("%02x", vsum[i]);
- puts(" ** ERROR **\n");
- return 1;
+ printf("\n");
+
+ if (argc) {
+ store_result(algo, output, *argv,
+ flags & HASH_FLAG_ENV);
+ }
}
+
+ /* Horrible code size hack for boards that just want crc32 */
} else {
- show_hash(algo, addr, len, output);
- printf("\n");
+ ulong crc;
+ ulong *ptr;
+
+ crc = crc32_wd(0, (const uchar *)addr, len, CHUNKSZ_CRC32);
- if (argc)
- store_result(algo, output, *argv);
+ printf("CRC32 for %08lx ... %08lx ==> %08lx\n",
+ addr, addr + len - 1, crc);
+
+ if (argc > 3) {
+ ptr = (ulong *)simple_strtoul(argv[3], NULL, 16);
+ *ptr = crc;
+ }
}
return 0;
diff --git a/common/image.c b/common/image.c
index ae1a9d3..6afbb40 100644
--- a/common/image.c
+++ b/common/image.c
@@ -74,6 +74,8 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch,
#include <image.h>
#endif /* !USE_HOSTCC*/
+#include <u-boot/crc.h>
+
static const table_entry_t uimage_arch[] = {
{ IH_ARCH_INVALID, NULL, "Invalid ARCH", },
{ IH_ARCH_ALPHA, "alpha", "Alpha", },
@@ -160,8 +162,6 @@ static const table_entry_t uimage_comp[] = {
{ -1, "", "", },
};
-uint32_t crc32(uint32_t, const unsigned char *, uint);
-uint32_t crc32_wd(uint32_t, const unsigned char *, uint, uint);
#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
static void genimg_print_time(time_t timestamp);
#endif