diff --git a/README.md b/README.md index 48512ec0..a022804d 100644 --- a/README.md +++ b/README.md @@ -149,17 +149,6 @@ $ riscv32-unknown-elf-gdb Congratulate yourself if `riscv-gdb` does not produce an error message. Now that the GDB command line is available, you can communicate with `rv32emu`. -### Limitation - -The development of `rv32emu`'s GDBRSP functionality is still ongoing. Due to the current -unfinished design, various restrictions on this feature are known. -* Since the 'G' packet is not supported yet, writing emulator registers with GDB is -not permitted. -* Consequently, the packets for binary download (the "X" packet) and memory writing -(the "M" packet) specified in GDBRSP are not allowed. It is forbidden to use GDB commands -such as "load" that aim to modify the emulator's internal memory. -* You can only set one breakpoint when debugging due to the inadequate breakpoint handling design. - ## Contributing See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines. diff --git a/src/gdbstub.c b/src/gdbstub.c index 78deda34..5f3e6ea8 100644 --- a/src/gdbstub.c +++ b/src/gdbstub.c @@ -18,6 +18,18 @@ static size_t rv_read_reg(void *args, int regno) return -1; } +static void rv_write_reg(void *args, int regno, size_t data) +{ + if (unlikely(regno > 32)) + return; + + struct riscv_t *rv = (struct riscv_t *) args; + if (regno == 32) + rv_set_pc(rv, data); + else + rv_set_reg(rv, regno, data); +} + static void rv_read_mem(void *args, size_t addr, size_t len, void *val) { struct riscv_t *rv = (struct riscv_t *) args; @@ -26,6 +38,14 @@ static void rv_read_mem(void *args, size_t addr, size_t len, void *val) *((uint8_t *) val + i) = rv->io.mem_read_b(rv, addr + i); } +static void rv_write_mem(void *args, size_t addr, size_t len, void *val) +{ + struct riscv_t *rv = (struct riscv_t *) args; + + for (size_t i = 0; i < len; i++) + rv->io.mem_write_b(rv, addr + i, *((uint8_t *) val + i)); +} + static gdb_action_t rv_cont(void *args) { struct riscv_t *rv = (struct riscv_t *) args; @@ -69,7 +89,9 @@ static bool rv_del_bp(void *args, size_t addr, bp_type_t type) const struct target_ops gdbstub_ops = { .read_reg = rv_read_reg, + .write_reg = rv_write_reg, .read_mem = rv_read_mem, + .write_mem = rv_write_mem, .cont = rv_cont, .stepi = rv_stepi, .set_bp = rv_set_bp, diff --git a/src/mini-gdbstub b/src/mini-gdbstub index 5fceda9b..4acb4c5d 160000 --- a/src/mini-gdbstub +++ b/src/mini-gdbstub @@ -1 +1 @@ -Subproject commit 5fceda9bcbb16f9901bdade1547cd79a0ab32bdb +Subproject commit 4acb4c5d79e02532c642509f476f975465632863