diff options
38 files changed, 761 insertions, 583 deletions
| @@ -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 02ce4a441..4fd0d4e58 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/cpu/os.c b/arch/sandbox/cpu/os.c index 36637af6c..3e37c930b 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/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 7603bf900..5287fd5ee 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;  } diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h index 0392d218e..d8c02364d 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/common/cmd_bootm.c b/common/cmd_bootm.c index 1312a0db8..b32991da0 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 3b6cfd879..f51534b07 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 e7f496e4e..0e43ab67c 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 fbee8614c..8ea1140e7 100644 --- a/common/cmd_fdos.c +++ b/common/cmd_fdos.c @@ -40,7 +40,6 @@ int do_fdosboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])      char *name;      char *ep;      int size; -    char buf [12];      int drive = CONFIG_SYS_FDC_DRIVE_NUMBER;      /* pre-set load_addr */ @@ -91,8 +90,7 @@ int do_fdosboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])      }      flush_cache (load_addr, size); -    sprintf(buf, "%x", size); -    setenv("filesize", buf); +    setenv_hex("filesize", size);      printf("Floppy DOS load complete: %d bytes loaded to 0x%lx\n",  	   size, load_addr); diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index 6eec947fc..ac77a08b7 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -55,12 +55,8 @@ struct fdt_header *working_fdt;  void set_working_fdt_addr(void *addr)  { -	char buf[17]; -  	working_fdt = addr; - -	sprintf(buf, "%lx", (unsigned long)addr); -	setenv("fdtaddr", buf); +	setenv_addr("fdtaddr", addr);  }  /* @@ -347,10 +343,7 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  			}  			if (subcmd[0] == 's') {  				/* get the num nodes at this level */ -				char buf[11]; - -				sprintf(buf, "%d", curIndex + 1); -				setenv(var, buf); +				setenv_ulong(var, curIndex + 1);  			} else {  				/* node index not found */  				printf("libfdt node not found\n"); diff --git a/common/cmd_hash.c b/common/cmd_hash.c index 689c60857..4fe0e7861 100644 --- a/common/cmd_hash.c +++ b/common/cmd_hash.c @@ -26,22 +26,30 @@  #include <common.h>  #include <command.h>  #include <hash.h> +#include <linux/ctype.h>  static int do_hash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  { +	char *s;  #ifdef CONFIG_HASH_VERIFY -	int verify = 0; +	int flags = HASH_FLAG_ENV; +	if (argc < 4) +		return CMD_RET_USAGE;  	if (!strcmp(argv[1], "-v")) { -		verify = 1; +		flags |= HASH_FLAG_VERIFY;  		argc--;  		argv++;  	} +#else +	const int flags = HASH_FLAG_ENV;  #endif  	/* Move forward to 'algorithm' parameter */  	argc--;  	argv++; -	return hash_command(*argv, verify, cmdtp, flag, argc - 1, argv + 1); +	for (s = *argv; *s; s++) +		*s = tolower(*s); +	return hash_command(*argv, flags, cmdtp, flag, argc - 1, argv + 1);  }  #ifdef CONFIG_HASH_VERIFY diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c index 27296ddd7..4a4a0000b 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 46db9626e..0832e92b1 100644 --- a/common/cmd_load.c +++ b/common/cmd_load.c @@ -149,7 +149,6 @@ static ulong load_serial(long offset)  	int	type;				/* return code for record type	*/  	ulong	addr;				/* load address from S-Record	*/  	ulong	size;				/* number of bytes transferred	*/ -	char	buf[32];  	ulong	store_addr;  	ulong	start_addr = ~0;  	ulong	end_addr   =  0; @@ -198,8 +197,7 @@ static ulong load_serial(long offset)  			    start_addr, end_addr, size, size  		    );  		    flush_cache(start_addr, size); -		    sprintf(buf, "%lX", size); -		    setenv("filesize", buf); +		    setenv_hex("filesize", size);  		    return (addr);  		case SREC_START:  		    break; @@ -519,7 +517,6 @@ static int do_load_serial_bin(cmd_tbl_t *cmdtp, int flag, int argc,  static ulong load_serial_bin(ulong offset)  {  	int size, i; -	char buf[32];  	set_kerm_bin_mode((ulong *) offset);  	size = k_recv(); @@ -539,8 +536,7 @@ static ulong load_serial_bin(ulong offset)  	flush_cache(offset, size);  	printf("## Total Size      = 0x%08x = %d Bytes\n", size, size); -	sprintf(buf, "%X", size); -	setenv("filesize", buf); +	setenv_hex("filesize", size);  	return offset;  } @@ -965,7 +961,6 @@ static int getcxmodem(void) {  static ulong load_serial_ymodem(ulong offset)  {  	int size; -	char buf[32];  	int err;  	int res;  	connection_info_t info; @@ -1012,8 +1007,7 @@ static ulong load_serial_ymodem(ulong offset)  	flush_cache(offset, size);  	printf("## Total Size      = 0x%08x = %d Bytes\n", size, size); -	sprintf(buf, "%X", size); -	setenv("filesize", buf); +	setenv_hex("filesize", size);  	return offset;  } diff --git a/common/cmd_mem.c b/common/cmd_mem.c index d44aa1d73..042c994a1 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -32,11 +32,17 @@  #ifdef CONFIG_HAS_DATAFLASH  #include <dataflash.h>  #endif +#include <hash.h>  #include <watchdog.h> +#include <asm/io.h>  #include <linux/compiler.h>  DECLARE_GLOBAL_DATA_PTR; +#ifndef CONFIG_SYS_MEMTEST_SCRATCH +#define CONFIG_SYS_MEMTEST_SCRATCH 0 +#endif +  static int mod_mem(cmd_tbl_t *, int, int, int, char * const []);  /* Display values from last command. @@ -138,9 +144,13 @@ static int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  # endif  	{ +		ulong bytes = size * length; +		const void *buf = map_sysmem(addr, bytes); +  		/* Print the lines. */ -		print_buffer(addr, (void*)addr, size, length, DISP_LINE_LEN/size); -		addr += size*length; +		print_buffer(addr, buf, size, length, DISP_LINE_LEN / size); +		addr += bytes; +		unmap_sysmem(buf);  	}  #endif @@ -163,6 +173,8 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  {  	ulong	addr, writeval, count;  	int	size; +	void *buf; +	ulong bytes;  	if ((argc < 3) || (argc > 4))  		return CMD_RET_USAGE; @@ -188,15 +200,18 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  		count = 1;  	} +	bytes = size * count; +	buf = map_sysmem(addr, bytes);  	while (count-- > 0) {  		if (size == 4) -			*((ulong  *)addr) = (ulong )writeval; +			*((ulong *)buf) = (ulong)writeval;  		else if (size == 2) -			*((ushort *)addr) = (ushort)writeval; +			*((ushort *)buf) = (ushort)writeval;  		else -			*((u_char *)addr) = (u_char)writeval; -		addr += size; +			*((u_char *)buf) = (u_char)writeval; +		buf += size;  	} +	unmap_sysmem(buf);  	return 0;  } @@ -258,10 +273,11 @@ int do_mem_mwc ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  { -	ulong	addr1, addr2, count, ngood; +	ulong	addr1, addr2, count, ngood, bytes;  	int	size;  	int     rcode = 0;  	const char *type; +	const void *buf1, *buf2, *base;  	if (argc != 4)  		return CMD_RET_USAGE; @@ -294,33 +310,40 @@ static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	}  #endif +	bytes = size * count; +	base = buf1 = map_sysmem(addr1, bytes); +	buf2 = map_sysmem(addr2, bytes);  	for (ngood = 0; ngood < count; ++ngood) {  		ulong word1, word2;  		if (size == 4) { -			word1 = *(ulong *)addr1; -			word2 = *(ulong *)addr2; +			word1 = *(ulong *)buf1; +			word2 = *(ulong *)buf2;  		} else if (size == 2) { -			word1 = *(ushort *)addr1; -			word2 = *(ushort *)addr2; +			word1 = *(ushort *)buf1; +			word2 = *(ushort *)buf2;  		} else { -			word1 = *(u_char *)addr1; -			word2 = *(u_char *)addr2; +			word1 = *(u_char *)buf1; +			word2 = *(u_char *)buf2;  		}  		if (word1 != word2) { +			ulong offset = buf1 - base; +  			printf("%s at 0x%08lx (%#0*lx) != %s at 0x%08lx (%#0*lx)\n", -				type, addr1, size, word1, -				type, addr2, size, word2); +				type, (ulong)(addr1 + offset), size, word1, +				type, (ulong)(addr2 + offset), size, word2);  			rcode = 1;  			break;  		} -		addr1 += size; -		addr2 += size; +		buf1 += size; +		buf2 += size;  		/* reset watchdog from time to time */  		if ((ngood % (64 << 10)) == 0)  			WATCHDOG_RESET();  	} +	unmap_sysmem(buf1); +	unmap_sysmem(buf2);  	printf("Total of %ld %s(s) were the same\n", ngood, type);  	return rcode; @@ -328,8 +351,10 @@ static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  static int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  { -	ulong	addr, dest, count; +	ulong	addr, dest, count, bytes;  	int	size; +	const void *src; +	void *buf;  	if (argc != 4)  		return CMD_RET_USAGE; @@ -419,15 +444,18 @@ static int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	}  #endif +	bytes = size * count; +	buf = map_sysmem(addr, bytes); +	src = map_sysmem(addr, bytes);  	while (count-- > 0) {  		if (size == 4) -			*((ulong  *)dest) = *((ulong  *)addr); +			*((ulong *)buf) = *((ulong  *)src);  		else if (size == 2) -			*((ushort *)dest) = *((ushort *)addr); +			*((ushort *)buf) = *((ushort *)src);  		else -			*((u_char *)dest) = *((u_char *)addr); -		addr += size; -		dest += size; +			*((u_char *)buf) = *((u_char *)src); +		src += size; +		buf += size;  		/* reset watchdog from time to time */  		if ((count % (64 << 10)) == 0) @@ -453,11 +481,12 @@ static int do_mem_base(cmd_tbl_t *cmdtp, int flag, int argc,  static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,  		       char * const argv[])  { -	ulong	addr, length, i; +	ulong	addr, length, i, bytes;  	int	size;  	volatile uint	*longp;  	volatile ushort *shortp;  	volatile u_char	*cp; +	const void *buf;  	if (argc < 3)  		return CMD_RET_USAGE; @@ -477,28 +506,31 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,  	*/  	length = simple_strtoul(argv[2], NULL, 16); +	bytes = size * length; +	buf = map_sysmem(addr, bytes); +  	/* We want to optimize the loops to run as fast as possible.  	 * If we have only one object, just run infinite loops.  	 */  	if (length == 1) {  		if (size == 4) { -			longp = (uint *)addr; +			longp = (uint *)buf;  			for (;;)  				i = *longp;  		}  		if (size == 2) { -			shortp = (ushort *)addr; +			shortp = (ushort *)buf;  			for (;;)  				i = *shortp;  		} -		cp = (u_char *)addr; +		cp = (u_char *)buf;  		for (;;)  			i = *cp;  	}  	if (size == 4) {  		for (;;) { -			longp = (uint *)addr; +			longp = (uint *)buf;  			i = length;  			while (i-- > 0)  				*longp++; @@ -506,28 +538,30 @@ static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,  	}  	if (size == 2) {  		for (;;) { -			shortp = (ushort *)addr; +			shortp = (ushort *)buf;  			i = length;  			while (i-- > 0)  				*shortp++;  		}  	}  	for (;;) { -		cp = (u_char *)addr; +		cp = (u_char *)buf;  		i = length;  		while (i-- > 0)  			*cp++;  	} +	unmap_sysmem(buf);  }  #ifdef CONFIG_LOOPW  int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  { -	ulong	addr, length, i, data; +	ulong	addr, length, i, data, bytes;  	int	size;  	volatile uint	*longp;  	volatile ushort *shortp;  	volatile u_char	*cp; +	void *buf;  	if (argc < 4)  		return CMD_RET_USAGE; @@ -550,28 +584,31 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	/* data to write */  	data = simple_strtoul(argv[3], NULL, 16); +	bytes = size * length; +	buf = map_sysmem(addr, bytes); +  	/* We want to optimize the loops to run as fast as possible.  	 * If we have only one object, just run infinite loops.  	 */  	if (length == 1) {  		if (size == 4) { -			longp = (uint *)addr; +			longp = (uint *)buf;  			for (;;)  				*longp = data;  					}  		if (size == 2) { -			shortp = (ushort *)addr; +			shortp = (ushort *)buf;  			for (;;)  				*shortp = data;  		} -		cp = (u_char *)addr; +		cp = (u_char *)buf;  		for (;;)  			*cp = data;  	}  	if (size == 4) {  		for (;;) { -			longp = (uint *)addr; +			longp = (uint *)buf;  			i = length;  			while (i-- > 0)  				*longp++ = data; @@ -579,14 +616,14 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	}  	if (size == 2) {  		for (;;) { -			shortp = (ushort *)addr; +			shortp = (ushort *)buf;  			i = length;  			while (i-- > 0)  				*shortp++ = data;  		}  	}  	for (;;) { -		cp = (u_char *)addr; +		cp = (u_char *)buf;  		i = length;  		while (i-- > 0)  			*cp++ = data; @@ -594,36 +631,19 @@ int do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  }  #endif /* CONFIG_LOOPW */ -/* - * Perform a memory test. A more complete alternative test can be - * configured using CONFIG_SYS_ALT_MEMTEST. The complete test loops until - * interrupted by ctrl-c or by a failure of one of the sub-tests. - */ -static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, -			char * const argv[]) +static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr, +			  vu_long *dummy)  { -	vu_long	*addr, *start, *end; -	ulong	val; -	ulong	readback; -	ulong	errs = 0; -	int iterations = 1; -	int iteration_limit; - -#if defined(CONFIG_SYS_ALT_MEMTEST) -	vu_long	len; -	vu_long	offset; -	vu_long	test_offset; -	vu_long	pattern; -	vu_long	temp; -	vu_long	anti_pattern; -	vu_long	num_words; -#if defined(CONFIG_SYS_MEMTEST_SCRATCH) -	vu_long *dummy = (vu_long*)CONFIG_SYS_MEMTEST_SCRATCH; -#else -	vu_long *dummy = NULL;	/* yes, this is address 0x0, not NULL */ -#endif -	int	j; - +	vu_long *addr; +	ulong errs = 0; +	ulong val, readback; +	int j; +	vu_long offset; +	vu_long test_offset; +	vu_long pattern; +	vu_long temp; +	vu_long anti_pattern; +	vu_long num_words;  	static const ulong bitpattern[] = {  		0x00000001,	/* single bit */  		0x00000003,	/* two adjacent bits */ @@ -634,320 +654,353 @@ static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,  		0x00000055,	/* four non-adjacent bits */  		0xaaaaaaaa,	/* alternating 1/0 */  	}; -#else -	ulong	incr; -	ulong	pattern; -#endif - -	if (argc > 1) -		start = (ulong *)simple_strtoul(argv[1], NULL, 16); -	else -		start = (ulong *)CONFIG_SYS_MEMTEST_START; -	if (argc > 2) -		end = (ulong *)simple_strtoul(argv[2], NULL, 16); -	else -		end = (ulong *)(CONFIG_SYS_MEMTEST_END); - -	if (argc > 3) -		pattern = (ulong)simple_strtoul(argv[3], NULL, 16); -	else -		pattern = 0; +	num_words = (end_addr - start_addr) / sizeof(vu_long); -	if (argc > 4) -		iteration_limit = (ulong)simple_strtoul(argv[4], NULL, 16); -	else -		iteration_limit = 0; - -#if defined(CONFIG_SYS_ALT_MEMTEST) -	printf ("Testing %08x ... %08x:\n", (uint)start, (uint)end); -	debug("%s:%d: start 0x%p end 0x%p\n", -		__FUNCTION__, __LINE__, start, end); - -	for (;;) { -		if (ctrlc()) { -			putc ('\n'); -			return 1; -		} - - -		if (iteration_limit && iterations > iteration_limit) { -			printf("Tested %d iteration(s) with %lu errors.\n", -				iterations-1, errs); -			return errs != 0; -		} - -		printf("Iteration: %6d\r", iterations); -		debug("\n"); -		iterations++; - -		/* -		 * Data line test: write a pattern to the first -		 * location, write the 1's complement to a 'parking' -		 * address (changes the state of the data bus so a -		 * floating bus doesn't give a false OK), and then -		 * read the value back. Note that we read it back -		 * into a variable because the next time we read it, -		 * it might be right (been there, tough to explain to -		 * the quality guys why it prints a failure when the -		 * "is" and "should be" are obviously the same in the -		 * error message). -		 * -		 * Rather than exhaustively testing, we test some -		 * patterns by shifting '1' bits through a field of -		 * '0's and '0' bits through a field of '1's (i.e. -		 * pattern and ~pattern). -		 */ -		addr = start; -		for (j = 0; j < sizeof(bitpattern)/sizeof(bitpattern[0]); j++) { -		    val = bitpattern[j]; -		    for(; val != 0; val <<= 1) { -			*addr  = val; -			*dummy  = ~val; /* clear the test data off of the bus */ +	/* +	 * Data line test: write a pattern to the first +	 * location, write the 1's complement to a 'parking' +	 * address (changes the state of the data bus so a +	 * floating bus doesn't give a false OK), and then +	 * read the value back. Note that we read it back +	 * into a variable because the next time we read it, +	 * it might be right (been there, tough to explain to +	 * the quality guys why it prints a failure when the +	 * "is" and "should be" are obviously the same in the +	 * error message). +	 * +	 * Rather than exhaustively testing, we test some +	 * patterns by shifting '1' bits through a field of +	 * '0's and '0' bits through a field of '1's (i.e. +	 * pattern and ~pattern). +	 */ +	addr = buf; +	for (j = 0; j < sizeof(bitpattern) / sizeof(bitpattern[0]); j++) { +		val = bitpattern[j]; +		for (; val != 0; val <<= 1) { +			*addr = val; +			*dummy  = ~val; /* clear the test data off the bus */  			readback = *addr; -			if(readback != val) { -			    printf ("FAILURE (data line): " -				"expected %08lx, actual %08lx\n", -					  val, readback); -			    errs++; -			    if (ctrlc()) { -				putc ('\n'); -				return 1; -			    } +			if (readback != val) { +				printf("FAILURE (data line): " +					"expected %08lx, actual %08lx\n", +						val, readback); +				errs++; +				if (ctrlc()) +					return -1;  			}  			*addr  = ~val;  			*dummy  = val;  			readback = *addr; -			if(readback != ~val) { -			    printf ("FAILURE (data line): " -				"Is %08lx, should be %08lx\n", -					readback, ~val); -			    errs++; -			    if (ctrlc()) { -				putc ('\n'); -				return 1; -			    } +			if (readback != ~val) { +				printf("FAILURE (data line): " +					"Is %08lx, should be %08lx\n", +						readback, ~val); +				errs++; +				if (ctrlc()) +					return -1;  			} -		    }  		} +	} -		/* -		 * Based on code whose Original Author and Copyright -		 * information follows: Copyright (c) 1998 by Michael -		 * Barr. This software is placed into the public -		 * domain and may be used for any purpose. However, -		 * this notice must not be changed or removed and no -		 * warranty is either expressed or implied by its -		 * publication or distribution. -		 */ +	/* +	 * Based on code whose Original Author and Copyright +	 * information follows: Copyright (c) 1998 by Michael +	 * Barr. This software is placed into the public +	 * domain and may be used for any purpose. However, +	 * this notice must not be changed or removed and no +	 * warranty is either expressed or implied by its +	 * publication or distribution. +	 */ -		/* -		 * Address line test -		 * -		 * Description: Test the address bus wiring in a -		 *              memory region by performing a walking -		 *              1's test on the relevant bits of the -		 *              address and checking for aliasing. -		 *              This test will find single-bit -		 *              address failures such as stuck-high, -		 *              stuck-low, and shorted pins. The base -		 *              address and size of the region are -		 *              selected by the caller. -		 * -		 * Notes:	For best results, the selected base -		 *              address should have enough LSB 0's to -		 *              guarantee single address bit changes. -		 *              For example, to test a 64-Kbyte -		 *              region, select a base address on a -		 *              64-Kbyte boundary. Also, select the -		 *              region size as a power-of-two if at -		 *              all possible. -		 * -		 * Returns:     0 if the test succeeds, 1 if the test fails. -		 */ -		len = ((ulong)end - (ulong)start)/sizeof(vu_long); -		pattern = (vu_long) 0xaaaaaaaa; -		anti_pattern = (vu_long) 0x55555555; +	/* +	* Address line test -		debug("%s:%d: length = 0x%.8lx\n", -			__FUNCTION__, __LINE__, -			len); -		/* -		 * Write the default pattern at each of the -		 * power-of-two offsets. -		 */ -		for (offset = 1; offset < len; offset <<= 1) { -			start[offset] = pattern; -		} +	 * 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. -		/* -		 * Check for address bits stuck high. -		 */ -		test_offset = 0; -		start[test_offset] = anti_pattern; +	 * Notes:	For best results, the selected base +	 *              address should have enough LSB 0's to +	 *              guarantee single address bit changes. +	 *              For example, to test a 64-Kbyte +	 *              region, select a base address on a +	 *              64-Kbyte boundary. Also, select the +	 *              region size as a power-of-two if at +	 *              all possible. +	 * +	 * Returns:     0 if the test succeeds, 1 if the test fails. +	 */ +	pattern = (vu_long) 0xaaaaaaaa; +	anti_pattern = (vu_long) 0x55555555; + +	debug("%s:%d: length = 0x%.8lx\n", __func__, __LINE__, num_words); +	/* +	 * Write the default pattern at each of the +	 * power-of-two offsets. +	 */ +	for (offset = 1; offset < num_words; offset <<= 1) +		addr[offset] = pattern; + +	/* +	 * Check for address bits stuck high. +	 */ +	test_offset = 0; +	addr[test_offset] = anti_pattern; -		for (offset = 1; offset < len; offset <<= 1) { -		    temp = start[offset]; -		    if (temp != pattern) { -			printf ("\nFAILURE: Address bit stuck high @ 0x%.8lx:" +	for (offset = 1; offset < num_words; offset <<= 1) { +		temp = addr[offset]; +		if (temp != pattern) { +			printf("\nFAILURE: Address bit stuck high @ 0x%.8lx:"  				" expected 0x%.8lx, actual 0x%.8lx\n", -				(ulong)&start[offset], pattern, temp); +				start_addr + offset, pattern, temp);  			errs++; -			if (ctrlc()) { -			    putc ('\n'); -			    return 1; -			} -		    } +			if (ctrlc()) +				return -1;  		} -		start[test_offset] = pattern; -		WATCHDOG_RESET(); +	} +	addr[test_offset] = pattern; +	WATCHDOG_RESET(); -		/* -		 * Check for addr bits stuck low or shorted. -		 */ -		for (test_offset = 1; test_offset < len; test_offset <<= 1) { -		    start[test_offset] = anti_pattern; +	/* +	 * Check for addr bits stuck low or shorted. +	 */ +	for (test_offset = 1; test_offset < num_words; test_offset <<= 1) { +		addr[test_offset] = anti_pattern; -		    for (offset = 1; offset < len; offset <<= 1) { -			temp = start[offset]; +		for (offset = 1; offset < num_words; offset <<= 1) { +			temp = addr[offset];  			if ((temp != pattern) && (offset != test_offset)) { -			    printf ("\nFAILURE: Address bit stuck low or shorted @" -				" 0x%.8lx: expected 0x%.8lx, actual 0x%.8lx\n", -				(ulong)&start[offset], pattern, temp); -			    errs++; -			    if (ctrlc()) { -				putc ('\n'); -				return 1; -			    } +				printf("\nFAILURE: Address bit stuck low or" +					" shorted @ 0x%.8lx: expected 0x%.8lx," +					" actual 0x%.8lx\n", +					start_addr + offset, pattern, temp); +				errs++; +				if (ctrlc()) +					return -1;  			} -		    } -		    start[test_offset] = pattern;  		} +		addr[test_offset] = pattern; +	} -		/* -		 * Description: Test the integrity of a physical -		 *		memory device by performing an -		 *		increment/decrement test over the -		 *		entire region. In the process every -		 *		storage bit in the device is tested -		 *		as a zero and a one. The base address -		 *		and the size of the region are -		 *		selected by the caller. -		 * -		 * Returns:     0 if the test succeeds, 1 if the test fails. -		 */ -		num_words = ((ulong)end - (ulong)start)/sizeof(vu_long) + 1; +	/* +	 * Description: Test the integrity of a physical +	 *		memory device by performing an +	 *		increment/decrement test over the +	 *		entire region. In the process every +	 *		storage bit in the device is tested +	 *		as a zero and a one. The base address +	 *		and the size of the region are +	 *		selected by the caller. +	 * +	 * Returns:     0 if the test succeeds, 1 if the test fails. +	 */ +	num_words++; -		/* -		 * Fill memory with a known pattern. -		 */ -		for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { -			WATCHDOG_RESET(); -			start[offset] = pattern; -		} +	/* +	 * Fill memory with a known pattern. +	 */ +	for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { +		WATCHDOG_RESET(); +		addr[offset] = pattern; +	} -		/* -		 * Check each location and invert it for the second pass. -		 */ -		for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { -		    WATCHDOG_RESET(); -		    temp = start[offset]; -		    if (temp != pattern) { -			printf ("\nFAILURE (read/write) @ 0x%.8lx:" +	/* +	 * Check each location and invert it for the second pass. +	 */ +	for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { +		WATCHDOG_RESET(); +		temp = addr[offset]; +		if (temp != pattern) { +			printf("\nFAILURE (read/write) @ 0x%.8lx:"  				" expected 0x%.8lx, actual 0x%.8lx)\n", -				(ulong)&start[offset], pattern, temp); +				start_addr + offset, pattern, temp);  			errs++; -			if (ctrlc()) { -			    putc ('\n'); -			    return 1; -			} -		    } - -		    anti_pattern = ~pattern; -		    start[offset] = anti_pattern; +			if (ctrlc()) +				return -1;  		} -		/* -		 * Check each location for the inverted pattern and zero it. -		 */ -		for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { -		    WATCHDOG_RESET(); -		    anti_pattern = ~pattern; -		    temp = start[offset]; -		    if (temp != anti_pattern) { -			printf ("\nFAILURE (read/write): @ 0x%.8lx:" +		anti_pattern = ~pattern; +		addr[offset] = anti_pattern; +	} + +	/* +	 * Check each location for the inverted pattern and zero it. +	 */ +	for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { +		WATCHDOG_RESET(); +		anti_pattern = ~pattern; +		temp = addr[offset]; +		if (temp != anti_pattern) { +			printf("\nFAILURE (read/write): @ 0x%.8lx:"  				" expected 0x%.8lx, actual 0x%.8lx)\n", -				(ulong)&start[offset], anti_pattern, temp); +				start_addr + offset, anti_pattern, temp);  			errs++; -			if (ctrlc()) { -			    putc ('\n'); -			    return 1; -			} -		    } -		    start[offset] = 0; +			if (ctrlc()) +				return -1;  		} +		addr[offset] = 0;  	} -#else /* The original, quickie test */ -	incr = 1; -	for (;;) { -		if (ctrlc()) { -			putc ('\n'); -			return 1; -		} - -		if (iteration_limit && iterations > iteration_limit) { -			printf("Tested %d iteration(s) with %lu errors.\n", -				iterations-1, errs); -			return errs != 0; -		} -		++iterations; - -		printf ("\rPattern %08lX  Writing..." -			"%12s" -			"\b\b\b\b\b\b\b\b\b\b", -			pattern, ""); - -		for (addr=start,val=pattern; addr<end; addr++) { -			WATCHDOG_RESET(); -			*addr = val; -			val  += incr; -		} - -		puts ("Reading..."); +	return 0; +} -		for (addr=start,val=pattern; addr<end; addr++) { -			WATCHDOG_RESET(); -			readback = *addr; -			if (readback != val) { -				printf ("\nMem error @ 0x%08X: " -					"found %08lX, expected %08lX\n", -					(uint)(uintptr_t)addr, readback, val); -				errs++; -				if (ctrlc()) { -					putc ('\n'); -					return 1; -				} -			} -			val += incr; -		} +static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr, +			    vu_long pattern, int iteration) +{ +	vu_long *end; +	vu_long *addr; +	ulong errs = 0; +	ulong incr, length; +	ulong val, readback; +	/* Alternate the pattern */ +	incr = 1; +	if (iteration & 1) { +		incr = -incr;  		/*  		 * Flip the pattern each time to make lots of zeros and  		 * then, the next time, lots of ones.  We decrement  		 * the "negative" patterns and increment the "positive"  		 * patterns to preserve this feature.  		 */ -		if(pattern & 0x80000000) { +		if (pattern & 0x80000000)  			pattern = -pattern;	/* complement & increment */ -		} -		else { +		else  			pattern = ~pattern; +	} +	length = (end_addr - start_addr) / sizeof(ulong); +	end = buf + length; +	printf("\rPattern %08lX  Writing..." +		"%12s" +		"\b\b\b\b\b\b\b\b\b\b", +		pattern, ""); + +	for (addr = buf, val = pattern; addr < end; addr++) { +		WATCHDOG_RESET(); +		*addr = val; +		val += incr; +	} + +	puts("Reading..."); + +	for (addr = buf, val = pattern; addr < end; addr++) { +		WATCHDOG_RESET(); +		readback = *addr; +		if (readback != val) { +			ulong offset = addr - buf; + +			printf("\nMem error @ 0x%08X: " +				"found %08lX, expected %08lX\n", +				(uint)(uintptr_t)(start_addr + offset), +				readback, val); +			errs++; +			if (ctrlc()) +				return -1;  		} -		incr = -incr; +		val += incr;  	} + +	return 0; +} + +/* + * Perform a memory test. A more complete alternative test can be + * configured using CONFIG_SYS_ALT_MEMTEST. The complete test loops until + * interrupted by ctrl-c or by a failure of one of the sub-tests. + */ +static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, +			char * const argv[]) +{ +	ulong start, end; +	vu_long *buf, *dummy; +	int iteration_limit; +	int ret; +	ulong errs = 0;	/* number of errors, or -1 if interrupted */ +	ulong pattern; +	int iteration; +#if defined(CONFIG_SYS_ALT_MEMTEST) +	const int alt_test = 1; +#else +	const int alt_test = 0;  #endif -	return 0;	/* not reached */ + +	if (argc > 1) +		start = simple_strtoul(argv[1], NULL, 16); +	else +		start = CONFIG_SYS_MEMTEST_START; + +	if (argc > 2) +		end = simple_strtoul(argv[2], NULL, 16); +	else +		end = CONFIG_SYS_MEMTEST_END; + +	if (argc > 3) +		pattern = (ulong)simple_strtoul(argv[3], NULL, 16); +	else +		pattern = 0; + +	if (argc > 4) +		iteration_limit = (ulong)simple_strtoul(argv[4], NULL, 16); +	else +		iteration_limit = 0; + +	printf("Testing %08x ... %08x:\n", (uint)start, (uint)end); +	debug("%s:%d: start %#08lx end %#08lx\n", __func__, __LINE__, +	      start, end); + +	buf = map_sysmem(start, end - start); +	dummy = map_sysmem(CONFIG_SYS_MEMTEST_SCRATCH, sizeof(vu_long)); +	for (iteration = 0; +			!iteration_limit || iteration < iteration_limit; +			iteration++) { +		if (ctrlc()) { +			errs = -1UL; +			break; +		} + +		printf("Iteration: %6d\r", iteration + 1); +		debug("\n"); +		if (alt_test) { +			errs = mem_test_alt(buf, start, end, dummy); +		} else { +			errs = mem_test_quick(buf, start, end, pattern, +					      iteration); +		} +		if (errs == -1UL) +			break; +	} + +	/* +	 * Work-around for eldk-4.2 which gives this warning if we try to +	 * case in the unmap_sysmem() call: +	 * warning: initialization discards qualifiers from pointer target type +	 */ +	{ +		void *vbuf = (void *)buf; +		void *vdummy = (void *)dummy; + +		unmap_sysmem(vbuf); +		unmap_sysmem(vdummy); +	} + +	if (errs == -1UL) { +		/* Memory test was aborted - write a newline to finish off */ +		putc('\n'); +		ret = 1; +	} else { +		printf("Tested %d iteration(s) with %lu errors.\n", +			iteration, errs); +		ret = errs != 0; +	} + +	return ret;	/* not reached */  } @@ -962,6 +1015,7 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])  {  	ulong	addr, i;  	int	nbytes, size; +	void *ptr = NULL;  	if (argc != 2)  		return CMD_RET_USAGE; @@ -1006,13 +1060,14 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])  	 * the next value.  A non-converted value exits.  	 */  	do { +		ptr = map_sysmem(addr, size);  		printf("%08lx:", addr);  		if (size == 4) -			printf(" %08x", *((uint   *)addr)); +			printf(" %08x", *((uint *)ptr));  		else if (size == 2) -			printf(" %04x", *((ushort *)addr)); +			printf(" %04x", *((ushort *)ptr));  		else -			printf(" %02x", *((u_char *)addr)); +			printf(" %02x", *((u_char *)ptr));  		nbytes = readline (" ? ");  		if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) { @@ -1042,16 +1097,18 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])  				reset_cmd_timeout();  #endif  				if (size == 4) -					*((uint   *)addr) = i; +					*((uint *)ptr) = i;  				else if (size == 2) -					*((ushort *)addr) = i; +					*((ushort *)ptr) = i;  				else -					*((u_char *)addr) = i; +					*((u_char *)ptr) = i;  				if (incrflag)  					addr += size;  			}  		}  	} while (nbytes); +	if (ptr) +		unmap_sysmem(ptr);  	mm_last_addr = addr;  	mm_last_size = size; @@ -1060,89 +1117,27 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])  #ifdef CONFIG_CMD_CRC32 -#ifndef CONFIG_CRC32_VERIFY -  static int do_mem_crc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  { -	ulong addr, length; -	ulong crc; -	ulong *ptr; - -	if (argc < 3) -		return CMD_RET_USAGE; - -	addr = simple_strtoul (argv[1], NULL, 16); -	addr += base_address; - -	length = simple_strtoul (argv[2], NULL, 16); - -	crc = crc32_wd (0, (const uchar *) addr, length, CHUNKSZ_CRC32); - -	printf ("CRC32 for %08lx ... %08lx ==> %08lx\n", -			addr, addr + length - 1, crc); - -	if (argc > 3) { -		ptr = (ulong *) simple_strtoul (argv[3], NULL, 16); -		*ptr = crc; -	} - -	return 0; -} - -#else	/* CONFIG_CRC32_VERIFY */ - -int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ -	ulong addr, length; -	ulong crc; -	ulong *ptr; -	ulong vcrc; -	int verify; +	int flags = 0;  	int ac;  	char * const *av; -	if (argc < 3) { -usage: +	if (argc < 3)  		return CMD_RET_USAGE; -	}  	av = argv + 1;  	ac = argc - 1; +#ifdef CONFIG_HASH_VERIFY  	if (strcmp(*av, "-v") == 0) { -		verify = 1; +		flags |= HASH_FLAG_VERIFY;  		av++;  		ac--; -		if (ac < 3) -			goto usage; -	} else -		verify = 0; - -	addr = simple_strtoul(*av++, NULL, 16); -	addr += base_address; -	length = simple_strtoul(*av++, NULL, 16); - -	crc = crc32_wd (0, (const uchar *) addr, length, CHUNKSZ_CRC32); - -	if (!verify) { -		printf ("CRC32 for %08lx ... %08lx ==> %08lx\n", -				addr, addr + length - 1, crc); -		if (ac > 2) { -			ptr = (ulong *) simple_strtoul (*av++, NULL, 16); -			*ptr = crc; -		} -	} else { -		vcrc = simple_strtoul(*av++, NULL, 16); -		if (vcrc != crc) { -			printf ("CRC32 for %08lx ... %08lx ==> %08lx != %08lx ** ERROR **\n", -					addr, addr + length - 1, crc, vcrc); -			return 1; -		}  	} +#endif -	return 0; - +	return hash_command("crc32", flags, cmdtp, flag, ac, av);  } -#endif	/* CONFIG_CRC32_VERIFY */  #endif diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c index 06fc171fe..0cfca0c46 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 495610c40..32348f377 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 7633f0c44..d646d9088 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -295,17 +295,17 @@ int setenv_ulong(const char *varname, ulong value)  }  /** - * Set an environment variable to an address in hex + * Set an environment variable to an value in hex   *   * @param varname	Environmet variable to set - * @param addr		Value to set it to + * @param value		Value to set it to   * @return 0 if ok, 1 on error   */ -int setenv_addr(const char *varname, const void *addr) +int setenv_hex(const char *varname, ulong value)  {  	char str[17]; -	sprintf(str, "%lx", (uintptr_t)addr); +	sprintf(str, "%lx", value);  	return setenv(varname, str);  } @@ -891,8 +891,7 @@ NXTARG:		;  		envp->flags = ACTIVE_FLAG;  #endif  	} -	sprintf(buf, "%zX", (size_t)(len + offsetof(env_t, data))); -	setenv("filesize", buf); +	setenv_hex("filesize", len + offsetof(env_t, data));  	return 0; diff --git a/common/cmd_reiser.c b/common/cmd_reiser.c index e658618c6..717c7f657 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 5a042951d..7a38e9450 100644 --- a/common/cmd_setexpr.c +++ b/common/cmd_setexpr.c @@ -53,7 +53,7 @@ static ulong get_arg(char *s, int w)  static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  {  	ulong a, b; -	char buf[16]; +	ulong value;  	int w;  	/* Validate arguments */ @@ -67,8 +67,7 @@ static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	a = get_arg(argv[2], w);  	if (argc == 3) { -		sprintf(buf, "%lx", a); -		setenv(argv[1], buf); +		setenv_hex(argv[1], a);  		return 0;  	} @@ -76,20 +75,36 @@ static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	b = get_arg(argv[4], w);  	switch (argv[3][0]) { -	case '|': sprintf(buf, "%lx", (a | b)); break; -	case '&': sprintf(buf, "%lx", (a & b)); break; -	case '+': sprintf(buf, "%lx", (a + b)); break; -	case '^': sprintf(buf, "%lx", (a ^ b)); break; -	case '-': sprintf(buf, "%lx", (a - b)); break; -	case '*': sprintf(buf, "%lx", (a * b)); break; -	case '/': sprintf(buf, "%lx", (a / b)); break; -	case '%': sprintf(buf, "%lx", (a % b)); break; +	case '|': +		value = a | b; +		break; +	case '&': +		value = a & b; +		break; +	case '+': +		value = a + b; +		break; +	case '^': +		value = a ^ b; +		break; +	case '-': +		value = a - b; +		break; +	case '*': +		value = a * b; +		break; +	case '/': +		value = a / b; +		break; +	case '%': +		value = a % b; +		break;  	default:  		printf("invalid op\n");  		return 1;  	} -	setenv(argv[1], buf); +	setenv_hex(argv[1], value);  	return 0;  } diff --git a/common/cmd_sha1sum.c b/common/cmd_sha1sum.c index fe927ab24..9f08629b8 100644 --- a/common/cmd_sha1sum.c +++ b/common/cmd_sha1sum.c @@ -31,7 +31,7 @@  int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  { -	int verify = 0; +	int flags = HASH_FLAG_ENV;  	int ac;  	char * const *av; @@ -42,13 +42,13 @@ int do_sha1sum(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	ac = argc - 1;  #ifdef CONFIG_SHA1SUM_VERIFY  	if (strcmp(*av, "-v") == 0) { -		verify = 1; +		flags |= HASH_FLAG_VERIFY;  		av++;  		ac--;  	}  #endif -	return hash_command("sha1", verify, cmdtp, flag, ac, av); +	return hash_command("sha1", flags, cmdtp, flag, ac, av);  }  #ifdef CONFIG_SHA1SUM_VERIFY diff --git a/common/cmd_unzip.c b/common/cmd_unzip.c index 43ed7915f..7470c2b12 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 42a7eba76..ea0a26e78 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 1df0c4d72..900e977c1 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 a73c86d59..8607da81e 100644 --- a/common/cmd_zip.c +++ b/common/cmd_zip.c @@ -28,7 +28,6 @@ static int do_zip(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  {  	unsigned long src, dst;  	unsigned long src_len, dst_len = ~0UL; -	char buf[32];  	switch (argc) {  		case 5: @@ -47,8 +46,7 @@ static int do_zip(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  		return 1;  	printf("Compressed size: %ld = 0x%lX\n", dst_len, dst_len); -	sprintf(buf, "%lX", dst_len); -	setenv("filesize", buf); +	setenv_hex("filesize", dst_len);  	return 0;  } diff --git a/common/hash.c b/common/hash.c index e3a6e438a..f5badcb93 100644 --- a/common/hash.c +++ b/common/hash.c @@ -28,49 +28,87 @@  #include <hash.h>  #include <sha1.h>  #include <sha256.h> +#include <asm/io.h>  /*   * These are the hash algorithms we support. Chips which support accelerated - * crypto could perhaps add named version of these algorithms here. + * crypto could perhaps add named version of these algorithms here. Note that + * algorithm names must be in lower case.   */  static struct hash_algo hash_algo[] = { -#ifdef CONFIG_SHA1 +	/* +	 * This is CONFIG_CMD_SHA1SUM instead of CONFIG_SHA1 since otherwise +	 * it bloats the code for boards which use SHA1 but not the 'hash' +	 * or 'sha1sum' commands. +	 */ +#ifdef CONFIG_CMD_SHA1SUM  	{ -		"SHA1", +		"sha1",  		SHA1_SUM_LEN,  		sha1_csum_wd,  		CHUNKSZ_SHA1,  	}, +#define MULTI_HASH  #endif  #ifdef CONFIG_SHA256  	{ -		"SHA256", +		"sha256",  		SHA256_SUM_LEN,  		sha256_csum_wd,  		CHUNKSZ_SHA256,  	}, +#define MULTI_HASH  #endif +	{ +		"crc32", +		4, +		crc32_wd_buf, +		CHUNKSZ_CRC32, +	},  }; +#if defined(CONFIG_HASH_VERIFY) || defined(CONFIG_CMD_HASH) +#define MULTI_HASH +#endif + +/* Try to minimize code size for boards that don't want much hashing */ +#ifdef MULTI_HASH +#define multi_hash()	1 +#else +#define multi_hash()	0 +#endif +  /**   * store_result: Store the resulting sum to an address or variable   *   * @algo:		Hash algorithm being used   * @sum:		Hash digest (algo->digest_size bytes)   * @dest:		Destination, interpreted as a hex address if it starts - *			with * or otherwise as an environment variable. + *			with * (or allow_env_vars is 0) or otherwise as an + *			environment variable. + * @allow_env_vars:	non-zero to permit storing the result to an + *			variable environment   */  static void store_result(struct hash_algo *algo, const u8 *sum, -			 const char *dest) +			 const char *dest, int allow_env_vars)  {  	unsigned int i; +	int env_var = 0; -	if (*dest == '*') { -		u8 *ptr; +	/* +	 * If environment variables are allowed, then we assume that 'dest' +	 * is an environment variable, unless it starts with *, in which +	 * case we assume it is an address. If not allowed, it is always an +	 * address. This is to support the crc32 command. +	 */ +	if (allow_env_vars) { +		if (*dest == '*') +			dest++; +		else +			env_var = 1; +	} -		ptr = (u8 *)simple_strtoul(dest + 1, NULL, 16); -		memcpy(ptr, sum, algo->digest_size); -	} else { +	if (env_var) {  		char str_output[HASH_MAX_DIGEST_SIZE * 2 + 1];  		char *str_ptr = str_output; @@ -80,6 +118,14 @@ static void store_result(struct hash_algo *algo, const u8 *sum,  		}  		str_ptr = '\0';  		setenv(dest, str_output); +	} else { +		ulong addr; +		void *buf; + +		addr = simple_strtoul(dest, NULL, 16); +		buf = map_sysmem(addr, algo->digest_size); +		memcpy(buf, sum, algo->digest_size); +		unmap_sysmem(buf);  	}  } @@ -94,15 +140,31 @@ static void store_result(struct hash_algo *algo, const u8 *sum,   *			Otherwise we assume it is an environment variable, and   *			look up its value (it must contain a hex digest).   * @vsum:		Returns binary digest value (algo->digest_size bytes) + * @allow_env_vars:	non-zero to permit storing the result to an environment + *			variable. If 0 then verify_str is assumed to be an + *			address, and the * prefix is not expected.   * @return 0 if ok, non-zero on error   */ -static int parse_verify_sum(struct hash_algo *algo, char *verify_str, u8 *vsum) +static int parse_verify_sum(struct hash_algo *algo, char *verify_str, u8 *vsum, +			    int allow_env_vars)  { -	if (*verify_str == '*') { -		u8 *ptr; +	int env_var = 0; + +	/* See comment above in store_result() */ +	if (allow_env_vars) { +		if (*verify_str == '*') +			verify_str++; +		else +			env_var = 1; +	} -		ptr = (u8 *)simple_strtoul(verify_str + 1, NULL, 16); -		memcpy(vsum, ptr, algo->digest_size); +	if (env_var) { +		ulong addr; +		void *buf; + +		addr = simple_strtoul(verify_str, NULL, 16); +		buf = map_sysmem(addr, algo->digest_size); +		memcpy(vsum, buf, algo->digest_size);  	} else {  		unsigned int i;  		char *vsum_str; @@ -141,7 +203,7 @@ static struct hash_algo *find_hash_algo(const char *name)  	int i;  	for (i = 0; i < ARRAY_SIZE(hash_algo); i++) { -		if (!strcasecmp(name, hash_algo[i].name)) +		if (!strcmp(name, hash_algo[i].name))  			return &hash_algo[i];  	} @@ -158,63 +220,87 @@ static void show_hash(struct hash_algo *algo, ulong addr, ulong len,  		printf("%02x", output[i]);  } -int hash_command(const char *algo_name, int verify, cmd_tbl_t *cmdtp, int flag, +int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,  		 int argc, char * const argv[])  { -	struct hash_algo *algo;  	ulong addr, len; -	u8 output[HASH_MAX_DIGEST_SIZE]; -	u8 vsum[HASH_MAX_DIGEST_SIZE];  	if (argc < 2)  		return CMD_RET_USAGE; -	algo = find_hash_algo(algo_name); -	if (!algo) { -		printf("Unknown hash algorithm '%s'\n", algo_name); -		return CMD_RET_USAGE; -	}  	addr = simple_strtoul(*argv++, NULL, 16);  	len = simple_strtoul(*argv++, NULL, 16); -	argc -= 2; -	if (algo->digest_size > HASH_MAX_DIGEST_SIZE) { -		puts("HASH_MAX_DIGEST_SIZE exceeded\n"); -		return 1; -	} +	if (multi_hash()) { +		struct hash_algo *algo; +		u8 output[HASH_MAX_DIGEST_SIZE]; +		u8 vsum[HASH_MAX_DIGEST_SIZE]; +		void *buf; -	algo->hash_func_ws((const unsigned char *)addr, len, output, -			   algo->chunk_size); +		algo = find_hash_algo(algo_name); +		if (!algo) { +			printf("Unknown hash algorithm '%s'\n", algo_name); +			return CMD_RET_USAGE; +		} +		argc -= 2; -	/* Try to avoid code bloat when verify is not needed */ +		if (algo->digest_size > HASH_MAX_DIGEST_SIZE) { +			puts("HASH_MAX_DIGEST_SIZE exceeded\n"); +			return 1; +		} + +		buf = map_sysmem(addr, len); +		algo->hash_func_ws(buf, len, output, algo->chunk_size); +		unmap_sysmem(buf); + +		/* Try to avoid code bloat when verify is not needed */  #ifdef CONFIG_HASH_VERIFY -	if (verify) { +		if (flags & HASH_FLAG_VERIFY) {  #else -	if (0) { +		if (0) {  #endif -		if (!argc) -			return CMD_RET_USAGE; -		if (parse_verify_sum(algo, *argv, vsum)) { -			printf("ERROR: %s does not contain a valid %s sum\n", -				*argv, algo->name); -			return 1; -		} -		if (memcmp(output, vsum, algo->digest_size) != 0) { -			int i; +			if (!argc) +				return CMD_RET_USAGE; +			if (parse_verify_sum(algo, *argv, vsum, +					flags & HASH_FLAG_ENV)) { +				printf("ERROR: %s does not contain a valid " +					"%s sum\n", *argv, algo->name); +				return 1; +			} +			if (memcmp(output, vsum, algo->digest_size) != 0) { +				int i; +				show_hash(algo, addr, len, output); +				printf(" != "); +				for (i = 0; i < algo->digest_size; i++) +					printf("%02x", vsum[i]); +				puts(" ** ERROR **\n"); +				return 1; +			} +		} else {  			show_hash(algo, addr, len, output); -			printf(" != "); -			for (i = 0; i < algo->digest_size; i++) -				printf("%02x", vsum[i]); -			puts(" ** ERROR **\n"); -			return 1; +			printf("\n"); + +			if (argc) { +				store_result(algo, output, *argv, +					flags & HASH_FLAG_ENV); +			}  		} + +	/* Horrible code size hack for boards that just want crc32 */  	} else { -		show_hash(algo, addr, len, output); -		printf("\n"); +		ulong crc; +		ulong *ptr; + +		crc = crc32_wd(0, (const uchar *)addr, len, CHUNKSZ_CRC32); -		if (argc) -			store_result(algo, output, *argv); +		printf("CRC32 for %08lx ... %08lx ==> %08lx\n", +				addr, addr + len - 1, crc); + +		if (argc > 3) { +			ptr = (ulong *)simple_strtoul(argv[3], NULL, 16); +			*ptr = crc; +		}  	}  	return 0; diff --git a/common/image.c b/common/image.c index ae1a9d3bd..6afbb40a9 100644 --- a/common/image.c +++ b/common/image.c @@ -74,6 +74,8 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch,  #include <image.h>  #endif /* !USE_HOSTCC*/ +#include <u-boot/crc.h> +  static const table_entry_t uimage_arch[] = {  	{	IH_ARCH_INVALID,	NULL,		"Invalid ARCH",	},  	{	IH_ARCH_ALPHA,		"alpha",	"Alpha",	}, @@ -160,8 +162,6 @@ static const table_entry_t uimage_comp[] = {  	{	-1,		"",		"",			},  }; -uint32_t crc32(uint32_t, const unsigned char *, uint); -uint32_t crc32_wd(uint32_t, const unsigned char *, uint, uint);  #if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)  static void genimg_print_time(time_t timestamp);  #endif diff --git a/drivers/net/fm/fm.c b/drivers/net/fm/fm.c index 49c74c278..8d7058693 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/drivers/serial/sandbox.c b/drivers/serial/sandbox.c index cb19401df..b73520ca9 100644 --- a/drivers/serial/sandbox.c +++ b/drivers/serial/sandbox.c @@ -30,6 +30,19 @@  #include <serial.h>  #include <linux/compiler.h> +/* + * + *   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 = { @@ -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 44be3f53e..273c0a963 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");  	} diff --git a/include/common.h b/include/common.h index 4ad17eafb..6d5292422 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); @@ -357,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 <asm/mach-types.h>  # include <asm/setup.h> @@ -869,6 +882,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 diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 9c431bf27..9f51a0b81 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" \ diff --git a/include/hash.h b/include/hash.h index 34ba558bd..2dbbd9b7d 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 @@ -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 + * @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)   * @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 diff --git a/include/os.h b/include/os.h index 699682a40..c452d1b56 100644 --- a/include/os.h +++ b/include/os.h @@ -40,6 +40,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   *   * \param fd	File descriptor as returned by os_open() diff --git a/include/u-boot/crc.h b/include/u-boot/crc.h index 07badbfc5..08e509edb 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 27335a3ed..76205da4f 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)); +} diff --git a/lib/display_options.c b/lib/display_options.c index 694d2f22e..0339970e7 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 { @@ -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(); |