jtag_vpi: ensured constant packet size & endianness
[fw/openocd] / 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 /* One jtag_vpi "packet" as sent over a TCP channel. */
57 struct vpi_cmd {
58         union {
59                 uint32_t cmd;
60                 unsigned char cmd_buf[4];
61         };
62         unsigned char buffer_out[XFERT_MAX_SIZE];
63         unsigned char buffer_in[XFERT_MAX_SIZE];
64         union {
65                 uint32_t length;
66                 unsigned char length_buf[4];
67         };
68         union {
69                 uint32_t nb_bits;
70                 unsigned char nb_bits_buf[4];
71         };
72 };
73
74 static int jtag_vpi_send_cmd(struct vpi_cmd *vpi)
75 {
76         /* Use little endian when transmitting/receiving jtag_vpi cmds.
77            The choice of little endian goes against usual networking conventions
78            but is intentional to remain compatible with most older OpenOCD builds
79            (i.e. builds on little-endian platforms). */
80         h_u32_to_le(vpi->cmd_buf, vpi->cmd);
81         h_u32_to_le(vpi->length_buf, vpi->length);
82         h_u32_to_le(vpi->nb_bits_buf, vpi->nb_bits);
83
84         int retval = write_socket(sockfd, vpi, sizeof(struct vpi_cmd));
85         if (retval <= 0)
86                 return ERROR_FAIL;
87
88         return ERROR_OK;
89 }
90
91 static int jtag_vpi_receive_cmd(struct vpi_cmd *vpi)
92 {
93         int retval = read_socket(sockfd, vpi, sizeof(struct vpi_cmd));
94         if (retval < (int)sizeof(struct vpi_cmd))
95                 return ERROR_FAIL;
96
97         /* Use little endian when transmitting/receiving jtag_vpi cmds. */
98         vpi->cmd = le_to_h_u32(vpi->cmd_buf);
99         vpi->length = le_to_h_u32(vpi->length_buf);
100         vpi->nb_bits = le_to_h_u32(vpi->nb_bits_buf);
101
102         return ERROR_OK;
103 }
104
105 /**
106  * jtag_vpi_reset - ask to reset the JTAG device
107  * @trst: 1 if TRST is to be asserted
108  * @srst: 1 if SRST is to be asserted
109  */
110 static int jtag_vpi_reset(int trst, int srst)
111 {
112         struct vpi_cmd vpi;
113
114         vpi.cmd = CMD_RESET;
115         vpi.length = 0;
116         return jtag_vpi_send_cmd(&vpi);
117 }
118
119 /**
120  * jtag_vpi_tms_seq - ask a TMS sequence transition to JTAG
121  * @bits: TMS bits to be written (bit0, bit1 .. bitN)
122  * @nb_bits: number of TMS bits (between 1 and 8)
123  *
124  * Write a serie of TMS transitions, where each transition consists in :
125  *  - writing out TCK=0, TMS=<new_state>, TDI=<???>
126  *  - writing out TCK=1, TMS=<new_state>, TDI=<???> which triggers the transition
127  * The function ensures that at the end of the sequence, the clock (TCK) is put
128  * low.
129  */
130 static int jtag_vpi_tms_seq(const uint8_t *bits, int nb_bits)
131 {
132         struct vpi_cmd vpi;
133         int nb_bytes;
134
135         nb_bytes = DIV_ROUND_UP(nb_bits, 8);
136
137         vpi.cmd = CMD_TMS_SEQ;
138         memcpy(vpi.buffer_out, bits, nb_bytes);
139         vpi.length = nb_bytes;
140         vpi.nb_bits = nb_bits;
141
142         return jtag_vpi_send_cmd(&vpi);
143 }
144
145 /**
146  * jtag_vpi_path_move - ask a TMS sequence transition to JTAG
147  * @cmd: path transition
148  *
149  * Write a serie of TMS transitions, where each transition consists in :
150  *  - writing out TCK=0, TMS=<new_state>, TDI=<???>
151  *  - writing out TCK=1, TMS=<new_state>, TDI=<???> which triggers the transition
152  * The function ensures that at the end of the sequence, the clock (TCK) is put
153  * low.
154  */
155
156 static int jtag_vpi_path_move(struct pathmove_command *cmd)
157 {
158         uint8_t trans[DIV_ROUND_UP(cmd->num_states, 8)];
159
160         memset(trans, 0, DIV_ROUND_UP(cmd->num_states, 8));
161
162         for (int i = 0; i < cmd->num_states; i++) {
163                 if (tap_state_transition(tap_get_state(), true) == cmd->path[i])
164                         buf_set_u32(trans, i, 1, 1);
165                 tap_set_state(cmd->path[i]);
166         }
167
168         return jtag_vpi_tms_seq(trans, cmd->num_states);
169 }
170
171 /**
172  * jtag_vpi_tms - ask a tms command
173  * @cmd: tms command
174  */
175 static int jtag_vpi_tms(struct tms_command *cmd)
176 {
177         return jtag_vpi_tms_seq(cmd->bits, cmd->num_bits);
178 }
179
180 static int jtag_vpi_state_move(tap_state_t state)
181 {
182         if (tap_get_state() == state)
183                 return ERROR_OK;
184
185         uint8_t tms_scan = tap_get_tms_path(tap_get_state(), state);
186         int tms_len = tap_get_tms_path_len(tap_get_state(), state);
187
188         int retval = jtag_vpi_tms_seq(&tms_scan, tms_len);
189         if (retval != ERROR_OK)
190                 return retval;
191
192         tap_set_state(state);
193
194         return ERROR_OK;
195 }
196
197 static int jtag_vpi_queue_tdi_xfer(uint8_t *bits, int nb_bits, int tap_shift)
198 {
199         struct vpi_cmd vpi;
200         int nb_bytes = DIV_ROUND_UP(nb_bits, 8);
201
202         vpi.cmd = tap_shift ? CMD_SCAN_CHAIN_FLIP_TMS : CMD_SCAN_CHAIN;
203
204         if (bits)
205                 memcpy(vpi.buffer_out, bits, nb_bytes);
206         else
207                 memset(vpi.buffer_out, 0xff, nb_bytes);
208
209         vpi.length = nb_bytes;
210         vpi.nb_bits = nb_bits;
211
212         int retval = jtag_vpi_send_cmd(&vpi);
213         if (retval != ERROR_OK)
214                 return retval;
215
216         retval = jtag_vpi_receive_cmd(&vpi);
217         if (retval != ERROR_OK)
218                 return retval;
219
220         if (bits)
221                 memcpy(bits, vpi.buffer_in, nb_bytes);
222
223         return ERROR_OK;
224 }
225
226 /**
227  * jtag_vpi_queue_tdi - short description
228  * @bits: bits to be queued on TDI (or NULL if 0 are to be queued)
229  * @nb_bits: number of bits
230  */
231 static int jtag_vpi_queue_tdi(uint8_t *bits, int nb_bits, int tap_shift)
232 {
233         int nb_xfer = DIV_ROUND_UP(nb_bits, XFERT_MAX_SIZE * 8);
234         int retval;
235
236         while (nb_xfer) {
237                 if (nb_xfer ==  1) {
238                         retval = jtag_vpi_queue_tdi_xfer(bits, nb_bits, tap_shift);
239                         if (retval != ERROR_OK)
240                                 return retval;
241                 } else {
242                         retval = jtag_vpi_queue_tdi_xfer(bits, XFERT_MAX_SIZE * 8, NO_TAP_SHIFT);
243                         if (retval != ERROR_OK)
244                                 return retval;
245                         nb_bits -= XFERT_MAX_SIZE * 8;
246                         if (bits)
247                                 bits += XFERT_MAX_SIZE;
248                 }
249
250                 nb_xfer--;
251         }
252
253         return ERROR_OK;
254 }
255
256 /**
257  * jtag_vpi_clock_tms - clock a TMS transition
258  * @tms: the TMS to be sent
259  *
260  * Triggers a TMS transition (ie. one JTAG TAP state move).
261  */
262 static int jtag_vpi_clock_tms(int tms)
263 {
264         const uint8_t tms_0 = 0;
265         const uint8_t tms_1 = 1;
266
267         return jtag_vpi_tms_seq(tms ? &tms_1 : &tms_0, 1);
268 }
269
270 /**
271  * jtag_vpi_scan - launches a DR-scan or IR-scan
272  * @cmd: the command to launch
273  *
274  * Launch a JTAG IR-scan or DR-scan
275  *
276  * Returns ERROR_OK if OK, ERROR_xxx if a read/write error occured.
277  */
278 static int jtag_vpi_scan(struct scan_command *cmd)
279 {
280         int scan_bits;
281         uint8_t *buf = NULL;
282         int retval = ERROR_OK;
283
284         scan_bits = jtag_build_buffer(cmd, &buf);
285
286         if (cmd->ir_scan) {
287                 retval = jtag_vpi_state_move(TAP_IRSHIFT);
288                 if (retval != ERROR_OK)
289                         return retval;
290         } else {
291                 retval = jtag_vpi_state_move(TAP_DRSHIFT);
292                 if (retval != ERROR_OK)
293                         return retval;
294         }
295
296         if (cmd->end_state == TAP_DRSHIFT) {
297                 retval = jtag_vpi_queue_tdi(buf, scan_bits, NO_TAP_SHIFT);
298                 if (retval != ERROR_OK)
299                         return retval;
300         } else {
301                 retval = jtag_vpi_queue_tdi(buf, scan_bits, TAP_SHIFT);
302                 if (retval != ERROR_OK)
303                         return retval;
304         }
305
306         if (cmd->end_state != TAP_DRSHIFT) {
307                 /*
308                  * As our JTAG is in an unstable state (IREXIT1 or DREXIT1), move it
309                  * forward to a stable IRPAUSE or DRPAUSE.
310                  */
311                 retval = jtag_vpi_clock_tms(0);
312                 if (retval != ERROR_OK)
313                         return retval;
314
315                 if (cmd->ir_scan)
316                         tap_set_state(TAP_IRPAUSE);
317                 else
318                         tap_set_state(TAP_DRPAUSE);
319         }
320
321         retval = jtag_read_buffer(buf, cmd);
322         if (retval != ERROR_OK)
323                 return retval;
324
325         if (buf)
326                 free(buf);
327
328         if (cmd->end_state != TAP_DRSHIFT) {
329                 retval = jtag_vpi_state_move(cmd->end_state);
330                 if (retval != ERROR_OK)
331                         return retval;
332         }
333
334         return ERROR_OK;
335 }
336
337 static int jtag_vpi_runtest(int cycles, tap_state_t state)
338 {
339         int retval;
340
341         retval = jtag_vpi_state_move(TAP_IDLE);
342         if (retval != ERROR_OK)
343                 return retval;
344
345         retval = jtag_vpi_queue_tdi(NULL, cycles, NO_TAP_SHIFT);
346         if (retval != ERROR_OK)
347                 return retval;
348
349         return jtag_vpi_state_move(state);
350 }
351
352 static int jtag_vpi_stableclocks(int cycles)
353 {
354         uint8_t tms_bits[4];
355         int cycles_remain = cycles;
356         int nb_bits;
357         int retval;
358         const int CYCLES_ONE_BATCH = sizeof(tms_bits) * 8;
359
360         assert(cycles >= 0);
361
362         /* use TMS=1 in TAP RESET state, TMS=0 in all other stable states */
363         memset(&tms_bits, (tap_get_state() == TAP_RESET) ? 0xff : 0x00, sizeof(tms_bits));
364
365         /* send the TMS bits */
366         while (cycles_remain > 0) {
367                 nb_bits = (cycles_remain < CYCLES_ONE_BATCH) ? cycles_remain : CYCLES_ONE_BATCH;
368                 retval = jtag_vpi_tms_seq(tms_bits, nb_bits);
369                 if (retval != ERROR_OK)
370                         return retval;
371                 cycles_remain -= nb_bits;
372         }
373
374         return ERROR_OK;
375 }
376
377 static int jtag_vpi_execute_queue(void)
378 {
379         struct jtag_command *cmd;
380         int retval = ERROR_OK;
381
382         for (cmd = jtag_command_queue; retval == ERROR_OK && cmd != NULL;
383              cmd = cmd->next) {
384                 switch (cmd->type) {
385                 case JTAG_RESET:
386                         retval = jtag_vpi_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
387                         break;
388                 case JTAG_RUNTEST:
389                         retval = jtag_vpi_runtest(cmd->cmd.runtest->num_cycles,
390                                                   cmd->cmd.runtest->end_state);
391                         break;
392                 case JTAG_STABLECLOCKS:
393                         retval = jtag_vpi_stableclocks(cmd->cmd.stableclocks->num_cycles);
394                         break;
395                 case JTAG_TLR_RESET:
396                         retval = jtag_vpi_state_move(cmd->cmd.statemove->end_state);
397                         break;
398                 case JTAG_PATHMOVE:
399                         retval = jtag_vpi_path_move(cmd->cmd.pathmove);
400                         break;
401                 case JTAG_TMS:
402                         retval = jtag_vpi_tms(cmd->cmd.tms);
403                         break;
404                 case JTAG_SLEEP:
405                         jtag_sleep(cmd->cmd.sleep->us);
406                         break;
407                 case JTAG_SCAN:
408                         retval = jtag_vpi_scan(cmd->cmd.scan);
409                         break;
410                 default:
411                         LOG_ERROR("BUG: unknown JTAG command type 0x%X",
412                                   cmd->type);
413                         retval = ERROR_FAIL;
414                         break;
415                 }
416         }
417
418         return retval;
419 }
420
421 static int jtag_vpi_init(void)
422 {
423         int flag = 1;
424
425         sockfd = socket(AF_INET, SOCK_STREAM, 0);
426         if (sockfd < 0) {
427                 LOG_ERROR("Could not create socket");
428                 return ERROR_FAIL;
429         }
430
431         memset(&serv_addr, 0, sizeof(serv_addr));
432
433         serv_addr.sin_family = AF_INET;
434         serv_addr.sin_port = htons(server_port);
435
436         if (!server_address)
437                 server_address = strdup(SERVER_ADDRESS);
438
439         serv_addr.sin_addr.s_addr = inet_addr(server_address);
440
441         if (serv_addr.sin_addr.s_addr == INADDR_NONE) {
442                 LOG_ERROR("inet_addr error occured");
443                 return ERROR_FAIL;
444         }
445
446         if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
447                 close(sockfd);
448                 LOG_ERROR("Can't connect to %s : %u", server_address, server_port);
449                 return ERROR_COMMAND_CLOSE_CONNECTION;
450         }
451
452         if (serv_addr.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
453                 /* This increases performance drematically for local
454                  * connections, which is the most likely arrangement
455                  * for a VPI connection. */
456                 setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
457         }
458
459         LOG_INFO("Connection to %s : %u succeed", server_address, server_port);
460
461         return ERROR_OK;
462 }
463
464 static int jtag_vpi_quit(void)
465 {
466         free(server_address);
467         return close(sockfd);
468 }
469
470 COMMAND_HANDLER(jtag_vpi_set_port)
471 {
472         if (CMD_ARGC == 0)
473                 LOG_WARNING("You need to set a port number");
474         else
475                 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], server_port);
476
477         LOG_INFO("Set server port to %u", server_port);
478
479         return ERROR_OK;
480 }
481
482 COMMAND_HANDLER(jtag_vpi_set_address)
483 {
484         free(server_address);
485
486         if (CMD_ARGC == 0) {
487                 LOG_WARNING("You need to set an address");
488                 server_address = strdup(SERVER_ADDRESS);
489         } else
490                 server_address = strdup(CMD_ARGV[0]);
491
492         LOG_INFO("Set server address to %s", server_address);
493
494         return ERROR_OK;
495 }
496
497 static const struct command_registration jtag_vpi_command_handlers[] = {
498         {
499                 .name = "jtag_vpi_set_port",
500                 .handler = &jtag_vpi_set_port,
501                 .mode = COMMAND_CONFIG,
502                 .help = "set the port of the VPI server",
503                 .usage = "description_string",
504         },
505         {
506                 .name = "jtag_vpi_set_address",
507                 .handler = &jtag_vpi_set_address,
508                 .mode = COMMAND_CONFIG,
509                 .help = "set the address of the VPI server",
510                 .usage = "description_string",
511         },
512         COMMAND_REGISTRATION_DONE
513 };
514
515 struct jtag_interface jtag_vpi_interface = {
516         .name = "jtag_vpi",
517         .supported = DEBUG_CAP_TMS_SEQ,
518         .commands = jtag_vpi_command_handlers,
519         .transports = jtag_only,
520
521         .init = jtag_vpi_init,
522         .quit = jtag_vpi_quit,
523         .execute_queue = jtag_vpi_execute_queue,
524 };