diff options
| -rw-r--r-- | common/cmd_mem.c | 65 | ||||
| -rw-r--r-- | include/common.h | 2 | ||||
| -rw-r--r-- | lib_generic/display_options.c | 70 | 
3 files changed, 86 insertions, 51 deletions
| diff --git a/common/cmd_mem.c b/common/cmd_mem.c index d0fae6b24..fcbb0236d 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -92,8 +92,9 @@ static	ulong	base_address = 0;  int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  {  	ulong	addr, length; -	ulong	i, nbytes, linebytes; -	u_char	*cp; +#if defined(CONFIG_HAS_DATAFLASH) +	ulong	nbytes, linebytes; +#endif  	int	size;  	int rc = 0; @@ -128,6 +129,7 @@ int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  			length = simple_strtoul(argv[2], NULL, 16);  	} +#if defined(CONFIG_HAS_DATAFLASH)  	/* Print the lines.  	 *  	 * We buffer all read data, so we can make sure data is read only @@ -136,64 +138,25 @@ int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  	nbytes = length * size;  	do {  		char	linebuf[DISP_LINE_LEN]; -		uint	*uip = (uint   *)linebuf; -		ushort	*usp = (ushort *)linebuf; -		u_char	*ucp = (u_char *)linebuf; -#ifdef CONFIG_HAS_DATAFLASH -		int rc; -#endif -		printf("%08lx:", addr); +		void* p;  		linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes; -#ifdef CONFIG_HAS_DATAFLASH -		if ((rc = read_dataflash(addr, (linebytes/size)*size, linebuf)) == DATAFLASH_OK){ -			/* if outside dataflash */ -			/*if (rc != 1) { -				dataflash_perror (rc); -				return (1); -			}*/ -			for (i=0; i<linebytes; i+= size) { -				if (size == 4) { -					printf(" %08x", *uip++); -				} else if (size == 2) { -					printf(" %04x", *usp++); -				} else { -					printf(" %02x", *ucp++); -				} -				addr += size; -			} +		rc = read_dataflash(addr, (linebytes/size)*size, linebuf); +		p = (rc == DATAFLASH_OK) ? linebuf : (void*)addr; +		print_buffer(addr, p, size, linebytes/size, DISP_LINE_LEN/size); -		} else {	/* addr does not correspond to DataFlash */ -#endif -		for (i=0; i<linebytes; i+= size) { -			if (size == 4) { -				printf(" %08x", (*uip++ = *((uint *)addr))); -			} else if (size == 2) { -				printf(" %04x", (*usp++ = *((ushort *)addr))); -			} else { -				printf(" %02x", (*ucp++ = *((u_char *)addr))); -			} -			addr += size; -		} -#ifdef CONFIG_HAS_DATAFLASH -		} -#endif -		puts ("    "); -		cp = (u_char *)linebuf; -		for (i=0; i<linebytes; i++) { -			if ((*cp < 0x20) || (*cp > 0x7e)) -				putc ('.'); -			else -				printf("%c", *cp); -			cp++; -		} -		putc ('\n');  		nbytes -= linebytes; +		addr += linebytes;  		if (ctrlc()) {  			rc = 1;  			break;  		}  	} while (nbytes > 0); +#else +	/* Print the lines. */ +	print_buffer(addr, (void*)addr, size, length, DISP_LINE_LEN/size); +	addr += size*length; +#endif  	dp_last_addr = addr;  	dp_last_length = length; diff --git a/include/common.h b/include/common.h index 982d6a863..5b2e71c98 100644 --- a/include/common.h +++ b/include/common.h @@ -187,6 +187,8 @@ void	hang		(void) __attribute__ ((noreturn));  long int initdram (int);  int	display_options (void);  void	print_size (ulong, const char *); +int	print_buffer (ulong addr, void* data, uint width, uint count, +                      uint linelen);  /* common/main.c */  void	main_loop	(void); diff --git a/lib_generic/display_options.c b/lib_generic/display_options.c index 512e8980d..5ddd94fd5 100644 --- a/lib_generic/display_options.c +++ b/lib_generic/display_options.c @@ -21,7 +21,10 @@   * MA 02111-1307 USA   */ +#include <config.h>  #include <common.h> +#include <linux/ctype.h> +#include <asm/io.h>  int display_options (void)  { @@ -65,3 +68,70 @@ void print_size (ulong size, const char *s)  	}  	printf (" %cB%s", c, s);  } + +/* + * Print data buffer in hex and ascii form to the terminal. + * + * data reads are buffered so that each memory address is only read once. + * Useful when displaying the contents of volatile registers. + * + * parameters: + *    addr: Starting address to display at start of line + *    data: pointer to data buffer + *    width: data value width.  May be 1, 2, or 4. + *    count: number of values to display + *    linelen: Number of values to print per line; specify 0 for default length + */ +#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) +{ +	uint8_t linebuf[MAX_LINE_LENGTH_BYTES]; +	uint32_t *uip = (void*)linebuf; +	uint16_t *usp = (void*)linebuf; +	uint8_t *ucp = (void*)linebuf; +	int i; + +	if (linelen*width > MAX_LINE_LENGTH_BYTES) +		linelen = MAX_LINE_LENGTH_BYTES / width; +	if (linelen < 1) +		linelen = DEFAULT_LINE_LENGTH_BYTES / width; + +	while (count) { +		printf("%08lx:", addr); + +		/* check for overflow condition */ +		if (count < linelen) +			linelen = count; + +		/* Copy from memory into linebuf and print hex values */ +		for (i = 0; i < linelen; i++) { +			if (width == 4) { +				uip[i] = *(volatile uint32_t *)data; +				printf(" %08x", uip[i]); +			} else if (width == 2) { +				usp[i] = *(volatile uint16_t *)data; +				printf(" %04x", usp[i]); +			} else { +				ucp[i] = *(volatile uint8_t *)data; +				printf(" %02x", ucp[i]); +			} +			data += width; +		} + +		/* Print data in ASCII characters */ +		puts("    "); +		for (i = 0; i < linelen * width; i++) +			putc(isprint(ucp[i]) && (ucp[i] < 0x80) ? ucp[i] : '.'); +		putc ('\n'); + +		/* update references */ +		addr += linelen * width; +		count -= linelen; + +		if (ctrlc()) +			return -1; +	} + +	return 0; +} |