OpenOCD
armv7m_trace.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2015 Paul Fertser <fercerpav@gmail.com> *
5  ***************************************************************************/
6 
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10 
11 #include <target/target.h>
12 #include <target/armv7m.h>
13 #include <target/cortex_m.h>
14 #include <target/armv7m_trace.h>
15 #include <jtag/interface.h>
16 #include <helper/time_support.h>
17 
19 {
20  struct armv7m_common *armv7m = target_to_armv7m(target);
21  struct armv7m_trace_config *trace_config = &armv7m->trace_config;
22  int retval;
23 
25  if (retval != ERROR_OK)
26  return retval;
27 
28  /* pg315 of CoreSight Components
29  * It is recommended that the ITMEn bit is cleared and waits for the
30  * ITMBusy bit to be cleared, before changing any fields in the
31  * Control Register, otherwise the behavior can be unpredictable.
32  */
33  uint32_t itm_tcr;
34  retval = target_read_u32(target, ITM_TCR, &itm_tcr);
35  if (retval != ERROR_OK)
36  return retval;
37  retval = target_write_u32(target,
38  ITM_TCR,
39  itm_tcr & ~ITM_TCR_ITMENA_BIT
40  );
41  if (retval != ERROR_OK)
42  return retval;
43 
44  int64_t then = timeval_ms() + 1000;
45  do {
46  retval = target_read_u32(target, ITM_TCR, &itm_tcr);
47  if (retval != ERROR_OK)
48  return retval;
49  if (timeval_ms() > then) {
50  LOG_ERROR("timeout waiting for ITM_TCR_BUSY_BIT");
51  return ERROR_FAIL;
52  }
53  } while (itm_tcr & ITM_TCR_BUSY_BIT);
54 
55  /* Enable ITM, TXENA, set TraceBusID and other parameters */
56  retval = target_write_u32(target, ITM_TCR, (1 << 0) | (1 << 3) |
57  (trace_config->itm_diff_timestamps << 1) |
58  (trace_config->itm_synchro_packets << 2) |
59  (trace_config->itm_async_timestamps << 4) |
60  (trace_config->itm_ts_prescale << 8) |
61  (trace_config->trace_bus_id << 16));
62  if (retval != ERROR_OK)
63  return retval;
64 
65  for (unsigned int i = 0; i < 8; i++) {
66  retval = target_write_u32(target, ITM_TER0 + i * 4,
67  trace_config->itm_ter[i]);
68  if (retval != ERROR_OK)
69  return retval;
70  }
71 
72  return ERROR_OK;
73 }
74 
75 COMMAND_HANDLER(handle_itm_port_command)
76 {
78  struct armv7m_common *armv7m = target_to_armv7m(target);
79  unsigned int reg_idx;
80  uint8_t port;
81  bool enable;
82 
83  if (CMD_ARGC != 2)
85 
86  COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], port);
87  COMMAND_PARSE_ON_OFF(CMD_ARGV[1], enable);
88  reg_idx = port / 32;
89  port = port % 32;
90  if (enable)
91  armv7m->trace_config.itm_ter[reg_idx] |= (1 << port);
92  else
93  armv7m->trace_config.itm_ter[reg_idx] &= ~(1 << port);
94 
95  if (CMD_CTX->mode == COMMAND_EXEC)
97 
98  armv7m->trace_config.itm_deferred_config = true;
99  return ERROR_OK;
100 }
101 
102 COMMAND_HANDLER(handle_itm_ports_command)
103 {
105  struct armv7m_common *armv7m = target_to_armv7m(target);
106  bool enable;
107 
108  if (CMD_ARGC != 1)
110 
111  COMMAND_PARSE_ON_OFF(CMD_ARGV[0], enable);
112  memset(armv7m->trace_config.itm_ter, enable ? 0xff : 0,
113  sizeof(armv7m->trace_config.itm_ter));
114 
115  if (CMD_CTX->mode == COMMAND_EXEC)
117 
118  armv7m->trace_config.itm_deferred_config = true;
119  return ERROR_OK;
120 }
121 
122 static const struct command_registration itm_command_handlers[] = {
123  {
124  .name = "port",
125  .handler = handle_itm_port_command,
126  .mode = COMMAND_ANY,
127  .help = "Enable or disable ITM stimulus port",
128  .usage = "<port> (0|1|on|off)",
129  },
130  {
131  .name = "ports",
132  .handler = handle_itm_ports_command,
133  .mode = COMMAND_ANY,
134  .help = "Enable or disable all ITM stimulus ports",
135  .usage = "(0|1|on|off)",
136  },
138 };
139 
141  {
142  .name = "itm",
143  .mode = COMMAND_ANY,
144  .help = "itm command group",
145  .usage = "",
146  .chain = itm_command_handlers,
147  },
149 };
static struct armv7m_common * target_to_armv7m(struct target *target)
Definition: armv7m.h:262
COMMAND_HANDLER(handle_itm_port_command)
Definition: armv7m_trace.c:75
const struct command_registration armv7m_trace_command_handlers[]
Definition: armv7m_trace.c:140
static const struct command_registration itm_command_handlers[]
Definition: armv7m_trace.c:122
int armv7m_trace_itm_config(struct target *target)
Configure hardware accordingly to the current ITM target settings.
Definition: armv7m_trace.c:18
Holds the interface to ITM and DWT configuration functions.
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:156
#define COMMAND_PARSE_ON_OFF(in, out)
parses an on/off command argument
Definition: command.h:521
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:402
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:151
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
Definition: command.h:442
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
Definition: command.h:146
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:253
@ COMMAND_ANY
Definition: command.h:42
@ COMMAND_EXEC
Definition: command.h:40
#define ITM_TCR_ITMENA_BIT
Definition: cortex_m.h:27
#define ITM_LAR_KEY
Definition: cortex_m.h:30
#define ITM_TCR
Definition: cortex_m.h:26
#define ITM_TER0
Definition: cortex_m.h:24
#define ITM_TCR_BUSY_BIT
Definition: cortex_m.h:28
#define ITM_LAR
Definition: cortex_m.h:29
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define ERROR_OK
Definition: log.h:164
struct armv7m_trace_config trace_config
Definition: armv7m.h:238
uint32_t itm_ter[8]
Bitmask of currently enabled ITM stimuli.
Definition: armv7m_trace.h:27
unsigned int trace_bus_id
Identifier for multi-source trace stream formatting.
Definition: armv7m_trace.h:29
bool itm_diff_timestamps
Enable differential timestamps.
Definition: armv7m_trace.h:33
bool itm_async_timestamps
Enable async timestamps model.
Definition: armv7m_trace.h:35
bool itm_synchro_packets
Enable synchronisation packet transmission (for sync port only)
Definition: armv7m_trace.h:37
bool itm_deferred_config
Config ITM after target examine.
Definition: armv7m_trace.h:39
enum itm_ts_prescaler itm_ts_prescale
Prescaler for the timestamp counter.
Definition: armv7m_trace.h:31
const char * name
Definition: command.h:235
Definition: target.h:116
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2641
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2550
struct target * get_current_target(struct command_context *cmd_ctx)
Definition: target.c:458
int64_t timeval_ms(void)