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