mdebug

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

commit d4e864786316d20aba890b7784c9a408d1ade6f4
parent fe8c772672f36a87bc12085c9c2cc898feb2e188
Author: Brian Swetland <swetland@frotz.net>
Date:   Mon,  3 Aug 2015 17:12:43 -0700

debugger: simplify "ui" output path

- all printing uses xprintf() now
- linenoise pause/resume handled only in xprintf
- xprintf takes a content type tag to allow fancier display

Diffstat:
Mtools/debugger-commands.c | 212++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mtools/debugger-core.c | 47+++++++++++++++++++----------------------------
Mtools/debugger.c | 4+++-
Mtools/debugger.h | 12++++++++++--
Mtools/gdb-bridge.c | 75++++++++++++++++++++++++++++++++-------------------------------------------
Mtools/lkdebug.c | 18+++++++++---------
Mtools/rswdp.c | 29+++++++++++++++++------------
7 files changed, 204 insertions(+), 193 deletions(-)

diff --git a/tools/debugger-commands.c b/tools/debugger-commands.c @@ -1,4 +1,4 @@ -/* debugger-commands.c +/* debugger-commands.); * * Copyright 2011 Brian Swetland <swetland@frotz.net> * @@ -69,7 +69,7 @@ int disassemble(u32 addr) { r = disassemble_thumb2(addr, mem.h[0], mem.h[1], text, 128); } if (r > 0) - xprintf("%s\n", text); + xprintf(XDATA, "%s\n", text); return r; #else return -1; @@ -91,16 +91,16 @@ int do_regs(int argc, param *argv) { if (swdp_core_read_all(lastregs)) return -1; - xprintf("r0 %08x r4 %08x r8 %08x ip %08x psr %08x\n", + xprintf(XDATA, "r0 %08x r4 %08x r8 %08x ip %08x psr %08x\n", lastregs[0], lastregs[4], lastregs[8], lastregs[12], lastregs[16]); - xprintf("r1 %08x r5 %08x r9 %08x sp %08x msp %08x\n", + xprintf(XDATA, "r1 %08x r5 %08x r9 %08x sp %08x msp %08x\n", lastregs[1], lastregs[5], lastregs[9], lastregs[13], lastregs[17]); - xprintf("r2 %08x r6 %08x 10 %08x lr %08x psp %08x\n", + xprintf(XDATA, "r2 %08x r6 %08x 10 %08x lr %08x psp %08x\n", lastregs[2], lastregs[6], lastregs[10], lastregs[14], lastregs[18]); - xprintf("r3 %08x r7 %08x 11 %08x pc %08x\n", + xprintf(XDATA, "r3 %08x r7 %08x 11 %08x pc %08x\n", lastregs[3], lastregs[7], lastregs[11], lastregs[15]); disassemble(lastregs[15]); @@ -125,13 +125,11 @@ int do_step(int argc, param *argv) { swdp_core_step(); swdp_core_wait_for_halt(); if (swdp_core_read(15, &pc)) { - xprintf("error\n"); + xprintf(XCORE, "step: error\n"); return -1; } - xprintf("."); fflush(stdout); } while (pc != argv[0].n); - xprintf("\n"); } else { swdp_core_step(); swdp_core_wait_for_halt(); @@ -189,12 +187,12 @@ int do_dr(int argc, param *argv) { for (n = 0; n < (sizeof(core_regmap) / sizeof(core_regmap[0])); n++) { if (!strcasecmp(argv[0].s, core_regmap[n].name)) { swdp_core_read(core_regmap[n].n, &x); - xprintf("%s: %08x\n", argv[0].s, x); + xprintf(XDATA, "%s: %08x\n", argv[0].s, x); return 0; } } swdp_ahb_read(argv[0].n, &x); - xprintf("%08x: %08x\n", argv[0].n, x); + xprintf(XDATA, "%08x: %08x\n", argv[0].n, x); return 0; } @@ -205,12 +203,12 @@ int do_wr(int argc, param *argv) { for (n = 0; n < (sizeof(core_regmap) / sizeof(core_regmap[0])); n++) { if (!strcasecmp(argv[0].s, core_regmap[n].name)) { swdp_core_write(core_regmap[n].n, argv[1].n); - xprintf("%s<<%08x\n", argv[0].s, argv[1].n); + xprintf(XDATA, "%s<<%08x\n", argv[0].s, argv[1].n); return 0; } } swdp_ahb_write(argv[0].n, argv[1].n); - xprintf("%08x<<%08x\n", argv[0].n, argv[1].n); + xprintf(XDATA, "%08x<<%08x\n", argv[0].n, argv[1].n); return 0; } @@ -222,7 +220,7 @@ int do_text(int argc, param *argv) { return -1; addr = argv[0].n; memset(data, 0, sizeof(data)); - + if (swdp_ahb_read32(addr, (void*) data, sizeof(data)/4)) return -1; @@ -234,7 +232,7 @@ int do_text(int argc, param *argv) { continue; *x = '.'; } - fprintf(stderr,"%s\n", (char*) data); + xprintf(XDATA, "%08x: %s\n", addr, (char*) data); return 0; } @@ -264,12 +262,30 @@ int do_dw(int argc, param *argv) { count /= 4; if (swdp_ahb_read32(addr, data, count)) return -1; - for (n = 0; n < count; n++) { - if ((n & 3) == 0) - xprintf("\n%08x:", addr + (n << 2)); - xprintf(" %08x", data[n]); + + for (n = 0; count > 0; n += 4, addr += 16) { + switch (count) { + case 1: + count = 0; + xprintf(XDATA, "%08x: %08x\n", addr, data[n]); + break; + case 2: + count = 0; + xprintf(XDATA, "%08x: %08x %08x\n", + addr, data[n], data[n+1]); + break; + case 3: + count = 0; + xprintf(XDATA, "%08x: %08x %08x %08x\n", + addr, data[n], data[n+1], data[n+2]); + break; + default: + count -= 4; + xprintf(XDATA, "%08x: %08x %08x %08x %08x\n", + addr, data[n], data[n+1], data[n+2], data[n+3]); + break; + } } - xprintf("\n"); return 0; } @@ -277,7 +293,8 @@ int do_dw(int argc, param *argv) { int do_db(int argc, param *argv) { u32 addr, count; u8 data[1024]; - unsigned n; + char line[256]; + unsigned n, m, xfer; if (argc < 2) return -1; @@ -289,7 +306,7 @@ int do_db(int argc, param *argv) { count = 1024; memset(data, 0xee, 1024); - + // todo: fix this swdp_ahb_write(AHB_CSW, AHB_CSW_MDEBUG | AHB_CSW_PRIV | AHB_CSW_DBG_EN | AHB_CSW_8BIT); for (n = 0; n < count; n++) { @@ -300,16 +317,17 @@ int do_db(int argc, param *argv) { } data[n] = tmp >> (8 * (n & 3)); } - swdp_ahb_write(AHB_CSW, AHB_CSW_MDEBUG | AHB_CSW_PRIV | AHB_CSW_DBG_EN | AHB_CSW_32BIT); - for (n = 0; n < count; n++) { - if ((n & 15) == 0) - xprintf("\n%08x:", addr + n); - xprintf(" %02x", data[n]); + for (n = 0; count > 0; count -= xfer) { + xfer = (count > 16) ? 16 : count; + char *p = line + sprintf(line, "%08x:", addr + n); + for (m = 0; m < xfer; m++) { + p += sprintf(p, " %02x", data[n++]); + } + xprintf(XDATA, "%s\n", line); } - xprintf("\n"); return 0; } @@ -317,7 +335,7 @@ int do_db(int argc, param *argv) { u32 vcflags = DEMCR_VC_HARDERR | DEMCR_VC_BUSERR | DEMCR_VC_STATERR | DEMCR_VC_CHKERR; int do_reset(int argc, param *argv) { - swdp_core_halt(); + swdp_core_halt(); swdp_ahb_write(DEMCR, DEMCR_TRCENA | vcflags); /* core reset and sys reset */ swdp_ahb_write(0xe000ed0c, 0x05fa0005); @@ -363,8 +381,7 @@ int do_watch_off(int argc, param *argv) { int do_print(int argc, param *argv) { while (argc-- > 0) - xprintf("%08x ", argv++[0].n); - xprintf("\n"); + xprintf(XCORE, "%08x\n", argv++[0].n); return 0; } @@ -374,12 +391,11 @@ int do_echo(int argc, param *argv) { const char *arg = argv++[0].s; if (arg[0] == '$') { - xprintf("%08x ", argn); + xprintf(XCORE, "%08x\n", argn); } else { - xprintf("%s ", arg, argn); + xprintf(XCORE, "%s\n", arg); } } - xprintf("\n"); return 0; } @@ -396,7 +412,7 @@ int do_setclock(int argc, param *argv) { int do_help(int argc, param *argv) { struct debugger_command *cmd; for (cmd = debugger_commands; cmd->func != NULL; cmd++) { - xprintf("%-16s: %s\n", cmd->name, cmd->help); + xprintf(XCORE, "%-16s: %s\n", cmd->name, cmd->help); } return 0; @@ -430,26 +446,26 @@ int do_download(int argc, param *argv) { long long t0, t1; if (argc != 2) { - xprintf("error: usage: download <file> <addr>\n"); + xprintf(XCORE, "error: usage: download <file> <addr>\n"); return -1; } if ((data = load_file(argv[0].s, &sz)) == NULL) { - xprintf("error: cannot read '%s'\n", argv[0].s); + xprintf(XCORE, "error: cannot read '%s'\n", argv[0].s); return -1; } sz = (sz + 3) & ~3; addr = argv[1].n; - xprintf("sending %d bytes...\n", sz); + xprintf(XCORE, "sending %d bytes...\n", sz); t0 = now(); if (swdp_ahb_write32(addr, (void*) data, sz / 4)) { - xprintf("error: failed to write data\n"); + xprintf(XCORE, "error: failed to write data\n"); free(data); return -1; } t1 = now(); - xprintf("%lld uS -> %lld B/s\n", (t1 - t0), + xprintf(XCORE, "%lld uS -> %lld B/s\n", (t1 - t0), (((long long)sz) * 1000000LL) / (t1 - t0)); free(data); return 0; @@ -461,18 +477,18 @@ int do_run(int argc, param *argv) { size_t sz; u32 sp, pc; if (argc != 2) { - xprintf("error: usage: run <file> <addr>\n"); + xprintf(XCORE, "error: usage: run <file> <addr>\n"); return -1; } if ((data = load_file(argv[0].s, &sz)) == NULL) { - xprintf("error: cannot read '%s'\n", argv[0].s); + xprintf(XCORE, "error: cannot read '%s'\n", argv[0].s); return -1; } swdp_core_halt(); sz = (sz + 3) & ~3; addr = argv[1].n; if (swdp_ahb_write32(addr, (void*) data, sz / 4)) { - xprintf("error: failed to write data\n"); + xprintf(XCORE, "error: failed to write data\n"); free(data); return -1; } @@ -536,7 +552,7 @@ int invoke(u32 agent, u32 func, u32 r0, u32 r1, u32 r2, u32 r3) { // todo: readback and verify? - xprintf("invoke <func@%08x>(0x%x,0x%x,0x%x,0x%x)\n", func, r0, r1, r2, r3); + xprintf(XCORE, "invoke <func@%08x>(0x%x,0x%x,0x%x,0x%x)\n", func, r0, r1, r2, r3); swdp_core_resume(); if (swdp_core_wait_for_halt() == 0) { @@ -545,13 +561,13 @@ int invoke(u32 agent, u32 func, u32 r0, u32 r1, u32 r2, u32 r3) { swdp_core_read(0, &res); swdp_core_read(15, &pc); if (pc != agent) { - xprintf("error: pc (%08x) is not at %08x\n", pc, agent); + xprintf(XCORE, "error: pc (%08x) is not at %08x\n", pc, agent); return -1; } - if (res) xprintf("failure code %08x\n", res); + if (res) xprintf(XCORE, "failure code %08x\n", res); return res; } - xprintf("interrupted\n"); + xprintf(XCORE, "interrupted\n"); return -1; } @@ -560,29 +576,29 @@ int run_flash_agent(u32 flashaddr, void *data, size_t data_sz) { size_t agent_sz; if ((agent = load_agent(agent_arch, &agent_sz)) == NULL) { - xprintf("error: cannot load flash agent for architecture '%s'\n", + xprintf(XCORE, "error: cannot load flash agent for architecture '%s'\n", agent_arch ? agent_arch : "unknown"); - xprintf("error: set architecture with: arch <name>\n"); + xprintf(XCORE, "error: set architecture with: arch <name>\n"); goto fail; } // sanity check if ((agent_sz < sizeof(flash_agent)) || (agent->magic != AGENT_MAGIC) || (agent->version != AGENT_VERSION)) { - xprintf("error: invalid agent image\n"); + xprintf(XCORE, "error: invalid agent image\n"); goto fail; } // replace magic with bkpt instructions agent->magic = 0xbe00be00; if (do_attach(0,0)) { - xprintf("error: failed to attach\n"); + xprintf(XCORE, "error: failed to attach\n"); goto fail; } do_reset_stop(0,0); if (agent->flags & FLAG_BOOT_ROM_HACK) { - xprintf("executing boot rom\n"); + xprintf(XCORE, "executing boot rom\n"); if (swdp_watchpoint_rw(0, 0)) { goto fail; } @@ -594,7 +610,7 @@ int run_flash_agent(u32 flashaddr, void *data, size_t data_sz) { } if (swdp_ahb_write32(agent->load_addr, (void*) agent, agent_sz / 4)) { - xprintf("error: failed to download agent\n"); + xprintf(XCORE, "error: failed to download agent\n"); goto fail; } if (invoke(agent->load_addr, agent->setup, 0, 0, 0, 0)) { @@ -603,7 +619,7 @@ int run_flash_agent(u32 flashaddr, void *data, size_t data_sz) { if (swdp_ahb_read32(agent->load_addr + 16, (void*) &agent->data_addr, 4)) { goto fail; } - xprintf("agent %d @%08x, buffer %dK @%08x, flash %dK @%08x\n", + xprintf(XCORE, "agent %d @%08x, buffer %dK @%08x, flash %dK @%08x\n", agent_sz, agent->load_addr, agent->data_size / 1024, agent->data_addr, agent->flash_size / 1024, agent->flash_addr); @@ -617,23 +633,23 @@ int run_flash_agent(u32 flashaddr, void *data, size_t data_sz) { if ((flashaddr < agent->flash_addr) || (data_sz > agent->flash_size) || ((flashaddr + data_sz) > (agent->flash_addr + agent->flash_size))) { - xprintf("invalid flash address %08x\n", flashaddr); + xprintf(XCORE, "invalid flash address %08x\n", flashaddr); goto fail; } if (data == NULL) { // erase if (invoke(agent->load_addr, agent->erase, flashaddr, data_sz, 0, 0)) { - xprintf("failed to erase %d bytes at %08x\n", data_sz, flashaddr); + xprintf(XCORE, "failed to erase %d bytes at %08x\n", data_sz, flashaddr); goto fail; } } else { // write u8 *ptr = (void*) data; u32 xfer; - xprintf("flashing %d bytes at %08x...\n", data_sz, flashaddr); + xprintf(XCORE, "flashing %d bytes at %08x...\n", data_sz, flashaddr); if (invoke(agent->load_addr, agent->erase, flashaddr, data_sz, 0, 0)) { - xprintf("failed to erase %d bytes at %08x\n", data_sz, flashaddr); + xprintf(XCORE, "failed to erase %d bytes at %08x\n", data_sz, flashaddr); goto fail; } while (data_sz > 0) { @@ -643,12 +659,12 @@ int run_flash_agent(u32 flashaddr, void *data, size_t data_sz) { xfer = data_sz; } if (swdp_ahb_write32(agent->data_addr, (void*) ptr, xfer / 4)) { - xprintf("download to %08x failed\n", agent->data_addr); + xprintf(XCORE, "download to %08x failed\n", agent->data_addr); goto fail; } if (invoke(agent->load_addr, agent->write, flashaddr, agent->data_addr, xfer, 0)) { - xprintf("failed to flash %d bytes to %08x\n", xfer, flashaddr); + xprintf(XCORE, "failed to flash %d bytes to %08x\n", xfer, flashaddr); goto fail; } ptr += xfer; @@ -670,11 +686,11 @@ int do_flash(int argc, param *argv) { void *data = NULL; size_t data_sz; if (argc != 2) { - xprintf("error: usage: flash <file> <addr>\n"); + xprintf(XCORE, "error: usage: flash <file> <addr>\n"); return -1; } if ((data = load_file(argv[0].s, &data_sz)) == NULL) { - xprintf("error: cannot load '%s'\n", argv[0].s); + xprintf(XCORE, "error: cannot load '%s'\n", argv[0].s); return -1; } // word align @@ -687,7 +703,7 @@ int do_erase(int argc, param *argv) { return run_flash_agent(0, NULL, 0xFFFFFFFF); } if (argc != 2) { - xprintf("error: usage: erase <addr> <length> | erase all\n"); + xprintf(XCORE, "error: usage: erase <addr> <length> | erase all\n"); return -1; } return run_flash_agent(argv[0].n, NULL, argv[1].n); @@ -701,7 +717,7 @@ int do_log(int argc, param *argv) { } else if (!strcmp(argv[0].s, "swd")) { flags |= LF_SWD; } else { - xprintf("error: allowed flags: gdb swd\n"); + xprintf(XCORE, "error: allowed flags: gdb swd\n"); return -1; } argc--; @@ -719,35 +735,35 @@ int do_finfo(int argc, param *argv) { swdp_ahb_read(MMFAR, &mmfar); swdp_ahb_read(BFAR, &bfar); - xprintf("CFSR %08x MMFAR %08x\n", cfsr, mmfar); - xprintf("HFSR %08x BFAR %08x\n", hfsr, bfar); - xprintf("DFSR %08x\n", dfsr); - - if (cfsr & CFSR_IACCVIOL) xprintf(">MM: Inst Access Violation\n"); - if (cfsr & CFSR_DACCVIOL) xprintf(">MM: Data Access Violation\n"); - if (cfsr & CFSR_MUNSTKERR) xprintf(">MM: Derived MM Fault on Exception Return\n"); - if (cfsr & CFSR_MSTKERR) xprintf(">MM: Derived MM Fault on Exception Entry\n"); - if (cfsr & CFSR_MLSPERR) xprintf(">MM: MM Fault During Lazy FP Save\n"); - if (cfsr & CFSR_MMARVALID) xprintf(">MM: MMFAR has valid contents\n"); - - if (cfsr & CFSR_IBUSERR) xprintf(">BF: Bus Fault on Instruction Prefetch\n"); - if (cfsr & CFSR_PRECISERR) xprintf(">BF: Precise Data Access Error, Addr in BFAR\n"); - if (cfsr & CFSR_IMPRECISERR) xprintf(">BF: Imprecise Data Access Error\n"); - if (cfsr & CFSR_UNSTKERR) xprintf(">BF: Derived Bus Fault on Exception Return\n"); - if (cfsr & CFSR_STKERR) xprintf(">BF: Derived Bus Fault on Exception Entry\n"); - if (cfsr & CFSR_LSPERR) xprintf(">BF: Bus Fault During Lazy FP Save\n"); - if (cfsr & CFSR_BFARVALID) xprintf(">BF: BFAR has valid contents\n"); - - if (cfsr & CFSR_UNDEFINSTR) xprintf(">UF: Undefined Instruction Usage Fault\n"); - if (cfsr & CFSR_INVSTATE) xprintf(">UF: EPSR.T or ESPR.IT invalid\n"); - if (cfsr & CFSR_INVPC) xprintf(">UF: Integrity Check Error on EXC_RETURN\n"); - if (cfsr & CFSR_NOCP) xprintf(">UF: Coprocessor Error\n"); - if (cfsr & CFSR_UNALIGNED) xprintf(">UF: Unaligned Access Error\n"); - if (cfsr & CFSR_DIVBYZERO) xprintf(">UF: Divide by Zero\n"); - - if (hfsr & HFSR_VECTTBL) xprintf(">HF: Vector Table Read Fault\n"); - if (hfsr & HFSR_FORCED) xprintf(">HF: Exception Escalated to Hard Fault\n"); - if (hfsr & HFSR_DEBUGEVT) xprintf(">HF: Debug Event\n"); + xprintf(XDATA, "CFSR %08x MMFAR %08x\n", cfsr, mmfar); + xprintf(XDATA, "HFSR %08x BFAR %08x\n", hfsr, bfar); + xprintf(XDATA, "DFSR %08x\n", dfsr); + + if (cfsr & CFSR_IACCVIOL) xprintf(XDATA, ">MM: Inst Access Violation\n"); + if (cfsr & CFSR_DACCVIOL) xprintf(XDATA, ">MM: Data Access Violation\n"); + if (cfsr & CFSR_MUNSTKERR) xprintf(XDATA, ">MM: Derived MM Fault on Exception Return\n"); + if (cfsr & CFSR_MSTKERR) xprintf(XDATA, ">MM: Derived MM Fault on Exception Entry\n"); + if (cfsr & CFSR_MLSPERR) xprintf(XDATA, ">MM: MM Fault During Lazy FP Save\n"); + if (cfsr & CFSR_MMARVALID) xprintf(XDATA, ">MM: MMFAR has valid contents\n"); + + if (cfsr & CFSR_IBUSERR) xprintf(XDATA, ">BF: Bus Fault on Instruction Prefetch\n"); + if (cfsr & CFSR_PRECISERR) xprintf(XDATA, ">BF: Precise Data Access Error, Addr in BFAR\n"); + if (cfsr & CFSR_IMPRECISERR) xprintf(XDATA, ">BF: Imprecise Data Access Error\n"); + if (cfsr & CFSR_UNSTKERR) xprintf(XDATA, ">BF: Derived Bus Fault on Exception Return\n"); + if (cfsr & CFSR_STKERR) xprintf(XDATA, ">BF: Derived Bus Fault on Exception Entry\n"); + if (cfsr & CFSR_LSPERR) xprintf(XDATA, ">BF: Bus Fault During Lazy FP Save\n"); + if (cfsr & CFSR_BFARVALID) xprintf(XDATA, ">BF: BFAR has valid contents\n"); + + if (cfsr & CFSR_UNDEFINSTR) xprintf(XDATA, ">UF: Undefined Instruction Usage Fault\n"); + if (cfsr & CFSR_INVSTATE) xprintf(XDATA, ">UF: EPSR.T or ESPR.IT invalid\n"); + if (cfsr & CFSR_INVPC) xprintf(XDATA, ">UF: Integrity Check Error on EXC_RETURN\n"); + if (cfsr & CFSR_NOCP) xprintf(XDATA, ">UF: Coprocessor Error\n"); + if (cfsr & CFSR_UNALIGNED) xprintf(XDATA, ">UF: Unaligned Access Error\n"); + if (cfsr & CFSR_DIVBYZERO) xprintf(XDATA, ">UF: Divide by Zero\n"); + + if (hfsr & HFSR_VECTTBL) xprintf(XDATA, ">HF: Vector Table Read Fault\n"); + if (hfsr & HFSR_FORCED) xprintf(XDATA, ">HF: Exception Escalated to Hard Fault\n"); + if (hfsr & HFSR_DEBUGEVT) xprintf(XDATA, ">HF: Debug Event\n"); // clear sticky fault bits swdp_ahb_write(CFSR, CFSR_ALL); @@ -759,18 +775,18 @@ extern int swdp_step_no_ints; int do_maskints(int argc, param *argv) { if (argc != 1) { - xprintf("usage: maskints [on|off|always]\n"); + xprintf(XCORE, "usage: maskints [on|off|always]\n"); return -1; } if (!strcmp(argv[0].s, "on")) { swdp_step_no_ints = 1; - xprintf("maskints: while stepping\n"); + xprintf(XCORE, "maskints: while stepping\n"); } else if (!strcmp(argv[0].s, "always")) { swdp_step_no_ints = 2; - xprintf("maskints: always\n"); + xprintf(XCORE, "maskints: always\n"); } else { swdp_step_no_ints = 0; - xprintf("maskints: never\n"); + xprintf(XCORE, "maskints: never\n"); } return 0; } @@ -778,7 +794,7 @@ int do_maskints(int argc, param *argv) { int do_threads(int argc, param *argv) { if (argc == 1) { if (strcmp(argv[0].s, "clear")) { - xprintf("usage: threads [clear]\n"); + xprintf(XCORE, "usage: threads [clear]\n"); return -1; } swdp_core_halt(); diff --git a/tools/debugger-core.c b/tools/debugger-core.c @@ -1,7 +1,7 @@ /* debugger-core.c * * Copyright 2011 Brian Swetland <swetland@frotz.net> - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -30,7 +30,6 @@ #include <protocol/rswdp.h> #include "debugger.h" #include "rswdp.h" -#include "linenoise.h" #define DHCSR_C_DEBUGEN (1 << 0) #define DHCSR_C_HALT (1 << 1) @@ -53,9 +52,7 @@ #define DFSR_MASK 0x1F static void m_event(const char *evt) { - linenoisePause(); - fprintf(stdout, "DEBUG EVENT: %s\n", evt); - linenoiseResume(); + xprintf(XCORE, "DEBUG EVENT: %s\n", evt); } static void monitor(void) { @@ -81,9 +78,7 @@ void debugger_lock() { if (swdp_clear_error()) { #if 0 // way too noisy if the link goes down - linenoisePause(); xprintf("SWD ERROR persists. Attempting link reset.\n"); - linenoiseResume(); #endif swdp_reset(); } @@ -91,9 +86,7 @@ void debugger_lock() { void debugger_unlock() { if (swdp_error()) { - linenoisePause(); - xprintf("SWD ERROR\n"); - linenoiseResume(); + xprintf(XCORE, "SWD ERROR\n"); } pthread_mutex_unlock(&_dbg_lock); } @@ -114,7 +107,7 @@ static pthread_t _listen_master; void *gdb_listener(void *arg) { int fd; if ((fd = socket_listen_tcp(5555)) < 0) { - fprintf(stderr, "gdb_listener() cannot bind to 5555\n"); + xprintf(XGDB, "gdb_listener() cannot bind to 5555\n"); return NULL; } for (;;) { @@ -185,7 +178,7 @@ static int do_script(int argc, param *argv) { fp = stdin; } else { if (!(fp = fopen(argv[0].s, "r"))) { - xprintf("error: cannot open '%s'\n", argv[0].s); + xprintf(XCORE, "error: cannot open '%s'\n", argv[0].s); return -1; } } @@ -200,7 +193,7 @@ static int do_script(int argc, param *argv) { char *name, *x; name = line + 9; if (newfunc) { - xprintf("error: nested functions not allowed\n"); + xprintf(XCORE, "error: nested functions not allowed\n"); break; } while (isspace(*name)) @@ -210,12 +203,12 @@ static int do_script(int argc, param *argv) { x++; *x = 0; if (*name == 0) { - xprintf("error: functions must have names\n"); + xprintf(XCORE, "error: functions must have names\n"); break; } newfunc = malloc(sizeof(*newfunc) + strlen(name) + 1); if (newfunc == 0) { - xprintf("error: out of memory\n"); + xprintf(XCORE, "error: out of memory\n"); break; } strcpy(newfunc->name, name); @@ -234,7 +227,7 @@ static int do_script(int argc, param *argv) { } fl = malloc(sizeof(*fl) + strlen(line) + 1); if (fl == 0) { - xprintf("out of memory"); + xprintf(XCORE, "out of memory"); newfunc = 0; if (fp != stdin) fclose(fp); @@ -249,7 +242,7 @@ static int do_script(int argc, param *argv) { } lastline = fl; } else { - xprintf("script> %s", line); + xprintf(XCORE, "script> %s", line); if (debugger_command(line)) return -1; } @@ -265,18 +258,18 @@ static int do_script(int argc, param *argv) { static int do_set(int argc, param *argv) { const char *name; if ((argc != 2) && (argc != 4)) { - xprintf("error: set requires two or four arguments\n"); + xprintf(XCORE, "error: set requires two or four arguments\n"); return -1; } name = argv[0].s; if (*name == '$') name++; if (*name == 0) { - xprintf("error: empty name?!\n"); + xprintf(XCORE, "error: empty name?!\n"); return -1; } if (!isalpha(*name)) { - xprintf("error: variable name must begin with a letter\n"); + xprintf(XCORE, "error: variable name must begin with a letter\n"); return -1; } @@ -303,7 +296,7 @@ static int do_set(int argc, param *argv) { n = a / b; } } else { - xprintf("error: set <var> <a> <op> <b> requires op: + - * / << >>\n"); + xprintf(XCORE, "error: set <var> <a> <op> <b> requires op: + - * / << >>\n"); return -1; } variable_set(name, n); @@ -352,14 +345,14 @@ static int parse_number(const char *in, unsigned *out) { return 0; } } - xprintf("no local variable %s\n", text); + xprintf(XCORE, "no local variable %s\n", text); *out = 0; return 0; } if (variable_get(text + 1, &value) == 0) { *out = value; } else { - xprintf("undefined variable '%s'\n", text + 1); + xprintf(XCORE, "undefined variable '%s'\n", text + 1); *out = 0; } return 0; @@ -397,7 +390,7 @@ static int exec_function(struct funcinfo *f, int argc, param *argv) { strcpy(text, line->text); r = debugger_command(text); if (r) { - xprintf("error: %s: line %d\n", f->name, n); + xprintf(XCORE, "error: %s: line %d\n", f->name, n); goto done; } } @@ -422,9 +415,7 @@ static int _debugger_exec(const char *cmd, unsigned argc, param *argv) { if (!strcasecmp(cmd, c->name)) { int n; debugger_lock(); - linenoisePause(); n = c->func(argc, argv); - linenoiseResume(); debugger_unlock(); return n; } @@ -485,14 +476,14 @@ int debugger_command(char *line) { for (c = 0; c < n; c++) { if (parse_number(arg[c].s, &(arg[c].n))) { - xprintf("error: bad number: %s\n", arg[c].s); + xprintf(XCORE, "error: bad number: %s\n", arg[c].s); return -1; } } r = _debugger_exec(arg[0].s, n - 1, arg + 1); if (r == ERROR_UNKNOWN) { - xprintf("unknown command: %s\n", arg[0].s); + xprintf(XCORE, "unknown command: %s\n", arg[0].s); } return r; } diff --git a/tools/debugger.c b/tools/debugger.c @@ -38,13 +38,15 @@ static const char *scriptfile = NULL; void gdb_console_puts(const char *msg); -void xprintf(const char *fmt, ...) { +void xprintf(xpchan ch, const char *fmt, ...) { char line[256]; va_list ap; va_start(ap, fmt); vsnprintf(line, 256, fmt, ap); va_end(ap); + linenoisePause(); if (write(1, line, strlen(line)) < 0) ; + linenoiseResume(); gdb_console_puts(line); } diff --git a/tools/debugger.h b/tools/debugger.h @@ -1,7 +1,7 @@ /* debugger.h * * Copyright 2011 Brian Swetland <swetland@frotz.net> - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -18,8 +18,16 @@ #ifndef _DEBUGGER_H_ #define _DEBUGGER_H_ +typedef enum { + XDEFAULT, + XSWD, // SWD transport & engine + XCORE, // debugger core + XDATA, // debugger command response + XGDB, // messages from GDB bridge +} xpchan; + #define printf __use_xprintf_in_debugger__ -extern void xprintf(const char *fmt, ...); +extern void xprintf(xpchan ch, const char *fmt, ...); #define ERROR -1 #define ERROR_UNKNOWN -2 diff --git a/tools/gdb-bridge.c b/tools/gdb-bridge.c @@ -1,7 +1,7 @@ /* gdb-bridge.c * * Copyright 2011 Brian Swetland <swetland@frotz.net> - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -28,7 +28,6 @@ #include "rswdp.h" #include <protocol/rswdp.h> #include "debugger.h" -#include "linenoise.h" #include "lkdebug.h" // useful gdb stuff @@ -54,7 +53,7 @@ struct gdbcnxn { unsigned txsum; unsigned rxsum; unsigned flags; - unsigned char *txptr; + unsigned char *txptr; unsigned char *rxptr; unsigned char rxbuf[MAXPKT]; unsigned char txbuf[MAXPKT]; @@ -64,15 +63,6 @@ struct gdbcnxn { lkthread_t *cselected; }; -void zprintf(const char *fmt, ...) { - linenoisePause(); - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - linenoiseResume(); -} - void gdb_init(struct gdbcnxn *gc, int fd) { gc->fd = fd; gc->state = S_IDLE; @@ -121,7 +111,7 @@ void gdb_epilogue(struct gdbcnxn *gc) { gdb_puts(gc, tmp); if (tx_full(gc)) { - zprintf("GDB: TX Packet Too Large\n"); + xprintf(XGDB, "gdb: TX Packet Too Large\n"); return; } @@ -131,7 +121,7 @@ void gdb_epilogue(struct gdbcnxn *gc) { r = write(gc->fd, ptr, len); if (r <= 0) { if (errno == EINTR) continue; - zprintf("GDB: TX Write Error\n"); + xprintf(XGDB, "gdb: TX Write Error\n"); return; } ptr += r; @@ -153,7 +143,7 @@ void handle_command(struct gdbcnxn *gc, unsigned char *cmd); void gdb_recv_cmd(struct gdbcnxn *gc) { if (log_flags & LF_GDB) { - zprintf("PKT: %s\n", gc->rxbuf); + xprintf(XGDB, "gdb: pkt: %s\n", gc->rxbuf); } debugger_lock(); handle_command(gc, gc->rxbuf); @@ -184,7 +174,7 @@ int gdb_recv(struct gdbcnxn *gc, unsigned char *ptr, int len) { gc->state = S_CHK1; } else { if (rx_full(gc)) { - zprintf("PKT: Too Large, Discarding."); + xprintf(XGDB, "gdb: pkt: Too Large, Discarding."); gc->rxptr = gc->rxbuf; gc->state = S_IDLE; } else { @@ -315,7 +305,7 @@ static void handle_query(struct gdbcnxn *gc, char *cmd, char *args) { p+=2; } *cmd = 0; - zprintf("GDB: %s\n", args); + xprintf(XGDB, "gdb: %s\n", args); gc->flags |= F_CONSOLE; debugger_unlock(); debugger_command(args); @@ -340,7 +330,7 @@ static void handle_query(struct gdbcnxn *gc, char *cmd, char *args) { } else if(!strcmp(cmd, "Attached")) { /* no process management. ignore */ } else { - zprintf("GDB: unsupported: q%s:%s\n", cmd, args); + xprintf(XGDB, "gdb: unsupported: q%s:%s\n", cmd, args); } } @@ -349,7 +339,7 @@ static void handle_set(struct gdbcnxn *gc, char *cmd, char *args) { gc->flags &= ~F_ACK; gdb_puts(gc, "OK"); } else { - zprintf("GDB: unsupported: Q%s:%s\n", cmd, args); + xprintf(XGDB, "gdb: unsupported: Q%s:%s\n", cmd, args); } } @@ -406,13 +396,13 @@ void write_memory(u32 addr, unsigned char *data, int len) { #define FP_REMAP 0xE0002004 #define FP_COMP(n) (0xE0002008 + ((n) * 4)) -#define MAXFP 16 +#define MAXFP 16 static u32 maxfp = 0; static u32 fp_addr[MAXFP] = { 0, }; static u32 fp_state[MAXFP] = { 0, }; #define MAXBP 16 -static u32 maxbp; +static u32 maxbp; static u32 bp_addr[MAXBP] = { 0, }; static u32 bp_state[MAXBP] = { 0, }; @@ -420,12 +410,12 @@ int handle_flashpatch(int add, u32 addr, u32 kind) { u32 x; int n; if (swdp_ahb_read(ROMTAB_FPB, &x)) { - zprintf("GDB: cannot read romtable\n"); + xprintf(XGDB, "gdb: cannot read romtable\n"); return -1; } if (x & 1) { if (swdp_ahb_read(FP_CTRL, &x)) { - zprintf("GDB: cannot read flashpatch ctrl\n"); + xprintf(XGDB, "gdb: cannot read flashpatch ctrl\n"); return -1; } n = ((x & 0xF0) >> 4) | ((x & 0x7000) >> 4); @@ -433,10 +423,10 @@ int handle_flashpatch(int add, u32 addr, u32 kind) { n = 0; } if (n != maxfp) { - zprintf("GDB: %d flashpatch breakpoint registers\n", n); + xprintf(XGDB, "gdb: %d flashpatch breakpoint registers\n", n); if (n > 16) n = 16; if (maxfp != 0) { - zprintf("GDB: previously %d registers...\n", maxfp); + xprintf(XGDB, "gdb: previously %d registers...\n", maxfp); } maxfp = n; } @@ -447,7 +437,7 @@ int handle_flashpatch(int add, u32 addr, u32 kind) { } else { fp_state[n] = 0; swdp_ahb_write(FP_COMP(n), 0); - zprintf("GDB: - FP BP @ %08x\n", addr); + xprintf(XGDB, "gdb: - FP BP @ %08x\n", addr); return 0; } } @@ -474,7 +464,7 @@ add1: fp_state[n] = 1; fp_addr[n] = addr; add0: - zprintf("GDB: + FP BP @ %08x\n", addr); + xprintf(XGDB, "gdb: + FP BP @ %08x\n", addr); return 0; } @@ -486,12 +476,12 @@ int handle_breakpoint(int add, u32 addr, u32 kind) { return 0; } if (swdp_ahb_read(ROMTAB_DWT, &x)) { - zprintf("GDB: cannot read romtable\n"); + xprintf(XGDB, "gdb: cannot read romtable\n"); return -1; } if (x & 1) { if (swdp_ahb_read(DWT_CTRL, &x)) { - zprintf("GDB: cannot read dwt ctrl\n"); + xprintf(XGDB, "gdb: cannot read dwt ctrl\n"); return -1; } n = x >> 28; @@ -499,9 +489,9 @@ int handle_breakpoint(int add, u32 addr, u32 kind) { n = 0; } if (n != maxbp) { - zprintf("GDB: %d dwt breakpoint registers\n", n); + xprintf(XGDB, "gdb: %d dwt breakpoint registers\n", n); if (maxbp != 0) { - zprintf("GDB: previously %d registers...\n", maxbp); + xprintf(XGDB, "gdb: previously %d registers...\n", maxbp); } maxbp = n; } @@ -518,12 +508,12 @@ int handle_breakpoint(int add, u32 addr, u32 kind) { bp_addr[n] = addr; bp_state[n] = 1; swdp_watchpoint_pc(n, addr); - zprintf("GDB: + HW BP @ %08x\n", addr); + xprintf(XGDB, "gdb: + HW BP @ %08x\n", addr); return 0; } } if (n == maxbp) { - zprintf("GDB: Out of hardware breakpoints.\n"); + xprintf(XGDB, "gdb: Out of hardware breakpoints.\n"); return 1; } return 0; @@ -535,17 +525,17 @@ int handle_breakpoint(int add, u32 addr, u32 kind) { break; } } - zprintf("GDB: - HW BP @ %08x\n", addr); + xprintf(XGDB, "gdb: - HW BP @ %08x\n", addr); return 0; } } void gdb_update_threads(struct gdbcnxn *gc) { - zprintf("GDB: sync threadlist\n"); + xprintf(XGDB, "gdb: sync threadlist\n"); free_lk_threads(gc->threadlist); if (gc->flags & F_LK_THREADS) { if ((gc->threadlist = find_lk_threads(0)) == NULL) { - zprintf("GDB: problem syncing threadlist\n"); + xprintf(XGDB, "gdb: problem syncing threadlist\n"); } gc->cselected = gc->threadlist; gc->gselected = gc->threadlist; @@ -609,7 +599,7 @@ void handle_command(struct gdbcnxn *gc, unsigned char *cmd) { } else if (cmd[1] == 'c') { gc->cselected = t; } else { - zprintf("GDB: selecting '%c' thread?!\n", cmd[1]); + xprintf(XGDB, "gdb: selecting '%c' thread?!\n", cmd[1]); } gdb_puts(gc, "OK"); break; @@ -669,7 +659,7 @@ void handle_command(struct gdbcnxn *gc, unsigned char *cmd) { // write registers 0... case 'G': { if (gc->gselected && !gc->gselected->active) { - zprintf("GDB: attempting to write to inactive registers\n"); + xprintf(XGDB, "gdb: attempting to write to inactive registers\n"); break; } int len = hextobin(gc->rxbuf, (char*) cmd + 1, MAXPKT); @@ -703,7 +693,7 @@ void handle_command(struct gdbcnxn *gc, unsigned char *cmd) { int len; char *data = strchr((char*) cmd + 1, '='); if (gc->gselected && !gc->gselected->active) { - zprintf("GDB: attempting to write to inactive registers\n"); + xprintf(XGDB, "gdb: attempting to write to inactive registers\n"); break; } if (data) { @@ -741,7 +731,6 @@ void handle_command(struct gdbcnxn *gc, unsigned char *cmd) { handle_set(gc, (char*) (cmd + 1), args); } break; - } case 'z': case 'Z': { @@ -760,7 +749,7 @@ void handle_command(struct gdbcnxn *gc, unsigned char *cmd) { break; } default: - zprintf("GDB: unknown command: %c\n", cmd[0]); + xprintf(XGDB, "gdb: unknown command: %c\n", cmd[0]); } gdb_epilogue(gc); } @@ -799,7 +788,7 @@ void gdb_server(int fd) { if (pipefds[0] == -1) { if (pipe(pipefds)) ; } - zprintf("[ gdb connected ]\n"); + xprintf(XGDB,"[ gdb connected ]\n"); debugger_unlock(); gc.flags |= F_LK_THREADS; @@ -862,6 +851,6 @@ void gdb_server(int fd) { debugger_lock(); active_gc = NULL; - zprintf("[ gdb connected ]\n"); + xprintf(XGDB, "[ gdb connected ]\n"); debugger_unlock(); } diff --git a/tools/lkdebug.c b/tools/lkdebug.c @@ -57,15 +57,15 @@ static char *lkstate[] = { }; void dump_lk_thread(lkthread_t *t) { - xprintf("thread: @%08x sp=%08x wq=%08x st=%d name='%s'\n", + xprintf(XDATA, "thread: @%08x sp=%08x wq=%08x st=%d name='%s'\n", t->threadptr, t->saved_sp, t->waitq, t->state, t->name); - xprintf(" r0 %08x r4 %08x r8 %08x ip %08x\n", + xprintf(XDATA, " r0 %08x r4 %08x r8 %08x ip %08x\n", t->regs[0], t->regs[4], t->regs[8], t->regs[12]); - xprintf(" r1 %08x r5 %08x r9 %08x sp %08x\n", + xprintf(XDATA, " r1 %08x r5 %08x r9 %08x sp %08x\n", t->regs[1], t->regs[5], t->regs[9], t->regs[13]); - xprintf(" r2 %08x r6 %08x 10 %08x lr %08x\n", + xprintf(XDATA, " r2 %08x r6 %08x 10 %08x lr %08x\n", t->regs[2], t->regs[6], t->regs[10], t->regs[14]); - xprintf(" r3 %08x r7 %08x 11 %08x pc %08x\n", + xprintf(XDATA, " r3 %08x r7 %08x 11 %08x pc %08x\n", t->regs[3], t->regs[7], t->regs[11], t->regs[15]); } @@ -148,21 +148,21 @@ static int load_debuginfo(lkdebuginfo_t *di, int verbose) { if (swdp_ahb_read(0xE000ED08, &vtbl)) vtbl = 0; if (swdp_ahb_read((DI_OFF_MAGIC + vtbl), &x)) return -1; if (x != DI_MAGIC) { - if (verbose) xprintf("debuginfo: bad magic\n"); + if (verbose) xprintf(XCORE, "debuginfo: bad magic\n"); return -1; } if (swdp_ahb_read((DI_OFF_PTR + vtbl), &x)) return -1; if (x & 3) return -1; - if (verbose) xprintf("debuginfo @ %08x\n", x); + if (verbose) xprintf(XCORE, "debuginfo @ %08x\n", x); if (swdp_ahb_read32(x, (void*) di, sizeof(lkdebuginfo_t) / 4)) return -1; if (verbose) { - xprintf("di %08x %08x %08x %d %d %d %d %d %d\n", + xprintf(XDATA, "di %08x %08x %08x %d %d %d %d %d %d\n", di->version, di->thread_list_ptr, di->current_thread_ptr, di->off_list_node, di->off_state, di->off_saved_sp, di->off_was_preempted, di->off_name, di->off_waitq); } if (di->version != 0x0100) { - if (verbose) xprintf("debuginfo: unsupported version\n"); + if (verbose) xprintf(XCORE, "debuginfo: unsupported version\n"); return -1; } return 0; diff --git a/tools/rswdp.c b/tools/rswdp.c @@ -29,6 +29,8 @@ #include "rswdp.h" #include "arm-v7m.h" +#include <debugger.h> + static volatile int ATTN; void swdp_interrupt(void) { @@ -101,7 +103,7 @@ static void process_async(u32 *data, unsigned count) { return; tmp = data[n]; data[n] = 0; - printf("%s",(char*) data); + xprintf(XSWD, "%s",(char*) data); data[n] = tmp; data += n; count -= n; @@ -129,7 +131,7 @@ static int process_reply(struct txn *t, u32 *data, int count) { continue; case CMD_SWD_DATA: if (n > rxc) { - fprintf(stderr,"reply overrun (%d > %d)\n", n, rxc); + xprintf(XSWD, "reply overrun (%d > %d)\n", n, rxc); return -1; } while (n-- > 0) { @@ -146,7 +148,7 @@ static int process_reply(struct txn *t, u32 *data, int count) { return 0; } default: - fprintf(stderr,"unknown command 0x%02x\n", RSWD_MSG_CMD(msg)); + xprintf(XSWD,"unknown command 0x%02x\n", RSWD_MSG_CMD(msg)); return -1; } } @@ -221,12 +223,13 @@ restart: if ((usb = usb_open(0x18d1, 0xdb03, 0))) break; if ((usb = usb_open(0x18d1, 0xdb04, 0))) break; if (once) { - fprintf(stderr, "\r\nusb: waiting for debugger device\r\n"); + xprintf(XSWD, "usb: waiting for debugger device\n"); once = 0; } usleep(250000); } - fprintf(stderr, "\r\nusb: debugger connected\r\n"); + once = 0; + xprintf(XSWD, "usb: debugger connected\n"); pthread_mutex_lock(&swd_lock); swd_online = 1; for (;;) { @@ -234,14 +237,14 @@ restart: r = usb_read_forever(usb, data, 4096); pthread_mutex_lock(&swd_lock); if (r < 0) { - fprintf(stderr,"\r\nusb: debugger disconnected\r\n"); + xprintf(XSWD, "usb: debugger disconnected\n"); swd_online = -1; swd_txn_status = TXN_STATUS_FAIL; pthread_cond_broadcast(&swd_event); break; } if ((r < 4) || (r & 3)) { - fprintf(stderr,"\r\nusb: rx: discard packet (%d)\r\n", r); + xprintf(XSWD, "usb: discard packet (%d)\n", r); continue; } if (swd_txn_status == TXN_STATUS_WAIT) { @@ -254,7 +257,7 @@ restart: process_async(data + 1, (r / 4) - 1); pthread_mutex_lock(&swd_lock); } else { - fprintf(stderr, "\r\nusb: rx: unexpected txn %08x (%d)\r\n", + xprintf(XSWD, "usb: rx: unexpected txn %08x (%d)\n", data[0], r); } } @@ -655,9 +658,11 @@ int swdp_reset(void) { t.tx[t.txc++] = RSWD_MSG(CMD_ATTACH, 0, 0); t.tx[t.txc++] = SWD_RD(DP_IDCODE, 1); t.rx[t.rxc++] = &idcode; - q_exec(&t); - - fprintf(stderr,"IDCODE: %08x\n", idcode); + if (q_exec(&t)) { + xprintf(XSWD, "attach: IDCODE: ????????\n"); + } else { + xprintf(XSWD, "attach: IDCODE: %08x\n", idcode); + } swd_error = 0; q_init(&t); @@ -678,7 +683,7 @@ int swdp_reset(void) { if (q_exec(&t)) return -1; - fprintf(stderr,"DPCTRL: %08x\n", n); + xprintf(XSWD, "attach: DPCTRL: %08x\n", n); return 0; }