Browse Source

ETM: rename registers, doc tweaks

The register names are perversely not documented as zero-indexed,
so rename them to match that convention.  Also switch to lowercase
suffixes and infix numbering, matching ETB and EmbeddedICE usage.

Update docs to be a bit more accurate, especially regarding what
the "trigger" event can cause; and to split the issues into a few
more paragraphs, for clarity.

Make "configure" helptext point out that "oocd_trace" is prototype
hardware, not anything "real".

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
tags/v0.3.0-rc0
David Brownell 12 years ago
parent
commit
344bed2f7e
3 changed files with 73 additions and 50 deletions
  1. +2
    -1
      configure.in
  2. +17
    -2
      doc/openocd.texi
  3. +54
    -47
      src/target/etm.c

+ 2
- 1
configure.in View File

@@ -377,7 +377,8 @@ AC_ARG_ENABLE(usbprog,
[build_usbprog=$enableval], [build_usbprog=no])

AC_ARG_ENABLE(oocd_trace,
AS_HELP_STRING([--enable-oocd_trace], [Enable building support for the OpenOCD+trace ETM capture device]),
AS_HELP_STRING([--enable-oocd_trace],
[Enable building support for some prototype OpenOCD+trace ETM capture hardware]),
[build_oocd_trace=$enableval], [build_oocd_trace=no])

