OpenOCD
hla_interface.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2011 by Mathias Kuester *
5  * Mathias Kuester <kesmtp@freenet.de> *
6  * *
7  * Copyright (C) 2012 by Spencer Oliver *
8  * spen@spen-soft.co.uk *
9  ***************************************************************************/
10 
11 #ifdef HAVE_CONFIG_H
12 #include "config.h"
13 #endif
14 
15 /* project specific includes */
16 #include <jtag/interface.h>
17 #include <transport/transport.h>
18 #include <helper/time_support.h>
19 
20 #include <jtag/hla/hla_layout.h>
21 #include <jtag/hla/hla_transport.h>
22 #include <jtag/hla/hla_interface.h>
23 
24 #include <target/target.h>
25 
26 static struct hl_interface hl_if = {
27  .param = {
28  .device_desc = NULL,
29  .transport = HL_TRANSPORT_UNKNOWN,
30  .connect_under_reset = false,
31  .use_stlink_tcp = false,
32  .stlink_tcp_port = 7184,
33  },
34  .layout = NULL,
35  .handle = NULL,
36 };
37 
39 {
40  LOG_DEBUG("hl_interface_open");
41 
43 
47  else
48  LOG_WARNING("\'srst_nogate\' reset_config option is required");
49  }
50 
51  /* set transport mode */
52  hl_if.param.transport = tr;
53 
54  int result = hl_if.layout->open(&hl_if);
55  if (result != ERROR_OK)
56  return result;
57 
58  return hl_interface_init_reset();
59 }
60 
62 {
63  int res;
64 
65  LOG_DEBUG("hl_interface_init_target");
66 
67  /* this is the interface for the current target and we
68  * can setup the private pointer in the tap structure
69  * if the interface match the tap idcode
70  */
71  res = hl_if.layout->api->idcode(hl_if.handle, &t->tap->idcode);
72 
73  if (res != ERROR_OK)
74  return res;
75 
76  unsigned int ii, limit = t->tap->expected_ids_cnt;
77  int found = 0;
78 
79  for (ii = 0; ii < limit; ii++) {
80  uint32_t expected = t->tap->expected_ids[ii];
81 
82  /* treat "-expected-id 0" as a "don't-warn" wildcard */
83  if (!expected || !t->tap->idcode ||
84  (t->tap->idcode == expected)) {
85  found = 1;
86  break;
87  }
88  }
89 
90  if (found == 0) {
91  LOG_WARNING("UNEXPECTED idcode: 0x%08" PRIx32, t->tap->idcode);
92  for (ii = 0; ii < limit; ii++)
93  LOG_ERROR("expected %u of %u: 0x%08" PRIx32, ii + 1, limit,
94  t->tap->expected_ids[ii]);
95 
96  return ERROR_FAIL;
97  }
98 
99  t->tap->priv = &hl_if;
100  t->tap->has_idcode = true;
101 
102  return ERROR_OK;
103 }
104 
105 static int hl_interface_init(void)
106 {
107  LOG_DEBUG("hl_interface_init");
108 
109  /* here we can initialize the layout */
110  return hl_layout_init(&hl_if);
111 }
112 
113 static int hl_interface_quit(void)
114 {
115  LOG_DEBUG("hl_interface_quit");
116 
117  if (hl_if.layout->api->close)
119 
121 
122  free((void *)hl_if.param.device_desc);
123 
124  return ERROR_OK;
125 }
126 
127 static int hl_interface_reset(int req_trst, int req_srst)
128 {
129  return hl_if.layout->api->assert_srst(hl_if.handle, req_srst ? 0 : 1);
130 }
131 
133 {
134  /* in case the adapter has not already handled asserting srst
135  * we will attempt it again */
138  } else {
140  }
141 
142  return ERROR_OK;
143 }
144 
145 static int hl_interface_khz(int khz, int *jtag_speed)
146 {
147  if (!hl_if.layout->api->speed)
148  return ERROR_OK;
149 
150  *jtag_speed = hl_if.layout->api->speed(hl_if.handle, khz, true);
151  return ERROR_OK;
152 }
153 
154 static int hl_interface_speed_div(int speed, int *khz)
155 {
156  *khz = speed;
157  return ERROR_OK;
158 }
159 
160 static int hl_interface_speed(int speed)
161 {
162  if (!hl_if.layout->api->speed)
163  return ERROR_OK;
164 
165  if (!hl_if.handle)
166  return ERROR_OK;
167 
168  hl_if.layout->api->speed(hl_if.handle, speed, false);
169 
170  return ERROR_OK;
171 }
172 
173 int hl_interface_override_target(const char **targetname)
174 {
176  if (hl_if.layout->api->override_target(*targetname)) {
177  *targetname = "hla_target";
178  return ERROR_OK;
179  } else
180  return ERROR_FAIL;
181  }
182  return ERROR_FAIL;
183 }
184 
185 static int hl_interface_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,
186  uint32_t port_size, unsigned int *trace_freq,
187  unsigned int traceclkin_freq, uint16_t *prescaler)
188 {
190  return hl_if.layout->api->config_trace(hl_if.handle, enabled,
191  pin_protocol, port_size, trace_freq, traceclkin_freq, prescaler);
192  else if (enabled) {
193  LOG_ERROR("The selected interface does not support tracing");
194  return ERROR_FAIL;
195  }
196 
197  return ERROR_OK;
198 }
199 
200 static int hl_interface_poll_trace(uint8_t *buf, size_t *size)
201 {
202  if (hl_if.layout->api->poll_trace)
203  return hl_if.layout->api->poll_trace(hl_if.handle, buf, size);
204 
205  return ERROR_FAIL;
206 }
207 
208 COMMAND_HANDLER(hl_interface_handle_device_desc_command)
209 {
210  LOG_DEBUG("hl_interface_handle_device_desc_command");
211 
212  if (CMD_ARGC == 1) {
213  hl_if.param.device_desc = strdup(CMD_ARGV[0]);
214  } else {
215  LOG_ERROR("expected exactly one argument to hl_device_desc <description>");
216  }
217 
218  return ERROR_OK;
219 }
220 
221 COMMAND_HANDLER(hl_interface_handle_layout_command)
222 {
223  LOG_DEBUG("hl_interface_handle_layout_command");
224 
225  if (CMD_ARGC != 1) {
226  LOG_ERROR("Need exactly one argument to stlink_layout");
228  }
229 
230  if (hl_if.layout) {
231  LOG_ERROR("already specified hl_layout %s",
232  hl_if.layout->name);
233  return (strcmp(hl_if.layout->name, CMD_ARGV[0]) != 0)
234  ? ERROR_FAIL : ERROR_OK;
235  }
236 
237  for (const struct hl_layout *l = hl_layout_get_list(); l->name;
238  l++) {
239  if (strcmp(l->name, CMD_ARGV[0]) == 0) {
240  hl_if.layout = l;
241  return ERROR_OK;
242  }
243  }
244 
245  LOG_ERROR("No adapter layout '%s' found", CMD_ARGV[0]);
246  return ERROR_FAIL;
247 }
248 
249 COMMAND_HANDLER(hl_interface_handle_stlink_backend_command)
250 {
251  /* default values */
252  bool use_stlink_tcp = false;
253  uint16_t stlink_tcp_port = 7184;
254 
255  if (CMD_ARGC == 0 || CMD_ARGC > 2)
257  else if (strcmp(CMD_ARGV[0], "usb") == 0) {
258  if (CMD_ARGC > 1)
260  /* else use_stlink_tcp = false (already the case ) */
261  } else if (strcmp(CMD_ARGV[0], "tcp") == 0) {
262  use_stlink_tcp = true;
263  if (CMD_ARGC == 2)
264  COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], stlink_tcp_port);
265  } else
267 
268  hl_if.param.use_stlink_tcp = use_stlink_tcp;
269  hl_if.param.stlink_tcp_port = stlink_tcp_port;
270 
271  return ERROR_OK;
272 }
273 
274 COMMAND_HANDLER(interface_handle_hla_command)
275 {
276  if (CMD_ARGC != 1)
278 
279  if (!hl_if.layout->api->custom_command) {
280  LOG_ERROR("The selected adapter doesn't support custom commands");
281  return ERROR_FAIL;
282  }
283 
285 
286  return ERROR_OK;
287 }
288 
290  {
291  .name = "device_desc",
292  .handler = &hl_interface_handle_device_desc_command,
293  .mode = COMMAND_CONFIG,
294  .help = "set the device description of the adapter",
295  .usage = "description_string",
296  },
297  {
298  .name = "layout",
299  .handler = &hl_interface_handle_layout_command,
300  .mode = COMMAND_CONFIG,
301  .help = "set the layout of the adapter",
302  .usage = "layout_name",
303  },
304  {
305  .name = "stlink_backend",
306  .handler = &hl_interface_handle_stlink_backend_command,
307  .mode = COMMAND_CONFIG,
308  .help = "select which ST-Link backend to use",
309  .usage = "usb | tcp [port]",
310  },
311  {
312  .name = "command",
313  .handler = &interface_handle_hla_command,
314  .mode = COMMAND_EXEC,
315  .help = "execute a custom adapter-specific command",
316  .usage = "<command>",
317  },
319 };
320 
321 static const struct command_registration hl_interface_command_handlers[] = {
322  {
323  .name = "hla",
324  .mode = COMMAND_ANY,
325  .help = "perform hla management",
327  .usage = "",
328  },
330 };
331 
333  .name = "hla",
334  .transport_ids = TRANSPORT_HLA_SWD | TRANSPORT_HLA_JTAG,
335  .transport_preferred_id = TRANSPORT_HLA_SWD,
336  .commands = hl_interface_command_handlers,
337 
338  .init = hl_interface_init,
339  .quit = hl_interface_quit,
340  .reset = hl_interface_reset,
341  .speed = &hl_interface_speed,
342  .khz = &hl_interface_khz,
343  .speed_div = &hl_interface_speed_div,
344  .config_trace = &hl_interface_config_trace,
345  .poll_trace = &hl_interface_poll_trace,
346 
347  /* no ops for HLA, targets hla_target and stm8 intercept them all */
348 };
tpiu_pin_protocol
Definition: arm_tpiu_swo.h:7
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:161
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:405
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:156
#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:445
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:256
@ COMMAND_CONFIG
Definition: command.h:41
@ COMMAND_ANY
Definition: command.h:42
@ COMMAND_EXEC
Definition: command.h:40
void jtag_command_queue_reset(void)
Definition: commands.c:142
uint32_t size
Size of dw_spi_transaction::buffer.
Definition: dw-spi-helper.h:4
int hl_interface_init_target(struct target *t)
Definition: hla_interface.c:61
COMMAND_HANDLER(hl_interface_handle_device_desc_command)
static int hl_interface_speed_div(int speed, int *khz)
static struct hl_interface hl_if
Definition: hla_interface.c:26
int hl_interface_open(enum hl_transports tr)
Definition: hla_interface.c:38
int hl_interface_override_target(const char **targetname)
static int hl_interface_speed(int speed)
static int hl_interface_init(void)
static int hl_interface_poll_trace(uint8_t *buf, size_t *size)
static const struct command_registration hl_interface_command_handlers[]
static int hl_interface_khz(int khz, int *jtag_speed)
static const struct command_registration hl_interface_subcommand_handlers[]
struct adapter_driver hl_adapter_driver
static int hl_interface_reset(int req_trst, int req_srst)
static int hl_interface_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, uint32_t port_size, unsigned int *trace_freq, unsigned int traceclkin_freq, uint16_t *prescaler)
static int hl_interface_quit(void)
int hl_interface_init_reset(void)
int hl_layout_init(struct hl_interface *adapter)
Definition: hla_layout.c:81
const struct hl_layout * hl_layout_get_list(void)
Definition: hla_layout.c:76
hl_transports
Definition: hla_transport.h:14
@ HL_TRANSPORT_UNKNOWN
Definition: hla_transport.h:15
static enum reset_types jtag_reset_config
Definition: jtag/core.c:89
int adapter_deassert_reset(void)
Definition: jtag/core.c:1910
enum reset_types jtag_get_reset_config(void)
Definition: jtag/core.c:1745
int adapter_assert_reset(void)
Definition: jtag/core.c:1890
reset_types
Definition: jtag.h:215
@ RESET_SRST_NO_GATING
Definition: jtag.h:224
@ RESET_CNCT_UNDER_SRST
Definition: jtag.h:225
#define LOG_WARNING(expr ...)
Definition: log.h:144
#define ERROR_FAIL
Definition: log.h:188
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define LOG_DEBUG(expr ...)
Definition: log.h:124
#define ERROR_OK
Definition: log.h:182
Represents a driver for a debugging interface.
Definition: interface.h:208
const char *const name
The name of the interface driver.
Definition: interface.h:210
const char * name
Definition: command.h:239
const char * usage
a string listing the options and arguments, required or optional
Definition: command.h:244
const char * device_desc
Definition: hla_interface.h:23
enum hl_transports transport
Definition: hla_interface.h:25
uint16_t stlink_tcp_port
Definition: hla_interface.h:31
struct hl_interface_param param
Definition: hla_interface.h:36
const struct hl_layout * layout
Definition: hla_interface.h:38
int(* idcode)(void *handle, uint32_t *idcode)
Read the idcode of the target connected to the adapter.
Definition: hla_layout.h:81
int(* override_target)(const char *targetname)
Definition: hla_layout.h:83
int(* assert_srst)(void *handle, int srst)
Definition: hla_layout.h:35
int(* poll_trace)(void *handle, uint8_t *buf, size_t *size)
Poll for new trace data.
Definition: hla_layout.h:114
int(* close)(void *handle)
Definition: hla_layout.h:31
int(* custom_command)(void *handle, const char *command)
Definition: hla_layout.h:85
int(* config_trace)(void *handle, bool enabled, enum tpiu_pin_protocol pin_protocol, uint32_t port_size, unsigned int *trace_freq, unsigned int traceclkin_freq, uint16_t *prescaler)
Configure trace parameters for the adapter.
Definition: hla_layout.h:100
int(* speed)(void *handle, int khz, bool query)
Definition: hla_layout.h:87
char * name
Definition: hla_layout.h:122
int(* open)(struct hl_interface *adapter)
Definition: hla_layout.h:124
struct hl_layout_api * api
Definition: hla_layout.h:128
void * priv
Definition: jtag.h:143
uint8_t expected_ids_cnt
Number of expected identification codes.
Definition: jtag.h:123
bool has_idcode
not all devices have idcode, we'll discover this during chain examination
Definition: jtag.h:118
uint32_t * expected_ids
Array of expected identification codes.
Definition: jtag.h:121
uint32_t idcode
device identification code
Definition: jtag.h:115
Definition: target.h:119
struct jtag_tap * tap
Definition: target.h:122
#define TRANSPORT_HLA_JTAG
Definition: transport.h:21
#define TRANSPORT_HLA_SWD
Definition: transport.h:22
#define NULL
Definition: usb.h:16