1 /* SPDX-License-Identifier: GPL-2.0-or-later */
6 * Copyright (C) 2013 Franck Jullien, <elec4fun@gmail.com>
8 * Copyright (C) 2019-2020, Ampere Computing LLC
10 * See file CREDITS for list of people who contributed to this
18 #include <jtag/interface.h>
19 #ifdef HAVE_ARPA_INET_H
20 #include <arpa/inet.h>
24 #include <netinet/tcp.h>
27 #define SERVER_ADDRESS "127.0.0.1"
28 #define SERVER_PORT 5555
30 static uint16_t server_port
= SERVER_PORT
;
31 static char *server_address
;
34 static struct sockaddr_in serv_addr
;
36 static uint8_t *last_ir_buf
;
37 static int last_ir_num_bits
;
39 static int write_sock(char *buf
, size_t len
)
42 LOG_ERROR("%s: NULL 'buf' argument, file %s, line %d",
43 __func__
, __FILE__
, __LINE__
);
46 if (write(sockfd
, buf
, len
) != (ssize_t
)len
) {
47 LOG_ERROR("%s: %s, file %s, line %d", __func__
,
48 strerror(errno
), __FILE__
, __LINE__
);
54 static int read_sock(char *buf
, size_t len
)
57 LOG_ERROR("%s: NULL 'buf' argument, file %s, line %d",
58 __func__
, __FILE__
, __LINE__
);
61 if (read(sockfd
, buf
, len
) != (ssize_t
)len
) {
62 LOG_ERROR("%s: %s, file %s, line %d", __func__
,
63 strerror(errno
), __FILE__
, __LINE__
);
70 * jtag_dpi_reset - ask to reset the JTAG device
71 * @param trst 1 if TRST is to be asserted
72 * @param srst 1 if SRST is to be asserted
74 static int jtag_dpi_reset(int trst
, int srst
)
76 char *buf
= "reset\n";
79 LOG_DEBUG_IO("JTAG DRIVER DEBUG: reset trst: %i srst %i", trst
, srst
);
82 /* reset the JTAG TAP controller */
83 ret
= write_sock(buf
, strlen(buf
));
84 if (ret
!= ERROR_OK
) {
85 LOG_ERROR("write_sock() fail, file %s, line %d",
91 /* System target reset not supported */
92 LOG_ERROR("DPI SRST not supported");
100 * jtag_dpi_scan - launches a DR-scan or IR-scan
101 * @param cmd the command to launch
103 * Launch a JTAG IR-scan or DR-scan
105 * Returns ERROR_OK if OK, ERROR_xxx if a read/write error occurred.
107 static int jtag_dpi_scan(struct scan_command
*cmd
)
114 num_bits
= jtag_build_buffer(cmd
, &data_buf
);
116 LOG_ERROR("jtag_build_buffer call failed, data_buf == NULL, "
117 "file %s, line %d", __FILE__
, __LINE__
);
121 bytes
= DIV_ROUND_UP(num_bits
, 8);
124 last_ir_buf
= (uint8_t *)malloc(bytes
* sizeof(uint8_t));
126 LOG_ERROR("%s: malloc fail, file %s, line %d",
127 __func__
, __FILE__
, __LINE__
);
131 memcpy(last_ir_buf
, data_buf
, bytes
);
132 last_ir_num_bits
= num_bits
;
134 snprintf(buf
, sizeof(buf
), "%s %d\n", cmd
->ir_scan
? "ib" : "db", num_bits
);
135 ret
= write_sock(buf
, strlen(buf
));
136 if (ret
!= ERROR_OK
) {
137 LOG_ERROR("write_sock() fail, file %s, line %d",
141 ret
= write_sock((char *)data_buf
, bytes
);
142 if (ret
!= ERROR_OK
) {
143 LOG_ERROR("write_sock() fail, file %s, line %d",
147 ret
= read_sock((char *)data_buf
, bytes
);
148 if (ret
!= ERROR_OK
) {
149 LOG_ERROR("read_sock() fail, file %s, line %d",
154 ret
= jtag_read_buffer(data_buf
, cmd
);
155 if (ret
!= ERROR_OK
) {
156 LOG_ERROR("jtag_read_buffer() fail, file %s, line %d",
166 static int jtag_dpi_runtest(int cycles
)
169 uint8_t *data_buf
= last_ir_buf
, *read_scan
;
170 int num_bits
= last_ir_num_bits
, bytes
;
174 LOG_ERROR("%s: NULL 'data_buf' argument, file %s, line %d",
175 __func__
, __FILE__
, __LINE__
);
179 LOG_ERROR("%s: 'num_bits' invalid value, file %s, line %d",
180 __func__
, __FILE__
, __LINE__
);
184 bytes
= DIV_ROUND_UP(num_bits
, 8);
185 read_scan
= (uint8_t *)malloc(bytes
* sizeof(uint8_t));
187 LOG_ERROR("%s: malloc fail, file %s, line %d",
188 __func__
, __FILE__
, __LINE__
);
191 snprintf(buf
, sizeof(buf
), "ib %d\n", num_bits
);
193 ret
= write_sock(buf
, strlen(buf
));
194 if (ret
!= ERROR_OK
) {
195 LOG_ERROR("write_sock() fail, file %s, line %d",
199 ret
= write_sock((char *)data_buf
, bytes
);
200 if (ret
!= ERROR_OK
) {
201 LOG_ERROR("write_sock() fail, file %s, line %d",
205 ret
= read_sock((char *)read_scan
, bytes
);
206 if (ret
!= ERROR_OK
) {
207 LOG_ERROR("read_sock() fail, file %s, line %d",
212 cycles
-= num_bits
+ 6;
220 static int jtag_dpi_stableclocks(int cycles
)
222 return jtag_dpi_runtest(cycles
);
225 static int jtag_dpi_execute_queue(void)
227 struct jtag_command
*cmd
;
230 for (cmd
= jtag_command_queue
; ret
== ERROR_OK
&& cmd
;
234 ret
= jtag_dpi_runtest(cmd
->cmd
.runtest
->num_cycles
);
236 case JTAG_STABLECLOCKS
:
237 ret
= jtag_dpi_stableclocks(cmd
->cmd
.stableclocks
->num_cycles
);
240 /* Enter Test-Logic-Reset state by asserting TRST */
241 if (cmd
->cmd
.statemove
->end_state
== TAP_RESET
)
242 jtag_dpi_reset(1, 0);
251 jtag_sleep(cmd
->cmd
.sleep
->us
);
254 ret
= jtag_dpi_scan(cmd
->cmd
.scan
);
257 LOG_ERROR("BUG: unknown JTAG command type 0x%X",
267 static int jtag_dpi_init(void)
269 sockfd
= socket(AF_INET
, SOCK_STREAM
, 0);
271 LOG_ERROR("socket: %s, function %s, file %s, line %d",
272 strerror(errno
), __func__
, __FILE__
, __LINE__
);
276 memset(&serv_addr
, 0, sizeof(serv_addr
));
278 serv_addr
.sin_family
= AF_INET
;
279 serv_addr
.sin_port
= htons(server_port
);
281 if (!server_address
) {
282 server_address
= strdup(SERVER_ADDRESS
);
283 if (!server_address
) {
284 LOG_ERROR("%s: strdup fail, file %s, line %d",
285 __func__
, __FILE__
, __LINE__
);
290 serv_addr
.sin_addr
.s_addr
= inet_addr(server_address
);
292 if (serv_addr
.sin_addr
.s_addr
== INADDR_NONE
) {
293 LOG_ERROR("inet_addr error occurred");
297 if (connect(sockfd
, (struct sockaddr
*)&serv_addr
, sizeof(serv_addr
)) < 0) {
299 LOG_ERROR("Can't connect to %s : %" PRIu16
, server_address
, server_port
);
302 if (serv_addr
.sin_addr
.s_addr
== htonl(INADDR_LOOPBACK
)) {
303 /* This increases performance dramatically for local
304 * connections, which is the most likely arrangement
305 * for a DPI connection. */
307 setsockopt(sockfd
, IPPROTO_TCP
, TCP_NODELAY
, (char *)&flag
, sizeof(int));
310 LOG_INFO("Connection to %s : %" PRIu16
" succeed", server_address
, server_port
);
315 static int jtag_dpi_quit(void)
317 free(server_address
);
318 server_address
= NULL
;
320 return close(sockfd
);
323 COMMAND_HANDLER(jtag_dpi_set_port
)
326 return ERROR_COMMAND_SYNTAX_ERROR
;
327 else if (CMD_ARGC
== 0)
328 LOG_INFO("Using server port %" PRIu16
, server_port
);
330 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0], server_port
);
331 LOG_INFO("Set server port to %" PRIu16
, server_port
);
337 COMMAND_HANDLER(jtag_dpi_set_address
)
340 return ERROR_COMMAND_SYNTAX_ERROR
;
341 else if (CMD_ARGC
== 0) {
342 if (!server_address
) {
343 server_address
= strdup(SERVER_ADDRESS
);
344 if (!server_address
) {
345 LOG_ERROR("%s: strdup fail, file %s, line %d",
346 __func__
, __FILE__
, __LINE__
);
350 LOG_INFO("Using server address %s", server_address
);
352 free(server_address
);
353 server_address
= strdup(CMD_ARGV
[0]);
354 if (!server_address
) {
355 LOG_ERROR("%s: strdup fail, file %s, line %d",
356 __func__
, __FILE__
, __LINE__
);
359 LOG_INFO("Set server address to %s", server_address
);
365 static const struct command_registration jtag_dpi_subcommand_handlers
[] = {
368 .handler
= &jtag_dpi_set_port
,
369 .mode
= COMMAND_CONFIG
,
370 .help
= "set the port of the DPI server",
374 .name
= "set_address",
375 .handler
= &jtag_dpi_set_address
,
376 .mode
= COMMAND_CONFIG
,
377 .help
= "set the address of the DPI server",
378 .usage
= "[address]",
380 COMMAND_REGISTRATION_DONE
383 static const struct command_registration jtag_dpi_command_handlers
[] = {
387 .help
= "perform jtag_dpi management",
388 .chain
= jtag_dpi_subcommand_handlers
,
391 COMMAND_REGISTRATION_DONE
394 static struct jtag_interface jtag_dpi_interface
= {
395 .supported
= DEBUG_CAP_TMS_SEQ
,
396 .execute_queue
= jtag_dpi_execute_queue
,
399 struct adapter_driver jtag_dpi_adapter_driver
= {
401 .transports
= jtag_only
,
402 .commands
= jtag_dpi_command_handlers
,
403 .init
= jtag_dpi_init
,
404 .quit
= jtag_dpi_quit
,
405 .reset
= jtag_dpi_reset
,
406 .jtag_ops
= &jtag_dpi_interface
,
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)