commit 9de704baccb3c82ed2ec62e2a4c241a52c437433
parent e2207b87cb4a174612b3deb8760740316ce78c24
Author: Brian Swetland <swetland@frotz.net>
Date:   Mon, 29 Jun 2015 18:10:00 -0700
debugger: maskints support
maskints on      -- disable IRQs while stepping
maskints always  -- disable when continuing too
maskints off     -- allow IRQs
Diffstat:
2 files changed, 77 insertions(+), 7 deletions(-)
diff --git a/tools/debugger-commands.c b/tools/debugger-commands.c
@@ -740,6 +740,26 @@ int do_finfo(int argc, param *argv) {
 	return 0;
 }
 
+extern int swdp_step_no_ints;
+
+int do_maskints(int argc, param *argv) {
+	if (argc != 1) {
+		xprintf("usage: maskints [on|off|always]\n");
+		return -1;
+	}
+	if (!strcmp(argv[0].s, "on")) {
+		swdp_step_no_ints = 1;
+		xprintf("maskints: while stepping\n");
+	} else if (!strcmp(argv[0].s, "always")) {
+		swdp_step_no_ints = 2;
+		xprintf("maskints: always\n");
+	} else {
+		swdp_step_no_ints = 0;
+		xprintf("maskints: never\n");
+	}
+	return 0;
+}
+
 struct debugger_command debugger_commands[] = {
 	{ "exit",	"", do_exit,		"" },
 	{ "attach",	"", do_attach,		"attach/reattach to sw-dp" },
@@ -762,6 +782,7 @@ struct debugger_command debugger_commands[] = {
 	{ "watch-rw",	"", do_watch_rw,	"set watchpoint at addr" },
 	{ "watch-off",	"", do_watch_off,	"disable watchpoint" },
 	{ "log",	"", do_log,		"enable/disable logging" },
+	{ "maskints",	"", do_maskints,	"enable/disable IRQ mask during step" },
 	{ "print",	"", do_print,		"print numeric arguments" },
 	{ "echo",	"", do_echo,		"echo command line" },
 	{ "bootloader", "", do_bootloader,	"reboot into bootloader" },
diff --git a/tools/rswdp.c b/tools/rswdp.c
@@ -424,12 +424,66 @@ int swdp_core_read_all(u32 *v) {
 	return q_exec(&t);
 }
 
+int swdp_step_no_ints = 0;
+
 int swdp_core_halt(void) {
-	return swdp_ahb_write(CDBG_CSR, CDBG_CSR_KEY | CDBG_C_HALT | CDBG_C_DEBUGEN);
+	u32 x;
+	if (swdp_ahb_read(CDBG_CSR, &x)) return -1;
+	x &= (CDBG_C_HALT | CDBG_C_DEBUGEN | CDBG_C_MASKINTS);
+	x |= CDBG_CSR_KEY | CDBG_C_DEBUGEN | CDBG_C_HALT;
+	return swdp_ahb_write(CDBG_CSR, x);
 }
 
 int swdp_core_step(void) {
-	return swdp_ahb_write(CDBG_CSR, CDBG_CSR_KEY | CDBG_C_STEP | CDBG_C_DEBUGEN);
+	u32 x;
+	if (swdp_ahb_read(CDBG_CSR, &x)) return -1;
+	x &= (CDBG_C_HALT | CDBG_C_DEBUGEN | CDBG_C_MASKINTS);
+	x |= CDBG_CSR_KEY;
+
+	if (!(x & CDBG_C_HALT)) {
+		// HALT if we're not already HALTED
+		x |= CDBG_C_HALT | CDBG_C_DEBUGEN;
+		swdp_ahb_write(CDBG_CSR, x);
+	}
+	if (swdp_step_no_ints) {
+		// set MASKINTS if not already set
+		if (!(x & CDBG_C_MASKINTS)) {
+			x |= CDBG_C_MASKINTS;
+			swdp_ahb_write(CDBG_CSR, x);
+		}
+	} else {
+		// clear MASKINTs if not already clear
+		if (x & CDBG_C_MASKINTS) {
+			x &= (~CDBG_C_MASKINTS);
+			swdp_ahb_write(CDBG_CSR, x);
+		}
+	}
+	// STEP
+	x &= (~CDBG_C_HALT);
+	return swdp_ahb_write(CDBG_CSR, x | CDBG_C_STEP);
+}
+
+int swdp_core_resume(void) {
+	u32 x;
+	if (swdp_ahb_read(CDBG_CSR, &x)) return -1;
+	x &= (CDBG_C_HALT | CDBG_C_DEBUGEN | CDBG_C_MASKINTS);
+	x |= CDBG_CSR_KEY | CDBG_C_DEBUGEN;
+
+	if (swdp_step_no_ints > 1) {
+		// not just on during step, but always
+		if (!(x & CDBG_C_MASKINTS)) {
+			x |= CDBG_C_MASKINTS;
+			swdp_ahb_write(CDBG_CSR, x);
+		}
+	} else {
+		if (x & CDBG_C_MASKINTS) {
+			x &= (~CDBG_C_MASKINTS);
+			swdp_ahb_write(CDBG_CSR, x);
+		}
+	}
+
+	x &= ~(CDBG_C_HALT | CDBG_C_STEP);
+	return swdp_ahb_write(CDBG_CSR, x);
 }
 
 int swdp_core_wait_for_halt(void) {
@@ -457,11 +511,6 @@ int swdp_ahb_wait_for_change(u32 addr, u32 oldval) {
 	return 0;
 }
 
-int swdp_core_resume(void) {
-	/* must leave DEBUGEN on to halt on vector catch, breakpoints, etc */
-	return swdp_ahb_write(CDBG_CSR, CDBG_CSR_KEY | CDBG_C_DEBUGEN);
-}
-
 int swdp_watchpoint(unsigned n, u32 addr, u32 func) {
 	struct txn t;