diff options
Diffstat (limited to 'lib_generic/display_options.c')
| -rw-r--r-- | lib_generic/display_options.c | 70 | 
1 files changed, 70 insertions, 0 deletions
| 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; +} |