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;