4 * Copyright (C) 2013 Franck Jullien, <elec4fun@gmail.com>
6 * Copyright (C) 2019-2020, Ampere Computing LLC
8 * See file CREDITS for list of people who contributed to this
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
29 #include <jtag/interface.h>
30 #ifdef HAVE_ARPA_INET_H
31 #include <arpa/inet.h>
35 #include <netinet/tcp.h>
38 #define SERVER_ADDRESS "127.0.0.1"
39 #define SERVER_PORT 5555
41 static uint16_t server_port
= SERVER_PORT
;
42 static char *server_address
;
45 static struct sockaddr_in serv_addr
;
47 static uint8_t *last_ir_buf
;
48 static int last_ir_num_bits
;
50 static int write_sock(char *buf
, size_t len
)
53 LOG_ERROR("%s: NULL 'buf' argument, file %s, line %d",
54 __func__
, __FILE__
, __LINE__
);
57 if (write(sockfd
, buf
, len
) != (ssize_t
)len
) {
58 LOG_ERROR("%s: %s, file %s, line %d", __func__
,
59 strerror(errno
), __FILE__
, __LINE__
);
65 static int read_sock(char *buf
, size_t len
)
68 LOG_ERROR("%s: NULL 'buf' argument, file %s, line %d",
69 __func__
, __FILE__
, __LINE__
);
72 if (read(sockfd
, buf
, len
) != (ssize_t
)len
) {
73 LOG_ERROR("%s: %s, file %s, line %d", __func__
,
74 strerror(errno
), __FILE__
, __LINE__
);
81 * jtag_dpi_reset - ask to reset the JTAG device
82 * @param trst 1 if TRST is to be asserted
83 * @param srst 1 if SRST is to be asserted
85 static int jtag_dpi_reset(int trst
, int srst
)
87 char *buf
= "reset\n";
90 LOG_DEBUG_IO("JTAG DRIVER DEBUG: reset trst: %i srst %i", trst
, srst
);
93 /* reset the JTAG TAP controller */
94 ret
= write_sock(buf
, strlen(buf
));
95 if (ret
!= ERROR_OK
) {
96 LOG_ERROR("write_sock() fail, file %s, line %d",
102 /* System target reset not supported */
103 LOG_ERROR("DPI SRST not supported");
111 * jtag_dpi_scan - launches a DR-scan or IR-scan
112 * @param cmd the command to launch
114 * Launch a JTAG IR-scan or DR-scan
116 * Returns ERROR_OK if OK, ERROR_xxx if a read/write error occurred.
118 static int jtag_dpi_scan(struct scan_command
*cmd
)
125 num_bits
= jtag_build_buffer(cmd
, &data_buf
);
127 LOG_ERROR("jtag_build_buffer call failed, data_buf == NULL, "
128 "file %s, line %d", __FILE__
, __LINE__
);
132 bytes
= DIV_ROUND_UP(num_bits
, 8);
135 last_ir_buf
= (uint8_t *)malloc(bytes
* sizeof(uint8_t));
137 LOG_ERROR("%s: malloc fail, file %s, line %d",
138 __func__
, __FILE__
, __LINE__
);
142 memcpy(last_ir_buf
, data_buf
, bytes
);
143 last_ir_num_bits
= num_bits
;
145 snprintf(buf
, sizeof(buf
), "%s %d\n", cmd
->ir_scan
? "ib" : "db", num_bits
);
146 ret
= write_sock(buf
, strlen(buf
));
147 if (ret
!= ERROR_OK
) {
148 LOG_ERROR("write_sock() fail, file %s, line %d",
152 ret
= write_sock((char *)data_buf
, bytes
);
153 if (ret
!= ERROR_OK
) {
154 LOG_ERROR("write_sock() fail, file %s, line %d",
158 ret
= read_sock((char *)data_buf
, bytes
);
159 if (ret
!= ERROR_OK
) {
160 LOG_ERROR("read_sock() fail, file %s, line %d",
165 ret
= jtag_read_buffer(data_buf
, cmd
);
166 if (ret
!= ERROR_OK
) {
167 LOG_ERROR("jtag_read_buffer() fail, file %s, line %d",
177 static int jtag_dpi_runtest(int cycles
)
180 uint8_t *data_buf
= last_ir_buf
, *read_scan
;
181 int num_bits
= last_ir_num_bits
, bytes
;
185 LOG_ERROR("%s: NULL 'data_buf' argument, file %s, line %d",
186 __func__
, __FILE__
, __LINE__
);
190 LOG_ERROR("%s: 'num_bits' invalid value, file %s, line %d",
191 __func__
, __FILE__
, __LINE__
);
195 bytes
= DIV_ROUND_UP(num_bits
, 8);
196 read_scan
= (uint8_t *)malloc(bytes
* sizeof(uint8_t));
198 LOG_ERROR("%s: malloc fail, file %s, line %d",
199 __func__
, __FILE__
, __LINE__
);
202 snprintf(buf
, sizeof(buf
), "ib %d\n", num_bits
);
204 ret
= write_sock(buf
, strlen(buf
));
205 if (ret
!= ERROR_OK
) {
206 LOG_ERROR("write_sock() fail, file %s, line %d",
210 ret
= write_sock((char *)data_buf
, bytes
);
211 if (ret
!= ERROR_OK
) {
212 LOG_ERROR("write_sock() fail, file %s, line %d",
216 ret
= read_sock((char *)read_scan
, bytes
);
217 if (ret
!= ERROR_OK
) {
218 LOG_ERROR("read_sock() fail, file %s, line %d",
223 cycles
-= num_bits
+ 6;
231 static int jtag_dpi_stableclocks(int cycles
)
233 return jtag_dpi_runtest(cycles
);
236 static int jtag_dpi_execute_queue(void)
238 struct jtag_command
*cmd
;
241 for (cmd
= jtag_command_queue
; ret
== ERROR_OK
&& cmd
;
245 ret
= jtag_dpi_runtest(cmd
->cmd
.runtest
->num_cycles
);
247 case JTAG_STABLECLOCKS
:
248 ret
= jtag_dpi_stableclocks(cmd
->cmd
.stableclocks
->num_cycles
);
251 /* Enter Test-Logic-Reset state by asserting TRST */
252 if (cmd
->cmd
.statemove
->end_state
== TAP_RESET
)
253 jtag_dpi_reset(1, 0);
262 jtag_sleep(cmd
->cmd
.sleep
->us
);
265 ret
= jtag_dpi_scan(cmd
->cmd
.scan
);
268 LOG_ERROR("BUG: unknown JTAG command type 0x%X",
278 static int jtag_dpi_init(void)
280 sockfd
= socket(AF_INET
, SOCK_STREAM
, 0);
282 LOG_ERROR("socket: %s, function %s, file %s, line %d",
283 strerror(errno
), __func__
, __FILE__
, __LINE__
);
287 memset(&serv_addr
, 0, sizeof(serv_addr
));
289 serv_addr
.sin_family
= AF_INET
;
290 serv_addr
.sin_port
= htons(server_port
);
292 if (!server_address
) {
293 server_address
= strdup(SERVER_ADDRESS
);
294 if (!server_address
) {
295 LOG_ERROR("%s: strdup fail, file %s, line %d",
296 __func__
, __FILE__
, __LINE__
);
301 serv_addr
.sin_addr
.s_addr
= inet_addr(server_address
);
303 if (serv_addr
.sin_addr
.s_addr
== INADDR_NONE
) {
304 LOG_ERROR("inet_addr error occurred");
308 if (connect(sockfd
, (struct sockaddr
*)&serv_addr
, sizeof(serv_addr
)) < 0) {
310 LOG_ERROR("Can't connect to %s : %" PRIu16
, server_address
, server_port
);
313 if (serv_addr
.sin_addr
.s_addr
== htonl(INADDR_LOOPBACK
)) {
314 /* This increases performance dramatically for local
315 * connections, which is the most likely arrangement
316 * for a DPI connection. */
318 setsockopt(sockfd
, IPPROTO_TCP
, TCP_NODELAY
, (char *)&flag
, sizeof(int));
321 LOG_INFO("Connection to %s : %" PRIu16
" succeed", server_address
, server_port
);
326 static int jtag_dpi_quit(void)
328 free(server_address
);
329 server_address
= NULL
;
331 return close(sockfd
);
334 COMMAND_HANDLER(jtag_dpi_set_port
)
337 return ERROR_COMMAND_SYNTAX_ERROR
;
338 else if (CMD_ARGC
== 0)
339 LOG_INFO("Using server port %" PRIu16
, server_port
);
341 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0], server_port
);
342 LOG_INFO("Set server port to %" PRIu16
, server_port
);
348 COMMAND_HANDLER(jtag_dpi_set_address
)
351 return ERROR_COMMAND_SYNTAX_ERROR
;
352 else if (CMD_ARGC
== 0) {
353 if (!server_address
) {
354 server_address
= strdup(SERVER_ADDRESS
);
355 if (!server_address
) {
356 LOG_ERROR("%s: strdup fail, file %s, line %d",
357 __func__
, __FILE__
, __LINE__
);
361 LOG_INFO("Using server address %s", server_address
);
363 free(server_address
);
364 server_address
= strdup(CMD_ARGV
[0]);
365 if (!server_address
) {
366 LOG_ERROR("%s: strdup fail, file %s, line %d",
367 __func__
, __FILE__
, __LINE__
);
370 LOG_INFO("Set server address to %s", server_address
);
376 static const struct command_registration jtag_dpi_subcommand_handlers
[] = {
379 .handler
= &jtag_dpi_set_port
,
380 .mode
= COMMAND_CONFIG
,
381 .help
= "set the port of the DPI server",
385 .name
= "set_address",
386 .handler
= &jtag_dpi_set_address
,
387 .mode
= COMMAND_CONFIG
,
388 .help
= "set the address of the DPI server",
389 .usage
= "[address]",
391 COMMAND_REGISTRATION_DONE
394 static const struct command_registration jtag_dpi_command_handlers
[] = {
398 .help
= "perform jtag_dpi management",
399 .chain
= jtag_dpi_subcommand_handlers
,
402 COMMAND_REGISTRATION_DONE
405 static struct jtag_interface jtag_dpi_interface
= {
406 .supported
= DEBUG_CAP_TMS_SEQ
,
407 .execute_queue
= jtag_dpi_execute_queue
,
410 struct adapter_driver jtag_dpi_adapter_driver
= {
412 .transports
= jtag_only
,
413 .commands
= jtag_dpi_command_handlers
,
414 .init
= jtag_dpi_init
,
415 .quit
= jtag_dpi_quit
,
416 .reset
= jtag_dpi_reset
,
417 .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)