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