Set TCP_NODELAY for local connections to jtag_vpi.
[openocd.git] / src / jtag / drivers / jtag_vpi.c
1 /*
2 * JTAG to VPI driver
3 *
4 * Copyright (C) 2013 Franck Jullien, <elec4fun@gmail.com>
5 *
6 * See file CREDITS for list of people who contributed to this
7 * project.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <jtag/interface.h>
28 #ifdef HAVE_ARPA_INET_H
29 #include <arpa/inet.h>
30 #endif
31
32 #ifndef _WIN32
33 #include <netinet/tcp.h>
34 #endif
35
36 #define NO_TAP_SHIFT 0
37 #define TAP_SHIFT 1
38
39 #define SERVER_ADDRESS "127.0.0.1"
40 #define SERVER_PORT 5555
41
42 #define XFERT_MAX_SIZE 512
43
44 #define CMD_RESET 0
45 #define CMD_TMS_SEQ 1
46 #define CMD_SCAN_CHAIN 2
47 #define CMD_SCAN_CHAIN_FLIP_TMS 3
48 #define CMD_STOP_SIMU 4
49
50 int server_port = SERVER_PORT;
51 char *server_address;
52
53 int sockfd;
54 struct sockaddr_in serv_addr;
55
56 struct vpi_cmd {
57 int cmd;
58 unsigned char buffer_out[XFERT_MAX_SIZE];
59 unsigned char buffer_in[XFERT_MAX_SIZE];
60 int length;
61 int nb_bits;
62 };
63
64 static int jtag_vpi_send_cmd(struct vpi_cmd *vpi)
65 {
66 int retval = write_socket(sockfd, vpi, sizeof(struct vpi_cmd));
67 if (retval <= 0)
68 return ERROR_FAIL;
69
70 return ERROR_OK;
71 }
72
73 static int jtag_vpi_receive_cmd(struct vpi_cmd *vpi)
74 {
75 int retval = read_socket(sockfd, vpi, sizeof(struct vpi_cmd));
76 if (retval < (int)sizeof(struct vpi_cmd))
77 return ERROR_FAIL;
78
79 return ERROR_OK;
80 }
81
82 /**
83 * jtag_vpi_reset - ask to reset the JTAG device
84 * @trst: 1 if TRST is to be asserted
85 * @srst: 1 if SRST is to be asserted
86 */
87 static int jtag_vpi_reset(int trst, int srst)
88 {
89 struct vpi_cmd vpi;
90
91 vpi.cmd = CMD_RESET;
92 vpi.length = 0;
93 return jtag_vpi_send_cmd(&vpi);
94 }
95
96 /**
97 * jtag_vpi_tms_seq - ask a TMS sequence transition to JTAG
98 * @bits: TMS bits to be written (bit0, bit1 .. bitN)
99 * @nb_bits: number of TMS bits (between 1 and 8)
100 *
101 * Write a serie of TMS transitions, where each transition consists in :
102 * - writing out TCK=0, TMS=<new_state>, TDI=<???>
103 * - writing out TCK=1, TMS=<new_state>, TDI=<???> which triggers the transition
104 * The function ensures that at the end of the sequence, the clock (TCK) is put
105 * low.
106 */
107 static int jtag_vpi_tms_seq(const uint8_t *bits, int nb_bits)
108 {
109 struct vpi_cmd vpi;
110 int nb_bytes;
111
112 nb_bytes = DIV_ROUND_UP(nb_bits, 8);
113
114 vpi.cmd = CMD_TMS_SEQ;
115 memcpy(vpi.buffer_out, bits, nb_bytes);
116 vpi.length = nb_bytes;
117 vpi.nb_bits = nb_bits;
118
119 return jtag_vpi_send_cmd(&vpi);
120 }
121
122 /**
123 * jtag_vpi_path_move - ask a TMS sequence transition to JTAG
124 * @cmd: path transition
125 *
126 * Write a serie of TMS transitions, where each transition consists in :
127 * - writing out TCK=0, TMS=<new_state>, TDI=<???>
128 * - writing out TCK=1, TMS=<new_state>, TDI=<???> which triggers the transition
129 * The function ensures that at the end of the sequence, the clock (TCK) is put
130 * low.
131 */
132
133 static int jtag_vpi_path_move(struct pathmove_command *cmd)
134 {
135 uint8_t trans[DIV_ROUND_UP(cmd->num_states, 8)];
136
137 memset(trans, 0, DIV_ROUND_UP(cmd->num_states, 8));
138
139 for (int i = 0; i < cmd->num_states; i++) {
140 if (tap_state_transition(tap_get_state(), true) == cmd->path[i])
141 buf_set_u32(trans, i, 1, 1);
142 tap_set_state(cmd->path[i]);
143 }
144
145 return jtag_vpi_tms_seq(trans, cmd->num_states);
146 }
147
148 /**
149 * jtag_vpi_tms - ask a tms command
150 * @cmd: tms command
151 */
152 static int jtag_vpi_tms(struct tms_command *cmd)
153 {
154 return jtag_vpi_tms_seq(cmd->bits, cmd->num_bits);
155 }
156
157 static int jtag_vpi_state_move(tap_state_t state)
158 {
159 if (tap_get_state() == state)
160 return ERROR_OK;
161
162 uint8_t tms_scan = tap_get_tms_path(tap_get_state(), state);
163 int tms_len = tap_get_tms_path_len(tap_get_state(), state);
164
165 int retval = jtag_vpi_tms_seq(&tms_scan, tms_len);
166 if (retval != ERROR_OK)
167 return retval;
168
169 tap_set_state(state);
170
171 return ERROR_OK;
172 }
173
174 static int jtag_vpi_queue_tdi_xfer(uint8_t *bits, int nb_bits, int tap_shift)
175 {
176 struct vpi_cmd vpi;
177 int nb_bytes = DIV_ROUND_UP(nb_bits, 8);
178
179 vpi.cmd = tap_shift ? CMD_SCAN_CHAIN_FLIP_TMS : CMD_SCAN_CHAIN;
180
181 if (bits)
182 memcpy(vpi.buffer_out, bits, nb_bytes);
183 else
184 memset(vpi.buffer_out, 0xff, nb_bytes);
185
186 vpi.length = nb_bytes;
187 vpi.nb_bits = nb_bits;
188
189 int retval = jtag_vpi_send_cmd(&vpi);
190 if (retval != ERROR_OK)
191 return retval;
192
193 retval = jtag_vpi_receive_cmd(&vpi);
194 if (retval != ERROR_OK)
195 return retval;
196
197 if (bits)
198 memcpy(bits, vpi.buffer_in, nb_bytes);
199
200 return ERROR_OK;
201 }
202
203 /**
204 * jtag_vpi_queue_tdi - short description
205 * @bits: bits to be queued on TDI (or NULL if 0 are to be queued)
206 * @nb_bits: number of bits
207 */
208 static int jtag_vpi_queue_tdi(uint8_t *bits, int nb_bits, int tap_shift)
209 {
210 int nb_xfer = DIV_ROUND_UP(nb_bits, XFERT_MAX_SIZE * 8);
211 int retval;
212
213 while (nb_xfer) {
214 if (nb_xfer == 1) {
215 retval = jtag_vpi_queue_tdi_xfer(bits, nb_bits, tap_shift);
216 if (retval != ERROR_OK)
217 return retval;
218 } else {
219 retval = jtag_vpi_queue_tdi_xfer(bits, XFERT_MAX_SIZE * 8, NO_TAP_SHIFT);
220 if (retval != ERROR_OK)
221 return retval;
222 nb_bits -= XFERT_MAX_SIZE * 8;
223 if (bits)
224 bits += XFERT_MAX_SIZE;
225 }
226
227 nb_xfer--;
228 }
229
230 return ERROR_OK;
231 }
232
233 /**
234 * jtag_vpi_clock_tms - clock a TMS transition
235 * @tms: the TMS to be sent
236 *
237 * Triggers a TMS transition (ie. one JTAG TAP state move).
238 */
239 static int jtag_vpi_clock_tms(int tms)
240 {
241 const uint8_t tms_0 = 0;
242 const uint8_t tms_1 = 1;
243
244 return jtag_vpi_tms_seq(tms ? &tms_1 : &tms_0, 1);
245 }
246
247 /**
248 * jtag_vpi_scan - launches a DR-scan or IR-scan
249 * @cmd: the command to launch
250 *
251 * Launch a JTAG IR-scan or DR-scan
252 *
253 * Returns ERROR_OK if OK, ERROR_xxx if a read/write error occured.
254 */
255 static int jtag_vpi_scan(struct scan_command *cmd)
256 {
257 int scan_bits;
258 uint8_t *buf = NULL;
259 int retval = ERROR_OK;
260
261 scan_bits = jtag_build_buffer(cmd, &buf);
262
263 if (cmd->ir_scan) {
264 retval = jtag_vpi_state_move(TAP_IRSHIFT);
265 if (retval != ERROR_OK)
266 return retval;
267 } else {
268 retval = jtag_vpi_state_move(TAP_DRSHIFT);
269 if (retval != ERROR_OK)
270 return retval;
271 }
272
273 if (cmd->end_state == TAP_DRSHIFT) {
274 retval = jtag_vpi_queue_tdi(buf, scan_bits, NO_TAP_SHIFT);
275 if (retval != ERROR_OK)
276 return retval;
277 } else {
278 retval = jtag_vpi_queue_tdi(buf, scan_bits, TAP_SHIFT);
279 if (retval != ERROR_OK)
280 return retval;
281 }
282
283 if (cmd->end_state != TAP_DRSHIFT) {
284 /*
285 * As our JTAG is in an unstable state (IREXIT1 or DREXIT1), move it
286 * forward to a stable IRPAUSE or DRPAUSE.
287 */
288 retval = jtag_vpi_clock_tms(0);
289 if (retval != ERROR_OK)
290 return retval;
291
292 if (cmd->ir_scan)
293 tap_set_state(TAP_IRPAUSE);
294 else
295 tap_set_state(TAP_DRPAUSE);
296 }
297
298 retval = jtag_read_buffer(buf, cmd);
299 if (retval != ERROR_OK)
300 return retval;
301
302 if (buf)
303 free(buf);
304
305 if (cmd->end_state != TAP_DRSHIFT) {
306 retval = jtag_vpi_state_move(cmd->end_state);
307 if (retval != ERROR_OK)
308 return retval;
309 }
310
311 return ERROR_OK;
312 }
313
314 static int jtag_vpi_runtest(int cycles, tap_state_t state)
315 {
316 int retval;
317
318 retval = jtag_vpi_state_move(TAP_IDLE);
319 if (retval != ERROR_OK)
320 return retval;
321
322 retval = jtag_vpi_queue_tdi(NULL, cycles, TAP_SHIFT);
323 if (retval != ERROR_OK)
324 return retval;
325
326 return jtag_vpi_state_move(state);
327 }
328
329 static int jtag_vpi_stableclocks(int cycles)
330 {
331 return jtag_vpi_queue_tdi(NULL, cycles, TAP_SHIFT);
332 }
333
334 static int jtag_vpi_execute_queue(void)
335 {
336 struct jtag_command *cmd;
337 int retval = ERROR_OK;
338
339 for (cmd = jtag_command_queue; retval == ERROR_OK && cmd != NULL;
340 cmd = cmd->next) {
341 switch (cmd->type) {
342 case JTAG_RESET:
343 retval = jtag_vpi_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
344 break;
345 case JTAG_RUNTEST:
346 retval = jtag_vpi_runtest(cmd->cmd.runtest->num_cycles,
347 cmd->cmd.runtest->end_state);
348 break;
349 case JTAG_STABLECLOCKS:
350 retval = jtag_vpi_stableclocks(cmd->cmd.stableclocks->num_cycles);
351 break;
352 case JTAG_TLR_RESET:
353 retval = jtag_vpi_state_move(cmd->cmd.statemove->end_state);
354 break;
355 case JTAG_PATHMOVE:
356 retval = jtag_vpi_path_move(cmd->cmd.pathmove);
357 break;
358 case JTAG_TMS:
359 retval = jtag_vpi_tms(cmd->cmd.tms);
360 break;
361 case JTAG_SLEEP:
362 jtag_sleep(cmd->cmd.sleep->us);
363 break;
364 case JTAG_SCAN:
365 retval = jtag_vpi_scan(cmd->cmd.scan);
366 break;
367 }
368 }
369
370 return retval;
371 }
372
373 static int jtag_vpi_init(void)
374 {
375 int flag = 1;
376
377 sockfd = socket(AF_INET, SOCK_STREAM, 0);
378 if (sockfd < 0) {
379 LOG_ERROR("Could not create socket");
380 return ERROR_FAIL;
381 }
382
383 memset(&serv_addr, 0, sizeof(serv_addr));
384
385 serv_addr.sin_family = AF_INET;
386 serv_addr.sin_port = htons(server_port);
387
388 if (!server_address)
389 server_address = strdup(SERVER_ADDRESS);
390
391 serv_addr.sin_addr.s_addr = inet_addr(server_address);
392
393 if (serv_addr.sin_addr.s_addr == INADDR_NONE) {
394 LOG_ERROR("inet_addr error occured");
395 return ERROR_FAIL;
396 }
397
398 if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
399 close(sockfd);
400 LOG_ERROR("Can't connect to %s : %u", server_address, server_port);
401 return ERROR_COMMAND_CLOSE_CONNECTION;
402 }
403
404 if (serv_addr.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
405 /* This increases performance drematically for local
406 * connections, which is the most likely arrangement
407 * for a VPI connection. */
408 setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
409 }
410
411 LOG_INFO("Connection to %s : %u succeed", server_address, server_port);
412
413 return ERROR_OK;
414 }
415
416 static int jtag_vpi_quit(void)
417 {
418 free(server_address);
419 return close(sockfd);
420 }
421
422 COMMAND_HANDLER(jtag_vpi_set_port)
423 {
424 if (CMD_ARGC == 0)
425 LOG_WARNING("You need to set a port number");
426 else
427 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], server_port);
428
429 LOG_INFO("Set server port to %u", server_port);
430
431 return ERROR_OK;
432 }
433
434 COMMAND_HANDLER(jtag_vpi_set_address)
435 {
436 free(server_address);
437
438 if (CMD_ARGC == 0) {
439 LOG_WARNING("You need to set an address");
440 server_address = strdup(SERVER_ADDRESS);
441 } else
442 server_address = strdup(CMD_ARGV[0]);
443
444 LOG_INFO("Set server address to %s", server_address);
445
446 return ERROR_OK;
447 }
448
449 static const struct command_registration jtag_vpi_command_handlers[] = {
450 {
451 .name = "jtag_vpi_set_port",
452 .handler = &jtag_vpi_set_port,
453 .mode = COMMAND_CONFIG,
454 .help = "set the port of the VPI server",
455 .usage = "description_string",
456 },
457 {
458 .name = "jtag_vpi_set_address",
459 .handler = &jtag_vpi_set_address,
460 .mode = COMMAND_CONFIG,
461 .help = "set the address of the VPI server",
462 .usage = "description_string",
463 },
464 COMMAND_REGISTRATION_DONE
465 };
466
467 struct jtag_interface jtag_vpi_interface = {
468 .name = "jtag_vpi",
469 .supported = DEBUG_CAP_TMS_SEQ,
470 .commands = jtag_vpi_command_handlers,
471 .transports = jtag_only,
472
473 .init = jtag_vpi_init,
474 .quit = jtag_vpi_quit,
475 .execute_queue = jtag_vpi_execute_queue,
476 };