diff options
author | Simon Glass | 2019-09-25 08:56:25 -0600 |
---|---|---|
committer | Bin Meng | 2019-10-08 13:57:44 +0800 |
commit | 9da3776bf6d782be47edcc8f15b89d1ffbd33724 (patch) | |
tree | d838dc74c9fe42498b72e36a69db1cd3eaa73554 /cmd/io.c | |
parent | e37d963ec80351e51c3b0832d9306bd91b1dafbf (diff) |
iod: Enhance to support display of multiple values
At present the 'iod' command differs from 'md' in that it only shows a
single value. It is useful to see a dump of multiple values, particularly
when x86 peripherals contain register sets accessible via I/O ports.
Enhance the command to match md.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
[bmeng: correct multi-line comment format style]
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'cmd/io.c')
-rw-r--r-- | cmd/io.c | 85 |
1 files changed, 66 insertions, 19 deletions
@@ -11,6 +11,13 @@ #include <command.h> #include <asm/io.h> +/* Display values from last command */ +static ulong last_addr, last_size; +static ulong last_length = 0x40; +static ulong base_address; + +#define DISP_LINE_LEN 16 + /* * IO Display * @@ -19,26 +26,66 @@ */ int do_io_iod(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - ulong addr; - int size; - - if (argc != 2) + ulong addr, length, bytes; + u8 buf[DISP_LINE_LEN]; + int size, todo; + + /* + * We use the last specified parameters, unless new ones are + * entered. + */ + addr = last_addr; + size = last_size; + length = last_length; + + if (argc < 2) return CMD_RET_USAGE; - size = cmd_get_data_size(argv[0], 4); - if (size < 0) - return 1; - - addr = simple_strtoul(argv[1], NULL, 16); - - printf("%04x: ", (u16) addr); - - if (size == 4) - printf("%08x\n", inl(addr)); - else if (size == 2) - printf("%04x\n", inw(addr)); - else - printf("%02x\n", inb(addr)); + if ((flag & CMD_FLAG_REPEAT) == 0) { + /* + * New command specified. Check for a size specification. + * Defaults to long if no or incorrect specification. + */ + size = cmd_get_data_size(argv[0], 4); + if (size < 0) + return 1; + + /* Address is specified since argc > 1 */ + addr = simple_strtoul(argv[1], NULL, 16); + addr += base_address; + + /* + * If another parameter, it is the length to display. + * Length is the number of objects, not number of bytes. + */ + if (argc > 2) + length = simple_strtoul(argv[2], NULL, 16); + } + + bytes = size * length; + + /* Print the lines */ + for (; bytes > 0; addr += todo) { + u8 *ptr = buf; + int i; + + todo = min(bytes, (ulong)DISP_LINE_LEN); + for (i = 0; i < todo; i += size, ptr += size) { + if (size == 4) + *(u32 *)ptr = inl(addr + i); + else if (size == 2) + *(u16 *)ptr = inw(addr + i); + else + *ptr = inb(addr + i); + } + print_buffer(addr, buf, size, todo / size, + DISP_LINE_LEN / size); + bytes -= todo; + } + + last_addr = addr; + last_length = length; + last_size = size; return 0; } @@ -69,7 +116,7 @@ int do_io_iow(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) } /**************************************************/ -U_BOOT_CMD(iod, 2, 0, do_io_iod, +U_BOOT_CMD(iod, 3, 1, do_io_iod, "IO space display", "[.b, .w, .l] address"); U_BOOT_CMD(iow, 3, 0, do_io_iow, |