mdebug

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 57e11b8a3fdad90f001f7a899fb4db86d0e80e22
parent dd0091f98422624598584141c5b51431974e3b5d
Author: Brian Swetland <swetland@frotz.net>
Date:   Sun, 21 Jun 2015 21:56:37 -0700

gdb-bridge: support register writes, start on memory writes

Diffstat:
Mtools/gdb-bridge.c | 86++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 77 insertions(+), 9 deletions(-)

diff --git a/tools/gdb-bridge.c b/tools/gdb-bridge.c @@ -208,14 +208,29 @@ int gdb_recv(struct gdbcnxn *gc, unsigned char *ptr, int len) { } unsigned unhex(char *x) { + char tmp[3]; unsigned n; - char t = x[2]; - x[2] = 0; - n = strtoul(x, 0, 16); - x[2] = t; + tmp[0] = x[0]; + tmp[1] = x[1]; + tmp[2] = 0; + n = strtoul(tmp, 0, 16); return n; } +int hextobin(void *_dst, char *src, int max) { + unsigned char *dst = _dst; + while (max > 0) { + if (src[0] && src[1]) { + *dst++ = unhex(src); + src += 2; + max -= 2; + } else { + break; + } + } + return dst - ((unsigned char*) _dst); +} + static const char *target_xml = "<?xml version=\"1.0\"?>" "<target>" @@ -318,34 +333,87 @@ void handle_command(struct gdbcnxn *gc, unsigned char *cmd) { swdp_core_halt(); break; case 'H': + /* select thread - we've only got one */ gdb_puts(gc, "OK"); break; + // m hexaddr , hexcount + // read from memory case 'm': - if (sscanf((char*) cmd + 1, "%x,%x", &x, &n) != 2) + if (sscanf((char*) cmd + 1, "%x,%x", &x, &n) != 2) { break; - - if (n > 1024) + } + if (n > 1024) { n = 1024; - + } swdp_ahb_read32(x & (~3), tmp.w, ((n + 3) & (~3)) / 4); gdb_puthex(gc, tmp.b + (x & 3), n); - break; + break; + // M hexaddr , hexcount : hexbytes + // write to memory + case 'M': { + char *data = strchr((char*) cmd + 1, ':'); + int len; + if (!data) { + break; + } + *data++ = 0; + if (sscanf((char*) cmd + 1, "%x,%x", &x, &n) != 2) { + break; + } + len = hextobin(gc->rxbuf, data, MAXPKT); + zprintf("write %d bytes at %x (%d recv)\n", n, x, len); + gdb_puts(gc, "EFF"); //Eerrno or OK + break; + } + // g + // read registers 0... case 'g': { u32 regs[19]; swdp_core_read_all(regs); gdb_puthex(gc, regs, sizeof(regs)); break; } + // G hexbytes + // write registers 0... + case 'G': { + int len = hextobin(gc->rxbuf, (char*) cmd + 1, MAXPKT); + for (n = 0; n < len / 4; n++) { + memcpy(&x, gc->rxbuf + (n * 4), sizeof(x)); + swdp_core_write(n, x); + } + gdb_puts(gc, "OK"); + break; + } + // p reghex + // read from register case 'p': { u32 v; swdp_core_read(strtoul((char*) cmd + 1, NULL, 16), &v); gdb_puthex(gc, &v, sizeof(v)); break; } + // P reghex = hexbytes + // write to register + case 'P': { + int len; + char *data = strchr((char*) cmd + 1, '='); + if (data) { + *data++ = 0; + n = strtoul((char*) cmd + 1, NULL, 16); + len = hextobin(gc->rxbuf, data, MAXPKT); + if (len != 4) break; + memcpy(&x, gc->rxbuf, sizeof(x)); + swdp_core_write(n, x); + gdb_puts(gc, "OK"); + } + break; + } + // single step case 's': swdp_core_step(); gdb_puts(gc, "S00"); break; + // extended query and set commands case 'q': case 'Q': { char *args = (char*) (cmd + 1);