AC_ARG_ENABLE(jlink,


+ 17
- 2
doc/openocd.texi View File

@@ -5114,14 +5114,23 @@ ETM support in OpenOCD doesn't seem to be widely used yet.
@quotation Issues
ETM support may be buggy, and at least some @command{etm config}
parameters should be detected by asking the ETM for them.

ETM trigger events could also implement a kind of complex
hardware breakpoint, much more powerful than the simple
watchpoint hardware exported by EmbeddedICE modules.
@emph{Such breakpoints can be triggered even when using the
dummy trace port driver}.

It seems like a GDB hookup should be possible,
as well as triggering trace on specific events
as well as tracing only during specific states
(perhaps @emph{handling IRQ 23} or @emph{calls foo()}).

There should be GUI tools to manipulate saved trace data and help
analyse it in conjunction with the source code.
It's unclear how much of a common interface is shared
with the current XScale trace support, or should be
shared with eventual Nexus-style trace module support.

At this writing (September 2009) only ARM7 and ARM9 support
for ETM modules is available. The code should be able to
work with some newer cores; but not all of them support
@@ -5135,7 +5144,10 @@ ETM setup is coupled with the trace port driver configuration.
Declares the ETM associated with @var{target}, and associates it
with a given trace port @var{driver}. @xref{Trace Port Drivers}.

Several of the parameters must reflect the trace port configuration.
Several of the parameters must reflect the trace port capabilities,
which are a function of silicon capabilties (exposed later
using @command{etm info}) and of what hardware is connected to
that port (such as an external pod, or ETB).
The @var{width} must be either 4, 8, or 16.
The @var{mode} must be @option{normal}, @option{multiplexted},
or @option{demultiplexted}.
@@ -5151,6 +5163,9 @@ what CPU activities are traced.

@deffn Command {etm info}
Displays information about the current target's ETM.
This includes resource counts from the @code{ETM_CONFIG} register,
as well as silicon capabilities (except on rather old modules).
from the @code{ETM_SYS_CONFIG} register.
@end deffn

@deffn Command {etm status}


+ 54
- 47
src/target/etm.c View File

@@ -76,47 +76,46 @@ struct etm_reg_info {
/* basic registers that are always there given the right ETM version */
static const struct etm_reg_info etm_core[] = {
/* NOTE: we "know" ETM_CONFIG is listed first */
{ ETM_CONFIG, 32, RO, 0x10, "ETM_CONFIG", },
{ ETM_CONFIG, 32, RO, 0x10, "ETM_config", },

/* ETM Trace Registers */
{ ETM_CTRL, 32, RW, 0x10, "ETM_CTRL", },
{ ETM_TRIG_EVENT, 17, WO, 0x10, "ETM_TRIG_EVENT", },
{ ETM_ASIC_CTRL, 8, WO, 0x10, "ETM_ASIC_CTRL", },
{ ETM_STATUS, 3, RO, 0x11, "ETM_STATUS", },
{ ETM_SYS_CONFIG, 9, RO, 0x12, "ETM_SYS_CONFIG", },
{ ETM_CTRL, 32, RW, 0x10, "ETM_ctrl", },
{ ETM_TRIG_EVENT, 17, WO, 0x10, "ETM_trig_event", },
{ ETM_ASIC_CTRL, 8, WO, 0x10, "ETM_asic_ctrl", },
{ ETM_STATUS, 3, RO, 0x11, "ETM_status", },
{ ETM_SYS_CONFIG, 9, RO, 0x12, "ETM_sys_config", },

/* TraceEnable configuration */
{ ETM_TRACE_RESOURCE_CTRL, 32, WO, 0x12, "ETM_TRACE_RESOURCE_CTRL", },
{ ETM_TRACE_EN_CTRL2, 16, WO, 0x12, "ETM_TRACE_EN_CTRL2", },
{ ETM_TRACE_EN_EVENT, 17, WO, 0x10, "ETM_TRACE_EN_EVENT", },
{ ETM_TRACE_EN_CTRL1, 26, WO, 0x10, "ETM_TRACE_EN_CTRL1", },
{ ETM_TRACE_RESOURCE_CTRL, 32, WO, 0x12, "ETM_trace_resource_ctrl", },
{ ETM_TRACE_EN_CTRL2, 16, WO, 0x12, "ETM_trace_en_ctrl2", },
{ ETM_TRACE_EN_EVENT, 17, WO, 0x10, "ETM_trace_en_event", },
{ ETM_TRACE_EN_CTRL1, 26, WO, 0x10, "ETM_trace_en_ctrl1", },

/* ViewData configuration (data trace) */
{ ETM_VIEWDATA_EVENT, 17, WO, 0x10, "ETM_VIEWDATA_EVENT", },
{ ETM_VIEWDATA_CTRL1, 32, WO, 0x10, "ETM_VIEWDATA_CTRL1", },
{ ETM_VIEWDATA_CTRL2, 32, WO, 0x10, "ETM_VIEWDATA_CTRL2", },
{ ETM_VIEWDATA_CTRL3, 17, WO, 0x10, "ETM_VIEWDATA_CTRL3", },
{ ETM_VIEWDATA_EVENT, 17, WO, 0x10, "ETM_viewdata_event", },
{ ETM_VIEWDATA_CTRL1, 32, WO, 0x10, "ETM_viewdata_ctrl1", },
{ ETM_VIEWDATA_CTRL2, 32, WO, 0x10, "ETM_viewdata_ctrl2", },
{ ETM_VIEWDATA_CTRL3, 17, WO, 0x10, "ETM_viewdata_ctrl3", },

/* REVISIT exclude VIEWDATA_CTRL2 when it's not there */

{ 0x78, 12, WO, 0x20, "ETM_SYNC_FREQ", },
{ 0x79, 32, RO, 0x20, "ETM_ID", },
{ 0x78, 12, WO, 0x20, "ETM_sync_freq", },
{ 0x79, 32, RO, 0x20, "ETM_id", },
};

static const struct etm_reg_info etm_fifofull[] = {
/* FIFOFULL configuration */
{ ETM_FIFOFULL_REGION, 25, WO, 0x10, "ETM_FIFOFULL_REGION", },
{ ETM_FIFOFULL_LEVEL, 8, WO, 0x10, "ETM_FIFOFULL_LEVEL", },
{ ETM_FIFOFULL_REGION, 25, WO, 0x10, "ETM_fifofull_region", },
{ ETM_FIFOFULL_LEVEL, 8, WO, 0x10, "ETM_fifofull_level", },
};

static const struct etm_reg_info etm_addr_comp[] = {
/* Address comparator register pairs */
#define ADDR_COMPARATOR(i) \
{ ETM_ADDR_COMPARATOR_VALUE + (i), 32, WO, 0x10, \
"ETM_ADDR_COMPARATOR_VALUE" #i, }, \
{ ETM_ADDR_ACCESS_TYPE + (i), 7, WO, 0x10, \
"ETM_ADDR_ACCESS_TYPE" #i, }
ADDR_COMPARATOR(0),
{ ETM_ADDR_COMPARATOR_VALUE + (i) - 1, 32, WO, 0x10, \
"ETM_addr_" #i "_comparator_value", }, \
{ ETM_ADDR_ACCESS_TYPE + (i) - 1, 7, WO, 0x10, \
"ETM_addr_" #i "_access_type", }
ADDR_COMPARATOR(1),
ADDR_COMPARATOR(2),
ADDR_COMPARATOR(3),
@@ -124,8 +123,8 @@ static const struct etm_reg_info etm_addr_comp[] = {
ADDR_COMPARATOR(5),
ADDR_COMPARATOR(6),
ADDR_COMPARATOR(7),

ADDR_COMPARATOR(8),

ADDR_COMPARATOR(9),
ADDR_COMPARATOR(10),
ADDR_COMPARATOR(11),
@@ -133,17 +132,17 @@ static const struct etm_reg_info etm_addr_comp[] = {
ADDR_COMPARATOR(13),
ADDR_COMPARATOR(14),
ADDR_COMPARATOR(15),
ADDR_COMPARATOR(16),
#undef ADDR_COMPARATOR
};

static const struct etm_reg_info etm_data_comp[] = {
/* Data Value Comparators (NOTE: odd addresses are reserved) */
#define DATA_COMPARATOR(i) \
{ ETM_DATA_COMPARATOR_VALUE + 2*(i), 32, WO, 0x10, \
"ETM_DATA_COMPARATOR_VALUE" #i, }, \
{ ETM_DATA_COMPARATOR_MASK + 2*(i), 32, WO, 0x10, \
"ETM_DATA_COMPARATOR_MASK" #i, }
DATA_COMPARATOR(0),
{ ETM_DATA_COMPARATOR_VALUE + 2*(i) - 1, 32, WO, 0x10, \
"ETM_data_" #i "_comparator_value", }, \
{ ETM_DATA_COMPARATOR_MASK + 2*(i) - 1, 32, WO, 0x10, \
"ETM_data_" #i "_comparator_mask", }
DATA_COMPARATOR(1),
DATA_COMPARATOR(2),
DATA_COMPARATOR(3),
@@ -151,30 +150,31 @@ static const struct etm_reg_info etm_data_comp[] = {
DATA_COMPARATOR(5),
DATA_COMPARATOR(6),
DATA_COMPARATOR(7),
DATA_COMPARATOR(8),
#undef DATA_COMPARATOR
};

static const struct etm_reg_info etm_counters[] = {
#define ETM_COUNTER(i) \
{ ETM_COUNTER_RELOAD_VALUE + (i), 16, WO, 0x10, \
"ETM_COUNTER_RELOAD_VALUE" #i, }, \
{ ETM_COUNTER_ENABLE + (i), 18, WO, 0x10, \
"ETM_COUNTER_ENABLE" #i, }, \
{ ETM_COUNTER_RELOAD_EVENT + (i), 17, WO, 0x10, \
"ETM_COUNTER_RELOAD_EVENT" #i, }, \
{ ETM_COUNTER_VALUE + (i), 16, RO, 0x10, \
"ETM_COUNTER_VALUE" #i, }
ETM_COUNTER(0),
{ ETM_COUNTER_RELOAD_VALUE + (i) - 1, 16, WO, 0x10, \
"ETM_counter_" #i "_reload_value", }, \
{ ETM_COUNTER_ENABLE + (i) - 1, 18, WO, 0x10, \
"ETM_counter_" #i "_enable", }, \
{ ETM_COUNTER_RELOAD_EVENT + (i) - 1, 17, WO, 0x10, \
"ETM_counter_" #i "_reload_event", }, \
{ ETM_COUNTER_VALUE + (i) - 1, 16, RO, 0x10, \
"ETM_counter_" #i "_value", }
ETM_COUNTER(1),
ETM_COUNTER(2),
ETM_COUNTER(3),
ETM_COUNTER(4),
#undef ETM_COUNTER
};

static const struct etm_reg_info etm_sequencer[] = {
#define ETM_SEQ(i) \
{ ETM_SEQUENCER_EVENT + (i), 17, WO, 0x10, \
"ETM_SEQUENCER_EVENT" #i, }
"ETM_sequencer_event" #i, }
ETM_SEQ(0), /* 1->2 */
ETM_SEQ(1), /* 2->1 */
ETM_SEQ(2), /* 2->3 */
@@ -183,18 +183,18 @@ static const struct etm_reg_info etm_sequencer[] = {
ETM_SEQ(5), /* 1->3 */
#undef ETM_SEQ
/* 0x66 reserved */
{ ETM_SEQUENCER_STATE, 2, RO, 0x10, "ETM_SEQUENCER_STATE", },
{ ETM_SEQUENCER_STATE, 2, RO, 0x10, "ETM_sequencer_state", },
};

static const struct etm_reg_info etm_outputs[] = {
#define ETM_OUTPUT(i) \
{ ETM_EXTERNAL_OUTPUT + (i), 17, WO, 0x10, \
"ETM_EXTERNAL_OUTPUT" #i, }
{ ETM_EXTERNAL_OUTPUT + (i) - 1, 17, WO, 0x10, \
"ETM_external_output" #i, }

ETM_OUTPUT(0),
ETM_OUTPUT(1),
ETM_OUTPUT(2),
ETM_OUTPUT(3),
ETM_OUTPUT(4),
#undef ETM_OUTPUT
};

@@ -202,10 +202,10 @@ static const struct etm_reg_info etm_outputs[] = {
/* registers from 0x6c..0x7f were added after ETMv1.3 */

/* Context ID Comparators */
{ 0x6c, 32, RO, 0x20, "ETM_CONTEXTID_COMPARATOR_VALUE1", }
{ 0x6d, 32, RO, 0x20, "ETM_CONTEXTID_COMPARATOR_VALUE1", }
{ 0x6e, 32, RO, 0x20, "ETM_CONTEXTID_COMPARATOR_VALUE1", }
{ 0x6f, 32, RO, 0x20, "ETM_CONTEXTID_COMPARATOR_MASK", }
{ 0x6c, 32, RO, 0x20, "ETM_contextid_comparator_value1", }
{ 0x6d, 32, RO, 0x20, "ETM_contextid_comparator_value2", }
{ 0x6e, 32, RO, 0x20, "ETM_contextid_comparator_value3", }
{ 0x6f, 32, RO, 0x20, "ETM_contextid_comparator_mask", }
#endif

static int etm_reg_arch_type = -1;
@@ -1180,6 +1180,7 @@ static int handle_etm_tracemode_command(struct command_context_s *cmd_ctx, char

if (argc == 4)
{
/* what parts of data access are traced? */
if (strcmp(args[0], "none") == 0)
{
tracemode = ETMV1_TRACE_NONE;
@@ -1248,6 +1249,12 @@ static int handle_etm_tracemode_command(struct command_context_s *cmd_ctx, char
command_print(cmd_ctx, "invalid option '%s'", args[2]);
return ERROR_OK;
}

/* IGNORED:
* - CPRT tracing (coprocessor register transfers)
* - debug request (causes debug entry on trigger)
* - stall on FIFOFULL (preventing tracedata lossage)
*/
}
else if (argc != 0)
{


Loading…
Cancel
Save