1
2
3
6
7
8
9
10
11
18
19
20
21
22
23
24
25
26
27
28
33
34
35
36
37
38
39
40
41
42
43
44
45
54
55
56
57
58
59
60
61
62
63
64
65
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
122
123
124
125
126
127
128
145
146
/* ... */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <target/target.h>
#include <target/armv7m.h>
#include <target/cortex_m.h>
#include <target/armv7m_trace.h>
#include <jtag/interface.h>
#include <helper/time_support.h>
6 includes
int armv7m_trace_itm_config(struct target *target)
{
struct armv7m_common *armv7m = target_to_armv7m(target);
struct armv7m_trace_config *trace_config = &armv7m->trace_config;
int retval;
retval = target_write_u32(target, ITM_LAR, ITM_LAR_KEY);
if (retval != ERROR_OK)
return retval;
/* ... */
uint32_t itm_tcr;
retval = target_read_u32(target, ITM_TCR, &itm_tcr);
if (retval != ERROR_OK)
return retval;
retval = target_write_u32(target,
ITM_TCR,
itm_tcr & ~ITM_TCR_ITMENA_BIT
);
if (retval != ERROR_OK)
return retval;
int64_t then = timeval_ms() + 1000;
do {
retval = target_read_u32(target, ITM_TCR, &itm_tcr);
if (retval != ERROR_OK)
return retval;
if (timeval_ms() > then) {
LOG_ERROR("timeout waiting for ITM_TCR_BUSY_BIT");
return ERROR_FAIL;
}if (timeval_ms() > then) { ... }
...} while (itm_tcr & ITM_TCR_BUSY_BIT);
retval = target_write_u32(target, ITM_TCR, (1 << 0) | (1 << 3) |
(trace_config->itm_diff_timestamps << 1) |
(trace_config->itm_synchro_packets << 2) |
(trace_config->itm_async_timestamps << 4) |
(trace_config->itm_ts_prescale << 8) |
(trace_config->trace_bus_id << 16));
if (retval != ERROR_OK)
return retval;
for (unsigned int i = 0; i < 8; i++) {
retval = target_write_u32(target, ITM_TER0 + i * 4,
trace_config->itm_ter[i]);
if (retval != ERROR_OK)
return retval;
}for (unsigned int i = 0; i < 8; i++) { ... }
return ERROR_OK;
}{ ... }
COMMAND_HANDLER(handle_itm_port_command)
{
struct target *target = get_current_target(CMD_CTX);
struct armv7m_common *armv7m = target_to_armv7m(target);
unsigned int reg_idx;
uint8_t port;
bool enable;
if (CMD_ARGC != 2)
return ERROR_COMMAND_SYNTAX_ERROR;
COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], port);
COMMAND_PARSE_ON_OFF(CMD_ARGV[1], enable);
reg_idx = port / 32;
port = port % 32;
if (enable)
armv7m->trace_config.itm_ter[reg_idx] |= (1 << port);
else
armv7m->trace_config.itm_ter[reg_idx] &= ~(1 << port);
/* ... */
if (CMD_CTX->mode == COMMAND_CONFIG)
return ERROR_OK;
return armv7m_trace_itm_config(target);
}{ ... }
COMMAND_HANDLER(handle_itm_ports_command)
{
struct target *target = get_current_target(CMD_CTX);
struct armv7m_common *armv7m = target_to_armv7m(target);
bool enable;
if (CMD_ARGC != 1)
return ERROR_COMMAND_SYNTAX_ERROR;
COMMAND_PARSE_ON_OFF(CMD_ARGV[0], enable);
memset(armv7m->trace_config.itm_ter, enable ? 0xff : 0,
sizeof(armv7m->trace_config.itm_ter));
/* ... */
if (CMD_CTX->mode == COMMAND_CONFIG)
return ERROR_OK;
return armv7m_trace_itm_config(target);
}{ ... }
static const struct command_registration itm_command_handlers[] = {
{
.name = "port",
.handler = handle_itm_port_command,
.mode = COMMAND_ANY,
.help = "Enable or disable ITM stimulus port",
.usage = "<port> (0|1|on|off)",
...},
{
.name = "ports",
.handler = handle_itm_ports_command,
.mode = COMMAND_ANY,
.help = "Enable or disable all ITM stimulus ports",
.usage = "(0|1|on|off)",
...},
COMMAND_REGISTRATION_DONE
...};
const struct command_registration armv7m_trace_command_handlers[] = {
{
.name = "itm",
.mode = COMMAND_ANY,
.help = "itm command group",
.usage = "",
.chain = itm_command_handlers,
...},
COMMAND_REGISTRATION_DONE
...};