aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2020-02-20 13:58:15 -0800
committerGitHub <noreply@github.com>2020-02-20 13:58:15 -0800
commit1449af5bdb99052c2f3bf92747f8438544cd8f3f (patch)
tree896d09d417af7c572837c74951ffd501248781ab
parent95462a8a35556259bd4555362f5367f8b48012f1 (diff)
downloadriscv-openocd-1449af5bdb99052c2f3bf92747f8438544cd8f3f.zip
riscv-openocd-1449af5bdb99052c2f3bf92747f8438544cd8f3f.tar.gz
riscv-openocd-1449af5bdb99052c2f3bf92747f8438544cd8f3f.tar.bz2
Give control over dcsr.ebreak[msu] bits. (#451)
This allows a user to debug code that uses software breakpoints itself. Change-Id: If40cb626354e11703017cdf8c5919a31e83ebc3f
-rw-r--r--doc/openocd.texi15
-rw-r--r--src/target/riscv/riscv-011.c12
-rw-r--r--src/target/riscv/riscv-013.c6
-rw-r--r--src/target/riscv/riscv.c57
-rw-r--r--src/target/riscv/riscv.h3
5 files changed, 87 insertions, 6 deletions
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 504ffeb..0e92a9d 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -9511,6 +9511,21 @@ Enable or disable use of a BSCAN tunnel to reach DM. Supply the width of
the DM transport TAP's instruction register to enable. Supply a value of 0 to disable.
@end deffn
+@deffn Command {riscv set_ebreakm} on|off
+Control dcsr.ebreakm. When on (default), M-mode ebreak instructions trap to
+OpenOCD. When off, they generate a breakpoint exception handled internally.
+@end deffn
+
+@deffn Command {riscv set_ebreaks} on|off
+Control dcsr.ebreaks. When on (default), S-mode ebreak instructions trap to
+OpenOCD. When off, they generate a breakpoint exception handled internally.
+@end deffn
+
+@deffn Command {riscv set_ebreaku} on|off
+Control dcsr.ebreaku. When on (default), U-mode ebreak instructions trap to
+OpenOCD. When off, they generate a breakpoint exception handled internally.
+@end deffn
+
@subsection RISC-V Authentication Commands
The following commands can be used to authenticate to a RISC-V system. Eg. a
diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c
index aad5b8b..dc09c96 100644
--- a/src/target/riscv/riscv-011.c
+++ b/src/target/riscv/riscv-011.c
@@ -1114,7 +1114,10 @@ static int execute_resume(struct target *target, bool step)
}
}
- info->dcsr |= DCSR_EBREAKM | DCSR_EBREAKH | DCSR_EBREAKS | DCSR_EBREAKU;
+ info->dcsr = set_field(info->dcsr, DCSR_EBREAKM, riscv_ebreakm);
+ info->dcsr = set_field(info->dcsr, DCSR_EBREAKS, riscv_ebreaks);
+ info->dcsr = set_field(info->dcsr, DCSR_EBREAKU, riscv_ebreaku);
+ info->dcsr = set_field(info->dcsr, DCSR_EBREAKH, 1);
info->dcsr &= ~DCSR_HALT;
if (step)
@@ -1946,8 +1949,11 @@ static int assert_reset(struct target *target)
/* Not sure what we should do when there are multiple cores.
* Here just reset the single hart we're talking to. */
- info->dcsr |= DCSR_EBREAKM | DCSR_EBREAKH | DCSR_EBREAKS |
- DCSR_EBREAKU | DCSR_HALT;
+ info->dcsr = set_field(info->dcsr, DCSR_EBREAKM, riscv_ebreakm);
+ info->dcsr = set_field(info->dcsr, DCSR_EBREAKS, riscv_ebreaks);
+ info->dcsr = set_field(info->dcsr, DCSR_EBREAKU, riscv_ebreaku);
+ info->dcsr = set_field(info->dcsr, DCSR_EBREAKH, 1);
+ info->dcsr |= DCSR_HALT;
if (target->reset_halt)
info->dcsr |= DCSR_NDRESET;
else
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 4381f41..487ed50 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -4310,9 +4310,9 @@ static int riscv013_on_step_or_resume(struct target *target, bool step)
if (result != ERROR_OK)
return result;
dcsr = set_field(dcsr, CSR_DCSR_STEP, step);
- dcsr = set_field(dcsr, CSR_DCSR_EBREAKM, 1);
- dcsr = set_field(dcsr, CSR_DCSR_EBREAKS, 1);
- dcsr = set_field(dcsr, CSR_DCSR_EBREAKU, 1);
+ dcsr = set_field(dcsr, CSR_DCSR_EBREAKM, riscv_ebreakm);
+ dcsr = set_field(dcsr, CSR_DCSR_EBREAKS, riscv_ebreaks);
+ dcsr = set_field(dcsr, CSR_DCSR_EBREAKU, riscv_ebreaku);
return riscv_set_register(target, GDB_REGNO_DCSR, dcsr);
}
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index 35dbe77..ae04897 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -252,6 +252,9 @@ int riscv_reset_timeout_sec = DEFAULT_RESET_TIMEOUT_SEC;
bool riscv_prefer_sba;
bool riscv_enable_virt2phys = true;
+bool riscv_ebreakm = true;
+bool riscv_ebreaks = true;
+bool riscv_ebreaku = true;
bool riscv_enable_virtual;
@@ -2465,6 +2468,36 @@ COMMAND_HANDLER(riscv_set_enable_virt2phys)
return ERROR_OK;
}
+COMMAND_HANDLER(riscv_set_ebreakm)
+{
+ if (CMD_ARGC != 1) {
+ LOG_ERROR("Command takes exactly 1 parameter");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ COMMAND_PARSE_ON_OFF(CMD_ARGV[0], riscv_ebreakm);
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(riscv_set_ebreaks)
+{
+ if (CMD_ARGC != 1) {
+ LOG_ERROR("Command takes exactly 1 parameter");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ COMMAND_PARSE_ON_OFF(CMD_ARGV[0], riscv_ebreaks);
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(riscv_set_ebreaku)
+{
+ if (CMD_ARGC != 1) {
+ LOG_ERROR("Command takes exactly 1 parameter");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ COMMAND_PARSE_ON_OFF(CMD_ARGV[0], riscv_ebreaku);
+ return ERROR_OK;
+}
+
static const struct command_registration riscv_exec_command_handlers[] = {
{
.name = "test_compliance",
@@ -2607,6 +2640,30 @@ static const struct command_registration riscv_exec_command_handlers[] = {
.usage = "riscv set_enable_virt2phys on|off",
.help = "Enable translation from virtual address to physical address."
},
+ {
+ .name = "set_ebreakm",
+ .handler = riscv_set_ebreakm,
+ .mode = COMMAND_ANY,
+ .usage = "riscv set_ebreakm on|off",
+ .help = "Control dcsr.ebreakm. When off, M-mode ebreak instructions "
+ "don't trap to OpenOCD. Defaults to on."
+ },
+ {
+ .name = "set_ebreaks",
+ .handler = riscv_set_ebreaks,
+ .mode = COMMAND_ANY,
+ .usage = "riscv set_ebreaks on|off",
+ .help = "Control dcsr.ebreaks. When off, S-mode ebreak instructions "
+ "don't trap to OpenOCD. Defaults to on."
+ },
+ {
+ .name = "set_ebreaku",
+ .handler = riscv_set_ebreaku,
+ .mode = COMMAND_ANY,
+ .usage = "riscv set_ebreaku on|off",
+ .help = "Control dcsr.ebreaku. When off, U-mode ebreak instructions "
+ "don't trap to OpenOCD. Defaults to on."
+ },
COMMAND_REGISTRATION_DONE
};
diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h
index 9fa2138..928e460 100644
--- a/src/target/riscv/riscv.h
+++ b/src/target/riscv/riscv.h
@@ -195,6 +195,9 @@ extern int riscv_reset_timeout_sec;
extern bool riscv_prefer_sba;
extern bool riscv_enable_virtual;
+extern bool riscv_ebreakm;
+extern bool riscv_ebreaks;
+extern bool riscv_ebreaku;
/* Everything needs the RISC-V specific info structure, so here's a nice macro
* that provides that. */