build: cleanup src/jtag/drivers directory
[openocd.git] / 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, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <sys/socket.h>
26 #include <sys/un.h>
27 #include <netdb.h>
28 #include <jtag/interface.h>
29 #include "bitbang.h"
30
31 /* from unix man page and sys/un.h: */
32 #define UNIX_PATH_MAX 108
33
34 /* arbitrary limit on host name length: */
35 #define REMOTE_BITBANG_HOST_MAX 255
36
37 #define REMOTE_BITBANG_RAISE_ERROR(expr ...) \
38 do { \
39 LOG_ERROR(expr); \
40 LOG_ERROR("Terminating openocd."); \
41 exit(-1); \
42 while (0)
43
44 static char remote_bitbang_host[REMOTE_BITBANG_HOST_MAX] = "openocd";
45 static uint16_t remote_bitbang_port;
46
47 FILE *remote_bitbang_in;
48 FILE *remote_bitbang_out;
49
50 static void remote_bitbang_putc(int c)
51 {
52 if (EOF == fputc(c, remote_bitbang_out))
53 REMOTE_BITBANG_RAISE_ERROR("remote_bitbang_putc: %s", strerror(errno));
54 }
55
56 static int remote_bitbang_quit(void)
57 {
58 if (EOF == fputc('Q', remote_bitbang_out)) {
59 LOG_ERROR("fputs: %s", strerror(errno));
60 return ERROR_FAIL;
61 }
62
63 if (EOF == fflush(remote_bitbang_out)) {
64 LOG_ERROR("fflush: %s", strerror(errno));
65 return ERROR_FAIL;
66 }
67
68 /* We only need to close one of the FILE*s, because they both use the same */
69 /* underlying file descriptor. */
70 if (EOF == fclose(remote_bitbang_out)) {
71 LOG_ERROR("fclose: %s", strerror(errno));
72 return ERROR_FAIL;
73 }
74
75 LOG_INFO("remote_bitbang interface quit");
76 return ERROR_OK;
77 }
78
79 /* Get the next read response. */
80 static int remote_bitbang_rread(void)
81 {
82 if (EOF == fflush(remote_bitbang_out)) {
83 remote_bitbang_quit();
84 REMOTE_BITBANG_RAISE_ERROR("fflush: %s", strerror(errno));
85 }
86
87 int c = fgetc(remote_bitbang_in);
88 switch (c) {
89 case '0':
90 return 0;
91 case '1':
92 return 1;
93 default:
94 remote_bitbang_quit();
95 REMOTE_BITBANG_RAISE_ERROR(
96 "remote_bitbang: invalid read response: %c(%i)", c, c);
97 }
98 }
99
100 static int remote_bitbang_read(void)
101 {
102 remote_bitbang_putc('R');
103 return remote_bitbang_rread();
104 }
105
106 static void remote_bitbang_write(int tck, int tms, int tdi)
107 {
108 char c = '0' + ((tck ? 0x4 : 0x0) | (tms ? 0x2 : 0x0) | (tdi ? 0x1 : 0x0));
109 remote_bitbang_putc(c);
110 }
111
112 static void remote_bitbang_reset(int trst, int srst)
113 {
114 char c = 'r' + ((trst ? 0x2 : 0x0) | (srst ? 0x1 : 0x0));
115 remote_bitbang_putc(c);
116 }
117
118 static void remote_bitbang_blink(int on)
119 {
120 char c = on ? 'B' : 'b';
121 remote_bitbang_putc(c);
122 }
123
124 static struct bitbang_interface remote_bitbang_bitbang = {
125 .read = &remote_bitbang_read,
126 .write = &remote_bitbang_write,
127 .reset = &remote_bitbang_reset,
128 .blink = &remote_bitbang_blink,
129 };
130
131 static int remote_bitbang_speed(int speed)
132 {
133 return ERROR_OK;
134 }
135
136 static int remote_bitbang_init_tcp(void)
137 {
138 LOG_INFO("Connecting to %s:%i", remote_bitbang_host, remote_bitbang_port);
139 int fd = socket(PF_INET, SOCK_STREAM, 0);
140 if (fd < 0) {
141 LOG_ERROR("socket: %s", strerror(errno));
142 return ERROR_FAIL;
143 }
144
145 struct hostent *hent = gethostbyname(remote_bitbang_host);
146 if (hent == NULL) {
147 char *errorstr = "???";
148 switch (h_errno) {
149 case HOST_NOT_FOUND:
150 errorstr = "host not found";
151 break;
152 case NO_ADDRESS:
153 errorstr = "no address";
154 break;
155 case NO_RECOVERY:
156 errorstr = "no recovery";
157 break;
158 case TRY_AGAIN:
159 errorstr = "try again";
160 break;
161 }
162 LOG_ERROR("gethostbyname: %s", errorstr);
163 return ERROR_FAIL;
164 }
165
166 struct sockaddr_in addr;
167 addr.sin_family = AF_INET;
168 addr.sin_port = htons(remote_bitbang_port);
169 addr.sin_addr = *(struct in_addr *)hent->h_addr;
170 if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) {
171 LOG_ERROR("connect: %s", strerror(errno));
172 return ERROR_FAIL;
173 }
174
175 remote_bitbang_in = fdopen(fd, "r");
176 if (remote_bitbang_in == NULL) {
177 LOG_ERROR("fdopen: failed to open read stream");
178 return ERROR_FAIL;
179 }
180
181 remote_bitbang_out = fdopen(fd, "w");
182 if (remote_bitbang_out == NULL) {
183 LOG_ERROR("fdopen: failed to open write stream");
184 return ERROR_FAIL;
185 }
186
187 LOG_INFO("remote_bitbang driver initialized");
188 return ERROR_OK;
189 }
190
191 static int remote_bitbang_init_unix(void)
192 {
193 LOG_INFO("Connecting to unix socket %s", remote_bitbang_host);
194 int fd = socket(PF_UNIX, SOCK_STREAM, 0);
195 if (fd < 0) {
196 LOG_ERROR("socket: %s", strerror(errno));
197 return ERROR_FAIL;
198 }
199
200 struct sockaddr_un addr;
201 addr.sun_family = AF_UNIX;
202 strncpy(addr.sun_path, remote_bitbang_host, UNIX_PATH_MAX);
203 addr.sun_path[UNIX_PATH_MAX-1] = '\0';
204
205 if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) {
206 LOG_ERROR("connect: %s", strerror(errno));
207 return ERROR_FAIL;
208 }
209
210 remote_bitbang_in = fdopen(fd, "r");
211 if (remote_bitbang_in == NULL) {
212 LOG_ERROR("fdopen: failed to open read stream");
213 return ERROR_FAIL;
214 }
215
216 remote_bitbang_out = fdopen(fd, "w");
217 if (remote_bitbang_out == NULL) {
218 LOG_ERROR("fdopen: failed to open write stream");
219 return ERROR_FAIL;
220 }
221
222 LOG_INFO("remote_bitbang driver initialized");
223 return ERROR_OK;
224 }
225
226 static int remote_bitbang_init(void)
227 {
228 bitbang_interface = &remote_bitbang_bitbang;
229
230 LOG_INFO("Initializing remote_bitbang driver");
231 if (remote_bitbang_port == 0)
232 return remote_bitbang_init_unix();
233 return remote_bitbang_init_tcp();
234 }
235
236 static int remote_bitbang_khz(int khz, int *jtag_speed)
237 {
238 *jtag_speed = 0;
239 return ERROR_OK;
240 }
241
242 static int remote_bitbang_speed_div(int speed, int *khz)
243 {
244 /* I don't think this really matters any. */
245 *khz = 1;
246 return ERROR_OK;
247 }
248
249
250 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_port_command)
251 {
252 if (CMD_ARGC == 1) {
253 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], remote_bitbang_port);
254 return ERROR_OK;
255 }
256 return ERROR_COMMAND_SYNTAX_ERROR;
257 }
258
259 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_host_command)
260 {
261 if (CMD_ARGC == 1) {
262 strncpy(remote_bitbang_host, CMD_ARGV[0], REMOTE_BITBANG_HOST_MAX);
263 remote_bitbang_host[REMOTE_BITBANG_HOST_MAX-1] = '\0';
264 return ERROR_OK;
265 }
266 return ERROR_COMMAND_SYNTAX_ERROR;
267 }
268
269
270 static const struct command_registration remote_bitbang_command_handlers[] = {
271 {
272 .name = "remote_bitbang_port",
273 .handler = remote_bitbang_handle_remote_bitbang_port_command,
274 .mode = COMMAND_CONFIG,
275 .help = "Set the port to use to connect to the remote jtag.\n"
276 " if 0, use unix sockets to connect to the remote jtag.",
277 .usage = "port_number",
278 },
279 {
280 .name = "remote_bitbang_host",
281 .handler = remote_bitbang_handle_remote_bitbang_host_command,
282 .mode = COMMAND_CONFIG,
283 .help = "Set the host to use to connect to the remote jtag.\n"
284 " if port is 0, this is the name of the unix socket to use.",
285 .usage = "host_name",
286 },
287 COMMAND_REGISTRATION_DONE,
288 };
289
290 struct jtag_interface remote_bitbang_interface = {
291 .name = "remote_bitbang",
292 .execute_queue = &bitbang_execute_queue,
293 .speed = &remote_bitbang_speed,
294 .commands = remote_bitbang_command_handlers,
295 .init = &remote_bitbang_init,
296 .quit = &remote_bitbang_quit,
297 .khz = &remote_bitbang_khz,
298 .speed_div = &remote_bitbang_speed_div,
299 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)