diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2007-02-20 09:05:00 +0100 |
---|---|---|
committer | Stefan Roese <sr@denx.de> | 2007-02-20 09:05:00 +0100 |
commit | c95c4280d751ca078c2ff58228d2f2b44ccf0600 (patch) | |
tree | 875524fdc1fde3868e34c9b003245adc079f3d3c /lib_generic | |
parent | 99b0f0fd3fbf2572ae1a7723dd90cffc8e85130a (diff) |
[PATCH 3_9] Move buffer print code from md command to common function
Printing a buffer is a darn useful thing. Move the buffer print code
into print_buffer() in lib_generic/
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'lib_generic')
-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 512e8980d9d..5ddd94fd5ac 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; +} |