Add remote bitbang write buffer.
[fw/openocd] / src / jtag / drivers / remote_bitbang.c
1 /***************************************************************************
2  *   Copyright (C) 2011 by Richard Uhler                                   *
3  *   ruhler@mit.edu                                                        *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
17  ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #ifndef _WIN32
24 #include <sys/un.h>
25 #include <netdb.h>
26 #endif
27 #include "helper/system.h"
28 #include "helper/replacements.h"
29 #include <jtag/interface.h>
30 #include "bitbang.h"
31
32 /* arbitrary limit on host name length: */
33 #define REMOTE_BITBANG_HOST_MAX 255
34
35 static char *remote_bitbang_host;
36 static char *remote_bitbang_port;
37
38 static int remote_bitbang_fd;
39 static uint8_t remote_bitbang_send_buf[512];
40 static unsigned int remote_bitbang_send_buf_used;
41
42 /* Circular buffer. When start == end, the buffer is empty. */
43 static char remote_bitbang_recv_buf[64];
44 static unsigned int remote_bitbang_recv_buf_start;
45 static unsigned int remote_bitbang_recv_buf_end;
46
47 static bool remote_bitbang_buf_full(void)
48 {
49         return remote_bitbang_recv_buf_end ==
50                 ((remote_bitbang_recv_buf_start + sizeof(remote_bitbang_recv_buf) - 1) %
51                  sizeof(remote_bitbang_recv_buf));
52 }
53
54 /* Read any incoming data, placing it into the buffer. */
55 static int remote_bitbang_fill_buf(void)
56 {
57         socket_nonblock(remote_bitbang_fd);
58         while (!remote_bitbang_buf_full()) {
59                 unsigned int contiguous_available_space;
60                 if (remote_bitbang_recv_buf_end >= remote_bitbang_recv_buf_start) {
61                         contiguous_available_space = sizeof(remote_bitbang_recv_buf) -
62                                 remote_bitbang_recv_buf_end;
63                         if (remote_bitbang_recv_buf_start == 0)
64                                 contiguous_available_space -= 1;
65                 } else {
66                         contiguous_available_space = remote_bitbang_recv_buf_start -
67                                 remote_bitbang_recv_buf_end - 1;
68                 }
69                 ssize_t count = read_socket(remote_bitbang_fd,
70                                 remote_bitbang_recv_buf + remote_bitbang_recv_buf_end,
71                                 contiguous_available_space);
72                 if (count > 0) {
73                         remote_bitbang_recv_buf_end += count;
74                         if (remote_bitbang_recv_buf_end == sizeof(remote_bitbang_recv_buf))
75                                 remote_bitbang_recv_buf_end = 0;
76                 } else if (count == 0) {
77                         return ERROR_OK;
78                 } else if (count < 0) {
79 #ifdef _WIN32
80                         if (WSAGetLastError() == WSAEWOULDBLOCK) {
81 #else
82                         if (errno == EAGAIN) {
83 #endif
84                                 return ERROR_OK;
85                         } else {
86                                 log_socket_error("remote_bitbang_fill_buf");
87                                 return ERROR_FAIL;
88                         }
89                 }
90         }
91
92         return ERROR_OK;
93 }
94
95 static int remote_bitbang_flush(void)
96 {
97         if (remote_bitbang_send_buf_used <= 0)
98                 return ERROR_OK;
99
100         unsigned int offset = 0;
101         while (offset < remote_bitbang_send_buf_used) {
102                 ssize_t written = write_socket(remote_bitbang_fd, remote_bitbang_send_buf + offset,
103                                                                            remote_bitbang_send_buf_used - offset);
104                 if (written < 0) {
105                         log_socket_error("remote_bitbang_putc");
106                         remote_bitbang_send_buf_used = 0;
107                         return ERROR_FAIL;
108                 }
109                 offset += written;
110         }
111         remote_bitbang_send_buf_used = 0;
112         return ERROR_OK;
113 }
114
115 typedef enum {
116         NO_FLUSH,
117         FLUSH_SEND_BUF
118 } flush_bool_t;
119
120 static int remote_bitbang_queue(int c, flush_bool_t flush)
121 {
122         remote_bitbang_send_buf[remote_bitbang_send_buf_used++] = c;
123         if (flush == FLUSH_SEND_BUF ||
124                         remote_bitbang_send_buf_used >= ARRAY_SIZE(remote_bitbang_send_buf))
125                 return remote_bitbang_flush();
126         return ERROR_OK;
127 }
128
129 static int remote_bitbang_quit(void)
130 {
131         if (remote_bitbang_queue('Q', FLUSH_SEND_BUF) == ERROR_FAIL)
132                 return ERROR_FAIL;
133
134         if (close_socket(remote_bitbang_fd) != 0) {
135                 log_socket_error("close_socket");
136                 return ERROR_FAIL;
137         }
138
139         free(remote_bitbang_host);
140         free(remote_bitbang_port);
141
142         LOG_INFO("remote_bitbang interface quit");
143         return ERROR_OK;
144 }
145
146 static bb_value_t char_to_int(int c)
147 {
148         switch (c) {
149                 case '0':
150                         return BB_LOW;
151                 case '1':
152                         return BB_HIGH;
153                 default:
154                         remote_bitbang_quit();
155                         LOG_ERROR("remote_bitbang: invalid read response: %c(%i)", c, c);
156                         return BB_ERROR;
157         }
158 }
159
160 /* Get the next read response. */
161 static bb_value_t remote_bitbang_rread(void)
162 {
163         if (remote_bitbang_flush() != ERROR_OK)
164                 return ERROR_FAIL;
165
166         /* Enable blocking access. */
167         socket_block(remote_bitbang_fd);
168         char c;
169         ssize_t count = read_socket(remote_bitbang_fd, &c, 1);
170         if (count == 1) {
171                 return char_to_int(c);
172         } else {
173                 remote_bitbang_quit();
174                 LOG_ERROR("read_socket: count=%d", (int) count);
175                 log_socket_error("read_socket");
176                 return BB_ERROR;
177         }
178 }
179
180 static int remote_bitbang_sample(void)
181 {
182         if (remote_bitbang_fill_buf() != ERROR_OK)
183                 return ERROR_FAIL;
184         assert(!remote_bitbang_buf_full());
185         return remote_bitbang_queue('R', NO_FLUSH);
186 }
187
188 static bb_value_t remote_bitbang_read_sample(void)
189 {
190         if (remote_bitbang_recv_buf_start == remote_bitbang_recv_buf_end) {
191                 if (remote_bitbang_fill_buf() != ERROR_OK)
192                         return ERROR_FAIL;
193         }
194         if (remote_bitbang_recv_buf_start != remote_bitbang_recv_buf_end) {
195                 int c = remote_bitbang_recv_buf[remote_bitbang_recv_buf_start];
196                 remote_bitbang_recv_buf_start =
197                         (remote_bitbang_recv_buf_start + 1) % sizeof(remote_bitbang_recv_buf);
198                 return char_to_int(c);
199         }
200         return remote_bitbang_rread();
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(). */
214         return remote_bitbang_queue(c, FLUSH_SEND_BUF);
215 }
216
217 static int remote_bitbang_blink(int on)
218 {
219         char c = on ? 'B' : 'b';
220         return remote_bitbang_queue(c, FLUSH_SEND_BUF);
221 }
222
223 static struct bitbang_interface remote_bitbang_bitbang = {
224         .buf_size = sizeof(remote_bitbang_recv_buf) - 1,
225         .sample = &remote_bitbang_sample,
226         .read_sample = &remote_bitbang_read_sample,
227         .write = &remote_bitbang_write,
228         .blink = &remote_bitbang_blink,
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",
238                         remote_bitbang_host ? remote_bitbang_host : "localhost",
239                         remote_bitbang_port);
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 != NULL ; 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         freeaddrinfo(result); /* No longer needed */
265
266         if (rp == NULL) { /* No address succeeded */
267                 log_socket_error("Failed to connect");
268                 return ERROR_FAIL;
269         }
270
271         return fd;
272 }
273
274 static int remote_bitbang_init_unix(void)
275 {
276         if (remote_bitbang_host == NULL) {
277                 LOG_ERROR("host/socket not specified");
278                 return ERROR_FAIL;
279         }
280
281         LOG_INFO("Connecting to unix socket %s", remote_bitbang_host);
282         int fd = socket(PF_UNIX, SOCK_STREAM, 0);
283         if (fd < 0) {
284                 log_socket_error("socket");
285                 return ERROR_FAIL;
286         }
287
288         struct sockaddr_un addr;
289         addr.sun_family = AF_UNIX;
290         strncpy(addr.sun_path, remote_bitbang_host, sizeof(addr.sun_path));
291         addr.sun_path[sizeof(addr.sun_path)-1] = '\0';
292
293         if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) {
294                 log_socket_error("connect");
295                 return ERROR_FAIL;
296         }
297
298         return fd;
299 }
300
301 static int remote_bitbang_init(void)
302 {
303         bitbang_interface = &remote_bitbang_bitbang;
304
305         remote_bitbang_recv_buf_start = 0;
306         remote_bitbang_recv_buf_end = 0;
307
308         LOG_INFO("Initializing remote_bitbang driver");
309         if (remote_bitbang_port == NULL)
310                 remote_bitbang_fd = remote_bitbang_init_unix();
311         else
312                 remote_bitbang_fd = remote_bitbang_init_tcp();
313
314         if (remote_bitbang_fd < 0)
315                 return remote_bitbang_fd;
316
317         LOG_INFO("remote_bitbang driver initialized");
318         return ERROR_OK;
319 }
320
321 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_port_command)
322 {
323         if (CMD_ARGC == 1) {
324                 uint16_t port;
325                 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port);
326                 free(remote_bitbang_port);
327                 remote_bitbang_port = port == 0 ? NULL : strdup(CMD_ARGV[0]);
328                 return ERROR_OK;
329         }
330         return ERROR_COMMAND_SYNTAX_ERROR;
331 }
332
333 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_host_command)
334 {
335         if (CMD_ARGC == 1) {
336                 free(remote_bitbang_host);
337                 remote_bitbang_host = strdup(CMD_ARGV[0]);
338                 return ERROR_OK;
339         }
340         return ERROR_COMMAND_SYNTAX_ERROR;
341 }
342
343 static const struct command_registration remote_bitbang_command_handlers[] = {
344         {
345                 .name = "remote_bitbang_port",
346                 .handler = remote_bitbang_handle_remote_bitbang_port_command,
347                 .mode = COMMAND_CONFIG,
348                 .help = "Set the port to use to connect to the remote jtag.\n"
349                         "  if 0 or unset, use unix sockets to connect to the remote jtag.",
350                 .usage = "port_number",
351         },
352         {
353                 .name = "remote_bitbang_host",
354                 .handler = remote_bitbang_handle_remote_bitbang_host_command,
355                 .mode = COMMAND_CONFIG,
356                 .help = "Set the host to use to connect to the remote jtag.\n"
357                         "  if port is 0 or unset, this is the name of the unix socket to use.",
358                 .usage = "host_name",
359         },
360         COMMAND_REGISTRATION_DONE,
361 };
362
363 static int remote_bitbang_execute_queue(void)
364 {
365         /* safety: the send buffer must be empty, no leftover characters from
366          * previous transactions */
367         assert(remote_bitbang_send_buf_used == 0);
368
369         /* process the JTAG command queue */
370         int ret = bitbang_execute_queue();
371         if (ret != ERROR_OK)
372                 return ret;
373
374         /* flush not-yet-sent characters, if any */
375         return remote_bitbang_flush();
376 }
377
378 static struct jtag_interface remote_bitbang_interface = {
379         .execute_queue = &remote_bitbang_execute_queue,
380 };
381
382 struct adapter_driver remote_bitbang_adapter_driver = {
383         .name = "remote_bitbang",
384         .transports = jtag_only,
385         .commands = remote_bitbang_command_handlers,
386
387         .init = &remote_bitbang_init,
388         .quit = &remote_bitbang_quit,
389         .reset = &remote_bitbang_reset,
390
391         .jtag_ops = &remote_bitbang_interface,
392 };