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 | |
parent | 99b0f0fd3fbf2572ae1a7723dd90cffc8e85130a (diff) | |
download | u-boot-imx-c95c4280d751ca078c2ff58228d2f2b44ccf0600.zip u-boot-imx-c95c4280d751ca078c2ff58228d2f2b44ccf0600.tar.gz u-boot-imx-c95c4280d751ca078c2ff58228d2f2b44ccf0600.tar.bz2 |
[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>
-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 d0fae6b..fcbb023 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 982d6a8..5b2e71c 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 512e898..5ddd94f 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; +} |