From 8ec21bbe5c45fc80ca74eb403ab5b00a9e1f699f Mon Sep 17 00:00:00 2001 From: Allen Martin Date: Tue, 22 Jan 2013 13:11:21 +0000 Subject: sandbox: fix compiler warning Add back return statement to fix compiler warning about control flow reaching end of non void function that was introduced with: e05e5de arm: move C runtime setup code in crt0.S Signed-off-by: Allen Martin Acked-by: Simon Glass --- arch/sandbox/cpu/start.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 7603bf9008..5287fd5ee8 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -122,4 +122,7 @@ int main(int argc, char *argv[]) * never return. */ board_init_f(0); + + /* NOTREACHED - board_init_f() does not return */ + return 0; } -- cgit v1.2.3 From 6b3ff98da41a084658877282057adeb59ff6e9f2 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:11 +0000 Subject: Tidy up error checking and fix bug in hash command There are two problems: 1. The argument count needs to be checked before argv is used 2. When verify is not enabled, we need to define a constant zero value Signed-off-by: Simon Glass --- common/cmd_hash.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/cmd_hash.c b/common/cmd_hash.c index 689c608572..eb6a33873b 100644 --- a/common/cmd_hash.c +++ b/common/cmd_hash.c @@ -32,11 +32,15 @@ static int do_hash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #ifdef CONFIG_HASH_VERIFY int verify = 0; + if (argc < 4) + return CMD_RET_USAGE; if (!strcmp(argv[1], "-v")) { verify = 1; argc--; argv++; } +#else + const int verify = 0; #endif /* Move forward to 'algorithm' parameter */ argc--; -- cgit v1.2.3 From bda32ffcf712806c7880ded25a012fbeede35e80 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:12 +0000 Subject: Update print_buffer() to use const The buffer cannot be changed by this function, so change the buffer pointer to a const. This allows callers with const pointer to use the function without a cast. Signed-off-by: Simon Glass --- include/common.h | 3 ++- lib/display_options.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/common.h b/include/common.h index 4ad17eafb9..170f4391a6 100644 --- a/include/common.h +++ b/include/common.h @@ -270,7 +270,8 @@ int cpu_init(void); phys_size_t initdram (int); int display_options (void); void print_size(unsigned long long, const char *); -int print_buffer (ulong addr, void* data, uint width, uint count, uint linelen); +int print_buffer(ulong addr, const void *data, uint width, uint count, + uint linelen); /* common/main.c */ void main_loop (void); diff --git a/lib/display_options.c b/lib/display_options.c index 694d2f22e8..0339970e7d 100644 --- a/lib/display_options.c +++ b/lib/display_options.c @@ -98,7 +98,8 @@ void print_size(unsigned long long size, const char *s) */ #define MAX_LINE_LENGTH_BYTES (64) #define DEFAULT_LINE_LENGTH_BYTES (16) -int print_buffer (ulong addr, void* data, uint width, uint count, uint linelen) +int print_buffer(ulong addr, const void *data, uint width, uint count, + uint linelen) { /* linebuf as a union causes proper alignment */ union linebuf { -- cgit v1.2.3 From e101550a9a8b956434cf2a73f66afbb42f4654bd Mon Sep 17 00:00:00 2001 From: Taylor Hutt Date: Sun, 24 Feb 2013 17:33:13 +0000 Subject: sandbox: Improve sandbox serial port keyboard interface Implements the tstc() interface for the serial driver. Multiplexing the console between the serial port and a keyboard uses a polling method of checking if characters are available; this means that the serial console must be non-blocking when attempting to read characters. Signed-off-by: Taylor Hutt Signed-off-by: Simon Glass --- arch/sandbox/cpu/os.c | 8 ++++++++ drivers/serial/sandbox.c | 44 ++++++++++++++++++++++++++++++++++++++------ include/os.h | 10 ++++++++++ 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 36637af6ce..3e37c930b0 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -44,6 +44,14 @@ ssize_t os_read(int fd, void *buf, size_t count) return read(fd, buf, count); } +ssize_t os_read_no_block(int fd, void *buf, size_t count) +{ + const int flags = fcntl(fd, F_GETFL, 0); + + fcntl(fd, F_SETFL, flags | O_NONBLOCK); + return os_read(fd, buf, count); +} + ssize_t os_write(int fd, const void *buf, size_t count) { return write(fd, buf, count); diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c index cb19401df6..b73520ca94 100644 --- a/drivers/serial/sandbox.c +++ b/drivers/serial/sandbox.c @@ -30,6 +30,19 @@ #include #include +/* + * + * serial_buf: A buffer that holds keyboard characters for the + * Sandbox U-boot. + * + * invariants: + * serial_buf_write == serial_buf_read -> empty buffer + * (serial_buf_write + 1) % 16 == serial_buf_read -> full buffer + */ +static char serial_buf[16]; +static unsigned int serial_buf_write; +static unsigned int serial_buf_read; + static int sandbox_serial_init(void) { os_tty_raw(0); @@ -50,18 +63,37 @@ static void sandbox_serial_puts(const char *str) os_write(1, str, strlen(str)); } -static int sandbox_serial_getc(void) +static unsigned int increment_buffer_index(unsigned int index) +{ + return (index + 1) % ARRAY_SIZE(serial_buf); +} + +static int sandbox_serial_tstc(void) { - char buf; + const unsigned int next_index = + increment_buffer_index(serial_buf_write); ssize_t count; - count = os_read(0, &buf, 1); - return count == 1 ? buf : 0; + os_usleep(100); + if (next_index == serial_buf_read) + return 1; /* buffer full */ + + count = os_read_no_block(0, &serial_buf[serial_buf_write], 1); + if (count == 1) + serial_buf_write = next_index; + return serial_buf_write != serial_buf_read; } -static int sandbox_serial_tstc(void) +static int sandbox_serial_getc(void) { - return 0; + int result; + + while (!sandbox_serial_tstc()) + ; /* buffer empty */ + + result = serial_buf[serial_buf_read]; + serial_buf_read = increment_buffer_index(serial_buf_read); + return result; } static struct serial_device sandbox_serial_drv = { diff --git a/include/os.h b/include/os.h index 699682a408..c452d1b56e 100644 --- a/include/os.h +++ b/include/os.h @@ -39,6 +39,16 @@ struct sandbox_state; */ ssize_t os_read(int fd, void *buf, size_t count); +/** + * Access to the OS read() system call with non-blocking access + * + * \param fd File descriptor as returned by os_open() + * \param buf Buffer to place data + * \param count Number of bytes to read + * \return number of bytes read, or -1 on error + */ +ssize_t os_read_no_block(int fd, void *buf, size_t count); + /** * Access to the OS write() system call * -- cgit v1.2.3 From 4213fc2913722045eb2c327a64b99e3e3178aa5c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:14 +0000 Subject: sandbox: Add un/map_sysmen() to deal with sandbox's ram_buf Sandbox doesn't actually provide U-Boot access to the machine's physical memory. Instead it provides a RAM buffer of configurable size, and all memory accesses are within that buffer. Sandbox memory starts at 0 and is CONFIG_DRAM_SIZE bytes in size. Allowing access outside this buffer might produce unpredictable results in the event of an error, and would expose the host machine's memory architecture to the sandbox U-Boot. Most U-Boot functions assume that they can just access memory at given address. For sandbox this is not true. Add a map_sysmem() call which converts a U-Boot address to a system address. In most cases this is a NOP, but for sandbox it returns a pointer to that memory inside the RAM buffer. To get a U-Boot feature to work correctly within sandbox, you should call map_sysmem() to get a pointer to the address, and then use that address for any U-Boot memory accesses. Signed-off-by: Simon Glass --- README | 9 +++++++++ arch/sandbox/config.mk | 1 + arch/sandbox/include/asm/io.h | 10 ++++++++++ include/common.h | 12 ++++++++++++ 4 files changed, 32 insertions(+) diff --git a/README b/README index 0070694438..51eb71b27c 100644 --- a/README +++ b/README @@ -3811,6 +3811,15 @@ Low Level (hardware related) configuration options: that is executed before the actual U-Boot. E.g. when compiling a NAND SPL. +- CONFIG_ARCH_MAP_SYSMEM + Generally U-Boot (and in particular the md command) uses + effective address. It is therefore not necessary to regard + U-Boot address as virtual addresses that need to be translated + to physical addresses. However, sandbox requires this, since + it maintains its own little RAM buffer which contains all + addressable memory. This option causes some memory accesses + to be mapped through map_sysmem() / unmap_sysmem(). + - CONFIG_USE_ARCH_MEMCPY CONFIG_USE_ARCH_MEMSET If these options are used a optimized version of memcpy/memset will diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk index 02ce4a4410..4fd0d4e58f 100644 --- a/arch/sandbox/config.mk +++ b/arch/sandbox/config.mk @@ -18,4 +18,5 @@ # MA 02111-1307 USA PLATFORM_CPPFLAGS += -DCONFIG_SANDBOX -D__SANDBOX__ -U_FORTIFY_SOURCE +PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM PLATFORM_LIBS += -lrt diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h index 0392d218ec..d8c02364d9 100644 --- a/arch/sandbox/include/asm/io.h +++ b/arch/sandbox/include/asm/io.h @@ -39,3 +39,13 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags) { } + +/* For sandbox, we want addresses to point into our RAM buffer */ +static inline void *map_sysmem(phys_addr_t paddr, unsigned long len) +{ + return map_physmem(paddr, len, MAP_WRBACK); +} + +static inline void unmap_sysmem(const void *vaddr) +{ +} diff --git a/include/common.h b/include/common.h index 170f4391a6..1d0728f847 100644 --- a/include/common.h +++ b/include/common.h @@ -870,6 +870,18 @@ int cpu_disable(int nr); int cpu_release(int nr, int argc, char * const argv[]); #endif +/* Define a null map_sysmem() if the architecture doesn't use it */ +# ifndef CONFIG_ARCH_MAP_SYSMEM +static inline void *map_sysmem(phys_addr_t paddr, unsigned long len) +{ + return (void *)(uintptr_t)paddr; +} + +static inline void unmap_sysmem(const void *vaddr) +{ +} +# endif + #endif /* __ASSEMBLY__ */ #ifdef CONFIG_PPC -- cgit v1.2.3 From 0628ab8ec59834f98ede267edd21ddb8ba0bb57b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:15 +0000 Subject: sandbox: Change memory commands to use map_physmem Sandbox wants to support commands which use memory. The map_sysmen() call provides this feature, so use this in the memory commands. Signed-off-by: Simon Glass --- common/cmd_mem.c | 122 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 43 deletions(-) diff --git a/common/cmd_mem.c b/common/cmd_mem.c index d44aa1d733..ee7bf9ad33 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -33,6 +33,7 @@ #include #endif #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -138,9 +139,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 +168,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 +195,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 +268,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 +305,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 +346,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 +439,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 +476,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 +501,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 +533,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 +579,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 +611,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; @@ -962,6 +994,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 +1039,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 +1076,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; -- cgit v1.2.3 From c9638f50fbd8e6973c296f6a8f2d5b91a4324c97 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:16 +0000 Subject: Split out the memory tests into separate functions Half of the code is currently hidden behind an #ifdef. Move the two memory tests into their own functions and use the compiler to eliminate the unused code. Signed-off-by: Simon Glass --- common/cmd_mem.c | 217 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 116 insertions(+), 101 deletions(-) diff --git a/common/cmd_mem.c b/common/cmd_mem.c index ee7bf9ad33..0e7a4c67c2 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -626,36 +626,26 @@ 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 int mem_test_alt(vu_long *start, vu_long *end, + int iteration_limit) { - vu_long *addr, *start, *end; - ulong val; - ulong readback; - ulong errs = 0; + vu_long *addr; 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; + ulong errs = 0; + ulong val, readback; + int j; + 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; + vu_long *dummy = (vu_long *)CONFIG_SYS_MEMTEST_SCRATCH; #else vu_long *dummy = NULL; /* yes, this is address 0x0, not NULL */ #endif - int j; - static const ulong bitpattern[] = { 0x00000001, /* single bit */ 0x00000003, /* two adjacent bits */ @@ -666,43 +656,18 @@ 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); + printf("Testing %08x ... %08x:\n", (uint)(uintptr_t)start, + (uint)(uintptr_t)end); debug("%s:%d: start 0x%p end 0x%p\n", - __FUNCTION__, __LINE__, start, end); + __func__, __LINE__, start, end); for (;;) { if (ctrlc()) { - putc ('\n'); + putc('\n'); return 1; } - if (iteration_limit && iterations > iteration_limit) { printf("Tested %d iteration(s) with %lu errors.\n", iterations-1, errs); @@ -731,34 +696,35 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, * pattern and ~pattern). */ addr = start; - for (j = 0; j < sizeof(bitpattern)/sizeof(bitpattern[0]); j++) { + for (j = 0; j < sizeof(bitpattern) / sizeof(bitpattern[0]); + j++) { val = bitpattern[j]; - for(; val != 0; val <<= 1) { + for (; val != 0; val <<= 1) { *addr = val; - *dummy = ~val; /* clear the test data off of the bus */ + *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; - } + printf("FAILURE (data line): " + "expected %08lx, actual %08lx\n", + val, readback); + errs++; + if (ctrlc()) { + putc('\n'); + 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()) { + putc('\n'); + return 1; + } } } } @@ -802,15 +768,13 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, anti_pattern = (vu_long) 0x55555555; debug("%s:%d: length = 0x%.8lx\n", - __FUNCTION__, __LINE__, - len); + __func__, __LINE__, len); /* * Write the default pattern at each of the * power-of-two offsets. */ - for (offset = 1; offset < len; offset <<= 1) { + for (offset = 1; offset < len; offset <<= 1) start[offset] = pattern; - } /* * Check for address bits stuck high. @@ -821,12 +785,12 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, for (offset = 1; offset < len; offset <<= 1) { temp = start[offset]; if (temp != pattern) { - printf ("\nFAILURE: Address bit stuck high @ 0x%.8lx:" + printf("\nFAILURE: Address bit stuck high @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx\n", (ulong)&start[offset], pattern, temp); errs++; if (ctrlc()) { - putc ('\n'); + putc('\n'); return 1; } } @@ -843,12 +807,12 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, for (offset = 1; offset < len; offset <<= 1) { temp = start[offset]; if ((temp != pattern) && (offset != test_offset)) { - printf ("\nFAILURE: Address bit stuck low or shorted @" + 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'); + putc('\n'); return 1; } } @@ -885,13 +849,13 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, WATCHDOG_RESET(); temp = start[offset]; if (temp != pattern) { - printf ("\nFAILURE (read/write) @ 0x%.8lx:" + printf("\nFAILURE (read/write) @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx)\n", (ulong)&start[offset], pattern, temp); errs++; if (ctrlc()) { - putc ('\n'); - return 1; + putc('\n'); + return 1; } } @@ -907,24 +871,33 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, anti_pattern = ~pattern; temp = start[offset]; if (temp != anti_pattern) { - printf ("\nFAILURE (read/write): @ 0x%.8lx:" + printf("\nFAILURE (read/write): @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx)\n", (ulong)&start[offset], anti_pattern, temp); errs++; if (ctrlc()) { - putc ('\n'); - return 1; + putc('\n'); + return 1; } } start[offset] = 0; } } +} + +static int mem_test_quick(vu_long *start, vu_long *end, + int iteration_limit, vu_long pattern) +{ + vu_long *addr; + int iterations = 1; + ulong errs = 0; + ulong incr; + ulong val, readback; -#else /* The original, quickie test */ incr = 1; for (;;) { if (ctrlc()) { - putc ('\n'); + putc('\n'); return 1; } @@ -935,29 +908,29 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, } ++iterations; - printf ("\rPattern %08lX Writing..." + printf("\rPattern %08lX Writing..." "%12s" "\b\b\b\b\b\b\b\b\b\b", pattern, ""); - for (addr=start,val=pattern; addr 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 (alt_test) + ret = mem_test_alt(start, end, iteration_limit); + else + ret = mem_test_quick(start, end, iteration_limit, pattern); + + return ret; /* not reached */ } -- cgit v1.2.3 From 51209b1f42cb6d1a7ce7c70be08aef2c988656cc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:17 +0000 Subject: Use common mtest iteration counting The iteration code is the same for each version of the memory test, so pull it out into the common function. Signed-off-by: Simon Glass --- common/cmd_mem.c | 123 ++++++++++++++++++++++++++----------------------------- 1 file changed, 59 insertions(+), 64 deletions(-) diff --git a/common/cmd_mem.c b/common/cmd_mem.c index 0e7a4c67c2..02ff65843a 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -626,11 +626,9 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } #endif /* CONFIG_LOOPW */ -static int mem_test_alt(vu_long *start, vu_long *end, - int iteration_limit) +static ulong mem_test_alt(vu_long *start, vu_long *end) { vu_long *addr; - int iterations = 1; ulong errs = 0; ulong val, readback; int j; @@ -657,27 +655,6 @@ static int mem_test_alt(vu_long *start, vu_long *end, 0xaaaaaaaa, /* alternating 1/0 */ }; - printf("Testing %08x ... %08x:\n", (uint)(uintptr_t)start, - (uint)(uintptr_t)end); - debug("%s:%d: start 0x%p end 0x%p\n", - __func__, __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++; - /* * Data line test: write a pattern to the first * location, write the 1's complement to a 'parking' @@ -710,7 +687,7 @@ static int mem_test_alt(vu_long *start, vu_long *end, errs++; if (ctrlc()) { putc('\n'); - return 1; + return -1; } } *addr = ~val; @@ -723,7 +700,7 @@ static int mem_test_alt(vu_long *start, vu_long *end, errs++; if (ctrlc()) { putc('\n'); - return 1; + return -1; } } } @@ -791,7 +768,7 @@ static int mem_test_alt(vu_long *start, vu_long *end, errs++; if (ctrlc()) { putc('\n'); - return 1; + return -1; } } } @@ -813,7 +790,7 @@ static int mem_test_alt(vu_long *start, vu_long *end, errs++; if (ctrlc()) { putc('\n'); - return 1; + return -1; } } } @@ -855,7 +832,7 @@ static int mem_test_alt(vu_long *start, vu_long *end, errs++; if (ctrlc()) { putc('\n'); - return 1; + return -1; } } @@ -877,37 +854,38 @@ static int mem_test_alt(vu_long *start, vu_long *end, errs++; if (ctrlc()) { putc('\n'); - return 1; + return -1; } } start[offset] = 0; } - } + + return 0; } -static int mem_test_quick(vu_long *start, vu_long *end, - int iteration_limit, vu_long pattern) +static ulong mem_test_quick(vu_long *start, vu_long *end, vu_long pattern, + int iteration) { vu_long *addr; - int iterations = 1; ulong errs = 0; ulong incr; ulong val, readback; + /* Alternate the pattern */ 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; - + 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) + pattern = -pattern; /* complement & increment */ + else + pattern = ~pattern; + } printf("\rPattern %08lX Writing..." "%12s" "\b\b\b\b\b\b\b\b\b\b", @@ -931,24 +909,13 @@ static int mem_test_quick(vu_long *start, vu_long *end, errs++; if (ctrlc()) { putc('\n'); - return 1; + return -1; } } val += 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) - pattern = -pattern; /* complement & increment */ - else - pattern = ~pattern; - incr = -incr; - } + return 0; } /* @@ -962,7 +929,9 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, vu_long *start, *end; 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 @@ -989,10 +958,36 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, else iteration_limit = 0; - if (alt_test) - ret = mem_test_alt(start, end, iteration_limit); - else - ret = mem_test_quick(start, end, iteration_limit, pattern); + printf("Testing %08x ... %08x:\n", (uint)(uintptr_t)start, + (uint)(uintptr_t)end); + debug("%s:%d: start 0x%p end 0x%p\n", + __func__, __LINE__, start, end); + + for (iteration = 0; + !iteration_limit || iteration < iteration_limit; + iteration++) { + if (ctrlc()) { + putc('\n'); + errs = -1UL; + break; + } + + printf("Iteration: %6d\r", iteration + 1); + debug("\n"); + if (alt_test) + errs = mem_test_alt(start, end); + else + errs = mem_test_quick(start, end, pattern, iteration); + } + + if (errs == -1UL) { + /* Memory test was aborted */ + ret = 1; + } else { + printf("Tested %d iteration(s) with %lu errors.\n", + iteration, errs); + ret = errs != 0; + } return ret; /* not reached */ } -- cgit v1.2.3 From 7ecbd4d70842362c3a8ad9393e9d9aab7e13afbf Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:18 +0000 Subject: Fix mtest indenting Some of the inner loops are not indented correctly. Fix this. Signed-off-by: Simon Glass --- common/cmd_mem.c | 322 +++++++++++++++++++++++++++---------------------------- 1 file changed, 161 insertions(+), 161 deletions(-) diff --git a/common/cmd_mem.c b/common/cmd_mem.c index 02ff65843a..5235bfe581 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -655,32 +655,31 @@ static ulong mem_test_alt(vu_long *start, vu_long *end) 0xaaaaaaaa, /* alternating 1/0 */ }; - /* - * 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) { + /* + * 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 the bus */ readback = *addr; - if(readback != val) { + if (readback != val) { printf("FAILURE (data line): " "expected %08lx, actual %08lx\n", val, readback); @@ -703,129 +702,130 @@ static ulong mem_test_alt(vu_long *start, vu_long *end) 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. + */ + len = ((ulong)end - (ulong)start)/sizeof(vu_long); + pattern = (vu_long) 0xaaaaaaaa; + anti_pattern = (vu_long) 0x55555555; - debug("%s:%d: length = 0x%.8lx\n", - __func__, __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__, len); + /* + * Write the default pattern at each of the + * power-of-two offsets. + */ + for (offset = 1; offset < len; offset <<= 1) + start[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; + start[test_offset] = anti_pattern; - for (offset = 1; offset < len; offset <<= 1) { - temp = start[offset]; - if (temp != pattern) { + for (offset = 1; offset < len; offset <<= 1) { + temp = start[offset]; + if (temp != pattern) { printf("\nFAILURE: Address bit stuck high @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx\n", (ulong)&start[offset], pattern, temp); errs++; if (ctrlc()) { - putc('\n'); - return -1; + putc('\n'); + return -1; } - } } - start[test_offset] = pattern; - WATCHDOG_RESET(); + } + start[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 < len; test_offset <<= 1) { + start[test_offset] = anti_pattern; - for (offset = 1; offset < len; offset <<= 1) { + for (offset = 1; offset < len; offset <<= 1) { temp = start[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", + (ulong)&start[offset], pattern, temp); + errs++; + if (ctrlc()) { + putc('\n'); + return -1; + } } - } - start[test_offset] = pattern; } + start[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 = ((ulong)end - (ulong)start)/sizeof(vu_long) + 1; - /* - * 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(); + start[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) { + /* + * 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:" " expected 0x%.8lx, actual 0x%.8lx)\n", (ulong)&start[offset], pattern, temp); @@ -834,20 +834,20 @@ static ulong mem_test_alt(vu_long *start, vu_long *end) putc('\n'); return -1; } - } - - anti_pattern = ~pattern; - start[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 = start[offset]; - if (temp != anti_pattern) { + anti_pattern = ~pattern; + start[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 = start[offset]; + if (temp != anti_pattern) { printf("\nFAILURE (read/write): @ 0x%.8lx:" " expected 0x%.8lx, actual 0x%.8lx)\n", (ulong)&start[offset], anti_pattern, temp); @@ -856,9 +856,9 @@ static ulong mem_test_alt(vu_long *start, vu_long *end) putc('\n'); return -1; } - } - start[offset] = 0; } + start[offset] = 0; + } return 0; } @@ -886,34 +886,34 @@ static ulong mem_test_quick(vu_long *start, vu_long *end, vu_long pattern, else pattern = ~pattern; } - printf("\rPattern %08lX Writing..." - "%12s" - "\b\b\b\b\b\b\b\b\b\b", - pattern, ""); + 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; - } + for (addr = start, val = pattern; addr < end; addr++) { + WATCHDOG_RESET(); + *addr = val; + val += incr; + } - puts("Reading..."); + puts("Reading..."); - 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; - } + 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; } + val += incr; + } return 0; } -- cgit v1.2.3 From c44d4386e67ac6dd57ddd60fdde54bf7ed581b6e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:19 +0000 Subject: Bring mtest putc() into common code If we get a Ctrl-C abort, we always print a newline. Move this repeated code out of the functions and into a single place in the caller. Signed-off-by: Simon Glass --- common/cmd_mem.c | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/common/cmd_mem.c b/common/cmd_mem.c index 5235bfe581..f5dd56db54 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -684,10 +684,8 @@ static ulong mem_test_alt(vu_long *start, vu_long *end) "expected %08lx, actual %08lx\n", val, readback); errs++; - if (ctrlc()) { - putc('\n'); + if (ctrlc()) return -1; - } } *addr = ~val; *dummy = val; @@ -697,10 +695,8 @@ static ulong mem_test_alt(vu_long *start, vu_long *end) "Is %08lx, should be %08lx\n", readback, ~val); errs++; - if (ctrlc()) { - putc('\n'); + if (ctrlc()) return -1; - } } } } @@ -765,10 +761,8 @@ static ulong mem_test_alt(vu_long *start, vu_long *end) " expected 0x%.8lx, actual 0x%.8lx\n", (ulong)&start[offset], pattern, temp); errs++; - if (ctrlc()) { - putc('\n'); + if (ctrlc()) return -1; - } } } start[test_offset] = pattern; @@ -788,10 +782,8 @@ static ulong mem_test_alt(vu_long *start, vu_long *end) " actual 0x%.8lx\n", (ulong)&start[offset], pattern, temp); errs++; - if (ctrlc()) { - putc('\n'); + if (ctrlc()) return -1; - } } } start[test_offset] = pattern; @@ -830,10 +822,8 @@ static ulong mem_test_alt(vu_long *start, vu_long *end) " expected 0x%.8lx, actual 0x%.8lx)\n", (ulong)&start[offset], pattern, temp); errs++; - if (ctrlc()) { - putc('\n'); + if (ctrlc()) return -1; - } } anti_pattern = ~pattern; @@ -852,10 +842,8 @@ static ulong mem_test_alt(vu_long *start, vu_long *end) " expected 0x%.8lx, actual 0x%.8lx)\n", (ulong)&start[offset], anti_pattern, temp); errs++; - if (ctrlc()) { - putc('\n'); + if (ctrlc()) return -1; - } } start[offset] = 0; } @@ -907,10 +895,8 @@ static ulong mem_test_quick(vu_long *start, vu_long *end, vu_long pattern, "found %08lX, expected %08lX\n", (uint)(uintptr_t)addr, readback, val); errs++; - if (ctrlc()) { - putc('\n'); + if (ctrlc()) return -1; - } } val += incr; } @@ -967,7 +953,6 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, !iteration_limit || iteration < iteration_limit; iteration++) { if (ctrlc()) { - putc('\n'); errs = -1UL; break; } @@ -981,7 +966,8 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, } if (errs == -1UL) { - /* Memory test was aborted */ + /* Memory test was aborted - write a newline to finish off */ + putc('\n'); ret = 1; } else { printf("Tested %d iteration(s) with %lu errors.\n", -- cgit v1.2.3 From 8c86bbe00f927de0655a65e43344ca0678d1bc34 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:20 +0000 Subject: Reduce casting in mtest Use a ulong for the command arguments, and only cast to an address when needed. This fixes warnings in sandbox where pointers are typically 64 bits long. Signed-off-by: Simon Glass --- common/cmd_mem.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/common/cmd_mem.c b/common/cmd_mem.c index f5dd56db54..12dbc1609c 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -626,8 +626,9 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } #endif /* CONFIG_LOOPW */ -static ulong mem_test_alt(vu_long *start, vu_long *end) +static ulong mem_test_alt(ulong start_addr, ulong end_addr) { + vu_long *start, *end; vu_long *addr; ulong errs = 0; ulong val, readback; @@ -655,6 +656,9 @@ static ulong mem_test_alt(vu_long *start, vu_long *end) 0xaaaaaaaa, /* alternating 1/0 */ }; + start = (vu_long *)start_addr; + end = (vu_long *)end_addr; + /* * Data line test: write a pattern to the first * location, write the 1's complement to a 'parking' @@ -735,7 +739,7 @@ static ulong mem_test_alt(vu_long *start, vu_long *end) * * Returns: 0 if the test succeeds, 1 if the test fails. */ - len = ((ulong)end - (ulong)start)/sizeof(vu_long); + len = (end_addr - start_addr) / sizeof(vu_long); pattern = (vu_long) 0xaaaaaaaa; anti_pattern = (vu_long) 0x55555555; @@ -851,9 +855,10 @@ static ulong mem_test_alt(vu_long *start, vu_long *end) return 0; } -static ulong mem_test_quick(vu_long *start, vu_long *end, vu_long pattern, +static ulong mem_test_quick(ulong start_addr, ulong end_addr, vu_long pattern, int iteration) { + vu_long *start, *end; vu_long *addr; ulong errs = 0; ulong incr; @@ -874,6 +879,8 @@ static ulong mem_test_quick(vu_long *start, vu_long *end, vu_long pattern, else pattern = ~pattern; } + start = (vu_long *)start_addr; + end = (vu_long *)end_addr; printf("\rPattern %08lX Writing..." "%12s" "\b\b\b\b\b\b\b\b\b\b", @@ -912,7 +919,7 @@ static ulong mem_test_quick(vu_long *start, vu_long *end, vu_long pattern, static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - vu_long *start, *end; + ulong start, end; int iteration_limit; int ret; ulong errs = 0; /* number of errors, or -1 if interrupted */ @@ -925,14 +932,14 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, #endif if (argc > 1) - start = (ulong *)simple_strtoul(argv[1], NULL, 16); + start = simple_strtoul(argv[1], NULL, 16); else - start = (ulong *)CONFIG_SYS_MEMTEST_START; + start = CONFIG_SYS_MEMTEST_START; if (argc > 2) - end = (ulong *)simple_strtoul(argv[2], NULL, 16); + end = simple_strtoul(argv[2], NULL, 16); else - end = (ulong *)(CONFIG_SYS_MEMTEST_END); + end = CONFIG_SYS_MEMTEST_END; if (argc > 3) pattern = (ulong)simple_strtoul(argv[3], NULL, 16); @@ -944,10 +951,9 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, else iteration_limit = 0; - printf("Testing %08x ... %08x:\n", (uint)(uintptr_t)start, - (uint)(uintptr_t)end); - debug("%s:%d: start 0x%p end 0x%p\n", - __func__, __LINE__, start, end); + printf("Testing %08x ... %08x:\n", (uint)start, (uint)end); + debug("%s:%d: start %#08lx end %#08lx\n", __func__, __LINE__, + start, end); for (iteration = 0; !iteration_limit || iteration < iteration_limit; -- cgit v1.2.3 From bfc59966431e6335fd5be0589eec073902cc7bb3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:21 +0000 Subject: Update set_working_fdt_addr() to use setenv_addr() We might as well use this common function instead of repeating the same code. Signed-off-by: Simon Glass --- common/cmd_fdt.c | 11 ++--------- common/cmd_nvedit.c | 8 ++++---- include/common.h | 14 +++++++++++++- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index 6eec947fcb..ac77a08b77 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_nvedit.c b/common/cmd_nvedit.c index 7633f0c44a..44e88aa401 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); } diff --git a/include/common.h b/include/common.h index 1d0728f847..6d52924225 100644 --- a/include/common.h +++ b/include/common.h @@ -358,7 +358,19 @@ int getenv_yesno(const char *var); int saveenv (void); int setenv (const char *, const char *); int setenv_ulong(const char *varname, ulong value); -int setenv_addr(const char *varname, const void *addr); +int setenv_hex(const char *varname, ulong value); +/** + * setenv_addr - Set an environment variable to an address in hex + * + * @varname: Environmet variable to set + * @addr: Value to set it to + * @return 0 if ok, 1 on error + */ +static inline int setenv_addr(const char *varname, const void *addr) +{ + return setenv_hex(varname, (ulong)addr); +} + #ifdef CONFIG_ARM # include # include -- cgit v1.2.3 From 41ef372c1a2d344621c74aa4bce5cdb0970ba5f1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:22 +0000 Subject: common: Use new numeric setenv functions Use setenv_ulong(), setenv_hex() and setenv_addr() in common/ Signed-off-by: Simon Glass --- common/cmd_bootm.c | 11 +++-------- common/cmd_cbfs.c | 4 +--- common/cmd_cramfs.c | 4 +--- common/cmd_fdos.c | 4 +--- common/cmd_jffs2.c | 4 +--- common/cmd_load.c | 12 +++--------- common/cmd_mtdparts.c | 4 +--- common/cmd_nand.c | 12 +++--------- common/cmd_nvedit.c | 3 +-- common/cmd_reiser.c | 4 +--- common/cmd_setexpr.c | 39 +++++++++++++++++++++++++++------------ common/cmd_unzip.c | 4 +--- common/cmd_ximg.c | 7 ++----- common/cmd_zfs.c | 3 +-- common/cmd_zip.c | 4 +--- 15 files changed, 48 insertions(+), 71 deletions(-) diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 1312a0db8a..b32991da0d 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 3b6cfd879b..f51534b07e 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 e7f496e4ea..0e43ab67c0 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 fbee8614ca..8ea1140e7f 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_jffs2.c b/common/cmd_jffs2.c index 27296ddd7d..4a4a0000b4 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 46db9626eb..0832e92b17 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_mtdparts.c b/common/cmd_mtdparts.c index 06fc171fe3..0cfca0c46b 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 495610c405..32348f3773 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 44e88aa401..d646d90880 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -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 e658618c6d..717c7f657b 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 5a042951da..7a38e94507 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_unzip.c b/common/cmd_unzip.c index 43ed7915fd..7470c2b12e 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 42a7eba766..ea0a26e784 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 1df0c4d72a..900e977c1c 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 a73c86d592..8607da81e2 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; } -- cgit v1.2.3 From 49c4f0370ba917a2608e933ca541898e9c098397 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:23 +0000 Subject: fs: Use new numeric setenv functions Use setenv_ulong(), setenv_hex() and setenv_addr() in fs/ Signed-off-by: Simon Glass --- fs/fs.c | 4 +--- fs/ubifs/ubifs.c | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/fs/fs.c b/fs/fs.c index 023e7ef16a..2c9f2c5ac1 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -256,7 +256,6 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], unsigned long bytes; unsigned long pos; int len_read; - char buf[12]; unsigned long time; if (argc < 2) @@ -308,8 +307,7 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], } puts("\n"); - sprintf(buf, "0x%x", len_read); - setenv("filesize", buf); + setenv_hex("filesize", len_read); return 0; } diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c index 44be3f53e0..273c0a9638 100644 --- a/fs/ubifs/ubifs.c +++ b/fs/ubifs/ubifs.c @@ -687,7 +687,6 @@ int ubifs_load(char *filename, u32 addr, u32 size) int i; int count; int last_block_size = 0; - char buf [10]; c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY); /* ubifs_findfile will resolve symlinks, so we know that we get @@ -740,8 +739,7 @@ int ubifs_load(char *filename, u32 addr, u32 size) if (err) printf("Error reading file '%s'\n", filename); else { - sprintf(buf, "%X", size); - setenv("filesize", buf); + setenv_hex("filesize", size); printf("Done\n"); } -- cgit v1.2.3 From 978226da5eb46bac23695d96a4ce8113b12640d5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:24 +0000 Subject: net: Use new numeric setenv functions Use setenv_ulong(), setenv_hex() and setenv_addr() in net/ Signed-off-by: Simon Glass --- drivers/net/fm/fm.c | 4 +--- net/net.c | 8 ++------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/net/fm/fm.c b/drivers/net/fm/fm.c index 49c74c278a..8d70586937 100644 --- a/drivers/net/fm/fm.c +++ b/drivers/net/fm/fm.c @@ -362,7 +362,6 @@ static void fm_init_qmi(struct fm_qmi_common *qmi) int fm_init_common(int index, struct ccsr_fman *reg) { int rc; - char env_addr[32]; #if defined(CONFIG_SYS_QE_FMAN_FW_IN_NOR) void *addr = (void *)CONFIG_SYS_QE_FMAN_FW_ADDR; #elif defined(CONFIG_SYS_QE_FMAN_FW_IN_NAND) @@ -416,8 +415,7 @@ int fm_init_common(int index, struct ccsr_fman *reg) rc = fman_upload_firmware(index, ®->fm_imem, addr); if (rc) return rc; - sprintf(env_addr, "0x%lx", (long unsigned int)addr); - setenv("fman_ucode", env_addr); + setenv_addr("fman_ucode", addr); fm_init_muram(index, ®->muram); fm_init_qmi(®->fm_qmi_common); diff --git a/net/net.c b/net/net.c index a40cde1e94..df94789de9 100644 --- a/net/net.c +++ b/net/net.c @@ -528,15 +528,11 @@ restart: case NETLOOP_SUCCESS: net_cleanup_loop(); if (NetBootFileXferSize > 0) { - char buf[20]; printf("Bytes transferred = %ld (%lx hex)\n", NetBootFileXferSize, NetBootFileXferSize); - sprintf(buf, "%lX", NetBootFileXferSize); - setenv("filesize", buf); - - sprintf(buf, "%lX", (unsigned long)load_addr); - setenv("fileaddr", buf); + setenv_hex("filesize", NetBootFileXferSize); + setenv_hex("fileaddr", load_addr); } if (protocol != NETCONS) eth_halt(); -- cgit v1.2.3 From 0ccff500cf787bb71e514eb2904d773ec84bf11d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:25 +0000 Subject: image: Use crc header file instead of C prototypes We have an existing header which the crc32 definitions, so use it. Signed-off-by: Simon Glass --- common/image.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/image.c b/common/image.c index ae1a9d3bd1..6afbb40a98 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 #endif /* !USE_HOSTCC*/ +#include + 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 -- cgit v1.2.3 From d5b76673a5dfe0b5250baea3c36cdfa7a9fd5230 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:26 +0000 Subject: hash: Add a flag to support saving hashes in the environment Some hashing commands permit saving the hash in an environment variable, and verifying a hash from there. But the crc32 command does not support this. In order to permit crc32 to use the generic hashing infrastructure, add a flag to select which behaviour to use. Signed-off-by: Simon Glass --- common/cmd_hash.c | 8 +++--- common/cmd_sha1sum.c | 6 ++--- common/hash.c | 69 +++++++++++++++++++++++++++++++++++++++------------- include/hash.h | 9 +++++-- 4 files changed, 66 insertions(+), 26 deletions(-) diff --git a/common/cmd_hash.c b/common/cmd_hash.c index eb6a33873b..8c03b5c723 100644 --- a/common/cmd_hash.c +++ b/common/cmd_hash.c @@ -30,22 +30,22 @@ static int do_hash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { #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 verify = 0; + 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); + return hash_command(*argv, flags, cmdtp, flag, argc - 1, argv + 1); } #ifdef CONFIG_HASH_VERIFY diff --git a/common/cmd_sha1sum.c b/common/cmd_sha1sum.c index fe927ab248..9f08629b87 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/hash.c b/common/hash.c index e3a6e438a3..462853d172 100644 --- a/common/hash.c +++ b/common/hash.c @@ -58,19 +58,31 @@ static struct hash_algo hash_algo[] = { * @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 +92,11 @@ static void store_result(struct hash_algo *algo, const u8 *sum, } str_ptr = '\0'; setenv(dest, str_output); + } else { + u8 *ptr; + + ptr = (u8 *)simple_strtoul(dest, NULL, 16); + memcpy(ptr, sum, algo->digest_size); } } @@ -94,14 +111,28 @@ 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 == '*') { + int env_var = 0; + + /* See comment above in store_result() */ + if (allow_env_vars) { + if (*verify_str == '*') + verify_str++; + else + env_var = 1; + } + + if (env_var) { u8 *ptr; - ptr = (u8 *)simple_strtoul(verify_str + 1, NULL, 16); + ptr = (u8 *)simple_strtoul(verify_str, NULL, 16); memcpy(vsum, ptr, algo->digest_size); } else { unsigned int i; @@ -158,7 +189,7 @@ 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; @@ -169,13 +200,14 @@ int hash_command(const char *algo_name, int verify, cmd_tbl_t *cmdtp, int flag, if (argc < 2) return CMD_RET_USAGE; + addr = simple_strtoul(*argv++, NULL, 16); + len = simple_strtoul(*argv++, NULL, 16); + 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) { @@ -188,13 +220,14 @@ int hash_command(const char *algo_name, int verify, cmd_tbl_t *cmdtp, int flag, /* Try to avoid code bloat when verify is not needed */ #ifdef CONFIG_HASH_VERIFY - if (verify) { + if (flags & HASH_FLAG_VERIFY) { #else if (0) { #endif if (!argc) return CMD_RET_USAGE; - if (parse_verify_sum(algo, *argv, vsum)) { + 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; @@ -213,8 +246,10 @@ int hash_command(const char *algo_name, int verify, cmd_tbl_t *cmdtp, int flag, show_hash(algo, addr, len, output); printf("\n"); - if (argc) - store_result(algo, output, *argv); + if (argc) { + store_result(algo, output, *argv, + flags & HASH_FLAG_ENV); + } } return 0; diff --git a/include/hash.h b/include/hash.h index 34ba558bd0..88fa2b5a57 100644 --- a/include/hash.h +++ b/include/hash.h @@ -51,19 +51,24 @@ struct hash_algo { */ #define HASH_MAX_DIGEST_SIZE 32 +enum { + HASH_FLAG_VERIFY = 1 << 0, /* Enable verify mode */ + HASH_FLAG_ENV = 1 << 1, /* Allow env vars */ +}; + /** * hash_command: Process a hash command for a particular algorithm * * This common function is used to implement specific hash commands. * * @algo_name: Hash algorithm being used - * @verify: Non-zero to enable verify mode + * @flags: Flags value (HASH_FLAG_...) * @cmdtp: Pointer to command table entry * @flag: Some flags normally 0 (see CMD_FLAG_.. above) * @argc: Number of arguments (arg 0 must be the command text) * @argv: Arguments */ -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[]); #endif -- cgit v1.2.3 From d20a40de9db07de1f1f06a79a4da1cdda5379b75 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 20:30:22 +0000 Subject: Roll crc32 into hash infrastructure Add the CRC32 algorithm to the list of available hashes, and make the crc32 command use hash_command(). Add a new crc32_wd_buf() to make this possible, which puts its result in a buffer rather than returning it as a 32-bit value. Note: For some boards the hash command is not enabled, neither are sha1, sha256 or the verify option. In this case the full hash implementation adds about 500 bytes of overhead. So as a special case, we use #ifdef to select very simple bahaviour in that case. The justification for this is that it is currently a very common case (virtually all boards enable crc32 but only some enable more advanced features). Signed-off-by: Simon Glass --- common/cmd_mem.c | 75 +++----------------------------- common/hash.c | 118 ++++++++++++++++++++++++++++++++++----------------- include/hash.h | 2 +- include/u-boot/crc.h | 11 +++++ lib/crc32.c | 9 ++++ 5 files changed, 108 insertions(+), 107 deletions(-) diff --git a/common/cmd_mem.c b/common/cmd_mem.c index 12dbc1609c..95b49b2100 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -32,6 +32,7 @@ #ifdef CONFIG_HAS_DATAFLASH #include #endif +#include #include #include #include @@ -1098,89 +1099,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/hash.c b/common/hash.c index 462853d172..ef6fe375d2 100644 --- a/common/hash.c +++ b/common/hash.c @@ -34,13 +34,19 @@ * crypto could perhaps add named version of these algorithms here. */ 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_SUM_LEN, sha1_csum_wd, CHUNKSZ_SHA1, }, +#define MULTI_HASH #endif #ifdef CONFIG_SHA256 { @@ -49,9 +55,27 @@ static struct hash_algo hash_algo[] = { 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 * @@ -192,10 +216,7 @@ static void show_hash(struct hash_algo *algo, ulong addr, ulong len, 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; @@ -203,52 +224,73 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag, addr = simple_strtoul(*argv++, NULL, 16); len = simple_strtoul(*argv++, NULL, 16); - algo = find_hash_algo(algo_name); - if (!algo) { - printf("Unknown hash algorithm '%s'\n", algo_name); - return CMD_RET_USAGE; - } - argc -= 2; + if (multi_hash()) { + struct hash_algo *algo; + u8 output[HASH_MAX_DIGEST_SIZE]; + u8 vsum[HASH_MAX_DIGEST_SIZE]; - if (algo->digest_size > HASH_MAX_DIGEST_SIZE) { - puts("HASH_MAX_DIGEST_SIZE exceeded\n"); - return 1; - } + algo = find_hash_algo(algo_name); + if (!algo) { + printf("Unknown hash algorithm '%s'\n", algo_name); + return CMD_RET_USAGE; + } + argc -= 2; + + if (algo->digest_size > HASH_MAX_DIGEST_SIZE) { + puts("HASH_MAX_DIGEST_SIZE exceeded\n"); + return 1; + } - algo->hash_func_ws((const unsigned char *)addr, len, output, - algo->chunk_size); + algo->hash_func_ws((const unsigned char *)addr, len, output, + algo->chunk_size); - /* Try to avoid code bloat when verify is not needed */ + /* Try to avoid code bloat when verify is not needed */ #ifdef CONFIG_HASH_VERIFY - if (flags & HASH_FLAG_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, + 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; + 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); + + printf("CRC32 for %08lx ... %08lx ==> %08lx\n", + addr, addr + len - 1, crc); - if (argc) { - store_result(algo, output, *argv, - flags & HASH_FLAG_ENV); + if (argc > 3) { + ptr = (ulong *)simple_strtoul(argv[3], NULL, 16); + *ptr = crc; } } diff --git a/include/hash.h b/include/hash.h index 88fa2b5a57..f2b2c4520d 100644 --- a/include/hash.h +++ b/include/hash.h @@ -22,7 +22,7 @@ #ifndef _HASH_H #define _HASH_H -#ifdef CONFIG_SHA1SUM_VERIFY +#if defined(CONFIG_SHA1SUM_VERIFY) || defined(CONFIG_CRC32_VERIFY) #define CONFIG_HASH_VERIFY #endif diff --git a/include/u-boot/crc.h b/include/u-boot/crc.h index 07badbfc5a..08e509edb4 100644 --- a/include/u-boot/crc.h +++ b/include/u-boot/crc.h @@ -30,4 +30,15 @@ uint32_t crc32 (uint32_t, const unsigned char *, uint); uint32_t crc32_wd (uint32_t, const unsigned char *, uint, uint); uint32_t crc32_no_comp (uint32_t, const unsigned char *, uint); +/** + * crc32_wd_buf - Perform CRC32 on a buffer and return result in buffer + * + * @input: Input buffer + * @ilen: Input buffer length + * @output: Place to put checksum result (4 bytes) + * @chunk_sz: Trigger watchdog after processing this many bytes + */ +void crc32_wd_buf(const unsigned char *input, uint ilen, + unsigned char *output, uint chunk_sz); + #endif /* _UBOOT_CRC_H */ diff --git a/lib/crc32.c b/lib/crc32.c index 27335a3ed9..76205da4f3 100644 --- a/lib/crc32.c +++ b/lib/crc32.c @@ -249,3 +249,12 @@ uint32_t ZEXPORT crc32_wd (uint32_t crc, return crc; } + +void crc32_wd_buf(const unsigned char *input, unsigned int ilen, + unsigned char *output, unsigned int chunk_sz) +{ + uint32_t crc; + + crc = crc32_wd(0, input, ilen, chunk_sz); + memcpy(output, &crc, sizeof(crc)); +} -- cgit v1.2.3 From ecdbf419f9c979cb6417df261c324c5beb63300d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 20:29:23 +0000 Subject: sandbox: config: Enable hash functions and mtest Enable the hash command and sha1/256 hashing for sandbox. Also use a better address for memory testing (since the existing one is set up for linux host memory space). Signed-off-by: Simon Glass --- include/configs/sandbox.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 9c431bf27a..9f51a0b813 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -63,8 +63,8 @@ #define CONFIG_SYS_HZ 1000 /* Memory things - we don't really want a memory test */ -#define CONFIG_SYS_LOAD_ADDR 0x10000000 -#define CONFIG_SYS_MEMTEST_START 0x10000000 +#define CONFIG_SYS_LOAD_ADDR 0x00000000 +#define CONFIG_SYS_MEMTEST_START 0x00100000 #define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + 0x1000) #define CONFIG_PHYS_64BIT @@ -85,6 +85,11 @@ #undef CONFIG_CMD_NET #undef CONFIG_CMD_NFS +#define CONFIG_CMD_HASH +#define CONFIG_HASH_VERIFY +#define CONFIG_SHA1 +#define CONFIG_SHA256 + #define CONFIG_BOOTARGS "" #define CONFIG_EXTRA_ENV_SETTINGS "stdin=serial\0" \ -- cgit v1.2.3 From 8e169cc943fcf93dd803adc70433b2c587db8796 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:29 +0000 Subject: Move CONFIG_SYS_MEMTEST_SCRATCH #ifdef to top of file This config effectively has a default value of 0, so add this setting at the top of the code to remove an #ifdef in the C function. Signed-off-by: Simon Glass --- common/cmd_mem.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/cmd_mem.c b/common/cmd_mem.c index 95b49b2100..50838a7614 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -39,6 +39,10 @@ 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. @@ -641,11 +645,7 @@ static ulong mem_test_alt(ulong start_addr, ulong end_addr) 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 static const ulong bitpattern[] = { 0x00000001, /* single bit */ 0x00000003, /* two adjacent bits */ -- cgit v1.2.3 From 5512d5b034d3f199f16f7c18171cae7732bb05eb Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 28 Feb 2013 17:47:14 +0000 Subject: sandbox: Update mtest to fix crashes Use map_sysmem() in the memory tester so that it works as expected on sandbox. Signed-off-by: Simon Glass --- common/cmd_mem.c | 108 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 63 insertions(+), 45 deletions(-) diff --git a/common/cmd_mem.c b/common/cmd_mem.c index 50838a7614..042c994a1b 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -631,21 +631,19 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } #endif /* CONFIG_LOOPW */ -static ulong mem_test_alt(ulong start_addr, ulong end_addr) +static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr, + vu_long *dummy) { - vu_long *start, *end; vu_long *addr; ulong errs = 0; ulong val, readback; int j; - vu_long len; vu_long offset; vu_long test_offset; vu_long pattern; vu_long temp; vu_long anti_pattern; vu_long num_words; - vu_long *dummy = (vu_long *)CONFIG_SYS_MEMTEST_SCRATCH; static const ulong bitpattern[] = { 0x00000001, /* single bit */ 0x00000003, /* two adjacent bits */ @@ -657,8 +655,7 @@ static ulong mem_test_alt(ulong start_addr, ulong end_addr) 0xaaaaaaaa, /* alternating 1/0 */ }; - start = (vu_long *)start_addr; - end = (vu_long *)end_addr; + num_words = (end_addr - start_addr) / sizeof(vu_long); /* * Data line test: write a pattern to the first @@ -677,11 +674,11 @@ static ulong mem_test_alt(ulong start_addr, ulong end_addr) * '0's and '0' bits through a field of '1's (i.e. * pattern and ~pattern). */ - addr = start; + addr = buf; for (j = 0; j < sizeof(bitpattern) / sizeof(bitpattern[0]); j++) { val = bitpattern[j]; for (; val != 0; val <<= 1) { - *addr = val; + *addr = val; *dummy = ~val; /* clear the test data off the bus */ readback = *addr; if (readback != val) { @@ -740,58 +737,56 @@ static ulong mem_test_alt(ulong start_addr, ulong end_addr) * * Returns: 0 if the test succeeds, 1 if the test fails. */ - len = (end_addr - start_addr) / sizeof(vu_long); pattern = (vu_long) 0xaaaaaaaa; anti_pattern = (vu_long) 0x55555555; - debug("%s:%d: length = 0x%.8lx\n", - __func__, __LINE__, len); + 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 < len; offset <<= 1) - start[offset] = pattern; + 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; + 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) { 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()) return -1; } } - start[test_offset] = pattern; + 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; + 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); + start_addr + offset, pattern, temp); errs++; if (ctrlc()) return -1; } } - start[test_offset] = pattern; + addr[test_offset] = pattern; } /* @@ -806,14 +801,14 @@ static ulong mem_test_alt(ulong start_addr, ulong end_addr) * * Returns: 0 if the test succeeds, 1 if the test fails. */ - num_words = ((ulong)end - (ulong)start)/sizeof(vu_long) + 1; + num_words++; /* * Fill memory with a known pattern. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { WATCHDOG_RESET(); - start[offset] = pattern; + addr[offset] = pattern; } /* @@ -821,18 +816,18 @@ static ulong mem_test_alt(ulong start_addr, ulong end_addr) */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { WATCHDOG_RESET(); - temp = start[offset]; + 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()) return -1; } anti_pattern = ~pattern; - start[offset] = anti_pattern; + addr[offset] = anti_pattern; } /* @@ -841,28 +836,28 @@ static ulong mem_test_alt(ulong start_addr, ulong end_addr) for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { WATCHDOG_RESET(); anti_pattern = ~pattern; - temp = start[offset]; + 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()) return -1; } - start[offset] = 0; + addr[offset] = 0; } return 0; } -static ulong mem_test_quick(ulong start_addr, ulong end_addr, vu_long pattern, - int iteration) +static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr, + vu_long pattern, int iteration) { - vu_long *start, *end; + vu_long *end; vu_long *addr; ulong errs = 0; - ulong incr; + ulong incr, length; ulong val, readback; /* Alternate the pattern */ @@ -880,14 +875,14 @@ static ulong mem_test_quick(ulong start_addr, ulong end_addr, vu_long pattern, else pattern = ~pattern; } - start = (vu_long *)start_addr; - end = (vu_long *)end_addr; + 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 = start, val = pattern; addr < end; addr++) { + for (addr = buf, val = pattern; addr < end; addr++) { WATCHDOG_RESET(); *addr = val; val += incr; @@ -895,13 +890,16 @@ static ulong mem_test_quick(ulong start_addr, ulong end_addr, vu_long pattern, puts("Reading..."); - for (addr = start, val = pattern; addr < end; addr++) { + 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)addr, readback, val); + (uint)(uintptr_t)(start_addr + offset), + readback, val); errs++; if (ctrlc()) return -1; @@ -921,6 +919,7 @@ 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 */ @@ -956,6 +955,8 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, 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++) { @@ -966,10 +967,27 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, printf("Iteration: %6d\r", iteration + 1); debug("\n"); - if (alt_test) - errs = mem_test_alt(start, end); - else - errs = mem_test_quick(start, end, pattern, iteration); + 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) { -- cgit v1.2.3 From bd091b67d0ef2959ed0ff2aa6575ddb0d21c1f71 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:31 +0000 Subject: sandbox: Allow hash functions to work correctly Use map_sysmem() so that hashing is possible on sandbox. Signed-off-by: Simon Glass --- common/hash.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/common/hash.c b/common/hash.c index ef6fe375d2..0d04c4c9a0 100644 --- a/common/hash.c +++ b/common/hash.c @@ -28,6 +28,7 @@ #include #include #include +#include /* * These are the hash algorithms we support. Chips which support accelerated @@ -117,10 +118,13 @@ static void store_result(struct hash_algo *algo, const u8 *sum, str_ptr = '\0'; setenv(dest, str_output); } else { - u8 *ptr; + ulong addr; + void *buf; - ptr = (u8 *)simple_strtoul(dest, NULL, 16); - memcpy(ptr, sum, algo->digest_size); + addr = simple_strtoul(dest, NULL, 16); + buf = map_sysmem(addr, algo->digest_size); + memcpy(buf, sum, algo->digest_size); + unmap_sysmem(buf); } } @@ -154,10 +158,12 @@ static int parse_verify_sum(struct hash_algo *algo, char *verify_str, u8 *vsum, } if (env_var) { - u8 *ptr; + ulong addr; + void *buf; - ptr = (u8 *)simple_strtoul(verify_str, NULL, 16); - memcpy(vsum, ptr, algo->digest_size); + 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; @@ -228,6 +234,7 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag, struct hash_algo *algo; u8 output[HASH_MAX_DIGEST_SIZE]; u8 vsum[HASH_MAX_DIGEST_SIZE]; + void *buf; algo = find_hash_algo(algo_name); if (!algo) { @@ -241,8 +248,9 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag, return 1; } - algo->hash_func_ws((const unsigned char *)addr, len, output, - algo->chunk_size); + 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 -- cgit v1.2.3 From 218da0f35f4b5e5bf13d3dba6d975d4d5d65516f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 24 Feb 2013 17:33:32 +0000 Subject: hash: Use lower case for hash algorithm names Rather than use strcasecmp() in the hash algorithm search, require the caller to do this first. Most of U-Boot can use lower case anyway, and the hash command can convert to lower case before calling hash_command(). This saves needing strcasecmp() for boards that use hashing but not the hash command. Signed-off-by: Simon Glass --- common/cmd_hash.c | 4 ++++ common/hash.c | 11 ++++++----- include/hash.h | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/common/cmd_hash.c b/common/cmd_hash.c index 8c03b5c723..4fe0e78613 100644 --- a/common/cmd_hash.c +++ b/common/cmd_hash.c @@ -26,9 +26,11 @@ #include #include #include +#include static int do_hash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { + char *s; #ifdef CONFIG_HASH_VERIFY int flags = HASH_FLAG_ENV; @@ -45,6 +47,8 @@ static int do_hash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /* Move forward to 'algorithm' parameter */ argc--; argv++; + for (s = *argv; *s; s++) + *s = tolower(*s); return hash_command(*argv, flags, cmdtp, flag, argc - 1, argv + 1); } diff --git a/common/hash.c b/common/hash.c index 0d04c4c9a0..f5badcb930 100644 --- a/common/hash.c +++ b/common/hash.c @@ -32,7 +32,8 @@ /* * 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[] = { /* @@ -42,7 +43,7 @@ static struct hash_algo hash_algo[] = { */ #ifdef CONFIG_CMD_SHA1SUM { - "SHA1", + "sha1", SHA1_SUM_LEN, sha1_csum_wd, CHUNKSZ_SHA1, @@ -51,7 +52,7 @@ static struct hash_algo hash_algo[] = { #endif #ifdef CONFIG_SHA256 { - "SHA256", + "sha256", SHA256_SUM_LEN, sha256_csum_wd, CHUNKSZ_SHA256, @@ -59,7 +60,7 @@ static struct hash_algo hash_algo[] = { #define MULTI_HASH #endif { - "CRC32", + "crc32", 4, crc32_wd_buf, CHUNKSZ_CRC32, @@ -202,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]; } diff --git a/include/hash.h b/include/hash.h index f2b2c4520d..2dbbd9b7d5 100644 --- a/include/hash.h +++ b/include/hash.h @@ -61,7 +61,7 @@ enum { * * This common function is used to implement specific hash commands. * - * @algo_name: Hash algorithm being used + * @algo_name: Hash algorithm being used (lower case!) * @flags: Flags value (HASH_FLAG_...) * @cmdtp: Pointer to command table entry * @flag: Some flags normally 0 (see CMD_FLAG_.. above) -- cgit v1.2.3