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 
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11 
12 #ifndef _WIN32
13 #include <sys/un.h>
14 #include <netdb.h>
15 #include <netinet/tcp.h>
16 #endif
17 #include "helper/system.h"
18 #include "helper/replacements.h"
19 #include <jtag/interface.h>
20 #include "bitbang.h"
21 
22 /* arbitrary limit on host name length: */
23 #define REMOTE_BITBANG_HOST_MAX 255
24 
25 static char *remote_bitbang_host;
26 static char *remote_bitbang_port;
27 
28 static int remote_bitbang_fd;
29 static uint8_t remote_bitbang_send_buf[512];
30 static unsigned int remote_bitbang_send_buf_used;
31 
32 /* Circular buffer. When start == end, the buffer is empty. */
33 static char remote_bitbang_recv_buf[256];
34 static unsigned int remote_bitbang_recv_buf_start;
35 static unsigned int remote_bitbang_recv_buf_end;
36 
38 {
41  sizeof(remote_bitbang_recv_buf));
42 }
43 
45 {
47 }
48 
50 {
52  unsigned int space = sizeof(remote_bitbang_recv_buf) -
55  space -= 1;
56  return space;
57  } else {
60  }
61 }
62 
63 static int remote_bitbang_flush(void)
64 {
66  return ERROR_OK;
67 
68  unsigned int offset = 0;
72  if (written < 0) {
73  log_socket_error("remote_bitbang_putc");
75  return ERROR_FAIL;
76  }
77  offset += written;
78  }
80  return ERROR_OK;
81 }
82 
83 enum block_bool {
85  BLOCK
86 };
87 
88 /* Read any incoming data, placing it into the buffer. */
89 static int remote_bitbang_fill_buf(enum block_bool block)
90 {
92  /* If the buffer is empty, reset it to 0 so we get more
93  * contiguous space. */
96  }
97 
98  if (block == BLOCK) {
100  return ERROR_FAIL;
102  }
103 
104  bool first = true;
105  while (!remote_bitbang_recv_buf_full()) {
106  unsigned int contiguous_available_space =
110  contiguous_available_space);
111  if (first && block == BLOCK)
113  first = false;
114  if (count > 0) {
118  } else if (count == 0) {
119  return ERROR_OK;
120  } else if (count < 0) {
121 #ifdef _WIN32
122  if (WSAGetLastError() == WSAEWOULDBLOCK) {
123 #else
124  if (errno == EAGAIN) {
125 #endif
126  return ERROR_OK;
127  } else {
128  log_socket_error("remote_bitbang_fill_buf");
129  return ERROR_FAIL;
130  }
131  }
132  }
133 
134  return ERROR_OK;
135 }
136 
137 typedef enum {
141 
142 static int remote_bitbang_queue(int c, flush_bool_t flush)
143 {
145  if (flush == FLUSH_SEND_BUF ||
147  return remote_bitbang_flush();
148  return ERROR_OK;
149 }
150 
151 static int remote_bitbang_quit(void)
152 {
154  return ERROR_FAIL;
155 
156  if (close_socket(remote_bitbang_fd) != 0) {
157  log_socket_error("close_socket");
158  return ERROR_FAIL;
159  }
160 
161  free(remote_bitbang_host);
162  free(remote_bitbang_port);
163 
164  LOG_INFO("remote_bitbang interface quit");
165  return ERROR_OK;
166 }
167 
168 static bb_value_t char_to_int(int c)
169 {
170  switch (c) {
171  case '0':
172  return BB_LOW;
173  case '1':
174  return BB_HIGH;
175  default:
177  LOG_ERROR("remote_bitbang: invalid read response: %c(%i)", c, c);
178  return BB_ERROR;
179  }
180 }
181 
182 static int remote_bitbang_sample(void)
183 {
185  return ERROR_FAIL;
186  assert(!remote_bitbang_recv_buf_full());
187  return remote_bitbang_queue('R', NO_FLUSH);
188 }
189 
191 {
194  return BB_ERROR;
195  }
200  return char_to_int(c);
201 }
202 
203 static int remote_bitbang_write(int tck, int tms, int tdi)
204 {
205  char c = '0' + ((tck ? 0x4 : 0x0) | (tms ? 0x2 : 0x0) | (tdi ? 0x1 : 0x0));
206  return remote_bitbang_queue(c, NO_FLUSH);
207 }
208 
209 static int remote_bitbang_reset(int trst, int srst)
210 {
211  char c = 'r' + ((trst ? 0x2 : 0x0) | (srst ? 0x1 : 0x0));
212  /* Always flush the send buffer on reset, because the reset call need not be
213  * followed by jtag_execute_queue(). */
215 }
216 
217 static int remote_bitbang_blink(int on)
218 {
219  char c = on ? 'B' : 'b';
221 }
222 
224  .buf_size = sizeof(remote_bitbang_recv_buf) - 1,
229 };
230 
231 static int remote_bitbang_init_tcp(void)
232 {
233  struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM };
234  struct addrinfo *result, *rp;
235  int fd = 0;
236 
237  LOG_INFO("Connecting to %s:%s",
240 
241  /* Obtain address(es) matching host/port */
242  int s = getaddrinfo(remote_bitbang_host, remote_bitbang_port, &hints, &result);
243  if (s != 0) {
244  LOG_ERROR("getaddrinfo: %s\n", gai_strerror(s));
245  return ERROR_FAIL;
246  }
247 
248  /* getaddrinfo() returns a list of address structures.
249  Try each address until we successfully connect(2).
250  If socket(2) (or connect(2)) fails, we (close the socket
251  and) try the next address. */
252 
253  for (rp = result; rp ; rp = rp->ai_next) {
254  fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
255  if (fd == -1)
256  continue;
257 
258  if (connect(fd, rp->ai_addr, rp->ai_addrlen) != -1)
259  break; /* Success */
260 
261  close(fd);
262  }
263 
264  /* We work hard to collapse the writes into the minimum number, so when
265  * we write something we want to get it to the other end of the
266  * connection as fast as possible. */
267  int one = 1;
268  /* On Windows optval has to be a const char *. */
269  setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&one, sizeof(one));
270 
271  freeaddrinfo(result); /* No longer needed */
272 
273  if (!rp) { /* No address succeeded */
274  log_socket_error("Failed to connect");
275  return ERROR_FAIL;
276  }
277 
278  return fd;
279 }
280 
281 static int remote_bitbang_init_unix(void)
282 {
283  if (!remote_bitbang_host) {
284  LOG_ERROR("host/socket not specified");
285  return ERROR_FAIL;
286  }
287 
288  LOG_INFO("Connecting to unix socket %s", remote_bitbang_host);
289  int fd = socket(PF_UNIX, SOCK_STREAM, 0);
290  if (fd < 0) {
291  log_socket_error("socket");
292  return ERROR_FAIL;
293  }
294 
295  struct sockaddr_un addr;
296  addr.sun_family = AF_UNIX;
297  strncpy(addr.sun_path, remote_bitbang_host, sizeof(addr.sun_path));
298  addr.sun_path[sizeof(addr.sun_path)-1] = '\0';
299 
300  if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) {
301  log_socket_error("connect");
302  return ERROR_FAIL;
303  }
304 
305  return fd;
306 }
307 
308 static int remote_bitbang_init(void)
309 {
311 
314 
315  LOG_INFO("Initializing remote_bitbang driver");
316  if (!remote_bitbang_port)
318  else
320 
321  if (remote_bitbang_fd < 0)
322  return remote_bitbang_fd;
323 
325 
326  LOG_INFO("remote_bitbang driver initialized");
327  return ERROR_OK;
328 }
329 
330 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_port_command)
331 {
332  if (CMD_ARGC == 1) {
333  uint16_t port;
334  COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port);
335  free(remote_bitbang_port);
336  remote_bitbang_port = port == 0 ? NULL : strdup(CMD_ARGV[0]);
337  return ERROR_OK;
338  }
340 }
341 
342 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_host_command)
343 {
344  if (CMD_ARGC == 1) {
345  free(remote_bitbang_host);
346  remote_bitbang_host = strdup(CMD_ARGV[0]);
347  return ERROR_OK;
348  }
350 }
351 
353  {
354  .name = "port",
355  .handler = remote_bitbang_handle_remote_bitbang_port_command,
356  .mode = COMMAND_CONFIG,
357  .help = "Set the port to use to connect to the remote jtag.\n"
358  " if 0 or unset, use unix sockets to connect to the remote jtag.",
359  .usage = "port_number",
360  },
361  {
362  .name = "host",
363  .handler = remote_bitbang_handle_remote_bitbang_host_command,
364  .mode = COMMAND_CONFIG,
365  .help = "Set the host to use to connect to the remote jtag.\n"
366  " if port is 0 or unset, this is the name of the unix socket to use.",
367  .usage = "host_name",
368  },
370 };
371 
373  {
374  .name = "remote_bitbang",
375  .mode = COMMAND_ANY,
376  .help = "perform remote_bitbang management",
378  .usage = "",
379  },
381 };
382 
384 {
385  /* safety: the send buffer must be empty, no leftover characters from
386  * previous transactions */
387  assert(remote_bitbang_send_buf_used == 0);
388 
389  /* process the JTAG command queue */
390  int ret = bitbang_execute_queue();
391  if (ret != ERROR_OK)
392  return ret;
393 
394  /* flush not-yet-sent characters, if any */
395  return remote_bitbang_flush();
396 }
397 
400 };
401 
403  .name = "remote_bitbang",
404  .transports = jtag_only,
406 
407  .init = &remote_bitbang_init,
408  .quit = &remote_bitbang_quit,
409  .reset = &remote_bitbang_reset,
410 
411  .jtag_ops = &remote_bitbang_interface,
412 };
const char *const jtag_only[]
Definition: adapter.c:31
int bitbang_execute_queue(void)
Definition: bitbang.c:281
bb_value_t
Definition: bitbang.h:16
@ BB_LOW
Definition: bitbang.h:17
@ BB_HIGH
Definition: bitbang.h:18
@ BB_ERROR
Definition: bitbang.h:19
#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_ANY
Definition: command.h:42
void log_socket_error(const char *socket_desc)
Definition: log.c:488
#define ERROR_FAIL
Definition: log.h:161
#define LOG_ERROR(expr ...)
Definition: log.h:123
#define LOG_INFO(expr ...)
Definition: log.h:117
#define ERROR_OK
Definition: log.h:155
uint32_t addr
Definition: nuttx.c:65
static int remote_bitbang_queue(int c, flush_bool_t flush)
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 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 unsigned int remote_bitbang_recv_buf_end
static bool remote_bitbang_recv_buf_full(void)
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)
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 int remote_bitbang_execute_queue(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:194
static int read_socket(int handle, void *buffer, unsigned int count)
Definition: replacements.h:176
static int close_socket(int sock)
Definition: replacements.h:185
static int write_socket(int handle, const void *buffer, unsigned int count)
Definition: replacements.h:167
static void socket_nonblock(int fd)
Definition: replacements.h:205
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:29
int(* sample)(void)
Sample TDO and put the result in a buffer.
Definition: bitbang.h:38
bb_value_t(* read_sample)(void)
Return the next unread value from the buffer.
Definition: bitbang.h:41
int(* write)(int tck, int tms, int tdi)
Set TCK, TMS, and TDI to the given values.
Definition: bitbang.h:44
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:35
int(* blink)(int on)
Blink led (optional).
Definition: bitbang.h:47
const char * name
Definition: command.h:229
const char * usage
a string listing the options and arguments, required or optional
Definition: command.h:235
Represents a driver for a debugging interface.
Definition: interface.h:184
int(* execute_queue)(void)
Execute queued commands.
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