ETM: add "etm trigger_debug" command

In conjunction with manual register setup, this lets the ETM trigger
cause entry to debug state.   It should make it easier to test and
bugfix the ETM code, by enabling non-trace usage and isolating bugs
specific to thef ETM support.  (One current issue being that trace
data collection using the ETB doesn't yet behave.)

For example, many ARM9 cores with an ETM should be able to implement
four more (simple) breakpoints and two more (simple) watchpoints than
the EmbeddedICE supports.  Or, they should be able to support complex
breakpoints, incorporating ETM sequencer, counters, and/or subroutine
entry/exit criteria int criteria used to trigger debug entry.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
__archive__
David Brownell 2009-12-19 13:09:19 -08:00
parent 64934d9204
commit abe8b43755
3 changed files with 75 additions and 5 deletions

1
NEWS
View File

@ -34,6 +34,7 @@ Target Layer:
- Exposed DWT registers like cycle counter - Exposed DWT registers like cycle counter
ETM, ETB ETM, ETB
- "trigger_percent" command moved ETM --> ETB - "trigger_percent" command moved ETM --> ETB
- "etm trigger_debug" command added
Flash Layer: Flash Layer:
'flash bank' and 'nand device' take <bank_name> as first argument. 'flash bank' and 'nand device' take <bank_name> as first argument.

View File

@ -5512,6 +5512,17 @@ trace stream without an image of the code.
@end itemize @end itemize
@end deffn @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 @subsection ETM Trace Operation
After setting up the ETM, you can use it to collect data. After setting up the ETM, you can use it to collect data.

View File

@ -446,12 +446,15 @@ int etm_setup(struct target *target)
etm_ctrl_value = (etm_ctrl_value etm_ctrl_value = (etm_ctrl_value
& ~ETM_PORT_WIDTH_MASK & ~ETM_PORT_WIDTH_MASK
& ~ETM_PORT_MODE_MASK & ~ETM_PORT_MODE_MASK
& ~ETM_CTRL_DBGRQ
& ~ETM_PORT_CLOCK_MASK) & ~ETM_PORT_CLOCK_MASK)
| etm_ctx->control; | etm_ctx->control;
buf_set_u32(etm_ctrl_reg->value, 0, 32, etm_ctrl_value); buf_set_u32(etm_ctrl_reg->value, 0, 32, etm_ctrl_value);
etm_store_reg(etm_ctrl_reg); etm_store_reg(etm_ctrl_reg);
etm_ctx->control = etm_ctrl_value;
if ((retval = jtag_execute_queue()) != ERROR_OK) if ((retval = jtag_execute_queue()) != ERROR_OK)
return retval; return retval;
@ -1338,8 +1341,6 @@ COMMAND_HANDLER(handle_etm_tracemode_command)
if (!etm_ctrl_reg) if (!etm_ctrl_reg)
return ERROR_FAIL; return ERROR_FAIL;
etm_get_reg(etm_ctrl_reg);
etm->control &= ~TRACEMODE_MASK; etm->control &= ~TRACEMODE_MASK;
etm->control |= tracemode & TRACEMODE_MASK; etm->control |= tracemode & TRACEMODE_MASK;
@ -2016,6 +2017,56 @@ COMMAND_HANDLER(handle_etm_stop_command)
return ERROR_OK; 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) COMMAND_HANDLER(handle_etm_analyze_command)
{ {
struct target *target; struct target *target;
@ -2112,10 +2163,17 @@ static const struct command_registration etm_exec_command_handlers[] = {
.help = "stop ETM trace collection", .help = "stop ETM trace collection",
}, },
{ {
.name = "analyze", .name = "trigger_debug",
.handler = &handle_etm_analyze_command, .handler = handle_etm_trigger_debug_command,
.mode = COMMAND_EXEC, .mode = COMMAND_EXEC,
.help = "anaylze collected ETM trace", .help = "enable/disable debug entry on trigger",
.usage = "(enable | disable)",
},
{
.name = "analyze",
.handler = handle_etm_analyze_command,
.mode = COMMAND_EXEC,
.help = "analyze collected ETM trace",
}, },
{ {
.name = "image", .name = "image",