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  first = false;
118  if (count > 0) {
122  } else if (count == 0) {
123  return ERROR_OK;
124  } else if (count < 0) {
125 #ifdef _WIN32
126  if (WSAGetLastError() == WSAEWOULDBLOCK) {
127 #else
128  if (errno == EAGAIN) {
129 #endif
130  return ERROR_OK;
131  } else {
132  log_socket_error("remote_bitbang_fill_buf");
133  return ERROR_FAIL;
134  }
135  }
136  }
137 
138  return ERROR_OK;
139 }
140 
141 typedef enum {
145 
146 static int remote_bitbang_queue(int c, flush_bool_t flush)
147 {
149  if (flush == FLUSH_SEND_BUF ||
151  return remote_bitbang_flush();
152  return ERROR_OK;
153 }
154 
155 static int remote_bitbang_quit(void)
156 {
158  return ERROR_FAIL;
159 
160  if (close_socket(remote_bitbang_fd) != 0) {
161  log_socket_error("close_socket");
162  return ERROR_FAIL;
163  }
164 
165  free(remote_bitbang_host);
166  free(remote_bitbang_port);
167 
168  LOG_INFO("remote_bitbang interface quit");
169  return ERROR_OK;
170 }
171 
172 static bb_value_t char_to_int(int c)
173 {
174  switch (c) {
175  case '0':
176  return BB_LOW;
177  case '1':
178  return BB_HIGH;
179  default:
181  LOG_ERROR("remote_bitbang: invalid read response: %c(%i)", c, c);
182  return BB_ERROR;
183  }
184 }
185 
186 static int remote_bitbang_sample(void)
187 {
189  return ERROR_FAIL;
190  assert(!remote_bitbang_recv_buf_full());
191  return remote_bitbang_queue('R', NO_FLUSH);
192 }
193 
195 {
198  return BB_ERROR;
199  }
204  return char_to_int(c);
205 }
206 
207 static int remote_bitbang_write(int tck, int tms, int tdi)
208 {
209  char c = '0' + ((tck ? 0x4 : 0x0) | (tms ? 0x2 : 0x0) | (tdi ? 0x1 : 0x0));
210  return remote_bitbang_queue(c, NO_FLUSH);
211 }
212 
213 static int remote_bitbang_reset(int trst, int srst)
214 {
215  char c = 'r' + ((trst ? 0x2 : 0x0) | (srst ? 0x1 : 0x0));
216  /* Always flush the send buffer on reset, because the reset call need not be
217  * followed by jtag_execute_queue(). */
219 }
220 
221 static int remote_bitbang_sleep(unsigned int microseconds)
222 {
223  if (!use_remote_sleep) {
224  jtag_sleep(microseconds);
225  return ERROR_OK;
226  }
227 
228  int tmp;
229  unsigned int ms = microseconds / 1000;
230  unsigned int us = microseconds % 1000;
231 
232  for (unsigned int i = 0; i < ms; i++) {
233  tmp = remote_bitbang_queue('Z', NO_FLUSH);
234  if (tmp != ERROR_OK)
235  return tmp;
236  }
237 
238  for (unsigned int i = 0; i < us; i++) {
239  tmp = remote_bitbang_queue('z', NO_FLUSH);
240  if (tmp != ERROR_OK)
241  return tmp;
242  }
243 
244  return remote_bitbang_flush();
245 }
246 
247 static int remote_bitbang_blink(int on)
248 {
249  char c = on ? 'B' : 'b';
251 }
252 
253 static void remote_bitbang_swdio_drive(bool is_output)
254 {
255  char c = is_output ? 'O' : 'o';
257  LOG_ERROR("Error setting direction for swdio");
258 }
259 
261 {
264  else
265  return BB_ERROR;
266 }
267 
268 static int remote_bitbang_swd_write(int swclk, int swdio)
269 {
270  char c = 'd' + ((swclk ? 0x2 : 0x0) | (swdio ? 0x1 : 0x0));
271  return remote_bitbang_queue(c, NO_FLUSH);
272 }
273 
275  .buf_size = sizeof(remote_bitbang_recv_buf) - 1,
285 };
286 
287 static int remote_bitbang_init_tcp(void)
288 {
289  struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM };
290  struct addrinfo *result, *rp;
291  int fd = 0;
292 
293  LOG_INFO("Connecting to %s:%s",
296 
297  /* Obtain address(es) matching host/port */
298  int s = getaddrinfo(remote_bitbang_host, remote_bitbang_port, &hints, &result);
299  if (s != 0) {
300  LOG_ERROR("getaddrinfo: %s\n", gai_strerror(s));
301  return ERROR_FAIL;
302  }
303 
304  /* getaddrinfo() returns a list of address structures.
305  Try each address until we successfully connect(2).
306  If socket(2) (or connect(2)) fails, we (close the socket
307  and) try the next address. */
308 
309  for (rp = result; rp ; rp = rp->ai_next) {
310  fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
311  if (fd == -1)
312  continue;
313 
314  if (connect(fd, rp->ai_addr, rp->ai_addrlen) != -1)
315  break; /* Success */
316 
317  close(fd);
318  }
319 
320  /* We work hard to collapse the writes into the minimum number, so when
321  * we write something we want to get it to the other end of the
322  * connection as fast as possible. */
323  int one = 1;
324  /* On Windows optval has to be a const char *. */
325  setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&one, sizeof(one));
326 
327  freeaddrinfo(result); /* No longer needed */
328 
329  if (!rp) { /* No address succeeded */
330  log_socket_error("Failed to connect");
331  return ERROR_FAIL;
332  }
333 
334  return fd;
335 }
336 
337 static int remote_bitbang_init_unix(void)
338 {
339  if (!remote_bitbang_host) {
340  LOG_ERROR("host/socket not specified");
341  return ERROR_FAIL;
342  }
343 
344  LOG_INFO("Connecting to unix socket %s", remote_bitbang_host);
345  int fd = socket(PF_UNIX, SOCK_STREAM, 0);
346  if (fd < 0) {
347  log_socket_error("socket");
348  return ERROR_FAIL;
349  }
350 
351  struct sockaddr_un addr;
352  addr.sun_family = AF_UNIX;
353  strncpy(addr.sun_path, remote_bitbang_host, sizeof(addr.sun_path));
354  addr.sun_path[sizeof(addr.sun_path)-1] = '\0';
355 
356  if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) {
357  log_socket_error("connect");
358  return ERROR_FAIL;
359  }
360 
361  return fd;
362 }
363 
364 static int remote_bitbang_init(void)
365 {
367 
370 
371  LOG_INFO("Initializing remote_bitbang driver");
372  if (!remote_bitbang_port)
374  else
376 
377  if (remote_bitbang_fd < 0)
378  return remote_bitbang_fd;
379 
381 
382  LOG_INFO("remote_bitbang driver initialized");
383  return ERROR_OK;
384 }
385 
386 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_port_command)
387 {
388  if (CMD_ARGC == 1) {
389  uint16_t port;
390  COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port);
391  free(remote_bitbang_port);
392  remote_bitbang_port = port == 0 ? NULL : strdup(CMD_ARGV[0]);
393  return ERROR_OK;
394  }
396 }
397 
398 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_host_command)
399 {
400  if (CMD_ARGC == 1) {
401  free(remote_bitbang_host);
402  remote_bitbang_host = strdup(CMD_ARGV[0]);
403  return ERROR_OK;
404  }
406 }
407 
408 static const char * const remote_bitbang_transports[] = { "jtag", "swd", NULL };
409 
410 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_use_remote_sleep_command)
411 {
412  if (CMD_ARGC != 1)
414 
416 
417  return ERROR_OK;
418 }
419 
421  {
422  .name = "port",
423  .handler = remote_bitbang_handle_remote_bitbang_port_command,
424  .mode = COMMAND_CONFIG,
425  .help = "Set the port to use to connect to the remote jtag.\n"
426  " if 0 or unset, use unix sockets to connect to the remote jtag.",
427  .usage = "port_number",
428  },
429  {
430  .name = "host",
431  .handler = remote_bitbang_handle_remote_bitbang_host_command,
432  .mode = COMMAND_CONFIG,
433  .help = "Set the host to use to connect to the remote jtag.\n"
434  " if port is 0 or unset, this is the name of the unix socket to use.",
435  .usage = "host_name",
436  },
437  {
438  .name = "use_remote_sleep",
439  .handler = remote_bitbang_handle_remote_bitbang_use_remote_sleep_command,
440  .mode = COMMAND_CONFIG,
441  .help = "Rather than executing sleep locally, include delays in the "
442  "instruction stream for the remote host.",
443  .usage = "(on|off)",
444  },
446 };
447 
449  {
450  .name = "remote_bitbang",
451  .mode = COMMAND_ANY,
452  .help = "perform remote_bitbang management",
454  .usage = "",
455  },
457 };
458 
459 static int remote_bitbang_execute_queue(struct jtag_command *cmd_queue)
460 {
461  /* safety: the send buffer must be empty, no leftover characters from
462  * previous transactions */
463  assert(remote_bitbang_send_buf_used == 0);
464 
465  /* process the JTAG command queue */
466  int ret = bitbang_execute_queue(cmd_queue);
467  if (ret != ERROR_OK)
468  return ret;
469 
470  /* flush not-yet-sent characters, if any */
471  return remote_bitbang_flush();
472 }
473 
476 };
477 
479  .name = "remote_bitbang",
480  .transports = remote_bitbang_transports,
482 
483  .init = &remote_bitbang_init,
484  .quit = &remote_bitbang_quit,
485  .reset = &remote_bitbang_reset,
486 
487  .jtag_ops = &remote_bitbang_interface,
488  .swd_ops = &bitbang_swd,
489 };
int bitbang_execute_queue(struct jtag_command *cmd_queue)
Definition: bitbang.c:296
const struct swd_driver bitbang_swd
Definition: bitbang.c:617
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:521
#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 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_blink(int on)
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
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
int(* blink)(int on)
Blink led (optional).
Definition: bitbang.h:48
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