1 // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
3 /* Copyright 2020-2022 Cadence Design Systems, Inc. */
8 * @brief the virtual debug interface provides a connection between a sw debugger
9 * and the simulated, emulated core. The openOCD client connects via TCP sockets
10 * with vdebug server and over DPI-based transactor with the emulation or simulation
11 * The vdebug debug driver supports JTAG and DAP-level transports
20 #define WIN32_LEAN_AND_MEAN
24 #include <unistd.h> /* close */
26 #ifdef HAVE_SYS_SOCKET_H
27 #include <sys/socket.h>
29 #ifdef HAVE_ARPA_INET_H
30 #include <arpa/inet.h>
47 #include "jtag/interface.h"
48 #include "jtag/commands.h"
49 #include "transport/transport.h"
50 #include "target/arm_adi_v5.h"
51 #include "helper/time_support.h"
52 #include "helper/replacements.h"
53 #include "helper/log.h"
54 #include "helper/list.h"
57 #define VD_BUFFER_LEN 4024
58 #define VD_CHEADER_LEN 24
59 #define VD_SHEADER_LEN 16
61 #define VD_MAX_MEMORIES 20
62 #define VD_POLL_INTERVAL 500
63 #define VD_SCALE_PSTOMS 1000000000
66 * @brief List of transactor types
69 VD_BFM_TPIU
= 0x0000, /* transactor trace TPIU */
70 VD_BFM_DAP6
= 0x0001, /* transactor DAP ADI V6 */
71 VD_BFM_SWDP
= 0x0002, /* transactor DAP SWD DP */
72 VD_BFM_AHB
= 0x0003, /* transactor AMBA AHB */
73 VD_BFM_APB
= 0x0004, /* transactor AMBA APB */
74 VD_BFM_AXI
= 0x0005, /* transactor AMBA AXI */
75 VD_BFM_JTAG
= 0x0006, /* transactor serial JTAG */
76 VD_BFM_SWD
= 0x0007, /* transactor serial SWD */
80 * @brief List of signals that can be read or written by the debugger
83 VD_SIG_TCK
= 0x0001, /* JTAG clock; tclk */
84 VD_SIG_TDI
= 0x0002, /* JTAG TDI; tdi */
85 VD_SIG_TMS
= 0x0004, /* JTAG TMS; tms */
86 VD_SIG_RESET
= 0x0008, /* DUT reset; rst */
87 VD_SIG_TRST
= 0x0010, /* JTAG Reset; trstn */
88 VD_SIG_TDO
= 0x0020, /* JTAG TDO; tdo */
89 VD_SIG_POWER
= 0x0100, /* BFM power; bfm_up */
90 VD_SIG_TCKDIV
= 0x0200, /* JTAG clock divider; tclkdiv */
91 VD_SIG_BUF
= 0x1000, /* memory buffer; mem */
95 * @brief List of errors
98 VD_ERR_NONE
= 0x0000, /* no error */
99 VD_ERR_NOT_IMPL
= 0x0100, /* feature not implemented */
100 VD_ERR_USAGE
= 0x0101, /* incorrect usage */
101 VD_ERR_PARAM
= 0x0102, /* incorrect parameter */
102 VD_ERR_CONFIG
= 0x0107, /* incorrect configuration */
103 VD_ERR_NO_MEMORY
= 0x0104, /* out of memory */
104 VD_ERR_SHM_OPEN
= 0x010a, /* cannot open shared memory */
105 VD_ERR_SHM_MAP
= 0x010b, /* cannot map shared memory */
106 VD_ERR_SOC_OPEN
= 0x011a, /* cannot open socket */
107 VD_ERR_SOC_OPT
= 0x011b, /* cannot set socket option */
108 VD_ERR_SOC_ADDR
= 0x011c, /* cannot resolve host address */
109 VD_ERR_SOC_CONN
= 0x011d, /* cannot connect to host */
110 VD_ERR_SOC_SEND
= 0x011e, /* error sending data on socket */
111 VD_ERR_SOC_RECV
= 0x011f, /* error receiving data from socket */
112 VD_ERR_LOCKED
= 0x0202, /* device locked */
113 VD_ERR_NOT_RUN
= 0x0204, /* transactor not running */
114 VD_ERR_NOT_OPEN
= 0x0205, /* transactor not open/connected */
115 VD_ERR_LICENSE
= 0x0206, /* cannot check out the license */
116 VD_ERR_VERSION
= 0x0207, /* transactor version mismatch */
117 VD_ERR_TIME_OUT
= 0x0301, /* time out, waiting */
118 VD_ERR_NO_POWER
= 0x0302, /* power out error */
119 VD_ERR_BUS_ERROR
= 0x0304, /* bus protocol error, like pslverr */
120 VD_ERR_NO_ACCESS
= 0x0306, /* no access to an object */
121 VD_ERR_INV_HANDLE
= 0x0307, /* invalid object handle */
122 VD_ERR_INV_SCOPE
= 0x0308, /* invalid scope */
128 VD_CMD_CONNECT
= 0x04,
129 VD_CMD_DISCONNECT
= 0x05,
131 VD_CMD_SIGSET
= 0x0a,
132 VD_CMD_SIGGET
= 0x0b,
133 VD_CMD_JTAGCLOCK
= 0x0f,
134 VD_CMD_REGWRITE
= 0x15,
135 VD_CMD_REGREAD
= 0x16,
136 VD_CMD_JTAGSHTAP
= 0x1a,
137 VD_CMD_MEMOPEN
= 0x21,
138 VD_CMD_MEMCLOSE
= 0x22,
139 VD_CMD_MEMWRITE
= 0x23,
156 struct { /* VD_CHEADER_LEN written by client */
157 uint8_t cmd
; /* 000; command */
158 uint8_t type
; /* 001; interface type */
159 uint8_t waddr
[2]; /* 002; write pointer */
160 uint8_t wbytes
[2]; /* 004; data bytes */
161 uint8_t rbytes
[2]; /* 006; data bytes to read */
162 uint8_t wwords
[2]; /* 008; data words */
163 uint8_t rwords
[2]; /* 00a; data words to read */
164 uint8_t rwdata
[4]; /* 00c; read/write data */
165 uint8_t offset
[4]; /* 010; address offset */
166 uint8_t offseth
[2]; /* 014; address offset 47:32 */
167 uint8_t wid
[2]; /* 016; request id*/
169 uint8_t wd8
[VD_BUFFER_LEN
]; /* 018; */
170 struct { /* VD_SHEADER_LEN written by server */
171 uint8_t rid
[2]; /* fd0: request id read */
172 uint8_t awords
[2]; /* fd2: actual data words read back */
173 uint8_t status
[4]; /* fd4; */
174 uint8_t duttime
[8]; /* fd8; */
176 uint8_t rd8
[VD_BUFFER_LEN
]; /* fe0: */
177 uint8_t state
[4]; /* 1f98; connection state */
178 uint8_t count
[4]; /* 1f9c; */
179 uint8_t dummy
[96]; /* 1fa0; 48+40B+8B; */
180 } __attribute__((packed
));
198 uint32_t mem_base
[VD_MAX_MEMORIES
];
199 uint32_t mem_size
[VD_MAX_MEMORIES
];
200 uint32_t mem_width
[VD_MAX_MEMORIES
];
201 uint32_t mem_depth
[VD_MAX_MEMORIES
];
202 uint16_t server_port
;
203 uint32_t poll_cycles
;
208 char server_name
[32];
210 char mem_path
[VD_MAX_MEMORIES
][128];
211 struct vd_rdata rdataq
;
233 static struct vd_shm
*pbuf
;
234 static struct vd_client vdc
;
236 static int vdebug_socket_error(void)
239 return WSAGetLastError();
245 static int vdebug_socket_open(char *server_addr
, uint32_t port
)
249 uint32_t buflen
= sizeof(struct vd_shm
); /* size of the send and rcv buffer */
250 struct addrinfo
*ainfo
= NULL
;
251 struct addrinfo ahint
= { 0, AF_INET
, SOCK_STREAM
, 0, 0, NULL
, NULL
, NULL
};
254 hsock
= socket(AF_INET
, SOCK_STREAM
, IPPROTO_IP
);
255 if (hsock
== INVALID_SOCKET
)
256 rc
= vdebug_socket_error();
257 #elif defined __CYGWIN__
258 /* SO_RCVLOWAT unsupported on CYGWIN */
259 hsock
= socket(AF_INET
, SOCK_STREAM
, IPPROTO_IP
);
263 uint32_t rcvwat
= VD_SHEADER_LEN
; /* size of the rcv header, as rcv min watermark */
264 hsock
= socket(AF_INET
, SOCK_STREAM
, IPPROTO_IP
);
267 else if (setsockopt(hsock
, SOL_SOCKET
, SO_RCVLOWAT
, &rcvwat
, sizeof(rcvwat
)) < 0)
270 else if (setsockopt(hsock
, SOL_SOCKET
, SO_SNDBUF
, (const char *)&buflen
, sizeof(buflen
)) < 0)
271 rc
= vdebug_socket_error();
272 else if (setsockopt(hsock
, SOL_SOCKET
, SO_RCVBUF
, (const char *)&buflen
, sizeof(buflen
)) < 0)
273 rc
= vdebug_socket_error();
276 LOG_ERROR("socket_open: cannot set socket option, error %d", rc
);
277 } else if (getaddrinfo(server_addr
, NULL
, &ahint
, &ainfo
) != 0) {
278 LOG_ERROR("socket_open: cannot resolve address %s, error %d", server_addr
, vdebug_socket_error());
279 rc
= VD_ERR_SOC_ADDR
;
281 h_u16_to_be((uint8_t *)ainfo
->ai_addr
->sa_data
, port
);
282 if (connect(hsock
, ainfo
->ai_addr
, sizeof(struct sockaddr
)) < 0) {
283 LOG_ERROR("socket_open: cannot connect to %s:%d, error %d", server_addr
, port
, vdebug_socket_error());
284 rc
= VD_ERR_SOC_CONN
;
299 static int vdebug_socket_receive(int hsock
, struct vd_shm
*pmem
)
303 int offset
= &pmem
->rid
[0] - &pmem
->cmd
;
304 int to_receive
= VD_SHEADER_LEN
+ le_to_h_u16(pmem
->rbytes
);
305 char *pb
= (char *)pmem
;
308 rc
= recv(hsock
, pb
+ offset
, to_receive
, 0);
310 LOG_WARNING("socket_receive: recv failed, error %d", rc
< 0 ? vdebug_socket_error() : 0);
315 LOG_DEBUG_IO("socket_receive: received %d, to receive %d", rc
, to_receive
);
317 } while (to_receive
);
322 static int vdebug_socket_send(int hsock
, struct vd_shm
*pmem
)
324 int rc
= send(hsock
, (const char *)&pmem
->cmd
, VD_CHEADER_LEN
+ le_to_h_u16(pmem
->wbytes
), 0);
326 LOG_WARNING("socket_send: send failed, error %d", vdebug_socket_error());
328 LOG_DEBUG_IO("socket_send: sent %d, to send 0", rc
);
333 static uint32_t vdebug_wait_server(int hsock
, struct vd_shm
*pmem
)
336 return VD_ERR_SOC_OPEN
;
338 int st
= vdebug_socket_send(hsock
, pmem
);
340 return VD_ERR_SOC_SEND
;
342 int rd
= vdebug_socket_receive(hsock
, pmem
);
344 return VD_ERR_SOC_RECV
;
346 int rc
= le_to_h_u32(pmem
->status
);
347 LOG_DEBUG_IO("wait_server: cmd %02" PRIx8
" done, sent %d, rcvd %d, status %d",
348 pmem
->cmd
, st
, rd
, rc
);
353 static int vdebug_run_jtag_queue(int hsock
, struct vd_shm
*pm
, unsigned int count
)
355 uint8_t num_pre
, num_post
, tdi
, tms
;
356 unsigned int num
, anum
, bytes
, hwords
, words
;
357 unsigned int req
, waddr
, rwords
;
364 req
= 0; /* beginning of request */
367 h_u16_to_le(pm
->wbytes
, le_to_h_u16(pm
->wwords
) * vdc
.buf_width
);
368 h_u16_to_le(pm
->rbytes
, le_to_h_u16(pm
->rwords
) * vdc
.buf_width
);
370 rc
= vdebug_wait_server(hsock
, pm
);
371 while (!rc
&& (req
< count
)) { /* loop over requests to read data and print out */
372 jhdr
= le_to_h_u64(&pm
->wd8
[waddr
* 4]);
374 hwords
= (jhdr
>> 32) & 0xffff;
375 anum
= jhdr
& 0xffffff;
376 num_pre
= (jhdr
>> 27) & 0x7;
377 num_post
= (jhdr
>> 24) & 0x7;
379 num
= anum
- num_pre
- num_post
+ 1;
381 num
= anum
- num_pre
;
382 bytes
= (num
+ 7) / 8;
383 vdc
.trans_last
= (req
+ 1) < count
? 0 : 1;
384 vdc
.trans_first
= waddr
? 0 : 1;
385 if (((jhdr
>> 30) & 0x3) == 3) { /* cmd is read */
390 rd
= list_first_entry(&vdc
.rdataq
.lh
, struct vd_rdata
, lh
);
395 for (unsigned int j
= 0; j
< bytes
; j
++) {
396 tdo
[j
] = (pm
->rd8
[rwords
* 8 + j
] >> num_pre
) | (pm
->rd8
[rwords
* 8 + j
+ 1] << (8 - num_pre
));
397 LOG_DEBUG_IO("%04x D0[%02x]:%02x", le_to_h_u16(pm
->wid
) - count
+ req
, j
, tdo
[j
]);
399 rwords
+= words
; /* read data offset */
403 waddr
+= sizeof(uint64_t) / 4; /* waddr past header */
404 tdi
= (pm
->wd8
[waddr
* 4] >> num_pre
) | (pm
->wd8
[waddr
* 4 + 1] << (8 - num_pre
));
405 tms
= (pm
->wd8
[waddr
* 4 + 4] >> num_pre
) | (pm
->wd8
[waddr
* 4 + 4 + 1] << (8 - num_pre
));
406 LOG_DEBUG_IO("%04x L:%02d O:%05x @%03x DI:%02x MS:%02x DO:%02x",
407 le_to_h_u16(pm
->wid
) - count
+ req
, num
, (vdc
.trans_first
<< 14) | (vdc
.trans_last
<< 15),
408 waddr
- 2, tdi
, tms
, (tdo
? tdo
[0] : 0xdd));
409 waddr
+= hwords
* 2; /* start of next request */
414 LOG_ERROR("0x%x executing transaction", rc
);
419 vdc
.targ_time
+= (uint32_t)(te
- ts
);
420 h_u16_to_le(pm
->offseth
, 0); /* reset buffer write address */
421 h_u32_to_le(pm
->offset
, 0);
422 h_u16_to_le(pm
->rwords
, 0);
423 h_u16_to_le(pm
->waddr
, 0);
424 assert(list_empty(&vdc
.rdataq
.lh
));/* list should be empty after run queue */
429 static int vdebug_run_reg_queue(int hsock
, struct vd_shm
*pm
, unsigned int count
)
431 unsigned int num
, awidth
, wwidth
;
432 unsigned int req
, waddr
, rwords
;
441 req
= 0; /* beginning of request */
444 h_u16_to_le(pm
->wbytes
, le_to_h_u16(pm
->wwords
) * vdc
.buf_width
);
445 h_u16_to_le(pm
->rbytes
, le_to_h_u16(pm
->rwords
) * vdc
.buf_width
);
447 rc
= vdebug_wait_server(hsock
, pm
);
448 while (!rc
&& (req
< count
)) { /* loop over requests to read data and print out */
449 rhdr
= le_to_h_u64(&pm
->wd8
[waddr
* 4]);
450 addr
= rhdr
>> 32; /* reconstruct data for a single request */
451 num
= (rhdr
>> 16) & 0x7ff;
453 awidth
= (1 << ((rhdr
>> 27) & 0x7));
454 wwidth
= (awidth
+ vdc
.buf_width
- 1) / vdc
.buf_width
;
455 vdc
.trans_last
= (req
+ 1) < count
? 0 : 1;
456 vdc
.trans_first
= waddr
? 0 : 1;
457 if (((rhdr
>> 30) & 0x3) == 2) { /* cmd is read */
463 rd
= list_first_entry(&vdc
.rdataq
.lh
, struct vd_rdata
, lh
);
468 for (unsigned int j
= 0; j
< num
; j
++)
469 memcpy(&data
[j
* awidth
], &pm
->rd8
[(rwords
+ j
) * awidth
], awidth
);
471 LOG_DEBUG("read %04x AS:%1x RG:%1x O:%05x @%03x D:%08x", le_to_h_u16(pm
->wid
) - count
+ req
,
472 aspace
, addr
<< 2, (vdc
.trans_first
<< 14) | (vdc
.trans_last
<< 15), waddr
,
473 (num
? le_to_h_u32(&pm
->rd8
[rwords
* 4]) : 0xdead));
474 rwords
+= num
* wwidth
;
475 waddr
+= sizeof(uint64_t) / 4; /* waddr past header */
477 LOG_DEBUG("write %04x AS:%1x RG:%1x O:%05x @%03x D:%08x", le_to_h_u16(pm
->wid
) - count
+ req
,
478 aspace
, addr
<< 2, (vdc
.trans_first
<< 14) | (vdc
.trans_last
<< 15), waddr
,
479 le_to_h_u32(&pm
->wd8
[(waddr
+ num
+ 1) * 4]));
480 waddr
+= sizeof(uint64_t) / 4 + (num
* wwidth
* awidth
+ 3) / 4;
486 LOG_ERROR("0x%x executing transaction", rc
);
491 vdc
.targ_time
+= (uint32_t)(te
- ts
);
492 h_u16_to_le(pm
->offseth
, 0); /* reset buffer write address */
493 h_u32_to_le(pm
->offset
, 0);
494 h_u16_to_le(pm
->rwords
, 0);
495 h_u16_to_le(pm
->waddr
, 0);
496 assert(list_empty(&vdc
.rdataq
.lh
));/* list should be empty after run queue */
501 static int vdebug_open(int hsock
, struct vd_shm
*pm
, const char *path
,
502 uint8_t type
, uint32_t period_ps
, uint32_t sig_mask
)
504 int rc
= VD_ERR_NOT_OPEN
;
506 pm
->cmd
= VD_CMD_OPEN
;
507 h_u16_to_le(pm
->wid
, VD_VERSION
); /* client version */
508 h_u16_to_le(pm
->wbytes
, 0);
509 h_u16_to_le(pm
->rbytes
, 0);
510 h_u16_to_le(pm
->wwords
, 0);
511 h_u16_to_le(pm
->rwords
, 0);
512 rc
= vdebug_wait_server(hsock
, pm
);
513 if (rc
!= 0) { /* communication problem */
514 LOG_ERROR("0x%x connecting to server", rc
);
515 } else if (le_to_h_u16(pm
->rid
) < le_to_h_u16(pm
->wid
)) {
516 LOG_ERROR("server version %d too old for the client %d", le_to_h_u16(pm
->rid
), le_to_h_u16(pm
->wid
));
517 pm
->cmd
= VD_CMD_CLOSE
; /* let server close the connection */
518 vdebug_wait_server(hsock
, pm
);
521 pm
->cmd
= VD_CMD_CONNECT
;
522 pm
->type
= type
; /* BFM type to connect to */
523 h_u32_to_le(pm
->rwdata
, sig_mask
| VD_SIG_BUF
| (VD_SIG_BUF
<< 16));
524 h_u16_to_le(pm
->wbytes
, strlen(path
) + 1);
525 h_u16_to_le(pm
->rbytes
, 12);
526 h_u16_to_le(pm
->wid
, 0); /* reset wid for transaction ID */
527 h_u16_to_le(pm
->wwords
, 0);
528 h_u16_to_le(pm
->rwords
, 0);
529 memcpy(pm
->wd8
, path
, le_to_h_u16(pm
->wbytes
));
530 rc
= vdebug_wait_server(hsock
, pm
);
531 vdc
.sig_read
= le_to_h_u32(pm
->rwdata
) >> 16; /* signal read mask */
532 vdc
.sig_write
= le_to_h_u32(pm
->rwdata
); /* signal write mask */
533 vdc
.bfm_period
= period_ps
;
534 vdc
.buf_width
= le_to_h_u32(&pm
->rd8
[0]) / 8;/* access width in bytes */
535 vdc
.addr_bits
= le_to_h_u32(&pm
->rd8
[2 * 4]); /* supported address bits */
539 LOG_ERROR("0x%x connecting to BFM %s", rc
, path
);
543 INIT_LIST_HEAD(&vdc
.rdataq
.lh
);
544 LOG_DEBUG("%s type %0x, period %dps, buffer %dx%dB signals r%04xw%04x",
545 path
, type
, vdc
.bfm_period
, VD_BUFFER_LEN
/ vdc
.buf_width
,
546 vdc
.buf_width
, vdc
.sig_read
, vdc
.sig_write
);
551 static int vdebug_close(int hsock
, struct vd_shm
*pm
, uint8_t type
)
553 pm
->cmd
= VD_CMD_DISCONNECT
;
554 pm
->type
= type
; /* BFM type, here JTAG */
555 h_u16_to_le(pm
->wbytes
, 0);
556 h_u16_to_le(pm
->rbytes
, 0);
557 h_u16_to_le(pm
->wwords
, 0);
558 h_u16_to_le(pm
->rwords
, 0);
559 vdebug_wait_server(hsock
, pm
);
560 pm
->cmd
= VD_CMD_CLOSE
;
561 h_u16_to_le(pm
->wid
, VD_VERSION
); /* client version */
562 h_u16_to_le(pm
->wbytes
, 0);
563 h_u16_to_le(pm
->rbytes
, 0);
564 h_u16_to_le(pm
->wwords
, 0);
565 h_u16_to_le(pm
->rwords
, 0);
566 vdebug_wait_server(hsock
, pm
);
567 LOG_DEBUG("type %0x", type
);
572 static int vdebug_wait(int hsock
, struct vd_shm
*pm
, uint32_t cycles
)
575 pm
->cmd
= VD_CMD_WAIT
;
576 h_u16_to_le(pm
->wbytes
, 0);
577 h_u16_to_le(pm
->rbytes
, 0);
578 h_u32_to_le(pm
->rwdata
, cycles
); /* clock sycles to wait */
579 int rc
= vdebug_wait_server(hsock
, pm
);
581 LOG_ERROR("0x%x waiting %" PRIx32
" cycles", rc
, cycles
);
584 LOG_DEBUG("%d cycles", cycles
);
590 static int vdebug_sig_set(int hsock
, struct vd_shm
*pm
, uint32_t write_mask
, uint32_t value
)
592 pm
->cmd
= VD_CMD_SIGSET
;
593 h_u16_to_le(pm
->wbytes
, 0);
594 h_u16_to_le(pm
->rbytes
, 0);
595 h_u32_to_le(pm
->rwdata
, (write_mask
<< 16) | (value
& 0xffff)); /* mask and value of signals to set */
596 int rc
= vdebug_wait_server(hsock
, pm
);
598 LOG_ERROR("0x%x setting signals %04" PRIx32
, rc
, write_mask
);
602 LOG_DEBUG("setting signals %04" PRIx32
" to %04" PRIx32
, write_mask
, value
);
607 static int vdebug_jtag_clock(int hsock
, struct vd_shm
*pm
, uint32_t value
)
609 pm
->cmd
= VD_CMD_JTAGCLOCK
;
610 h_u16_to_le(pm
->wbytes
, 0);
611 h_u16_to_le(pm
->rbytes
, 0);
612 h_u32_to_le(pm
->rwdata
, value
); /* divider value */
613 int rc
= vdebug_wait_server(hsock
, pm
);
615 LOG_ERROR("0x%x setting jtag_clock", rc
);
619 LOG_DEBUG("setting jtag clock divider to %" PRIx32
, value
);
624 static int vdebug_jtag_shift_tap(int hsock
, struct vd_shm
*pm
, uint8_t num_pre
,
625 const uint8_t tms_pre
, uint32_t num
, const uint8_t *tdi
,
626 uint8_t num_post
, const uint8_t tms_post
, uint8_t *tdo
,
629 const uint32_t tobits
= 8;
630 uint16_t bytes
, hwords
, anum
, words
, waddr
;
633 pm
->cmd
= VD_CMD_JTAGSHTAP
;
634 vdc
.trans_last
= f_last
|| (vdc
.trans_batch
== VD_BATCH_NO
);
636 waddr
= 0; /* reset buffer offset */
638 waddr
= le_to_h_u32(pm
->offseth
); /* continue from the previous transaction */
639 if (num_post
) /* actual number of bits to shift */
640 anum
= num
+ num_pre
+ num_post
- 1;
642 anum
= num
+ num_pre
;
643 hwords
= (anum
+ 4 * vdc
.buf_width
- 1) / (4 * vdc
.buf_width
); /* in 4B TDI/TMS words */
644 words
= (hwords
+ 1) / 2; /* in 8B TDO words to read */
645 bytes
= (num
+ 7) / 8; /* data only portion in bytes */
646 /* buffer overflow check and flush */
647 if (4 * waddr
+ sizeof(uint64_t) + 8 * hwords
+ 64 > VD_BUFFER_LEN
) {
648 vdc
.trans_last
= 1; /* force flush within 64B of buffer end */
649 } else if (4 * waddr
+ sizeof(uint64_t) + 8 * hwords
> VD_BUFFER_LEN
) {
650 /* this req does not fit, discard it */
651 LOG_ERROR("%04x L:%02d O:%05x @%04x too many bits to shift",
652 le_to_h_u16(pm
->wid
), anum
, (vdc
.trans_first
<< 14) | (vdc
.trans_last
<< 15), waddr
);
657 uint16_t i
, j
; /* portability requires to use bit operations for 8B JTAG header */
658 uint64_t jhdr
= (tdo
? ((uint64_t)(words
) << 48) : 0) + ((uint64_t)(hwords
) << 32) +
659 ((tdo
? 3UL : 1UL) << 30) + (num_pre
<< 27) + (num_post
<< 24) + anum
;
660 h_u64_to_le(&pm
->wd8
[4 * waddr
], jhdr
);
662 h_u16_to_le(pm
->wid
, le_to_h_u16(pm
->wid
) + 1); /* transaction ID */
663 waddr
+= 2; /* waddr past header */
664 /* TDI/TMS data follows as 32 bit word pairs {TMS,TDI} */
665 pm
->wd8
[4 * waddr
] = (tdi
? (tdi
[0] << num_pre
) : 0);
666 pm
->wd8
[4 * waddr
+ 4] = tms_pre
; /* init with tms_pre */
667 if (num
+ num_pre
<= 8) /* and tms_post for num <=4 */
668 pm
->wd8
[4 * waddr
+ 4] |= (tms_post
<< (num
+ num_pre
- 1));
669 for (i
= 1, j
= 4 * waddr
; i
< bytes
; i
++) {
670 if (i
== bytes
- 1 && num
+ num_pre
<= bytes
* tobits
)
671 pm
->wd8
[j
+ i
+ 4] = tms_post
<< ((num
+ num_pre
- 1) % 8);
673 pm
->wd8
[j
+ i
+ 4] = 0x0;/* placing 4 bytes of TMS bits into high word */
674 if (!tdi
) /* placing 4 bytes of TDI bits into low word */
675 pm
->wd8
[j
+ i
] = 0x0;
677 pm
->wd8
[j
+ i
] = (tdi
[i
] << num_pre
) | (tdi
[i
- 1] >> (8 - num_pre
));
683 if (num
+ num_pre
> bytes
* tobits
) /* in case 1 additional byte needed for TDI */
684 pm
->wd8
[j
+ i
] = (tdi
[i
- 1] >> (8 - num_pre
)); /* put last TDI bits there */
686 if (num
+ num_pre
<= bytes
* tobits
) { /* in case no or 1 additional byte needed */
687 pm
->wd8
[j
+ i
+ 4] = tms_post
>> (8 - (num
+ num_pre
- 1) % 8); /* may need to add higher part */
688 /* in case exactly 1 additional byte needed */
689 } else if (num
+ num_pre
> bytes
* tobits
&& anum
<= (bytes
+ 1) * tobits
) {
690 pm
->wd8
[j
+ i
+ 4] = tms_post
<< ((num
+ num_pre
- 1) % 8); /* add whole tms_post */
691 } else { /* in case 2 additional bytes, tms_post split */
692 pm
->wd8
[j
+ i
+ 4] = tms_post
<< ((num
+ num_pre
- 1) % 8);/* add lower part of tms_post */
693 if (i
% 4 == 3) /* next byte is in the next 32b word */
694 pm
->wd8
[j
+ i
+ 4 + 5] = tms_post
>> (8 - (num
+ num_pre
- 1) % 8); /* and higher part */
695 else /* next byte is in the same 32b word */
696 pm
->wd8
[j
+ i
+ 4 + 1] = tms_post
>> (8 - (num
+ num_pre
- 1) % 8); /* and higher part */
701 if (le_to_h_u16(pm
->rwords
) == 0) {
704 rd
= calloc(1, sizeof(struct vd_rdata
));
705 if (!rd
) /* check allocation for 24B */
707 list_add_tail(&rd
->lh
, &vdc
.rdataq
.lh
);
710 h_u16_to_le(pm
->rwords
, le_to_h_u16(pm
->rwords
) + words
);/* keep track of the words to read */
712 h_u16_to_le(pm
->wwords
, waddr
/ 2 + hwords
); /* payload size *2 to include both TDI and TMS data */
713 h_u16_to_le(pm
->waddr
, le_to_h_u16(pm
->waddr
) + 1);
716 if (!waddr
) /* flush issued, but buffer empty */
718 else if (!vdc
.trans_last
) /* buffered request */
719 h_u16_to_le(pm
->offseth
, waddr
+ hwords
* 2); /* offset for next transaction, must be even */
720 else /* execute batch of requests */
721 rc
= vdebug_run_jtag_queue(hsock
, pm
, le_to_h_u16(pm
->waddr
));
722 vdc
.trans_first
= vdc
.trans_last
; /* flush forces trans_first flag */
727 static int vdebug_reg_write(int hsock
, struct vd_shm
*pm
, const uint32_t reg
,
728 const uint32_t data
, uint8_t aspace
, uint8_t f_last
)
733 pm
->cmd
= VD_CMD_REGWRITE
;
734 vdc
.trans_last
= f_last
|| (vdc
.trans_batch
== VD_BATCH_NO
);
736 waddr
= 0; /* reset buffer offset */
738 waddr
= le_to_h_u16(pm
->offseth
); /* continue from the previous transaction */
740 if (4 * waddr
+ 2 * sizeof(uint64_t) + 4 > VD_BUFFER_LEN
)
741 vdc
.trans_last
= 1; /* force flush, no room for next request */
743 uint64_t rhdr
= ((uint64_t)reg
<< 32) + (1UL << 30) + (2UL << 27) + (1UL << 16) + aspace
;
744 h_u64_to_le(&pm
->wd8
[4 * waddr
], rhdr
);
745 h_u32_to_le(&pm
->wd8
[4 * (waddr
+ 2)], data
);
746 h_u16_to_le(pm
->wid
, le_to_h_u16(pm
->wid
) + 1);
747 h_u16_to_le(pm
->wwords
, waddr
+ 3);
748 h_u16_to_le(pm
->waddr
, le_to_h_u16(pm
->waddr
) + 1);
749 if (!vdc
.trans_last
) /* buffered request */
750 h_u16_to_le(pm
->offseth
, waddr
+ 3);
752 rc
= vdebug_run_reg_queue(hsock
, pm
, le_to_h_u16(pm
->waddr
));
753 vdc
.trans_first
= vdc
.trans_last
; /* flush forces trans_first flag */
758 static int vdebug_reg_read(int hsock
, struct vd_shm
*pm
, const uint32_t reg
,
759 uint32_t *data
, uint8_t aspace
, uint8_t f_last
)
764 pm
->cmd
= VD_CMD_REGREAD
;
765 vdc
.trans_last
= f_last
|| (vdc
.trans_batch
== VD_BATCH_NO
);
767 waddr
= 0; /* reset buffer offset */
769 waddr
= le_to_h_u16(pm
->offseth
); /* continue from the previous transaction */
771 if (4 * waddr
+ 2 * sizeof(uint64_t) + 4 > VD_BUFFER_LEN
)
772 vdc
.trans_last
= 1; /* force flush, no room for next request */
774 uint64_t rhdr
= ((uint64_t)reg
<< 32) + (2UL << 30) + (2UL << 27) + ((data
? 1UL : 0UL) << 16) + aspace
;
775 h_u64_to_le(&pm
->wd8
[4 * waddr
], rhdr
);
776 h_u16_to_le(pm
->wid
, le_to_h_u16(pm
->wid
) + 1);
779 if (le_to_h_u16(pm
->rwords
) == 0) {
782 rd
= calloc(1, sizeof(struct vd_rdata
));
783 if (!rd
) /* check allocation for 24B */
785 list_add_tail(&rd
->lh
, &vdc
.rdataq
.lh
);
787 rd
->rdata
= (uint8_t *)data
;
788 h_u16_to_le(pm
->rwords
, le_to_h_u16(pm
->rwords
) + 1);
790 h_u16_to_le(pm
->wwords
, waddr
+ 2);
791 h_u16_to_le(pm
->waddr
, le_to_h_u16(pm
->waddr
) + 1);
792 if (!vdc
.trans_last
) /* buffered request */
793 h_u16_to_le(pm
->offseth
, waddr
+ 2);
795 rc
= vdebug_run_reg_queue(hsock
, pm
, le_to_h_u16(pm
->waddr
));
796 vdc
.trans_first
= vdc
.trans_last
; /* flush forces trans_first flag */
801 static int vdebug_mem_open(int hsock
, struct vd_shm
*pm
, const char *path
, uint8_t ndx
)
808 pm
->cmd
= VD_CMD_MEMOPEN
;
809 h_u16_to_le(pm
->wbytes
, strlen(path
) + 1); /* includes terminating 0 */
810 h_u16_to_le(pm
->rbytes
, 8);
811 h_u16_to_le(pm
->wwords
, 0);
812 h_u16_to_le(pm
->rwords
, 0);
813 memcpy(pm
->wd8
, path
, le_to_h_u16(pm
->wbytes
));
814 rc
= vdebug_wait_server(hsock
, pm
);
816 LOG_ERROR("0x%x opening memory %s", rc
, path
);
817 } else if (ndx
!= pm
->rd8
[2]) {
818 LOG_WARNING("Invalid memory index %" PRIu16
" returned. Direct memory access disabled", pm
->rd8
[2]);
820 vdc
.mem_width
[ndx
] = le_to_h_u16(&pm
->rd8
[0]) / 8; /* memory width in bytes */
821 vdc
.mem_depth
[ndx
] = le_to_h_u32(&pm
->rd8
[4]); /* memory depth in words */
822 LOG_DEBUG("%" PRIx8
": %s memory %" PRIu32
"x%" PRIu32
"B, buffer %" PRIu32
"x%" PRIu32
"B", ndx
, path
,
823 vdc
.mem_depth
[ndx
], vdc
.mem_width
[ndx
], VD_BUFFER_LEN
/ vdc
.mem_width
[ndx
], vdc
.mem_width
[ndx
]);
829 static void vdebug_mem_close(int hsock
, struct vd_shm
*pm
, uint8_t ndx
)
831 pm
->cmd
= VD_CMD_MEMCLOSE
;
832 h_u32_to_le(pm
->rwdata
, ndx
); /* which memory */
833 h_u16_to_le(pm
->wbytes
, 0);
834 h_u16_to_le(pm
->rbytes
, 0);
835 h_u16_to_le(pm
->wwords
, 0);
836 h_u16_to_le(pm
->rwords
, 0);
837 vdebug_wait_server(hsock
, pm
);
838 LOG_DEBUG("%" PRIx8
": %s", ndx
, vdc
.mem_path
[ndx
]);
842 static int vdebug_init(void)
844 vdc
.hsocket
= vdebug_socket_open(vdc
.server_name
, vdc
.server_port
);
845 pbuf
= calloc(1, sizeof(struct vd_shm
));
847 close_socket(vdc
.hsocket
);
849 LOG_ERROR("cannot allocate %zu bytes", sizeof(struct vd_shm
));
852 if (vdc
.hsocket
<= 0) {
855 LOG_ERROR("cannot connect to vdebug server %s:%" PRIu16
,
856 vdc
.server_name
, vdc
.server_port
);
860 vdc
.poll_cycles
= vdc
.poll_max
;
861 uint32_t sig_mask
= VD_SIG_RESET
;
862 if (transport_is_jtag())
863 sig_mask
|= VD_SIG_TRST
| VD_SIG_TCKDIV
;
865 int rc
= vdebug_open(vdc
.hsocket
, pbuf
, vdc
.bfm_path
, vdc
.bfm_type
, vdc
.bfm_period
, sig_mask
);
867 LOG_ERROR("0x%x cannot connect to %s", rc
, vdc
.bfm_path
);
868 close_socket(vdc
.hsocket
);
873 for (uint8_t i
= 0; i
< vdc
.mem_ndx
; i
++) {
874 rc
= vdebug_mem_open(vdc
.hsocket
, pbuf
, vdc
.mem_path
[i
], i
);
876 LOG_ERROR("0x%x cannot connect to %s", rc
, vdc
.mem_path
[i
]);
879 LOG_INFO("vdebug %d connected to %s through %s:%" PRIu16
,
880 VD_VERSION
, vdc
.bfm_path
, vdc
.server_name
, vdc
.server_port
);
886 static int vdebug_quit(void)
888 for (uint8_t i
= 0; i
< vdc
.mem_ndx
; i
++)
889 if (vdc
.mem_width
[i
])
890 vdebug_mem_close(vdc
.hsocket
, pbuf
, i
);
891 int rc
= vdebug_close(vdc
.hsocket
, pbuf
, vdc
.bfm_type
);
892 LOG_INFO("vdebug %d disconnected from %s through %s:%" PRIu16
" rc:%d", VD_VERSION
,
893 vdc
.bfm_path
, vdc
.server_name
, vdc
.server_port
, rc
);
895 close_socket(vdc
.hsocket
);
902 static int vdebug_reset(int trst
, int srst
)
904 uint16_t sig_val
= 0xffff;
905 uint16_t sig_mask
= 0;
907 sig_mask
|= VD_SIG_RESET
;
909 sig_val
&= ~VD_SIG_RESET
;/* active low */
910 if (transport_is_jtag()) {
911 sig_mask
|= VD_SIG_TRST
;
913 sig_val
&= ~VD_SIG_TRST
; /* active low */
916 LOG_INFO("rst trst:%d srst:%d mask:%" PRIx16
" val:%" PRIx16
, trst
, srst
, sig_mask
, sig_val
);
917 int rc
= vdebug_sig_set(vdc
.hsocket
, pbuf
, sig_mask
, sig_val
);
919 rc
= vdebug_wait(vdc
.hsocket
, pbuf
, 20); /* 20 clock cycles pulse */
924 static int vdebug_jtag_tms_seq(const uint8_t *tms
, int num
, uint8_t f_flush
)
926 LOG_DEBUG_IO("tms len:%d tms:%x", num
, *tms
);
928 return vdebug_jtag_shift_tap(vdc
.hsocket
, pbuf
, num
, *tms
, 0, NULL
, 0, 0, NULL
, f_flush
);
931 static int vdebug_jtag_path_move(struct pathmove_command
*cmd
, uint8_t f_flush
)
933 uint8_t tms
[DIV_ROUND_UP(cmd
->num_states
, 8)];
934 LOG_DEBUG_IO("path num states %d", cmd
->num_states
);
936 memset(tms
, 0, DIV_ROUND_UP(cmd
->num_states
, 8));
938 for (uint8_t i
= 0; i
< cmd
->num_states
; i
++) {
939 if (tap_state_transition(tap_get_state(), true) == cmd
->path
[i
])
940 buf_set_u32(tms
, i
, 1, 1);
941 tap_set_state(cmd
->path
[i
]);
944 return vdebug_jtag_tms_seq(tms
, cmd
->num_states
, f_flush
);
947 static int vdebug_jtag_tlr(tap_state_t state
, uint8_t f_flush
)
951 tap_state_t cur
= tap_get_state();
952 uint8_t tms_pre
= tap_get_tms_path(cur
, state
);
953 uint8_t num_pre
= tap_get_tms_path_len(cur
, state
);
954 LOG_DEBUG_IO("tlr from %x to %x", cur
, state
);
956 rc
= vdebug_jtag_shift_tap(vdc
.hsocket
, pbuf
, num_pre
, tms_pre
, 0, NULL
, 0, 0, NULL
, f_flush
);
957 tap_set_state(state
);
963 static int vdebug_jtag_scan(struct scan_command
*cmd
, uint8_t f_flush
)
967 tap_state_t cur
= tap_get_state();
968 uint8_t state
= cmd
->ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
;
969 uint8_t tms_pre
= tap_get_tms_path(cur
, state
);
970 uint8_t num_pre
= tap_get_tms_path_len(cur
, state
);
971 uint8_t tms_post
= tap_get_tms_path(state
, cmd
->end_state
);
972 uint8_t num_post
= tap_get_tms_path_len(state
, cmd
->end_state
);
973 int num_bits
= jtag_scan_size(cmd
);
974 LOG_DEBUG_IO("scan len:%d fields:%d ir/!dr:%d state cur:%x end:%x",
975 num_bits
, cmd
->num_fields
, cmd
->ir_scan
, cur
, cmd
->end_state
);
976 for (int i
= 0; i
< cmd
->num_fields
; i
++) {
977 uint8_t cur_num_pre
= i
== 0 ? num_pre
: 0;
978 uint8_t cur_tms_pre
= i
== 0 ? tms_pre
: 0;
979 uint8_t cur_num_post
= i
== cmd
->num_fields
- 1 ? num_post
: 0;
980 uint8_t cur_tms_post
= i
== cmd
->num_fields
- 1 ? tms_post
: 0;
981 uint8_t cur_flush
= i
== cmd
->num_fields
- 1 ? f_flush
: 0;
982 rc
= vdebug_jtag_shift_tap(vdc
.hsocket
, pbuf
, cur_num_pre
, cur_tms_pre
,
983 cmd
->fields
[i
].num_bits
, cmd
->fields
[i
].out_value
, cur_num_post
, cur_tms_post
,
984 cmd
->fields
[i
].in_value
, cur_flush
);
989 if (cur
!= cmd
->end_state
)
990 tap_set_state(cmd
->end_state
);
995 static int vdebug_jtag_runtest(int cycles
, tap_state_t state
, uint8_t f_flush
)
997 tap_state_t cur
= tap_get_state();
998 uint8_t tms_pre
= tap_get_tms_path(cur
, state
);
999 uint8_t num_pre
= tap_get_tms_path_len(cur
, state
);
1000 LOG_DEBUG_IO("idle len:%d state cur:%x end:%x", cycles
, cur
, state
);
1001 int rc
= vdebug_jtag_shift_tap(vdc
.hsocket
, pbuf
, num_pre
, tms_pre
, cycles
, NULL
, 0, 0, NULL
, f_flush
);
1003 tap_set_state(state
);
1008 static int vdebug_jtag_stableclocks(int num
, uint8_t f_flush
)
1010 LOG_DEBUG("stab len:%d state cur:%x", num
, tap_get_state());
1012 return vdebug_jtag_shift_tap(vdc
.hsocket
, pbuf
, 0, 0, num
, NULL
, 0, 0, NULL
, f_flush
);
1015 static int vdebug_sleep(int us
)
1017 LOG_INFO("sleep %d us", us
);
1019 return vdebug_wait(vdc
.hsocket
, pbuf
, us
/ 1000);
1022 static int vdebug_jtag_speed(int speed
)
1024 unsigned int clkmax
= VD_SCALE_PSTOMS
/ (vdc
.bfm_period
* 2); /* kHz */
1025 unsigned int divval
= clkmax
/ speed
;
1026 LOG_INFO("jclk speed:%d kHz set, BFM divider %u", speed
, divval
);
1028 return vdebug_jtag_clock(vdc
.hsocket
, pbuf
, divval
);
1031 static int vdebug_jtag_khz(int khz
, int *jtag_speed
)
1033 unsigned int clkmax
= VD_SCALE_PSTOMS
/ (vdc
.bfm_period
* 2); /* kHz */
1034 unsigned int divval
= khz
? clkmax
/ khz
: 1;
1035 *jtag_speed
= clkmax
/ divval
;
1036 LOG_DEBUG("khz speed:%d from khz:%d", *jtag_speed
, khz
);
1041 static int vdebug_jtag_div(int speed
, int *khz
)
1044 LOG_DEBUG("div khz:%d from speed:%d", *khz
, speed
);
1049 static int vdebug_jtag_execute_queue(void)
1053 for (struct jtag_command
*cmd
= jtag_command_queue
; rc
== ERROR_OK
&& cmd
; cmd
= cmd
->next
) {
1054 switch (cmd
->type
) {
1056 rc
= vdebug_jtag_runtest(cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
, !cmd
->next
);
1058 case JTAG_STABLECLOCKS
:
1059 rc
= vdebug_jtag_stableclocks(cmd
->cmd
.stableclocks
->num_cycles
, !cmd
->next
);
1061 case JTAG_TLR_RESET
:
1062 rc
= vdebug_jtag_tlr(cmd
->cmd
.statemove
->end_state
, !cmd
->next
);
1065 rc
= vdebug_jtag_path_move(cmd
->cmd
.pathmove
, !cmd
->next
);
1068 rc
= vdebug_jtag_tms_seq(cmd
->cmd
.tms
->bits
, cmd
->cmd
.tms
->num_bits
, !cmd
->next
);
1071 rc
= vdebug_sleep(cmd
->cmd
.sleep
->us
);
1074 rc
= vdebug_jtag_scan(cmd
->cmd
.scan
, !cmd
->next
);
1077 LOG_ERROR("Unknown JTAG command type 0x%x encountered", cmd
->type
);
1085 static int vdebug_dap_bankselect(struct adiv5_ap
*ap
, unsigned int reg
)
1090 if (is_adiv6(ap
->dap
)) {
1091 sel
= ap
->ap_num
| (reg
& 0x00000FF0);
1092 if (sel
!= (ap
->dap
->select
& ~0xfull
)) {
1093 sel
|= ap
->dap
->select
& DP_SELECT_DPBANK
;
1094 if (ap
->dap
->asize
> 32)
1095 sel
|= (DP_SELECT1
>> 4) & DP_SELECT_DPBANK
;
1096 ap
->dap
->select
= sel
;
1097 ap
->dap
->select_valid
= true;
1098 rc
= vdebug_reg_write(vdc
.hsocket
, pbuf
, DP_SELECT
>> 2, (uint32_t)sel
, VD_ASPACE_DP
, 0);
1099 if (rc
== ERROR_OK
) {
1100 ap
->dap
->select_valid
= true;
1101 if (ap
->dap
->asize
> 32)
1102 rc
= vdebug_reg_write(vdc
.hsocket
, pbuf
, (DP_SELECT1
& DP_SELECT_DPBANK
) >> 2,
1103 (uint32_t)(sel
>> 32), VD_ASPACE_DP
, 0);
1105 ap
->dap
->select1_valid
= true;
1108 } else { /* ADIv5 */
1109 sel
= (ap
->ap_num
<< 24) | (reg
& ADIV5_DP_SELECT_APBANK
);
1110 if (sel
!= ap
->dap
->select
) {
1111 ap
->dap
->select
= sel
;
1112 rc
= vdebug_reg_write(vdc
.hsocket
, pbuf
, DP_SELECT
>> 2, (uint32_t)sel
, VD_ASPACE_DP
, 0);
1114 ap
->dap
->select_valid
= true;
1120 static int vdebug_dap_connect(struct adiv5_dap
*dap
)
1122 return dap_dp_init(dap
);
1125 static int vdebug_dap_send_sequence(struct adiv5_dap
*dap
, enum swd_special_seq seq
)
1130 static int vdebug_dap_queue_dp_read(struct adiv5_dap
*dap
, unsigned int reg
, uint32_t *data
)
1132 if (reg
!= DP_SELECT
&& reg
!= DP_RDBUFF
1133 && (!dap
->select_valid
|| ((reg
>> 4) & DP_SELECT_DPBANK
) != (dap
->select
& DP_SELECT_DPBANK
))) {
1134 dap
->select
= (dap
->select
& ~DP_SELECT_DPBANK
) | ((reg
>> 4) & DP_SELECT_DPBANK
);
1135 vdebug_reg_write(vdc
.hsocket
, pbuf
, DP_SELECT
>> 2, dap
->select
, VD_ASPACE_DP
, 0);
1136 dap
->select_valid
= true;
1138 return vdebug_reg_read(vdc
.hsocket
, pbuf
, (reg
& DP_SELECT_DPBANK
) >> 2, data
, VD_ASPACE_DP
, 0);
1141 static int vdebug_dap_queue_dp_write(struct adiv5_dap
*dap
, unsigned int reg
, uint32_t data
)
1143 if (reg
!= DP_SELECT
&& reg
!= DP_RDBUFF
1144 && (!dap
->select_valid
|| ((reg
>> 4) & DP_SELECT_DPBANK
) != (dap
->select
& DP_SELECT_DPBANK
))) {
1145 dap
->select
= (dap
->select
& ~DP_SELECT_DPBANK
) | ((reg
>> 4) & DP_SELECT_DPBANK
);
1146 vdebug_reg_write(vdc
.hsocket
, pbuf
, DP_SELECT
>> 2, dap
->select
, VD_ASPACE_DP
, 0);
1147 dap
->select_valid
= true;
1149 return vdebug_reg_write(vdc
.hsocket
, pbuf
, (reg
& DP_SELECT_DPBANK
) >> 2, data
, VD_ASPACE_DP
, 0);
1152 static int vdebug_dap_queue_ap_read(struct adiv5_ap
*ap
, unsigned int reg
, uint32_t *data
)
1154 vdebug_dap_bankselect(ap
, reg
);
1156 vdebug_reg_read(vdc
.hsocket
, pbuf
, (reg
& DP_SELECT_DPBANK
) >> 2, NULL
, VD_ASPACE_AP
, 0);
1158 return vdebug_reg_read(vdc
.hsocket
, pbuf
, DP_RDBUFF
>> 2, data
, VD_ASPACE_DP
, 0);
1161 static int vdebug_dap_queue_ap_write(struct adiv5_ap
*ap
, unsigned int reg
, uint32_t data
)
1163 vdebug_dap_bankselect(ap
, reg
);
1164 return vdebug_reg_write(vdc
.hsocket
, pbuf
, (reg
& DP_SELECT_DPBANK
) >> 2, data
, VD_ASPACE_AP
, 0);
1167 static int vdebug_dap_queue_ap_abort(struct adiv5_dap
*dap
, uint8_t *ack
)
1169 return vdebug_reg_write(vdc
.hsocket
, pbuf
, 0, 0x1, VD_ASPACE_AB
, 0);
1172 static int vdebug_dap_run(struct adiv5_dap
*dap
)
1174 if (le_to_h_u16(pbuf
->waddr
))
1175 return vdebug_run_reg_queue(vdc
.hsocket
, pbuf
, le_to_h_u16(pbuf
->waddr
));
1180 COMMAND_HANDLER(vdebug_set_server
)
1182 if ((CMD_ARGC
!= 1) || !strchr(CMD_ARGV
[0], ':'))
1183 return ERROR_COMMAND_SYNTAX_ERROR
;
1185 char *pchar
= strchr(CMD_ARGV
[0], ':');
1187 strncpy(vdc
.server_name
, CMD_ARGV
[0], sizeof(vdc
.server_name
) - 1);
1188 int port
= atoi(++pchar
);
1189 if (port
< 0 || port
> UINT16_MAX
) {
1190 LOG_ERROR("invalid port number %d specified", port
);
1191 return ERROR_COMMAND_SYNTAX_ERROR
;
1193 vdc
.server_port
= port
;
1194 LOG_DEBUG("server: %s port %u", vdc
.server_name
, vdc
.server_port
);
1199 COMMAND_HANDLER(vdebug_set_bfm
)
1203 if ((CMD_ARGC
!= 2) || (sscanf(CMD_ARGV
[1], "%u%c", &vdc
.bfm_period
, &prefix
) != 2))
1204 return ERROR_COMMAND_SYNTAX_ERROR
;
1206 strncpy(vdc
.bfm_path
, CMD_ARGV
[0], sizeof(vdc
.bfm_path
) - 1);
1209 vdc
.bfm_period
*= 1000000;
1212 vdc
.bfm_period
*= 1000;
1218 if (transport_is_dapdirect_swd())
1219 vdc
.bfm_type
= strstr(vdc
.bfm_path
, "dap6") ? VD_BFM_DAP6
: VD_BFM_SWDP
;
1221 vdc
.bfm_type
= VD_BFM_JTAG
;
1222 LOG_DEBUG("bfm_path: %s clk_period %ups", vdc
.bfm_path
, vdc
.bfm_period
);
1227 COMMAND_HANDLER(vdebug_set_mem
)
1230 return ERROR_COMMAND_SYNTAX_ERROR
;
1232 if (vdc
.mem_ndx
>= VD_MAX_MEMORIES
) {
1233 LOG_ERROR("mem_path declared more than %d allowed times", VD_MAX_MEMORIES
);
1237 strncpy(vdc
.mem_path
[vdc
.mem_ndx
], CMD_ARGV
[0], sizeof(vdc
.mem_path
[vdc
.mem_ndx
]) - 1);
1238 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], vdc
.mem_base
[vdc
.mem_ndx
]);
1239 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], vdc
.mem_size
[vdc
.mem_ndx
]);
1240 LOG_DEBUG("mem_path: set %s @ 0x%08x+0x%08x", vdc
.mem_path
[vdc
.mem_ndx
],
1241 vdc
.mem_base
[vdc
.mem_ndx
], vdc
.mem_size
[vdc
.mem_ndx
]);
1247 COMMAND_HANDLER(vdebug_set_batching
)
1250 return ERROR_COMMAND_SYNTAX_ERROR
;
1252 if (isdigit((unsigned char)CMD_ARGV
[0][0]))
1253 vdc
.trans_batch
= (CMD_ARGV
[0][0] == '0' ? 0 : (CMD_ARGV
[0][0] == '1' ? 1 : 2));
1254 else if (CMD_ARGV
[0][0] == 'r')
1255 vdc
.trans_batch
= VD_BATCH_WR
;
1256 else if (CMD_ARGV
[0][0] == 'w')
1257 vdc
.trans_batch
= VD_BATCH_WO
;
1259 vdc
.trans_batch
= VD_BATCH_NO
;
1260 LOG_DEBUG("batching: set to %u", vdc
.trans_batch
);
1265 COMMAND_HANDLER(vdebug_set_polling
)
1268 return ERROR_COMMAND_SYNTAX_ERROR
;
1270 vdc
.poll_min
= atoi(CMD_ARGV
[0]);
1271 vdc
.poll_max
= atoi(CMD_ARGV
[1]);
1272 LOG_DEBUG("polling: set min %u max %u", vdc
.poll_min
, vdc
.poll_max
);
1277 static const struct command_registration vdebug_command_handlers
[] = {
1280 .handler
= &vdebug_set_server
,
1281 .mode
= COMMAND_CONFIG
,
1282 .help
= "set the vdebug server name or address",
1283 .usage
= "<host:port>",
1287 .handler
= &vdebug_set_bfm
,
1288 .mode
= COMMAND_CONFIG
,
1289 .help
= "set the vdebug BFM hierarchical path",
1290 .usage
= "<path> <clk_period[p|n|u]s>",
1294 .handler
= &vdebug_set_mem
,
1295 .mode
= COMMAND_CONFIG
,
1296 .help
= "set the design memory for the code load",
1297 .usage
= "<path> <base_address> <size>",
1301 .handler
= &vdebug_set_batching
,
1302 .mode
= COMMAND_CONFIG
,
1303 .help
= "set the transaction batching no|wr|rd [0|1|2]",
1308 .handler
= &vdebug_set_polling
,
1309 .mode
= COMMAND_CONFIG
,
1310 .help
= "set the polling pause, executing hardware cycles between min and max",
1311 .usage
= "<min cycles> <max cycles>",
1313 COMMAND_REGISTRATION_DONE
1316 static const struct command_registration vdebug_command
[] = {
1319 .chain
= vdebug_command_handlers
,
1320 .mode
= COMMAND_ANY
,
1321 .help
= "vdebug command group",
1324 COMMAND_REGISTRATION_DONE
1327 static struct jtag_interface vdebug_jtag_ops
= {
1328 .supported
= DEBUG_CAP_TMS_SEQ
,
1329 .execute_queue
= vdebug_jtag_execute_queue
,
1332 static const struct dap_ops vdebug_dap_ops
= {
1333 .connect
= vdebug_dap_connect
,
1334 .send_sequence
= vdebug_dap_send_sequence
,
1335 .queue_dp_read
= vdebug_dap_queue_dp_read
,
1336 .queue_dp_write
= vdebug_dap_queue_dp_write
,
1337 .queue_ap_read
= vdebug_dap_queue_ap_read
,
1338 .queue_ap_write
= vdebug_dap_queue_ap_write
,
1339 .queue_ap_abort
= vdebug_dap_queue_ap_abort
,
1340 .run
= vdebug_dap_run
,
1341 .sync
= NULL
, /* optional */
1342 .quit
= NULL
, /* optional */
1345 static const char *const vdebug_transports
[] = { "jtag", "dapdirect_swd", NULL
};
1347 struct adapter_driver vdebug_adapter_driver
= {
1349 .transports
= vdebug_transports
,
1350 .speed
= vdebug_jtag_speed
,
1351 .khz
= vdebug_jtag_khz
,
1352 .speed_div
= vdebug_jtag_div
,
1353 .commands
= vdebug_command
,
1354 .init
= vdebug_init
,
1355 .quit
= vdebug_quit
,
1356 .reset
= vdebug_reset
,
1357 .jtag_ops
= &vdebug_jtag_ops
,
1358 .dap_swd_ops
= &vdebug_dap_ops
,
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)