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);