commit ae7e5259441321338769bacf0895af7fd604c474
parent bdbe4957e7c9c0a82a878000e21a96e5619930fa
Author: Brian Swetland <swetland@frotz.net>
Date: Sat, 20 Jun 2015 19:00:40 -0700
debugger: start of state monitoring and async reporting
- run a monitor thread that samples target state every 250ms
- necessary locking so this and the main debug thread play nice
- use linenoisePause()/Resume() to play nice with input
Diffstat:
4 files changed, 106 insertions(+), 8 deletions(-)
diff --git a/tools/debugger-commands.c b/tools/debugger-commands.c
@@ -117,8 +117,6 @@ int do_stop(int argc, param *argv) {
int do_resume(int argc, param *argv) {
swdp_core_resume();
- if (swdp_core_wait_for_halt() == 0)
- do_regs(0, 0);
return 0;
}
@@ -581,7 +579,8 @@ int run_flash_agent(u32 flashaddr, void *data, size_t data_sz) {
if (swdp_watchpoint_rw(0, 0)) {
goto fail;
}
- do_resume(0,0);
+ swdp_core_resume();
+ swdp_core_wait_for_halt();
// todo: timeout?
// todo: confirm halted
}
diff --git a/tools/debugger-core.c b/tools/debugger-core.c
@@ -26,6 +26,92 @@
#include <fw/types.h>
#include "debugger.h"
+#include <pthread.h>
+
+#include "rswdp.h"
+
+// for core debug regs
+#include <protocol/rswdp.h>
+
+#include "linenoise.h"
+
+#define DHCSR_C_DEBUGEN (1 << 0)
+#define DHCSR_C_HALT (1 << 1)
+#define DHCSR_C_STEP (1 << 2)
+#define DHCSR_C_MASKINTS (1 << 3)
+#define DHCSR_C_SNAPSTALL (1 << 5)
+#define DHCSR_S_REGRDY (1 << 16)
+#define DHCSR_S_HALT (1 << 17)
+#define DHCSR_S_SLEEP (1 << 18)
+#define DHCSR_S_LOCKUP (1 << 19)
+#define DHCSR_S_RETIRE_ST (1 << 24)
+#define DHCSR_S_RESET_ST (1 << 25)
+
+#define DFSR 0xE000ED30
+#define DFSR_HALTED (1 << 0)
+#define DFSR_BKPT (1 << 1)
+#define DFSR_DWTTRAP (1 << 2)
+#define DFSR_VCATCH (1 << 3)
+#define DFSR_EXTERNAL (1 << 4)
+#define DFSR_MASK 0x1F
+
+#define DEBUG_MONITOR 1
+
+#if DEBUG_MONITOR
+
+static void m_event(const char *evt) {
+ linenoisePause();
+ fprintf(stdout, "DEBUG EVENT: %s\n", evt);
+ linenoiseResume();
+}
+
+static void monitor(void) {
+ u32 v;
+ if (swdp_ahb_read(DFSR, &v) == 0) {
+ if (v & DFSR_MASK) {
+ swdp_ahb_write(DFSR, DFSR_MASK);
+ }
+ if (v & DFSR_HALTED) m_event("HALTED");
+ if (v & DFSR_BKPT) m_event("BKPT");
+ if (v & DFSR_DWTTRAP) m_event("DWTTRAP");
+ if (v & DFSR_VCATCH) m_event("VCATCH");
+ if (v & DFSR_EXTERNAL) m_event("EXTERNAL");
+ }
+}
+
+static pthread_mutex_t _dbg_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_t _dbg_thread;
+
+void debugger_lock() {
+ pthread_mutex_lock(&_dbg_lock);
+}
+
+void debugger_unlock() {
+ pthread_mutex_unlock(&_dbg_lock);
+}
+
+void *debugger_monitor(void *arg) {
+ for (;;) {
+ debugger_lock();
+ monitor();
+ debugger_unlock();
+ usleep(250000);
+ }
+}
+
+void debugger_init() {
+ pthread_create(&_dbg_thread, NULL, debugger_monitor, NULL);
+}
+
+#else
+
+void debugger_lock() { }
+void debugger_unlock() { }
+void debugger_init() { }
+
+#endif
+
+
static struct varinfo *all_variables = 0;
static struct funcinfo *allfuncs = 0;
@@ -313,7 +399,11 @@ static int _debugger_exec(const char *cmd, unsigned argc, param *argv) {
for (c = debugger_commands; c->name; c++) {
if (!strcasecmp(cmd, c->name)) {
- return c->func(argc, argv);
+ int n;
+ debugger_lock();
+ n = c->func(argc, argv);
+ debugger_unlock();
+ return n;
}
}
for (f = allfuncs; f; f = f->next) {
diff --git a/tools/debugger.c b/tools/debugger.c
@@ -24,11 +24,14 @@
#include <fcntl.h>
#include <getopt.h>
-#include "linenoise.h"
-
#include <fw/types.h>
#include "rswdp.h"
+#include "linenoise.h"
+#include "debugger.h"
+
+void linenoiseInit(void);
+
static const char *scriptfile = NULL;
void xprintf(const char *fmt, ...) {
@@ -38,8 +41,6 @@ void xprintf(const char *fmt, ...) {
va_end(ap);
}
-void debugger_command(char *line);
-
static void handler(int n) {
swdp_interrupt();
}
@@ -108,6 +109,9 @@ int main(int argc, char **argv) {
free(buf);
}
+ linenoiseInit();
+ debugger_init();
+
while ((line = linenoise("debugger> ")) != NULL) {
if (line[0] == 0) {
strcpy(line, lastline);
diff --git a/tools/debugger.h b/tools/debugger.h
@@ -58,6 +58,11 @@ int debugger_command(char *line);
int debugger_invoke(const char *cmd, unsigned argc, ...);
int debugger_variable(const char *name, u32 *value);
+/* lock to protect underlying rswdp state */
+void debugger_init();
+void debugger_lock();
+void debugger_unlock();
+
/* provided by debugger-commands.c */
extern struct debugger_command debugger_commands[];
int read_register(const char *name, u32 *value);