4 * Copyright (C) 2013 Franck Jullien, <elec4fun@gmail.com>
6 * See file CREDITS for list of people who contributed to this
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.
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.
25 #include <jtag/interface.h>
26 #ifdef HAVE_ARPA_INET_H
27 #include <arpa/inet.h>
30 #define NO_TAP_SHIFT 0
33 #define SERVER_ADDRESS "127.0.0.1"
34 #define SERVER_PORT 5555
36 #define XFERT_MAX_SIZE 512
40 #define CMD_SCAN_CHAIN 2
41 #define CMD_SCAN_CHAIN_FLIP_TMS 3
42 #define CMD_STOP_SIMU 4
44 int server_port
= SERVER_PORT
;
48 struct sockaddr_in serv_addr
;
52 unsigned char buffer_out
[XFERT_MAX_SIZE
];
53 unsigned char buffer_in
[XFERT_MAX_SIZE
];
58 static int jtag_vpi_send_cmd(struct vpi_cmd
*vpi
)
60 int retval
= write_socket(sockfd
, vpi
, sizeof(struct vpi_cmd
));
67 static int jtag_vpi_receive_cmd(struct vpi_cmd
*vpi
)
69 int retval
= read_socket(sockfd
, vpi
, sizeof(struct vpi_cmd
));
70 if (retval
< (int)sizeof(struct vpi_cmd
))
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
81 static int jtag_vpi_reset(int trst
, int srst
)
87 return jtag_vpi_send_cmd(&vpi
);
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)
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
101 static int jtag_vpi_tms_seq(const uint8_t *bits
, int nb_bits
)
106 nb_bytes
= DIV_ROUND_UP(nb_bits
, 8);
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
;
113 return jtag_vpi_send_cmd(&vpi
);
117 * jtag_vpi_path_move - ask a TMS sequence transition to JTAG
118 * @cmd: path transition
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
127 static int jtag_vpi_path_move(struct pathmove_command
*cmd
)
129 uint8_t trans
[DIV_ROUND_UP(cmd
->num_states
, 8)];
131 memset(trans
, 0, DIV_ROUND_UP(cmd
->num_states
, 8));
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
]);
139 return jtag_vpi_tms_seq(trans
, cmd
->num_states
);
143 * jtag_vpi_tms - ask a tms command
146 static int jtag_vpi_tms(struct tms_command
*cmd
)
148 return jtag_vpi_tms_seq(cmd
->bits
, cmd
->num_bits
);
151 static int jtag_vpi_state_move(tap_state_t state
)
153 if (tap_get_state() == state
)
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
);
159 int retval
= jtag_vpi_tms_seq(&tms_scan
, tms_len
);
160 if (retval
!= ERROR_OK
)
163 tap_set_state(state
);
168 static int jtag_vpi_queue_tdi_xfer(uint8_t *bits
, int nb_bits
, int tap_shift
)
171 int nb_bytes
= DIV_ROUND_UP(nb_bits
, 8);
173 vpi
.cmd
= tap_shift
? CMD_SCAN_CHAIN_FLIP_TMS
: CMD_SCAN_CHAIN
;
176 memcpy(vpi
.buffer_out
, bits
, nb_bytes
);
178 memset(vpi
.buffer_out
, 0xff, nb_bytes
);
180 vpi
.length
= nb_bytes
;
181 vpi
.nb_bits
= nb_bits
;
183 int retval
= jtag_vpi_send_cmd(&vpi
);
184 if (retval
!= ERROR_OK
)
187 retval
= jtag_vpi_receive_cmd(&vpi
);
188 if (retval
!= ERROR_OK
)
192 memcpy(bits
, vpi
.buffer_in
, nb_bytes
);
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
202 static int jtag_vpi_queue_tdi(uint8_t *bits
, int nb_bits
, int tap_shift
)
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
;
213 retval
= jtag_vpi_queue_tdi_xfer(&xmit_buffer
[i
], xmit_nb_bits
, tap_shift
);
214 if (retval
!= ERROR_OK
)
217 retval
= jtag_vpi_queue_tdi_xfer(&xmit_buffer
[i
], XFERT_MAX_SIZE
* 8, NO_TAP_SHIFT
);
218 if (retval
!= ERROR_OK
)
220 xmit_nb_bits
-= XFERT_MAX_SIZE
* 8;
231 * jtag_vpi_clock_tms - clock a TMS transition
232 * @tms: the TMS to be sent
234 * Triggers a TMS transition (ie. one JTAG TAP state move).
236 static int jtag_vpi_clock_tms(int tms
)
238 const uint8_t tms_0
= 0;
239 const uint8_t tms_1
= 1;
241 return jtag_vpi_tms_seq(tms
? &tms_1
: &tms_0
, 1);
245 * jtag_vpi_scan - launches a DR-scan or IR-scan
246 * @cmd: the command to launch
248 * Launch a JTAG IR-scan or DR-scan
250 * Returns ERROR_OK if OK, ERROR_xxx if a read/write error occured.
252 static int jtag_vpi_scan(struct scan_command
*cmd
)
256 int retval
= ERROR_OK
;
258 scan_bits
= jtag_build_buffer(cmd
, &buf
);
261 retval
= jtag_vpi_state_move(TAP_IRSHIFT
);
262 if (retval
!= ERROR_OK
)
265 retval
= jtag_vpi_state_move(TAP_DRSHIFT
);
266 if (retval
!= ERROR_OK
)
270 if (cmd
->end_state
== TAP_DRSHIFT
) {
271 retval
= jtag_vpi_queue_tdi(buf
, scan_bits
, NO_TAP_SHIFT
);
272 if (retval
!= ERROR_OK
)
275 retval
= jtag_vpi_queue_tdi(buf
, scan_bits
, TAP_SHIFT
);
276 if (retval
!= ERROR_OK
)
280 if (cmd
->end_state
!= TAP_DRSHIFT
) {
282 * As our JTAG is in an unstable state (IREXIT1 or DREXIT1), move it
283 * forward to a stable IRPAUSE or DRPAUSE.
285 retval
= jtag_vpi_clock_tms(0);
286 if (retval
!= ERROR_OK
)
290 tap_set_state(TAP_IRPAUSE
);
292 tap_set_state(TAP_DRPAUSE
);
295 retval
= jtag_read_buffer(buf
, cmd
);
296 if (retval
!= ERROR_OK
)
302 if (cmd
->end_state
!= TAP_DRSHIFT
) {
303 retval
= jtag_vpi_state_move(cmd
->end_state
);
304 if (retval
!= ERROR_OK
)
311 static int jtag_vpi_runtest(int cycles
, tap_state_t state
)
315 retval
= jtag_vpi_state_move(TAP_IDLE
);
316 if (retval
!= ERROR_OK
)
319 retval
= jtag_vpi_queue_tdi(NULL
, cycles
, TAP_SHIFT
);
320 if (retval
!= ERROR_OK
)
323 return jtag_vpi_state_move(state
);
326 static int jtag_vpi_stableclocks(int cycles
)
328 return jtag_vpi_queue_tdi(NULL
, cycles
, TAP_SHIFT
);
331 static int jtag_vpi_execute_queue(void)
333 struct jtag_command
*cmd
;
334 int retval
= ERROR_OK
;
336 for (cmd
= jtag_command_queue
; retval
== ERROR_OK
&& cmd
!= NULL
;
340 retval
= jtag_vpi_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
343 retval
= jtag_vpi_runtest(cmd
->cmd
.runtest
->num_cycles
,
344 cmd
->cmd
.runtest
->end_state
);
346 case JTAG_STABLECLOCKS
:
347 retval
= jtag_vpi_stableclocks(cmd
->cmd
.stableclocks
->num_cycles
);
350 retval
= jtag_vpi_state_move(cmd
->cmd
.statemove
->end_state
);
353 retval
= jtag_vpi_path_move(cmd
->cmd
.pathmove
);
356 retval
= jtag_vpi_tms(cmd
->cmd
.tms
);
359 jtag_sleep(cmd
->cmd
.sleep
->us
);
362 retval
= jtag_vpi_scan(cmd
->cmd
.scan
);
370 static int jtag_vpi_init(void)
372 sockfd
= socket(AF_INET
, SOCK_STREAM
, 0);
374 LOG_ERROR("Could not create socket");
378 memset(&serv_addr
, 0, sizeof(serv_addr
));
380 serv_addr
.sin_family
= AF_INET
;
381 serv_addr
.sin_port
= htons(server_port
);
384 server_address
= strdup(SERVER_ADDRESS
);
386 serv_addr
.sin_addr
.s_addr
= inet_addr(server_address
);
388 if (serv_addr
.sin_addr
.s_addr
== INADDR_NONE
) {
389 LOG_ERROR("inet_addr error occured");
393 if (connect(sockfd
, (struct sockaddr
*)&serv_addr
, sizeof(serv_addr
)) < 0) {
395 LOG_ERROR("Can't connect to %s : %u", server_address
, server_port
);
396 return ERROR_COMMAND_CLOSE_CONNECTION
;
399 LOG_INFO("Connection to %s : %u succeed", server_address
, server_port
);
404 static int jtag_vpi_quit(void)
406 free(server_address
);
407 return close(sockfd
);
410 COMMAND_HANDLER(jtag_vpi_set_port
)
413 LOG_WARNING("You need to set a port number");
415 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], server_port
);
417 LOG_INFO("Set server port to %u", server_port
);
422 COMMAND_HANDLER(jtag_vpi_set_address
)
424 free(server_address
);
427 LOG_WARNING("You need to set an address");
428 server_address
= strdup(SERVER_ADDRESS
);
430 server_address
= strdup(CMD_ARGV
[0]);
432 LOG_INFO("Set server address to %s", server_address
);
437 static const struct command_registration jtag_vpi_command_handlers
[] = {
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",
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",
452 COMMAND_REGISTRATION_DONE
455 struct jtag_interface jtag_vpi_interface
= {
457 .supported
= DEBUG_CAP_TMS_SEQ
,
458 .commands
= jtag_vpi_command_handlers
,
459 .transports
= jtag_only
,
461 .init
= jtag_vpi_init
,
462 .quit
= jtag_vpi_quit
,
463 .execute_queue
= jtag_vpi_execute_queue
,
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)