mdebug

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

commit 483e0ff30303655eb57c3fad6732cc4b5ea0584e
parent 9c73597781b798b1f50f36a575ffb21509e3715d
Author: Brian Swetland <swetland@frotz.net>
Date:   Mon, 22 Jun 2015 19:00:56 -0700

gdb-bridge: handle set/clear hw breakpoint

Diffstat:
Mtools/gdb-bridge.c | 63++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 62 insertions(+), 1 deletion(-)

diff --git a/tools/gdb-bridge.c b/tools/gdb-bridge.c @@ -160,7 +160,7 @@ int gdb_recv(struct gdbcnxn *gc, unsigned char *ptr, int len) { switch (gc->state) { case S_IDLE: if (c == 3) { - gc->rxbuf[0] = 's'; + gc->rxbuf[0] = '$'; gc->rxbuf[1] = 0; gdb_recv_cmd(gc); } else if (c == '$') { @@ -351,6 +351,46 @@ void write_memory(u32 addr, unsigned char *data, int len) { } } +#define MAXBP 4 +static u32 bp_addr[MAXBP]; +static u32 bp_state[MAXBP]; + +int handle_breakpoint(int add, u32 addr, u32 kind) { + int n; + if (add) { + for (n = 0; n < MAXBP; n++) { + if (bp_state[n] && (bp_addr[n] == addr)) { + // already setup + return 0; + } + } + for (n = 0; n < MAXBP; n++) { + if (bp_state[n] == 0) { + bp_addr[n] = addr; + bp_state[n] = 1; + swdp_watchpoint_pc(n, addr); + zprintf("GDB: + HW BP @ %08x\n", addr); + return 0; + } + } + if (n == MAXBP) { + zprintf("GDB: Out of hardware breakpoints.\n"); + return 1; + } + return 0; + } else { + for (n = 0; n < MAXBP; n++) { + if (bp_state[n] && (bp_addr[n] == addr)) { + bp_state[n] = 0; + swdp_watchpoint_disable(n); + break; + } + } + zprintf("GDB: - HW BP @ %08x\n", addr); + return 0; + } +} + void handle_command(struct gdbcnxn *gc, unsigned char *cmd) { union { u32 w[256+2]; @@ -448,6 +488,11 @@ void handle_command(struct gdbcnxn *gc, unsigned char *cmd) { } break; } + // halt (^c) + case '$': + swdp_core_halt(); + gdb_puts(gc, "S00"); + break; // single step case 's': swdp_core_step(); @@ -472,6 +517,22 @@ void handle_command(struct gdbcnxn *gc, unsigned char *cmd) { break; } + case 'z': + case 'Z': { + u32 type, addr, kind; + if (sscanf((char*) cmd + 1, "%x,%x,%x", &type, &addr, &kind) != 3) { + break; + } + if (type != 1) { + // only support hw breakpoints + } + if (handle_breakpoint(cmd[0] == 'Z', addr, kind)) { + gdb_puts(gc, "OK"); + } else { + gdb_puts(gc, "E1"); + } + break; + } default: zprintf("GDB: unknown command: %c\n", cmd[0]); }