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 %u", cmd
->num_states
);
936 memset(tms
, 0, DIV_ROUND_UP(cmd
->num_states
, 8));
938 for (unsigned int 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 const unsigned int num_bits
= jtag_scan_size(cmd
);
974 LOG_DEBUG_IO("scan len:%u fields:%u ir/!dr:%d state cur:%x end:%x",
975 num_bits
, cmd
->num_fields
, cmd
->ir_scan
, cur
, cmd
->end_state
);
976 for (unsigned 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(unsigned int num_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:%u state cur:%x end:%x", num_cycles
, cur
, state
);
1001 int rc
= vdebug_jtag_shift_tap(vdc
.hsocket
, pbuf
, num_pre
, tms_pre
, num_cycles
, NULL
, 0, 0, NULL
, f_flush
);
1003 tap_set_state(state
);
1008 static int vdebug_jtag_stableclocks(unsigned int num_cycles
, uint8_t f_flush
)
1010 LOG_DEBUG("stab len:%u state cur:%x", num_cycles
, tap_get_state());
1012 return vdebug_jtag_shift_tap(vdc
.hsocket
, pbuf
, 0, 0, num_cycles
, 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(struct jtag_command
*cmd_queue
)
1053 for (struct jtag_command
*cmd
= cmd_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
,