Skip to content

Commit 03b9a73

Browse files
committed
Implement memory write and register write
The `mini-gdbstub` library supports the functionality to write register and write memory now. After this PR, `rv32emu` is enabled to do those commands that will try to write register and memory, e.g. the `load` command.
1 parent e985dfb commit 03b9a73

File tree

3 files changed

+23
-12
lines changed

3 files changed

+23
-12
lines changed

README.md

-11
Original file line numberDiff line numberDiff line change
@@ -149,17 +149,6 @@ $ riscv32-unknown-elf-gdb
149149
Congratulate yourself if `riscv-gdb` does not produce an error message. Now that the GDB
150150
command line is available, you can communicate with `rv32emu`.
151151

152-
### Limitation
153-
154-
The development of `rv32emu`'s GDBRSP functionality is still ongoing. Due to the current
155-
unfinished design, various restrictions on this feature are known.
156-
* Since the 'G' packet is not supported yet, writing emulator registers with GDB is
157-
not permitted.
158-
* Consequently, the packets for binary download (the "X" packet) and memory writing
159-
(the "M" packet) specified in GDBRSP are not allowed. It is forbidden to use GDB commands
160-
such as "load" that aim to modify the emulator's internal memory.
161-
* You can only set one breakpoint when debugging due to the inadequate breakpoint handling design.
162-
163152
## Contributing
164153
See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.
165154

src/gdbstub.c

+22
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ static size_t rv_read_reg(void *args, int regno)
1818
return -1;
1919
}
2020

21+
static void rv_write_reg(void *args, int regno, size_t data)
22+
{
23+
if (unlikely(regno > 32))
24+
return;
25+
26+
struct riscv_t *rv = (struct riscv_t *) args;
27+
if (regno == 32)
28+
rv_set_pc(rv, data);
29+
else
30+
rv_set_reg(rv, regno, data);
31+
}
32+
2133
static void rv_read_mem(void *args, size_t addr, size_t len, void *val)
2234
{
2335
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)
2638
*((uint8_t *) val + i) = rv->io.mem_read_b(rv, addr + i);
2739
}
2840

41+
static void rv_write_mem(void *args, size_t addr, size_t len, void *val)
42+
{
43+
struct riscv_t *rv = (struct riscv_t *) args;
44+
45+
for (size_t i = 0; i < len; i++)
46+
rv->io.mem_write_b(rv, addr + i, *((uint8_t *) val + i));
47+
}
48+
2949
static gdb_action_t rv_cont(void *args)
3050
{
3151
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)
6989

7090
const struct target_ops gdbstub_ops = {
7191
.read_reg = rv_read_reg,
92+
.write_reg = rv_write_reg,
7293
.read_mem = rv_read_mem,
94+
.write_mem = rv_write_mem,
7395
.cont = rv_cont,
7496
.stepi = rv_stepi,
7597
.set_bp = rv_set_bp,

0 commit comments

Comments
 (0)