diff --git a/ui/cmddb.c b/ui/cmddb.c index 9c97eb4..79c1a75 100644 --- a/ui/cmddb.c +++ b/ui/cmddb.c @@ -301,6 +301,13 @@ const struct cmddb_record commands[] = { " Remove an alias definition.\n" "alias \n" " Define a new alias.\n" + }, + { + .name = "fill", + .func = cmd_fill, + .help = +"fill
[b1 b2 ...]\n" +" Fill the given memory range with a repeated byte sequence.\n" } }; diff --git a/ui/devcmd.c b/ui/devcmd.c index ecf6ad2..76a27f5 100644 --- a/ui/devcmd.c +++ b/ui/devcmd.c @@ -753,3 +753,64 @@ int cmd_locka(char **arg) printc("LOCKA is %s\n", (regval[0] & FCTL3_LOCKA) ? "set" : "clear"); return 0; } + +int cmd_fill(char **arg) +{ + char *addr_text = get_arg(arg); + char *len_text = get_arg(arg); + char *byte_text; + address_t addr = 0; + address_t len = 0; + uint8_t buf[256]; + int period = 0; + int phase = 0; + int i; + + if (!(addr_text && len_text)) { + printc_err("fill: address and length must be supplied\n"); + return -1; + } + + if (expr_eval(addr_text, &addr) < 0) { + printc_err("fill: invalid address\n"); + return -1; + } + + if (expr_eval(len_text, &len) < 0) { + printc_err("fill: invalid length\n"); + return -1; + } + + while ((byte_text = get_arg(arg))) { + if (period >= sizeof(buf)) { + printc_err("fill: maximum length exceeded\n"); + return -1; + } + + buf[period++] = strtoul(byte_text, NULL, 16); + } + + if (!period) { + printc_err("fill: no pattern supplied\n"); + return -1; + } + + for (i = period; i < sizeof(buf); i++) + buf[i] = buf[i % period]; + + while (len > 0) { + int plen = sizeof(buf) - phase; + + if (plen > len) + plen = len; + + if (device_writemem(addr, buf + phase, plen) < 0) + return -1; + + addr += plen; + len -= plen; + phase = (phase + plen) % period; + } + + return 0; +} diff --git a/ui/devcmd.h b/ui/devcmd.h index a0bd419..e37b4d7 100644 --- a/ui/devcmd.h +++ b/ui/devcmd.h @@ -39,5 +39,6 @@ int cmd_setwatch_w(char **arg); int cmd_delbreak(char **arg); int cmd_break(char **arg); int cmd_locka(char **arg); +int cmd_fill(char **arg); #endif