OpenOCD
remote_bitbang.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2011 by Richard Uhler *
5  * ruhler@mit.edu *
6  * *
7  * Copyright (C) 2021 by Manuel Wick <manuel@matronix.de> *
8  ***************************************************************************/
9 
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
13 
14 #ifndef _WIN32
15 #include <sys/un.h>
16 #include <netdb.h>
17 #include <netinet/tcp.h>
18 #endif
19 #include "helper/system.h"
20 #include "helper/replacements.h"
21 #include <jtag/interface.h>
22 #include "bitbang.h"
23 
24 /* arbitrary limit on host name length: */
25 #define REMOTE_BITBANG_HOST_MAX 255
26 
27 static char *remote_bitbang_host;
28 static char *remote_bitbang_port;
29 
30 static int remote_bitbang_fd;
31 static uint8_t remote_bitbang_send_buf[512];
32 static unsigned int remote_bitbang_send_buf_used;
33 
34 static bool use_remote_sleep;
35 
36 /* Circular buffer. When start == end, the buffer is empty. */
37 static char remote_bitbang_recv_buf[256];
38 static unsigned int remote_bitbang_recv_buf_start;
39 static unsigned int remote_bitbang_recv_buf_end;
40 
42 {
45  sizeof(remote_bitbang_recv_buf));
46 }
47 
49 {
51 }
52 
54 {
56  unsigned int space = sizeof(remote_bitbang_recv_buf) -
59  space -= 1;
60  return space;
61  } else {
64  }
65 }
66 
67 static int remote_bitbang_flush(void)
68 {
70  return ERROR_OK;
71 
72  unsigned int offset = 0;
76  if (written < 0) {
77  log_socket_error("remote_bitbang_putc");
79  return ERROR_FAIL;
80  }
81  offset += written;
82  }
84  return ERROR_OK;
85 }
86 
87 enum block_bool {
89  BLOCK
90 };
91 
92 /* Read any incoming data, placing it into the buffer. */
93 static int remote_bitbang_fill_buf(enum block_bool block)
94 {
96  /* If the buffer is empty, reset it to 0 so we get more
97  * contiguous space. */
100  }
101 
102  if (block == BLOCK) {
104  return ERROR_FAIL;
106  }
107 
108  bool first = true;
109  while (!remote_bitbang_recv_buf_full()) {
110  unsigned int contiguous_available_space =
114  contiguous_available_space);
115  if (first && block == BLOCK)
117  if (count > 0) {
121  } else if (count == 0) {
122  /* When read_socket returns 0, socket reached EOF and there is
123  * no data to read. But if request was blocking, the caller
124  * expected some data. Such situations should be treated as ERROR. */
125  if (first && block == BLOCK) {
126  LOG_ERROR("remote_bitbang: socket closed by remote");
127  return ERROR_FAIL;
128  }
129  return ERROR_OK;
130  } else if (count < 0) {
131 #ifdef _WIN32
132  if (WSAGetLastError() == WSAEWOULDBLOCK) {
133 #else
134  if (errno == EAGAIN) {
135 #endif
136  return ERROR_OK;
137  } else {
138  log_socket_error("remote_bitbang_fill_buf");
139  return ERROR_FAIL;
140  }
141  }
142  first = false;
143  }
144 
145  return ERROR_OK;
146 }
147 
148 typedef enum {
152 
153 static int remote_bitbang_queue(int c, flush_bool_t flush)
154 {
156  if (flush == FLUSH_SEND_BUF ||
158  return remote_bitbang_flush();
159  return ERROR_OK;
160 }
161 
162 static int remote_bitbang_quit(void)
163 {
165  return ERROR_FAIL;
166 
167  if (close_socket(remote_bitbang_fd) != 0) {
168  log_socket_error("close_socket");
169  return ERROR_FAIL;
170  }
171 
172  free(remote_bitbang_host);
173  free(remote_bitbang_port);
174 
175  LOG_INFO("remote_bitbang interface quit");
176  return ERROR_OK;
177 }
178 
179 static bb_value_t char_to_int(int c)
180 {
181  switch (c) {
182  case '0':
183  return BB_LOW;
184  case '1':
185  return BB_HIGH;
186  default:
188  LOG_ERROR("remote_bitbang: invalid read response: %c(%i)", c, c);
189  return BB_ERROR;
190  }
191 }
192 
193 static int remote_bitbang_sample(void)
194 {
196  return ERROR_FAIL;
197  assert(!remote_bitbang_recv_buf_full());
198  return remote_bitbang_queue('R', NO_FLUSH);
199 }
200 
202 {
205  return BB_ERROR;
206  }
211  return char_to_int(c);
212 }
213 
214 static int remote_bitbang_write(int tck, int tms, int tdi)
215 {
216  char c = '0' + ((tck ? 0x4 : 0x0) | (tms ? 0x2 : 0x0) | (tdi ? 0x1 : 0x0));
217  return remote_bitbang_queue(c, NO_FLUSH);
218 }
219 
220 static int remote_bitbang_reset(int trst, int srst)
221 {
222  char c = 'r' + ((trst ? 0x2 : 0x0) | (srst ? 0x1 : 0x0));
223  /* Always flush the send buffer on reset, because the reset call need not be
224  * followed by jtag_execute_queue(). */
226 }
227 
228 static int remote_bitbang_sleep(unsigned int microseconds)
229 {
230  if (!use_remote_sleep) {
231  jtag_sleep(microseconds);
232  return ERROR_OK;
233  }
234 
235  int tmp;
236  unsigned int ms = microseconds / 1000;
237  unsigned int us = microseconds % 1000;
238 
239  for (unsigned int i = 0; i < ms; i++) {
240  tmp = remote_bitbang_queue('Z', NO_FLUSH);
241  if (tmp != ERROR_OK)
242  return tmp;
243  }
244 
245  for (unsigned int i = 0; i < us; i++) {
246  tmp = remote_bitbang_queue('z', NO_FLUSH);
247  if (tmp != ERROR_OK)
248  return tmp;
249  }
250 
251  return remote_bitbang_flush();
252 }
253 
254 static int remote_bitbang_blink(bool on)
255 {
256  char c = on ? 'B' : 'b';
258 }
259 
260 static void remote_bitbang_swdio_drive(bool is_output)
261 {
262  char c = is_output ? 'O' : 'o';
264  LOG_ERROR("Error setting direction for swdio");
265 }
266 
268 {
271  else
272  return BB_ERROR;
273 }
274 
275 static int remote_bitbang_swd_write(int swclk, int swdio)
276 {
277  char c = 'd' + ((swclk ? 0x2 : 0x0) | (swdio ? 0x1 : 0x0));
278  return remote_bitbang_queue(c, NO_FLUSH);
279 }
280 
282  .buf_size = sizeof(remote_bitbang_recv_buf) - 1,
292 };
293 
294 static int remote_bitbang_init_tcp(void)
295 {
296  struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM };
297  struct addrinfo *result, *rp;
298  int fd = 0;
299 
300  LOG_INFO("Connecting to %s:%s",
303 
304  /* Obtain address(es) matching host/port */
305  int s = getaddrinfo(remote_bitbang_host, remote_bitbang_port, &hints, &result);
306  if (s != 0) {
307  LOG_ERROR("getaddrinfo: %s\n", gai_strerror(s));
308  return ERROR_FAIL;
309  }
310 
311  /* getaddrinfo() returns a list of address structures.
312  Try each address until we successfully connect(2).
313  If socket(2) (or connect(2)) fails, we (close the socket
314  and) try the next address. */
315 
316  for (rp = result; rp ; rp = rp->ai_next) {
317  fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
318  if (fd == -1)
319  continue;
320 
321  if (connect(fd, rp->ai_addr, rp->ai_addrlen) != -1)
322  break; /* Success */
323 
324  close(fd);
325  }
326 
327  /* We work hard to collapse the writes into the minimum number, so when
328  * we write something we want to get it to the other end of the
329  * connection as fast as possible. */
330  int one = 1;
331  /* On Windows optval has to be a const char *. */
332  setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&one, sizeof(one));
333 
334  freeaddrinfo(result); /* No longer needed */
335 
336  if (!rp) { /* No address succeeded */
337  log_socket_error("Failed to connect");
338  return ERROR_FAIL;
339  }
340 
341  return fd;
342 }
343 
344 static int remote_bitbang_init_unix(void)
345 {
346  if (!remote_bitbang_host) {
347  LOG_ERROR("host/socket not specified");
348  return ERROR_FAIL;
349  }
350 
351  LOG_INFO("Connecting to unix socket %s", remote_bitbang_host);
352  int fd = socket(PF_UNIX, SOCK_STREAM, 0);
353  if (fd < 0) {
354  log_socket_error("socket");
355  return ERROR_FAIL;
356  }
357 
358  struct sockaddr_un addr;
359  addr.sun_family = AF_UNIX;
360  strncpy(addr.sun_path, remote_bitbang_host, sizeof(addr.sun_path));
361  addr.sun_path[sizeof(addr.sun_path)-1] = '\0';
362 
363  if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) {
364  log_socket_error("connect");
365  return ERROR_FAIL;
366  }
367 
368  return fd;
369 }
370 
371 static int remote_bitbang_init(void)
372 {
374 
377 
378  LOG_INFO("Initializing remote_bitbang driver");
379  if (!remote_bitbang_port)
381  else
383 
384  if (remote_bitbang_fd < 0)
385  return remote_bitbang_fd;
386 
388 
389  LOG_INFO("remote_bitbang driver initialized");
390  return ERROR_OK;
391 }
392 
393 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_port_command)
394 {
395  if (CMD_ARGC == 1) {
396  uint16_t port;
397  COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port);
398  free(remote_bitbang_port);
399  remote_bitbang_port = port == 0 ? NULL : strdup(CMD_ARGV[0]);
400  return ERROR_OK;
401  }
403 }
404 
405 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_host_command)
406 {
407  if (CMD_ARGC == 1) {
408  free(remote_bitbang_host);
409  remote_bitbang_host = strdup(CMD_ARGV[0]);
410  return ERROR_OK;
411  }
413 }
414 
415 static const char * const remote_bitbang_transports[] = { "jtag", "swd", NULL };
416 
417 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_use_remote_sleep_command)
418 {
419  if (CMD_ARGC != 1)
421 
423 
424  return ERROR_OK;
425 }
426 
428  {
429  .name = "port",
430  .handler = remote_bitbang_handle_remote_bitbang_port_command,
431  .mode = COMMAND_CONFIG,
432  .help = "Set the port to use to connect to the remote jtag.\n"
433  " if 0 or unset, use unix sockets to connect to the remote jtag.",
434  .usage = "port_number",
435  },
436  {
437  .name = "host",
438  .handler = remote_bitbang_handle_remote_bitbang_host_command,
439  .mode = COMMAND_CONFIG,
440  .help = "Set the host to use to connect to the remote jtag.\n"
441  " if port is 0 or unset, this is the name of the unix socket to use.",
442  .usage = "host_name",
443  },
444  {
445  .name = "use_remote_sleep",
446  .handler = remote_bitbang_handle_remote_bitbang_use_remote_sleep_command,
447  .mode = COMMAND_CONFIG,
448  .help = "Rather than executing sleep locally, include delays in the "
449  "instruction stream for the remote host.",
450  .usage = "(on|off)",
451  },
453 };
454 
456  {
457  .name = "remote_bitbang",
458  .mode = COMMAND_ANY,
459  .help = "perform remote_bitbang management",
461  .usage = "",
462  },
464 };
465 
466 static int remote_bitbang_execute_queue(struct jtag_command *cmd_queue)
467 {
468  /* safety: the send buffer must be empty, no leftover characters from
469  * previous transactions */
470  assert(remote_bitbang_send_buf_used == 0);
471 
472  /* process the JTAG command queue */
473  int ret = bitbang_execute_queue(cmd_queue);
474  if (ret != ERROR_OK)
475  return ret;
476 
477  /* flush not-yet-sent characters, if any */
478  return remote_bitbang_flush();
479 }
480 
483 };
484 
486  .name = "remote_bitbang",
487  .transports = remote_bitbang_transports,
489 
490  .init = &remote_bitbang_init,
491  .quit = &remote_bitbang_quit,
492  .reset = &remote_bitbang_reset,
493 
494  .jtag_ops = &remote_bitbang_interface,
495  .swd_ops = &bitbang_swd,
496 };
int bitbang_execute_queue(struct jtag_command *cmd_queue)
Definition: bitbang.c:293
const struct swd_driver bitbang_swd
Definition: bitbang.c:614
bb_value_t
Definition: bitbang.h:17
@ BB_LOW
Definition: bitbang.h:18
@ BB_HIGH
Definition: bitbang.h:19
@ BB_ERROR
Definition: bitbang.h:20
#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:530
#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
void jtag_sleep(uint32_t us)
Definition: jtag/core.c:1062
void log_socket_error(const char *socket_desc)
Definition: log.c:484
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_INFO(expr ...)
Definition: log.h:126
#define ERROR_OK
Definition: log.h:164
static int remote_bitbang_queue(int c, flush_bool_t flush)
static int remote_bitbang_swdio_read(void)
static const char *const remote_bitbang_transports[]
static char remote_bitbang_recv_buf[256]
static int remote_bitbang_init_tcp(void)
static int remote_bitbang_sample(void)
static const struct command_registration remote_bitbang_subcommand_handlers[]
static bool remote_bitbang_recv_buf_empty(void)
static struct bitbang_interface remote_bitbang_bitbang
static int remote_bitbang_execute_queue(struct jtag_command *cmd_queue)
static int remote_bitbang_swd_write(int swclk, int swdio)
static unsigned int remote_bitbang_recv_buf_contiguous_available_space(void)
static uint8_t remote_bitbang_send_buf[512]
static int remote_bitbang_fill_buf(enum block_bool block)
static int remote_bitbang_init(void)
static struct jtag_interface remote_bitbang_interface
static int remote_bitbang_blink(bool on)
static void remote_bitbang_swdio_drive(bool is_output)
static unsigned int remote_bitbang_recv_buf_end
static bool remote_bitbang_recv_buf_full(void)
static int remote_bitbang_sleep(unsigned int microseconds)
static int remote_bitbang_init_unix(void)
static int remote_bitbang_reset(int trst, int srst)
static const struct command_registration remote_bitbang_command_handlers[]
static unsigned int remote_bitbang_recv_buf_start
flush_bool_t
@ FLUSH_SEND_BUF
@ NO_FLUSH
static bb_value_t char_to_int(int c)
static int remote_bitbang_quit(void)
static bb_value_t remote_bitbang_read_sample(void)
static int remote_bitbang_write(int tck, int tms, int tdi)
static bool use_remote_sleep
COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_port_command)
static int remote_bitbang_flush(void)
static char * remote_bitbang_port
static int remote_bitbang_fd
static unsigned int remote_bitbang_send_buf_used
static char * remote_bitbang_host
block_bool
@ BLOCK
@ NO_BLOCK
struct adapter_driver remote_bitbang_adapter_driver
static void socket_block(int fd)
Definition: replacements.h:193
static int read_socket(int handle, void *buffer, unsigned int count)
Definition: replacements.h:175
static int close_socket(int sock)
Definition: replacements.h:184
static int write_socket(int handle, const void *buffer, unsigned int count)
Definition: replacements.h:166
static void socket_nonblock(int fd)
Definition: replacements.h:204
target_addr_t addr
Start address to search for the control block.
Definition: rtt/rtt.c:28
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
Low level callbacks (for bitbang).
Definition: bitbang.h:30
int(* sleep)(unsigned int microseconds)
Sleep for some number of microseconds.
Definition: bitbang.h:60
int(* swdio_read)(void)
Sample SWDIO and return the value.
Definition: bitbang.h:51
int(* swd_write)(int swclk, int swdio)
Set SWCLK and SWDIO to the given value.
Definition: bitbang.h:57
int(* sample)(void)
Sample TDO and put the result in a buffer.
Definition: bitbang.h:39
bb_value_t(* read_sample)(void)
Return the next unread value from the buffer.
Definition: bitbang.h:42
int(* flush)(void)
Force a flush.
Definition: bitbang.h:63
int(* write)(int tck, int tms, int tdi)
Set TCK, TMS, and TDI to the given values.
Definition: bitbang.h:45
void(* swdio_drive)(bool on)
Set direction of SWDIO.
Definition: bitbang.h:54
int(* blink)(bool on)
Blink led (optional).
Definition: bitbang.h:48
size_t buf_size
The number of TDO samples that can be buffered up before the caller has to call read_sample.
Definition: bitbang.h:36
const char * name
Definition: command.h:235
const char * usage
a string listing the options and arguments, required or optional
Definition: command.h:241
Represents a driver for a debugging interface.
Definition: interface.h:182
int(* execute_queue)(struct jtag_command *cmd_queue)
Execute commands in the supplied queue.
Definition: interface.h:195
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
Definition: types.h:57
#define NULL
Definition: usb.h:16
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t count[4]
Definition: vdebug.c:22