xdebug

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

commit c58a39db2158380f9f44a52999c0dd1d6344e9c7
parent a40174ffcba9b1331b3e8857c4b4b3fc781e0aac
Author: Brian Swetland <swetland@frotz.net>
Date:   Tue,  7 Mar 2023 18:19:55 -0800

commands: db, reset, and reset-stop

Diffstat:
Msrc/commands.c | 136+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Msrc/transport-dap.c | 8++++----
Msrc/xdebug.c | 8+++++++-
3 files changed, 130 insertions(+), 22 deletions(-)

diff --git a/src/commands.c b/src/commands.c @@ -59,6 +59,9 @@ int do_dw(DC* dc, CC* cc) { if (cmd_arg_u32_opt(cc, 1, &addr, lastaddr)) return DBG_ERR; if (cmd_arg_u32_opt(cc, 2, &count, lastcount)) return DBG_ERR; + if (count > 1024) count = 1024; + lastaddr = addr; + lastcount = count; if (addr & 3) { ERROR("address is not word-aligned\n"); @@ -94,6 +97,46 @@ int do_dw(DC* dc, CC* cc) { return 0; } +int do_db(DC* dc, CC* cc) { + uint32_t data[1024 + 8]; + uint32_t addr, count, bytecount; + uint8_t *x; + unsigned n; + + if (cmd_arg_u32_opt(cc, 1, &addr, lastaddr)) return DBG_ERR; + if (cmd_arg_u32_opt(cc, 2, &count, lastcount)) return DBG_ERR; + if (count > 1024) count = 1024; + lastaddr = addr; + lastcount = count; + + bytecount = count; + x = (void*) data; + if (addr & 3) { + x += (addr & 3); + count += 4 - (addr & 3); + addr &= 3; + } + if (count & 3) { + count += 4 - (count & 3); + } + count /= 4; + if (count < 1) return 0; + + if (dc_mem_rd_words(dc, addr, count, data)) return DBG_ERR; + + while (bytecount > 0) { + n = (bytecount > 16) ? 16 : bytecount; + INFO("%08x:", addr); + bytecount -= n; + addr += n; + while (n-- > 0) { + INFO(" %02x", *x++); + } + INFO("\n"); + } + return 0; +} + int do_rd(DC* dc, CC* cc) { uint32_t addr, val; if (cmd_arg_u32(cc, 1, &addr)) return DBG_ERR; @@ -143,8 +186,66 @@ int do_step(DC* dc, CC* cc) { return read_show_regs(dc); } +static uint32_t vcflags = 0; + int do_reset(DC* dc, CC* cc) { - return -1; //return dc_core_reset(dc); + int r; + if ((r = dc_core_halt(dc)) < 0) { + return r; + } + if ((r = dc_mem_wr32(dc, DEMCR, DEMCR_TRCENA | vcflags)) < 0) { + return r; + } + if ((r = dc_mem_wr32(dc, AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ)) < 0) { + return r; + } + return 0; +} + +static int wait_for_stop(DC* dc) { + unsigned m = 0; + uint32_t val; + int r; + for (unsigned n = 0; n < 100; n++) { + if ((r = dc_mem_rd32(dc, DHCSR, &val)) < 0) { + dc_attach(dc, 0, 0, &val); + } else { + if (val & DHCSR_S_HALT) { + INFO("halt: CPU HALTED (%u,%u)\n", n, m); + uint32_t dfsr = -1, demcr = -1; + dc_mem_rd32(dc, DFSR, &dfsr); + dc_mem_rd32(dc, DEMCR, &demcr); + INFO("halt: DHCSR %08x, DFSR %08x, DEMCR %08x\n", val, dfsr, demcr); + return 0; + } + if (val & DHCSR_S_RESET_ST) { + m++; + } + dc_mem_wr32(dc, DHCSR, DHCSR_DBGKEY | DHCSR_C_HALT | DHCSR_C_DEBUGEN); + } + } + return DC_ERR_FAILED; +} + +int do_reset_stop(DC* dc, CC* cc) { + int r; + if ((r = dc_core_halt(dc)) < 0) { + return r; + } + if ((r = wait_for_stop(dc)) < 0) { + return r; + } + if ((r = dc_mem_wr32(dc, DEMCR, DEMCR_VC_CORERESET | DEMCR_TRCENA | vcflags)) < 0) { + return r; + } + if ((r = dc_mem_wr32(dc, AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ)) < 0) { + return r; + } + if ((r = wait_for_stop(dc)) < 0) { + INFO("reset-stop: CPU DID NOT HALT\n"); + return r; + } + return 0; } int do_exit(DC* dc, CC* cc) { @@ -159,22 +260,23 @@ struct { int (*func)(DC* dc, CC* cc); const char* help; } CMDS[] = { - { "attach", do_attach, "connect to target" }, - { "stop", do_stop, "halt core" }, - { "halt", do_stop, NULL }, - { "go", do_resume, NULL }, - { "resume", do_resume, "resume core" }, - { "step", do_step, "single-step core" }, - { "reset", do_reset, "reset core" }, - { "dw", do_dw, "dump words dw <addr> [ <count> ]" }, - //{ "db", do_db, "dump bytes db <addr> [ <count> ]" }, - { "rd", do_rd, "read word rd <addr>" }, - { "dr", do_rd, NULL }, - { "wr", do_wr, "write word wr <addr> <val>" }, - { "regs", do_regs, "dump registers" }, - { "help", do_help, "list commands" }, - { "exit", do_exit, "exit debugger" }, - { "quit", do_exit, NULL }, +{ "attach", do_attach, "connect to target" }, +{ "stop", do_stop, "halt core" }, +{ "halt", do_stop, NULL }, +{ "go", do_resume, NULL }, +{ "resume", do_resume, "resume core" }, +{ "step", do_step, "single-step core" }, +{ "reset", do_reset, "reset core" }, +{ "reset-stop", do_reset_stop, "reset core and halt" }, +{ "dw", do_dw, "dump words dw <addr> [ <count> ]" }, +{ "db", do_db, "dump bytes db <addr> [ <count> ]" }, +{ "rd", do_rd, "read word rd <addr>" }, +{ "dr", do_rd, NULL }, +{ "wr", do_wr, "write word wr <addr> <val>" }, +{ "regs", do_regs, "dump registers" }, +{ "help", do_help, "list commands" }, +{ "exit", do_exit, "exit debugger" }, +{ "quit", do_exit, NULL }, }; int do_help(DC* dc, CC* cc) { diff --git a/src/transport-dap.c b/src/transport-dap.c @@ -468,7 +468,7 @@ int dc_attach(DC* dc, unsigned flags, unsigned tgt, uint32_t* idcode) { uint32_t n; _dc_attach(dc, 0, 0, &n); - INFO("IDCODE %08x\n", n); + INFO("attach: IDCODE %08x\n", n); // If this is a RP2040, we need to connect in multidrop // mode before doing anything else. @@ -480,7 +480,7 @@ int dc_attach(DC* dc, unsigned flags, unsigned tgt, uint32_t* idcode) { } dc_dp_rd(dc, DP_CS, &n); - INFO("CTRL/STAT %08x\n", n); + DEBUG("attach: CTRL/STAT %08x\n", n); // clear all sticky errors dc_dp_wr(dc, DP_ABORT, DP_ABORT_ALLCLR); @@ -493,8 +493,8 @@ int dc_attach(DC* dc, unsigned flags, unsigned tgt, uint32_t* idcode) { dc_q_dp_rd(dc, DP_CS, &n); dc_q_ap_rd(dc, MAP_CSW, &dc->map_csw_keep); dc_q_exec(dc); - INFO("CTRL/STAT %08x\n", n); - INFO("MAP.CSW %08x\n", dc->map_csw_keep); + DEBUG("attach: CTRL/STAT %08x\n", n); + DEBUG("attach: MAP.CSW %08x\n", dc->map_csw_keep); dc->map_csw_keep &= MAP_CSW_KEEP; diff --git a/src/xdebug.c b/src/xdebug.c @@ -18,6 +18,8 @@ #define MAX_ARGS 16 +static int debug = 0; + static const char* NTH(unsigned n) { switch (n) { case 1: return "1st "; @@ -285,7 +287,11 @@ void MSG(uint32_t flags, const char* fmt, ...) { va_start(ap, fmt); switch (flags) { case mDEBUG: - tui_ch_printf(ch, "debug: "); + if (debug) { + tui_ch_printf(ch, "debug: "); + } else { + return; + } break; case mTRACE: tui_ch_printf(ch, "trace: ");