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  .vid = { 0 },
30  .pid = { 0 },
31  .transport = HL_TRANSPORT_UNKNOWN,
32  .connect_under_reset = false,
33  .use_stlink_tcp = false,
34  .stlink_tcp_port = 7184,
35  },
36  .layout = NULL,
37  .handle = NULL,
38 };
39 
41 {
42  LOG_DEBUG("hl_interface_open");
43 
45 
49  else
50  LOG_WARNING("\'srst_nogate\' reset_config option is required");
51  }
52 
53  /* set transport mode */
54  hl_if.param.transport = tr;
55 
56  int result = hl_if.layout->open(&hl_if);
57  if (result != ERROR_OK)
58  return result;
59 
60  return hl_interface_init_reset();
61 }
62 
64 {
65  int res;
66 
67  LOG_DEBUG("hl_interface_init_target");
68 
69  /* this is the interface for the current target and we
70  * can setup the private pointer in the tap structure
71  * if the interface match the tap idcode
72  */
73  res = hl_if.layout->api->idcode(hl_if.handle, &t->tap->idcode);
74 
75  if (res != ERROR_OK)
76  return res;
77 
78  unsigned int ii, limit = t->tap->expected_ids_cnt;
79  int found = 0;
80 
81  for (ii = 0; ii < limit; ii++) {
82  uint32_t expected = t->tap->expected_ids[ii];
83 
84  /* treat "-expected-id 0" as a "don't-warn" wildcard */
85  if (!expected || !t->tap->idcode ||
86  (t->tap->idcode == expected)) {
87  found = 1;
88  break;
89  }
90  }
91 
92  if (found == 0) {
93  LOG_WARNING("UNEXPECTED idcode: 0x%08" PRIx32, t->tap->idcode);
94  for (ii = 0; ii < limit; ii++)
95  LOG_ERROR("expected %u of %u: 0x%08" PRIx32, ii + 1, limit,
96  t->tap->expected_ids[ii]);
97 
98  return ERROR_FAIL;
99  }
100 
101  t->tap->priv = &hl_if;
102  t->tap->has_idcode = true;
103 
104  return ERROR_OK;
105 }
106 
107 static int hl_interface_init(void)
108 {
109  LOG_DEBUG("hl_interface_init");
110 
111  /* here we can initialize the layout */
112  return hl_layout_init(&hl_if);
113 }
114 
115 static int hl_interface_quit(void)
116 {
117  LOG_DEBUG("hl_interface_quit");
118 
119  if (hl_if.layout->api->close)
121 
123 
124  free((void *)hl_if.param.device_desc);
125 
126  return ERROR_OK;
127 }
128 
129 static int hl_interface_reset(int req_trst, int req_srst)
130 {
131  return hl_if.layout->api->assert_srst(hl_if.handle, req_srst ? 0 : 1);
132 }
133 
135 {
136  /* in case the adapter has not already handled asserting srst
137  * we will attempt it again */
140  } else {
142  }
143 
144  return ERROR_OK;
145 }
146 
147 static int hl_interface_khz(int khz, int *jtag_speed)
148 {
149  if (!hl_if.layout->api->speed)
150  return ERROR_OK;
151 
152  *jtag_speed = hl_if.layout->api->speed(hl_if.handle, khz, true);
153  return ERROR_OK;
154 }
155 
156 static int hl_interface_speed_div(int speed, int *khz)
157 {
158  *khz = speed;
159  return ERROR_OK;
160 }
161 
162 static int hl_interface_speed(int speed)
163 {
164  if (!hl_if.layout->api->speed)
165  return ERROR_OK;
166 
167  if (!hl_if.handle)
168  return ERROR_OK;
169 
170  hl_if.layout->api->speed(hl_if.handle, speed, false);
171 
172  return ERROR_OK;
173 }
174 
175 int hl_interface_override_target(const char **targetname)
176 {
178  if (hl_if.layout->api->override_target(*targetname)) {
179  *targetname = "hla_target";
180  return ERROR_OK;
181  } else
182  return ERROR_FAIL;
183  }
184  return ERROR_FAIL;
185 }
186 
187 static int hl_interface_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,
188  uint32_t port_size, unsigned int *trace_freq,
189  unsigned int traceclkin_freq, uint16_t *prescaler)
190 {
192  return hl_if.layout->api->config_trace(hl_if.handle, enabled,
193  pin_protocol, port_size, trace_freq, traceclkin_freq, prescaler);
194  else if (enabled) {
195  LOG_ERROR("The selected interface does not support tracing");
196  return ERROR_FAIL;
197  }
198 
199  return ERROR_OK;
200 }
201 
202 static int hl_interface_poll_trace(uint8_t *buf, size_t *size)
203 {
204  if (hl_if.layout->api->poll_trace)
205  return hl_if.layout->api->poll_trace(hl_if.handle, buf, size);
206 
207  return ERROR_FAIL;
208 }
209 
210 COMMAND_HANDLER(hl_interface_handle_device_desc_command)
211 {
212  LOG_DEBUG("hl_interface_handle_device_desc_command");
213 
214  if (CMD_ARGC == 1) {
215  hl_if.param.device_desc = strdup(CMD_ARGV[0]);
216  } else {
217  LOG_ERROR("expected exactly one argument to hl_device_desc <description>");
218  }
219 
220  return ERROR_OK;
221 }
222 
223 COMMAND_HANDLER(hl_interface_handle_layout_command)
224 {
225  LOG_DEBUG("hl_interface_handle_layout_command");
226 
227  if (CMD_ARGC != 1) {
228  LOG_ERROR("Need exactly one argument to stlink_layout");
230  }
231 
232  if (hl_if.layout) {
233  LOG_ERROR("already specified hl_layout %s",
234  hl_if.layout->name);
235  return (strcmp(hl_if.layout->name, CMD_ARGV[0]) != 0)
236  ? ERROR_FAIL : ERROR_OK;
237  }
238 
239  for (const struct hl_layout *l = hl_layout_get_list(); l->name;
240  l++) {
241  if (strcmp(l->name, CMD_ARGV[0]) == 0) {
242  hl_if.layout = l;
243  return ERROR_OK;
244  }
245  }
246 
247  LOG_ERROR("No adapter layout '%s' found", CMD_ARGV[0]);
248  return ERROR_FAIL;
249 }
250 
251 COMMAND_HANDLER(hl_interface_handle_vid_pid_command)
252 {
253  if (CMD_ARGC > HLA_MAX_USB_IDS * 2) {
254  LOG_WARNING("ignoring extra IDs in hla_vid_pid "
255  "(maximum is %d pairs)", HLA_MAX_USB_IDS);
257  }
258  if (CMD_ARGC < 2 || (CMD_ARGC & 1)) {
259  LOG_WARNING("incomplete hla_vid_pid configuration directive");
261  }
262 
263  unsigned int i;
264  for (i = 0; i < CMD_ARGC; i += 2) {
265  COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], hl_if.param.vid[i / 2]);
266  COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], hl_if.param.pid[i / 2]);
267  }
268 
269  /*
270  * Explicitly terminate, in case there are multiple instances of
271  * hla_vid_pid.
272  */
273  hl_if.param.vid[i / 2] = hl_if.param.pid[i / 2] = 0;
274 
275  return ERROR_OK;
276 }
277 
278 COMMAND_HANDLER(hl_interface_handle_stlink_backend_command)
279 {
280  /* default values */
281  bool use_stlink_tcp = false;
282  uint16_t stlink_tcp_port = 7184;
283 
284  if (CMD_ARGC == 0 || CMD_ARGC > 2)
286  else if (strcmp(CMD_ARGV[0], "usb") == 0) {
287  if (CMD_ARGC > 1)
289  /* else use_stlink_tcp = false (already the case ) */
290  } else if (strcmp(CMD_ARGV[0], "tcp") == 0) {
291  use_stlink_tcp = true;
292  if (CMD_ARGC == 2)
293  COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], stlink_tcp_port);
294  } else
296 
297  hl_if.param.use_stlink_tcp = use_stlink_tcp;
298  hl_if.param.stlink_tcp_port = stlink_tcp_port;
299 
300  return ERROR_OK;
301 }
302 
303 COMMAND_HANDLER(interface_handle_hla_command)
304 {
305  if (CMD_ARGC != 1)
307 
308  if (!hl_if.layout->api->custom_command) {
309  LOG_ERROR("The selected adapter doesn't support custom commands");
310  return ERROR_FAIL;
311  }
312 
314 
315  return ERROR_OK;
316 }
317 
319  {
320  .name = "device_desc",
321  .handler = &hl_interface_handle_device_desc_command,
322  .mode = COMMAND_CONFIG,
323  .help = "set the device description of the adapter",
324  .usage = "description_string",
325  },
326  {
327  .name = "layout",
328  .handler = &hl_interface_handle_layout_command,
329  .mode = COMMAND_CONFIG,
330  .help = "set the layout of the adapter",
331  .usage = "layout_name",
332  },
333  {
334  .name = "vid_pid",
335  .handler = &hl_interface_handle_vid_pid_command,
336  .mode = COMMAND_CONFIG,
337  .help = "the vendor and product ID of the adapter",
338  .usage = "(vid pid)*",
339  },
340  {
341  .name = "stlink_backend",
342  .handler = &hl_interface_handle_stlink_backend_command,
343  .mode = COMMAND_CONFIG,
344  .help = "select which ST-Link backend to use",
345  .usage = "usb | tcp [port]",
346  },
347  {
348  .name = "command",
349  .handler = &interface_handle_hla_command,
350  .mode = COMMAND_EXEC,
351  .help = "execute a custom adapter-specific command",
352  .usage = "<command>",
353  },
355 };
356 
357 static const struct command_registration hl_interface_command_handlers[] = {
358  {
359  .name = "hla",
360  .mode = COMMAND_ANY,
361  .help = "perform hla management",
363  .usage = "",
364  },
366 };
367 
369  .name = "hla",
370  .transports = hl_transports,
371  .commands = hl_interface_command_handlers,
372 
373  .init = hl_interface_init,
374  .quit = hl_interface_quit,
375  .reset = hl_interface_reset,
376  .speed = &hl_interface_speed,
377  .khz = &hl_interface_khz,
378  .speed_div = &hl_interface_speed_div,
379  .config_trace = &hl_interface_config_trace,
380  .poll_trace = &hl_interface_poll_trace,
381 
382  /* no ops for HLA, targets hla_target and stm8 intercept them all */
383 };
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:156
#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 COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:253
@ 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
int hl_interface_init_target(struct target *t)
Definition: hla_interface.c:63
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:40
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)
#define HLA_MAX_USB_IDS
Definition: hla_interface.h:21
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:1905
enum reset_types jtag_get_reset_config(void)
Definition: jtag/core.c:1740
int adapter_assert_reset(void)
Definition: jtag/core.c:1885
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:129
#define ERROR_FAIL
Definition: log.h:173
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:167
size_t size
Size of the control block search area.
Definition: rtt/rtt.c:30
Represents a driver for a debugging interface.
Definition: interface.h:207
const char *const name
The name of the interface driver.
Definition: interface.h:209
const char * name
Definition: command.h:235
const char * usage
a string listing the options and arguments, required or optional
Definition: command.h:241
const char * device_desc
Definition: hla_interface.h:25
enum hl_transports transport
Definition: hla_interface.h:31
uint16_t pid[HLA_MAX_USB_IDS+1]
List of recognised PIDs.
Definition: hla_interface.h:29
uint16_t stlink_tcp_port
Definition: hla_interface.h:37
uint16_t vid[HLA_MAX_USB_IDS+1]
List of recognised VIDs.
Definition: hla_interface.h:27
struct hl_interface_param param
Definition: hla_interface.h:42
const struct hl_layout * layout
Definition: hla_interface.h:44
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:116
struct jtag_tap * tap
Definition: target.h:119
#define NULL
Definition: usb.h:16