summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--doc/openocd.texi11
-rw-r--r--src/target/etm.c66
3 files changed, 74 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index efcf8f61..e1229122 100644
--- a/NEWS
+++ b/NEWS
@@ -34,6 +34,7 @@ Target Layer:
- Exposed DWT registers like cycle counter
ETM, ETB
- "trigger_percent" command moved ETM --> ETB
+ - "etm trigger_debug" command added
Flash Layer:
'flash bank' and 'nand device' take <bank_name> as first argument.
diff --git a/doc/openocd.texi b/doc/openocd.texi
index bb3e51ac..d9cb4ea6 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -5512,6 +5512,17 @@ trace stream without an image of the code.
@end itemize
@end deffn
+@deffn Command {etm trigger_debug} (@option{enable}|@option{disable})
+Displays whether ETM triggering debug entry (like a breakpoint) is
+enabled or disabled, after optionally modifying that configuration.
+The default behaviour is @option{disable}.
+Any change takes effect after the next @command{etm start}.
+
+By using script commands to configure ETM registers, you can make the
+processor enter debug state automatically when certain conditions,
+more complex than supported by the breakpoint hardware, happen.
+@end deffn
+
@subsection ETM Trace Operation
After setting up the ETM, you can use it to collect data.
diff --git a/src/target/etm.c b/src/target/etm.c
index a506d1c4..d22bc407 100644
--- a/src/target/etm.c
+++ b/src/target/etm.c
@@ -446,12 +446,15 @@ int etm_setup(struct target *target)
etm_ctrl_value = (etm_ctrl_value
& ~ETM_PORT_WIDTH_MASK
& ~ETM_PORT_MODE_MASK
+ & ~ETM_CTRL_DBGRQ
& ~ETM_PORT_CLOCK_MASK)
| etm_ctx->control;
buf_set_u32(etm_ctrl_reg->value, 0, 32, etm_ctrl_value);
etm_store_reg(etm_ctrl_reg);
+ etm_ctx->control = etm_ctrl_value;
+
if ((retval = jtag_execute_queue()) != ERROR_OK)
return retval;
@@ -1338,8 +1341,6 @@ COMMAND_HANDLER(handle_etm_tracemode_command)
if (!etm_ctrl_reg)
return ERROR_FAIL;
- etm_get_reg(etm_ctrl_reg);
-
etm->control &= ~TRACEMODE_MASK;
etm->control |= tracemode & TRACEMODE_MASK;
@@ -2016,6 +2017,56 @@ COMMAND_HANDLER(handle_etm_stop_command)
return ERROR_OK;
}
+COMMAND_HANDLER(handle_etm_trigger_debug_command)
+{
+ struct target *target;
+ struct arm *arm;
+ struct etm_context *etm;
+
+ target = get_current_target(CMD_CTX);
+ arm = target_to_arm(target);
+ if (!is_arm(arm))
+ {
+ command_print(CMD_CTX, "ETM: %s isn't an ARM",
+ target_name(target));
+ return ERROR_FAIL;
+ }
+
+ etm = arm->etm;
+ if (!etm)
+ {
+ command_print(CMD_CTX, "ETM: no ETM configured for %s",
+ target_name(target));
+ return ERROR_FAIL;
+ }
+
+ if (CMD_ARGC == 1) {
+ struct reg *etm_ctrl_reg;
+ bool dbgrq;
+
+ etm_ctrl_reg = etm_reg_lookup(etm, ETM_CTRL);
+ if (!etm_ctrl_reg)
+ return ERROR_FAIL;
+
+ COMMAND_PARSE_ENABLE(CMD_ARGV[0], dbgrq);
+ if (dbgrq)
+ etm->control |= ETM_CTRL_DBGRQ;
+ else
+ etm->control &= ~ETM_CTRL_DBGRQ;
+
+ /* etm->control will be written to hardware
+ * the next time an "etm start" is issued.
+ */
+ buf_set_u32(etm_ctrl_reg->value, 0, 32, etm->control);
+ }
+
+ command_print(CMD_CTX, "ETM: %s debug halt",
+ (etm->control & ETM_CTRL_DBGRQ)
+ ? "triggers"
+ : "does not trigger");
+ return ERROR_OK;
+}
+
COMMAND_HANDLER(handle_etm_analyze_command)
{
struct target *target;
@@ -2112,10 +2163,17 @@ static const struct command_registration etm_exec_command_handlers[] = {
.help = "stop ETM trace collection",
},
{
+ .name = "trigger_debug",
+ .handler = handle_etm_trigger_debug_command,
+ .mode = COMMAND_EXEC,
+ .help = "enable/disable debug entry on trigger",
+ .usage = "(enable | disable)",
+ },
+ {
.name = "analyze",
- .handler = &handle_etm_analyze_command,
+ .handler = handle_etm_analyze_command,
.mode = COMMAND_EXEC,
- .help = "anaylze collected ETM trace",
+ .help = "analyze collected ETM trace",
},
{
.name = "image",