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 static char *remote_bitbang_host;
25 static char *remote_bitbang_port;
26 
27 static int remote_bitbang_fd;
28 static uint8_t remote_bitbang_send_buf[512];
29 static unsigned int remote_bitbang_send_buf_used;
30 
31 static bool use_remote_sleep;
32 
33 /* Circular buffer. When start == end, the buffer is empty. */
34 static char remote_bitbang_recv_buf[256];
35 static unsigned int remote_bitbang_recv_buf_start;
36 static unsigned int remote_bitbang_recv_buf_end;
37 
39 {
42  sizeof(remote_bitbang_recv_buf));
43 }
44 
46 {
48 }
49 
51 {
53  unsigned int space = sizeof(remote_bitbang_recv_buf) -
56  space -= 1;
57  return space;
58  } else {
61  }
62 }
63 
64 static int remote_bitbang_flush(void)
65 {
67  return ERROR_OK;
68 
69  unsigned int offset = 0;
73  if (written < 0) {
74  log_socket_error("remote_bitbang_putc");
76  return ERROR_FAIL;
77  }
78  offset += written;
79  }
81  return ERROR_OK;
82 }
83 
84 enum block_bool {
86  BLOCK
87 };
88 
89 /* Read any incoming data, placing it into the buffer. */
90 static int remote_bitbang_fill_buf(enum block_bool block)
91 {
93  /* If the buffer is empty, reset it to 0 so we get more
94  * contiguous space. */
97  }
98 
99  if (block == BLOCK) {
101  return ERROR_FAIL;
103  }
104 
105  bool first = true;
106  while (!remote_bitbang_recv_buf_full()) {
107  unsigned int contiguous_available_space =
111  contiguous_available_space);
112  if (first && block == BLOCK)
114  if (count > 0) {
118  } else if (count == 0) {
119  /* When read_socket returns 0, socket reached EOF and there is
120  * no data to read. But if request was blocking, the caller
121  * expected some data. Such situations should be treated as ERROR. */
122  if (first && block == BLOCK) {
123  LOG_ERROR("remote_bitbang: socket closed by remote");
124  return ERROR_FAIL;
125  }
126  return ERROR_OK;
127  } else if (count < 0) {
128 #ifdef _WIN32
129  if (WSAGetLastError() == WSAEWOULDBLOCK) {
130 #else
131  if (errno == EAGAIN) {
132 #endif
133  return ERROR_OK;
134  } else {
135  log_socket_error("remote_bitbang_fill_buf");
136  return ERROR_FAIL;
137  }
138  }
139  first = false;
140  }
141 
142  return ERROR_OK;
143 }
144 
148 };
149 
150 static int remote_bitbang_queue(int c, enum flush_bool flush)
151 {
153  if (flush == FLUSH_SEND_BUF ||
155  return remote_bitbang_flush();
156  return ERROR_OK;
157 }
158 
159 static int remote_bitbang_quit(void)
160 {
162  return ERROR_FAIL;
163 
164  if (close_socket(remote_bitbang_fd) != 0) {
165  log_socket_error("close_socket");
166  return ERROR_FAIL;
167  }
168 
169  free(remote_bitbang_host);
170  free(remote_bitbang_port);
171 
172  LOG_INFO("remote_bitbang interface quit");
173  return ERROR_OK;
174 }
175 
176 static enum bb_value char_to_int(int c)
177 {
178  switch (c) {
179  case '0':
180  return BB_LOW;
181  case '1':
182  return BB_HIGH;
183  default:
185  LOG_ERROR("remote_bitbang: invalid read response: %c(%i)", c, c);
186  return BB_ERROR;
187  }
188 }
189 
190 static int remote_bitbang_sample(void)
191 {
193  return ERROR_FAIL;
194  assert(!remote_bitbang_recv_buf_full());
195  return remote_bitbang_queue('R', NO_FLUSH);
196 }
197 
198 static enum bb_value remote_bitbang_read_sample(void)
199 {
202  return BB_ERROR;
203  }
208  return char_to_int(c);
209 }
210 
211 static int remote_bitbang_write(int tck, int tms, int tdi)
212 {
213  char c = '0' + ((tck ? 0x4 : 0x0) | (tms ? 0x2 : 0x0) | (tdi ? 0x1 : 0x0));
214  return remote_bitbang_queue(c, NO_FLUSH);
215 }
216 
217 static int remote_bitbang_reset(int trst, int srst)
218 {
219  char c = 'r' + ((trst ? 0x2 : 0x0) | (srst ? 0x1 : 0x0));
220  /* Always flush the send buffer on reset, because the reset call need not be
221  * followed by jtag_execute_queue(). */
223 }
224 
225 static int remote_bitbang_sleep(unsigned int microseconds)
226 {
227  if (!use_remote_sleep) {
228  jtag_sleep(microseconds);
229  return ERROR_OK;
230  }
231 
232  int tmp;
233  unsigned int ms = microseconds / 1000;
234  unsigned int us = microseconds % 1000;
235 
236  for (unsigned int i = 0; i < ms; i++) {
237  tmp = remote_bitbang_queue('Z', NO_FLUSH);
238  if (tmp != ERROR_OK)
239  return tmp;
240  }
241 
242  for (unsigned int i = 0; i < us; i++) {
243  tmp = remote_bitbang_queue('z', NO_FLUSH);
244  if (tmp != ERROR_OK)
245  return tmp;
246  }
247 
248  return remote_bitbang_flush();
249 }
250 
251 static int remote_bitbang_blink(bool on)
252 {
253  char c = on ? 'B' : 'b';
255 }
256 
257 static void remote_bitbang_swdio_drive(bool is_output)
258 {
259  char c = is_output ? 'O' : 'o';
261  LOG_ERROR("Error setting direction for swdio");
262 }
263 
265 {
268  else
269  return BB_ERROR;
270 }
271 
272 static int remote_bitbang_swd_write(int swclk, int swdio)
273 {
274  char c = 'd' + ((swclk ? 0x2 : 0x0) | (swdio ? 0x1 : 0x0));
275  return remote_bitbang_queue(c, NO_FLUSH);
276 }
277 
278 static const struct bitbang_interface remote_bitbang_bitbang = {
279  .buf_size = sizeof(remote_bitbang_recv_buf) - 1,
289 };
290 
291 static int remote_bitbang_init_tcp(void)
292 {
293  struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM };
294  struct addrinfo *result, *rp;
295  int fd = 0;
296 
297  LOG_INFO("Connecting to %s:%s",
300 
301  /* Obtain address(es) matching host/port */
302  int s = getaddrinfo(remote_bitbang_host, remote_bitbang_port, &hints, &result);
303  if (s != 0) {
304  LOG_ERROR("getaddrinfo: %s\n", gai_strerror(s));
305  return ERROR_FAIL;
306  }
307 
308  /* getaddrinfo() returns a list of address structures.
309  Try each address until we successfully connect(2).
310  If socket(2) (or connect(2)) fails, we (close the socket
311  and) try the next address. */
312 
313  for (rp = result; rp ; rp = rp->ai_next) {
314  fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
315  if (fd == -1)
316  continue;
317 
318  if (connect(fd, rp->ai_addr, rp->ai_addrlen) != -1)
319  break; /* Success */
320 
321  close(fd);
322  }
323 
324  /* We work hard to collapse the writes into the minimum number, so when
325  * we write something we want to get it to the other end of the
326  * connection as fast as possible. */
327  int one = 1;
328  /* On Windows optval has to be a const char *. */
329  setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&one, sizeof(one));
330 
331  freeaddrinfo(result); /* No longer needed */
332 
333  if (!rp) { /* No address succeeded */
334  log_socket_error("Failed to connect");
335  return ERROR_FAIL;
336  }
337 
338  return fd;
339 }
340 
341 static int remote_bitbang_init_unix(void)
342 {
343  if (!remote_bitbang_host) {
344  LOG_ERROR("host/socket not specified");
345  return ERROR_FAIL;
346  }
347 
348  LOG_INFO("Connecting to unix socket %s", remote_bitbang_host);
349  int fd = socket(PF_UNIX, SOCK_STREAM, 0);
350  if (fd < 0) {
351  log_socket_error("socket");
352  return ERROR_FAIL;
353  }
354 
355  struct sockaddr_un addr;
356  addr.sun_family = AF_UNIX;
357  strncpy(addr.sun_path, remote_bitbang_host, sizeof(addr.sun_path));
358  addr.sun_path[sizeof(addr.sun_path)-1] = '\0';
359 
360  if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) {
361  log_socket_error("connect");
362  return ERROR_FAIL;
363  }
364 
365  return fd;
366 }
367 
368 static int remote_bitbang_init(void)
369 {
371 
374 
375  LOG_INFO("Initializing remote_bitbang driver");
376  if (!remote_bitbang_port)
378  else
380 
381  if (remote_bitbang_fd < 0)
382  return remote_bitbang_fd;
383 
385 
386  LOG_INFO("remote_bitbang driver initialized");
387  return ERROR_OK;
388 }
389 
390 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_port_command)
391 {
392  if (CMD_ARGC == 1) {
393  uint16_t port;
394  COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port);
395  free(remote_bitbang_port);
396  remote_bitbang_port = port == 0 ? NULL : strdup(CMD_ARGV[0]);
397  return ERROR_OK;
398  }
400 }
401 
402 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_host_command)
403 {
404  if (CMD_ARGC == 1) {
405  free(remote_bitbang_host);
406  remote_bitbang_host = strdup(CMD_ARGV[0]);
407  return ERROR_OK;
408  }
410 }
411 
412 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_use_remote_sleep_command)
413 {
414  if (CMD_ARGC != 1)
416 
418 
419  return ERROR_OK;
420 }
421 
423  {
424  .name = "port",
425  .handler = remote_bitbang_handle_remote_bitbang_port_command,
426  .mode = COMMAND_CONFIG,
427  .help = "Set the port to use to connect to the remote jtag.\n"
428  " if 0 or unset, use unix sockets to connect to the remote jtag.",
429  .usage = "port_number",
430  },
431  {
432  .name = "host",
433  .handler = remote_bitbang_handle_remote_bitbang_host_command,
434  .mode = COMMAND_CONFIG,
435  .help = "Set the host to use to connect to the remote jtag.\n"
436  " if port is 0 or unset, this is the name of the unix socket to use.",
437  .usage = "host_name",
438  },
439  {
440  .name = "use_remote_sleep",
441  .handler = remote_bitbang_handle_remote_bitbang_use_remote_sleep_command,
442  .mode = COMMAND_CONFIG,
443  .help = "Rather than executing sleep locally, include delays in the "
444  "instruction stream for the remote host.",
445  .usage = "(on|off)",
446  },
448 };
449 
451  {
452  .name = "remote_bitbang",
453  .mode = COMMAND_ANY,
454  .help = "perform remote_bitbang management",
456  .usage = "",
457  },
459 };
460 
461 static int remote_bitbang_execute_queue(struct jtag_command *cmd_queue)
462 {
463  /* safety: the send buffer must be empty, no leftover characters from
464  * previous transactions */
465  assert(remote_bitbang_send_buf_used == 0);
466 
467  /* process the JTAG command queue */
468  int ret = bitbang_execute_queue(cmd_queue);
469  if (ret != ERROR_OK)
470  return ret;
471 
472  /* flush not-yet-sent characters, if any */
473  return remote_bitbang_flush();
474 }
475 
478 };
479 
481  .name = "remote_bitbang",
482  .transport_ids = TRANSPORT_JTAG | TRANSPORT_SWD,
483  .transport_preferred_id = TRANSPORT_JTAG,
485 
486  .init = &remote_bitbang_init,
487  .quit = &remote_bitbang_quit,
488  .reset = &remote_bitbang_reset,
489 
490  .jtag_ops = &remote_bitbang_interface,
491  .swd_ops = &bitbang_swd,
492 };
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
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:161
#define COMMAND_PARSE_ON_OFF(in, out)
parses an on/off command argument
Definition: command.h:533
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:405
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:156
#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:445
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:256
@ COMMAND_CONFIG
Definition: command.h:41
@ COMMAND_ANY
Definition: command.h:42
void jtag_sleep(uint32_t us)
Definition: jtag/core.c:1070
void log_socket_error(const char *socket_desc)
Definition: log.c:506
#define ERROR_FAIL
Definition: log.h:188
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define LOG_INFO(expr ...)
Definition: log.h:141
#define ERROR_OK
Definition: log.h:182
static int remote_bitbang_swdio_read(void)
static char remote_bitbang_recv_buf[256]
flush_bool
@ FLUSH_SEND_BUF
@ NO_FLUSH
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 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 enum bb_value char_to_int(int c)
static void remote_bitbang_swdio_drive(bool is_output)
static int remote_bitbang_queue(int c, enum flush_bool flush)
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
static int remote_bitbang_quit(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 const struct bitbang_interface remote_bitbang_bitbang
static char * remote_bitbang_port
static int remote_bitbang_fd
static unsigned int remote_bitbang_send_buf_used
static enum bb_value remote_bitbang_read_sample(void)
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:208
const char *const name
The name of the interface driver.
Definition: interface.h:210
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
enum bb_value(* 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:239
const char * usage
a string listing the options and arguments, required or optional
Definition: command.h:244
Represents a driver for a debugging interface.
Definition: interface.h:183
int(* execute_queue)(struct jtag_command *cmd_queue)
Execute commands in the supplied queue.
Definition: interface.h:196
#define TRANSPORT_SWD
Definition: transport.h:20
#define TRANSPORT_JTAG
Definition: transport.h:19
#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