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