diff options
author | Jon Doron <arilou@gmail.com> | 2019-05-29 09:41:48 +0300 |
---|---|---|
committer | Alex Bennée <alex.bennee@linaro.org> | 2019-06-12 17:53:23 +0100 |
commit | ab4752ec8d9b0b19ab80915016b739350418a078 (patch) | |
tree | c4f58c4ec8f7328a175a6b99dac5e82c2716227a /gdbstub.c | |
parent | 3f1cbac73a441c518e27184bf24bc56796f4ab5a (diff) |
gdbstub: Implement qemu physical memory mode
Add a new query/set which changes the memory GDB sees to physical memory
only.
gdb> maint packet qqemu.PhyMemMode
will reply the current phy_mem_mode state (1 for enabled, 0 for disabled)
gdb> maint packet Qqemu.PhyMemMode:1
Will make GDB read/write only to physical memory, set to 0 to disable
Signed-off-by: Jon Doron <arilou@gmail.com>
Message-Id: <20190529064148.19856-21-arilou@gmail.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Diffstat (limited to 'gdbstub.c')
-rw-r--r-- | gdbstub.c | 62 |
1 files changed, 60 insertions, 2 deletions
@@ -50,11 +50,27 @@ #define GDB_ATTACHED "1" #endif +#ifndef CONFIG_USER_ONLY +static int phy_memory_mode; +#endif + static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr, uint8_t *buf, int len, bool is_write) { - CPUClass *cc = CPU_GET_CLASS(cpu); + CPUClass *cc; +#ifndef CONFIG_USER_ONLY + if (phy_memory_mode) { + if (is_write) { + cpu_physical_memory_write(addr, buf, len); + } else { + cpu_physical_memory_read(addr, buf, len); + } + return 0; + } +#endif + + cc = CPU_GET_CLASS(cpu); if (cc->memory_rw_debug) { return cc->memory_rw_debug(cpu, addr, buf, len, is_write); } @@ -2136,8 +2152,36 @@ static void handle_query_attached(GdbCmdContext *gdb_ctx, void *user_ctx) static void handle_query_qemu_supported(GdbCmdContext *gdb_ctx, void *user_ctx) { - put_packet(gdb_ctx->s, "sstepbits;sstep"); + snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), "sstepbits;sstep"); +#ifndef CONFIG_USER_ONLY + pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), ";PhyMemMode"); +#endif + put_packet(gdb_ctx->s, gdb_ctx->str_buf); +} + +#ifndef CONFIG_USER_ONLY +static void handle_query_qemu_phy_mem_mode(GdbCmdContext *gdb_ctx, + void *user_ctx) +{ + snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), "%d", phy_memory_mode); + put_packet(gdb_ctx->s, gdb_ctx->str_buf); +} + +static void handle_set_qemu_phy_mem_mode(GdbCmdContext *gdb_ctx, void *user_ctx) +{ + if (!gdb_ctx->num_params) { + put_packet(gdb_ctx->s, "E22"); + return; + } + + if (!gdb_ctx->params[0].val_ul) { + phy_memory_mode = 0; + } else { + phy_memory_mode = 1; + } + put_packet(gdb_ctx->s, "OK"); } +#endif static GdbCmdParseEntry gdb_gen_query_set_common_table[] = { /* Order is important if has same prefix */ @@ -2219,6 +2263,12 @@ static GdbCmdParseEntry gdb_gen_query_table[] = { .handler = handle_query_qemu_supported, .cmd = "qemu.Supported", }, +#ifndef CONFIG_USER_ONLY + { + .handler = handle_query_qemu_phy_mem_mode, + .cmd = "qemu.PhyMemMode", + }, +#endif }; static GdbCmdParseEntry gdb_gen_set_table[] = { @@ -2229,6 +2279,14 @@ static GdbCmdParseEntry gdb_gen_set_table[] = { .cmd_startswith = 1, .schema = "l0" }, +#ifndef CONFIG_USER_ONLY + { + .handler = handle_set_qemu_phy_mem_mode, + .cmd = "qemu.PhyMemMode:", + .cmd_startswith = 1, + .schema = "l0" + }, +#endif }; static void handle_gen_query(GdbCmdContext *gdb_ctx, void *user_ctx) |