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_JTDP
= 0x0001, /* transactor DAP JTAG DP */
70 VD_BFM_SWDP
= 0x0002, /* transactor DAP SWD DP */
71 VD_BFM_AHB
= 0x0003, /* transactor AMBA AHB */
72 VD_BFM_APB
= 0x0004, /* transactor AMBA APB */
73 VD_BFM_AXI
= 0x0005, /* transactor AMBA AXI */
74 VD_BFM_JTAG
= 0x0006, /* transactor serial JTAG */
75 VD_BFM_SWD
= 0x0007, /* transactor serial SWD */
79 * @brief List of signals that can be read or written by the debugger
82 VD_SIG_TCK
= 0x0001, /* JTAG clock; tclk */
83 VD_SIG_TDI
= 0x0002, /* JTAG TDI; tdi */
84 VD_SIG_TMS
= 0x0004, /* JTAG TMS; tms */
85 VD_SIG_RESET
= 0x0008, /* DUT reset; rst */
86 VD_SIG_TRST
= 0x0010, /* JTAG Reset; trstn */
87 VD_SIG_TDO
= 0x0020, /* JTAG TDO; tdo */
88 VD_SIG_POWER
= 0x0100, /* BFM power; bfm_up */
89 VD_SIG_TCKDIV
= 0x0200, /* JTAG clock divider; tclkdiv */
90 VD_SIG_BUF
= 0x1000, /* memory buffer; mem */
94 * @brief List of errors
97 VD_ERR_NONE
= 0x0000, /* no error */
98 VD_ERR_NOT_IMPL
= 0x0100, /* feature not implemented */
99 VD_ERR_USAGE
= 0x0101, /* incorrect usage */
100 VD_ERR_PARAM
= 0x0102, /* incorrect parameter */
101 VD_ERR_CONFIG
= 0x0107, /* incorrect configuration */
102 VD_ERR_NO_MEMORY
= 0x0104, /* out of memory */
103 VD_ERR_SHM_OPEN
= 0x010a, /* cannot open shared memory */
104 VD_ERR_SHM_MAP
= 0x010b, /* cannot map shared memory */
105 VD_ERR_SOC_OPEN
= 0x011a, /* cannot open socket */
106 VD_ERR_SOC_OPT
= 0x011b, /* cannot set socket option */
107 VD_ERR_SOC_ADDR
= 0x011c, /* cannot resolve host address */
108 VD_ERR_SOC_CONN
= 0x011d, /* cannot connect to host */
109 VD_ERR_SOC_SEND
= 0x011e, /* error sending data on socket */
110 VD_ERR_SOC_RECV
= 0x011f, /* error receiving data from socket */
111 VD_ERR_LOCKED
= 0x0202, /* device locked */
112 VD_ERR_NOT_RUN
= 0x0204, /* transactor not running */
113 VD_ERR_NOT_OPEN
= 0x0205, /* transactor not open/connected */
114 VD_ERR_LICENSE
= 0x0206, /* cannot check out the license */
115 VD_ERR_VERSION
= 0x0207, /* transactor version mismatch */
116 VD_ERR_TIME_OUT
= 0x0301, /* time out, waiting */
117 VD_ERR_NO_POWER
= 0x0302, /* power out error */
118 VD_ERR_BUS_ERROR
= 0x0304, /* bus protocol error, like pslverr */
119 VD_ERR_NO_ACCESS
= 0x0306, /* no access to an object */
120 VD_ERR_INV_HANDLE
= 0x0307, /* invalid object handle */
121 VD_ERR_INV_SCOPE
= 0x0308, /* invalid scope */
127 VD_CMD_CONNECT
= 0x04,
128 VD_CMD_DISCONNECT
= 0x05,
130 VD_CMD_SIGSET
= 0x0a,
131 VD_CMD_SIGGET
= 0x0b,
132 VD_CMD_JTAGCLOCK
= 0x0f,
133 VD_CMD_REGWRITE
= 0x15,
134 VD_CMD_REGREAD
= 0x16,
135 VD_CMD_JTAGSHTAP
= 0x1a,
136 VD_CMD_MEMOPEN
= 0x21,
137 VD_CMD_MEMCLOSE
= 0x22,
138 VD_CMD_MEMWRITE
= 0x23,
155 struct { /* VD_CHEADER_LEN written by client */
156 uint8_t cmd
; /* 000; command */
157 uint8_t type
; /* 001; interface type */
158 uint8_t waddr
[2]; /* 002; write pointer */
159 uint8_t wbytes
[2]; /* 004; data bytes */
160 uint8_t rbytes
[2]; /* 006; data bytes to read */
161 uint8_t wwords
[2]; /* 008; data words */
162 uint8_t rwords
[2]; /* 00a; data words to read */
163 uint8_t rwdata
[4]; /* 00c; read/write data */
164 uint8_t offset
[4]; /* 010; address offset */
165 uint8_t offseth
[2]; /* 014; address offset 47:32 */
166 uint8_t wid
[2]; /* 016; request id*/
168 uint8_t wd8
[VD_BUFFER_LEN
]; /* 018; */
169 struct { /* VD_SHEADER_LEN written by server */
170 uint8_t rid
[2]; /* fd0: request id read */
171 uint8_t awords
[2]; /* fd2: actual data words read back */
172 uint8_t status
[4]; /* fd4; */
173 uint8_t duttime
[8]; /* fd8; */
175 uint8_t rd8
[VD_BUFFER_LEN
]; /* fe0: */
176 uint8_t state
[4]; /* 1f98; connection state */
177 uint8_t count
[4]; /* 1f9c; */
178 uint8_t dummy
[96]; /* 1fa0; 48+40B+8B; */
179 } __attribute__((packed
));
197 uint32_t mem_base
[VD_MAX_MEMORIES
];
198 uint32_t mem_size
[VD_MAX_MEMORIES
];
199 uint32_t mem_width
[VD_MAX_MEMORIES
];
200 uint32_t mem_depth
[VD_MAX_MEMORIES
];
201 uint16_t server_port
;
202 uint32_t poll_cycles
;
207 char server_name
[32];
209 char mem_path
[VD_MAX_MEMORIES
][128];
210 struct vd_rdata rdataq
;
232 static struct vd_shm
*pbuf
;
233 static struct vd_client vdc
;
235 static int vdebug_socket_error(void)
238 return WSAGetLastError();
244 static int vdebug_socket_open(char *server_addr
, uint32_t port
)
248 uint32_t buflen
= sizeof(struct vd_shm
); /* size of the send and rcv buffer */
249 struct addrinfo
*ainfo
= NULL
;
250 struct addrinfo ahint
= { 0, AF_INET
, SOCK_STREAM
, 0, 0, NULL
, NULL
, NULL
};
253 hsock
= socket(AF_INET
, SOCK_STREAM
, IPPROTO_IP
);
254 if (hsock
== INVALID_SOCKET
)
255 rc
= vdebug_socket_error();
257 uint32_t rcvwat
= VD_SHEADER_LEN
; /* size of the rcv header, as rcv min watermark */
258 hsock
= socket(AF_INET
, SOCK_STREAM
, IPPROTO_IP
);
261 else if (setsockopt(hsock
, SOL_SOCKET
, SO_RCVLOWAT
, &rcvwat
, sizeof(rcvwat
)) < 0)
264 else if (setsockopt(hsock
, SOL_SOCKET
, SO_SNDBUF
, (const char *)&buflen
, sizeof(buflen
)) < 0)
265 rc
= vdebug_socket_error();
266 else if (setsockopt(hsock
, SOL_SOCKET
, SO_RCVBUF
, (const char *)&buflen
, sizeof(buflen
)) < 0)
267 rc
= vdebug_socket_error();
270 LOG_ERROR("socket_open: cannot set socket option, error %d", rc
);
271 } else if (getaddrinfo(server_addr
, NULL
, &ahint
, &ainfo
) != 0) {
272 LOG_ERROR("socket_open: cannot resolve address %s, error %d", server_addr
, vdebug_socket_error());
273 rc
= VD_ERR_SOC_ADDR
;
275 h_u16_to_be((uint8_t *)ainfo
->ai_addr
->sa_data
, port
);
276 if (connect(hsock
, ainfo
->ai_addr
, sizeof(struct sockaddr
)) < 0) {
277 LOG_ERROR("socket_open: cannot connect to %s:%d, error %d", server_addr
, port
, vdebug_socket_error());
278 rc
= VD_ERR_SOC_CONN
;
293 static int vdebug_socket_receive(int hsock
, struct vd_shm
*pmem
)
297 int offset
= &pmem
->rid
[0] - &pmem
->cmd
;
298 int to_receive
= VD_SHEADER_LEN
+ le_to_h_u16(pmem
->rbytes
);
299 char *pb
= (char *)pmem
;
302 rc
= recv(hsock
, pb
+ offset
, to_receive
, 0);
304 LOG_WARNING("socket_receive: recv failed, error %d", rc
< 0 ? vdebug_socket_error() : 0);
309 LOG_DEBUG_IO("socket_receive: received %d, to receive %d", rc
, to_receive
);
311 } while (to_receive
);
316 static int vdebug_socket_send(int hsock
, struct vd_shm
*pmem
)
318 int rc
= send(hsock
, (const char *)&pmem
->cmd
, VD_CHEADER_LEN
+ le_to_h_u16(pmem
->wbytes
), 0);
320 LOG_WARNING("socket_send: send failed, error %d", vdebug_socket_error());
322 LOG_DEBUG_IO("socket_send: sent %d, to send 0", rc
);
327 static uint32_t vdebug_wait_server(int hsock
, struct vd_shm
*pmem
)
330 return VD_ERR_SOC_OPEN
;
332 int st
= vdebug_socket_send(hsock
, pmem
);
334 return VD_ERR_SOC_SEND
;
336 int rd
= vdebug_socket_receive(hsock
, pmem
);
338 return VD_ERR_SOC_RECV
;
340 int rc
= le_to_h_u32(pmem
->status
);
341 LOG_DEBUG_IO("wait_server: cmd %02" PRIx8
" done, sent %d, rcvd %d, status %d",
342 pmem
->cmd
, st
, rd
, rc
);
347 static int vdebug_run_jtag_queue(int hsock
, struct vd_shm
*pm
, unsigned int count
)
349 uint8_t num_pre
, num_post
, tdi
, tms
;
350 unsigned int num
, anum
, bytes
, hwords
, words
;
351 unsigned int req
, waddr
, rwords
;
358 req
= 0; /* beginning of request */
361 h_u16_to_le(pm
->wbytes
, le_to_h_u16(pm
->wwords
) * vdc
.buf_width
);
362 h_u16_to_le(pm
->rbytes
, le_to_h_u16(pm
->rwords
) * vdc
.buf_width
);
364 rc
= vdebug_wait_server(hsock
, pm
);
365 while (!rc
&& (req
< count
)) { /* loop over requests to read data and print out */
366 jhdr
= le_to_h_u64(&pm
->wd8
[waddr
* 4]);
368 hwords
= (jhdr
>> 32) & 0xffff;
369 anum
= jhdr
& 0xffffff;
370 num_pre
= (jhdr
>> 27) & 0x7;
371 num_post
= (jhdr
>> 24) & 0x7;
373 num
= anum
- num_pre
- num_post
+ 1;
375 num
= anum
- num_pre
;
376 bytes
= (num
+ 7) / 8;
377 vdc
.trans_last
= (req
+ 1) < count
? 0 : 1;
378 vdc
.trans_first
= waddr
? 0 : 1;
379 if (((jhdr
>> 30) & 0x3) == 3) { /* cmd is read */
384 rd
= list_first_entry(&vdc
.rdataq
.lh
, struct vd_rdata
, lh
);
389 for (unsigned int j
= 0; j
< bytes
; j
++) {
390 tdo
[j
] = (pm
->rd8
[rwords
* 8 + j
] >> num_pre
) | (pm
->rd8
[rwords
* 8 + j
+ 1] << (8 - num_pre
));
391 LOG_DEBUG_IO("%04x D0[%02x]:%02x", le_to_h_u16(pm
->wid
) - count
+ req
, j
, tdo
[j
]);
393 rwords
+= words
; /* read data offset */
397 waddr
+= sizeof(uint64_t) / 4; /* waddr past header */
398 tdi
= (pm
->wd8
[waddr
* 4] >> num_pre
) | (pm
->wd8
[waddr
* 4 + 1] << (8 - num_pre
));
399 tms
= (pm
->wd8
[waddr
* 4 + 4] >> num_pre
) | (pm
->wd8
[waddr
* 4 + 4 + 1] << (8 - num_pre
));
400 LOG_DEBUG_IO("%04x L:%02d O:%05x @%03x DI:%02x MS:%02x DO:%02x",
401 le_to_h_u16(pm
->wid
) - count
+ req
, num
, (vdc
.trans_first
<< 14) | (vdc
.trans_last
<< 15),
402 waddr
- 2, tdi
, tms
, (tdo
? tdo
[0] : 0xdd));
403 waddr
+= hwords
* 2; /* start of next request */
408 LOG_ERROR("0x%x executing transaction", rc
);
413 vdc
.targ_time
+= (uint32_t)(te
- ts
);
414 h_u16_to_le(pm
->offseth
, 0); /* reset buffer write address */
415 h_u32_to_le(pm
->offset
, 0);
416 h_u16_to_le(pm
->rwords
, 0);
417 h_u16_to_le(pm
->waddr
, 0);
418 assert(list_empty(&vdc
.rdataq
.lh
));/* list should be empty after run queue */
423 static int vdebug_run_reg_queue(int hsock
, struct vd_shm
*pm
, unsigned int count
)
425 unsigned int num
, awidth
, wwidth
;
426 unsigned int req
, waddr
, rwords
;
435 req
= 0; /* beginning of request */
438 h_u16_to_le(pm
->wbytes
, le_to_h_u16(pm
->wwords
) * vdc
.buf_width
);
439 h_u16_to_le(pm
->rbytes
, le_to_h_u16(pm
->rwords
) * vdc
.buf_width
);
441 rc
= vdebug_wait_server(hsock
, pm
);
442 while (!rc
&& (req
< count
)) { /* loop over requests to read data and print out */
443 rhdr
= le_to_h_u64(&pm
->wd8
[waddr
* 4]);
444 addr
= rhdr
>> 32; /* reconstruct data for a single request */
445 num
= (rhdr
>> 16) & 0x7ff;
447 awidth
= (1 << ((rhdr
>> 27) & 0x7));
448 wwidth
= (awidth
+ vdc
.buf_width
- 1) / vdc
.buf_width
;
449 vdc
.trans_last
= (req
+ 1) < count
? 0 : 1;
450 vdc
.trans_first
= waddr
? 0 : 1;
451 if (((rhdr
>> 30) & 0x3) == 2) { /* cmd is read */
457 rd
= list_first_entry(&vdc
.rdataq
.lh
, struct vd_rdata
, lh
);
462 for (unsigned int j
= 0; j
< num
; j
++)
463 memcpy(&data
[j
* awidth
], &pm
->rd8
[(rwords
+ j
) * awidth
], awidth
);
465 LOG_DEBUG_IO("read %04x AS:%02x RG:%02x O:%05x @%03x D:%08x", le_to_h_u16(pm
->wid
) - count
+ req
,
466 aspace
, addr
, (vdc
.trans_first
<< 14) | (vdc
.trans_last
<< 15), waddr
,
467 (num
? le_to_h_u32(&pm
->rd8
[rwords
* 4]) : 0xdead));
468 rwords
+= num
* wwidth
;
469 waddr
+= sizeof(uint64_t) / 4; /* waddr past header */
471 LOG_DEBUG_IO("write %04x AS:%02x RG:%02x O:%05x @%03x D:%08x", le_to_h_u16(pm
->wid
) - count
+ req
,
472 aspace
, addr
, (vdc
.trans_first
<< 14) | (vdc
.trans_last
<< 15), waddr
,
473 le_to_h_u32(&pm
->wd8
[(waddr
+ num
+ 1) * 4]));
474 waddr
+= sizeof(uint64_t) / 4 + (num
* wwidth
* awidth
+ 3) / 4;
480 LOG_ERROR("0x%x executing transaction", rc
);
485 vdc
.targ_time
+= (uint32_t)(te
- ts
);
486 h_u16_to_le(pm
->offseth
, 0); /* reset buffer write address */
487 h_u32_to_le(pm
->offset
, 0);
488 h_u16_to_le(pm
->rwords
, 0);
489 h_u16_to_le(pm
->waddr
, 0);
490 assert(list_empty(&vdc
.rdataq
.lh
));/* list should be empty after run queue */
495 static int vdebug_open(int hsock
, struct vd_shm
*pm
, const char *path
,
496 uint8_t type
, uint32_t period_ps
, uint32_t sig_mask
)
498 int rc
= VD_ERR_NOT_OPEN
;
500 pm
->cmd
= VD_CMD_OPEN
;
501 h_u16_to_le(pm
->wid
, VD_VERSION
); /* client version */
502 h_u16_to_le(pm
->wbytes
, 0);
503 h_u16_to_le(pm
->rbytes
, 0);
504 h_u16_to_le(pm
->wwords
, 0);
505 h_u16_to_le(pm
->rwords
, 0);
506 rc
= vdebug_wait_server(hsock
, pm
);
507 if (rc
!= 0) { /* communication problem */
508 LOG_ERROR("0x%x connecting to server", rc
);
509 } else if (le_to_h_u16(pm
->rid
) < le_to_h_u16(pm
->wid
)) {
510 LOG_ERROR("server version %d too old for the client %d", le_to_h_u16(pm
->rid
), le_to_h_u16(pm
->wid
));
511 pm
->cmd
= VD_CMD_CLOSE
; /* let server close the connection */
512 vdebug_wait_server(hsock
, pm
);
515 pm
->cmd
= VD_CMD_CONNECT
;
516 pm
->type
= type
; /* BFM type to connect to, here JTAG */
517 h_u32_to_le(pm
->rwdata
, sig_mask
| VD_SIG_BUF
| (VD_SIG_BUF
<< 16));
518 h_u16_to_le(pm
->wbytes
, strlen(path
) + 1);
519 h_u16_to_le(pm
->rbytes
, 12);
520 h_u16_to_le(pm
->wid
, 0); /* reset wid for transaction ID */
521 h_u16_to_le(pm
->wwords
, 0);
522 h_u16_to_le(pm
->rwords
, 0);
523 memcpy(pm
->wd8
, path
, le_to_h_u16(pm
->wbytes
));
524 rc
= vdebug_wait_server(hsock
, pm
);
525 vdc
.sig_read
= le_to_h_u32(pm
->rwdata
) >> 16; /* signal read mask */
526 vdc
.sig_write
= le_to_h_u32(pm
->rwdata
); /* signal write mask */
527 vdc
.bfm_period
= period_ps
;
528 vdc
.buf_width
= le_to_h_u32(&pm
->rd8
[0]) / 8;/* access width in bytes */
529 vdc
.addr_bits
= le_to_h_u32(&pm
->rd8
[2 * 4]); /* supported address bits */
533 LOG_ERROR("0x%x connecting to BFM %s", rc
, path
);
537 INIT_LIST_HEAD(&vdc
.rdataq
.lh
);
538 LOG_DEBUG("%s type %0x, period %dps, buffer %dx%dB signals r%04xw%04x",
539 path
, type
, vdc
.bfm_period
, VD_BUFFER_LEN
/ vdc
.buf_width
,
540 vdc
.buf_width
, vdc
.sig_read
, vdc
.sig_write
);
545 static int vdebug_close(int hsock
, struct vd_shm
*pm
, uint8_t type
)
547 pm
->cmd
= VD_CMD_DISCONNECT
;
548 pm
->type
= type
; /* BFM type, here JTAG */
549 h_u16_to_le(pm
->wbytes
, 0);
550 h_u16_to_le(pm
->rbytes
, 0);
551 h_u16_to_le(pm
->wwords
, 0);
552 h_u16_to_le(pm
->rwords
, 0);
553 vdebug_wait_server(hsock
, pm
);
554 pm
->cmd
= VD_CMD_CLOSE
;
555 h_u16_to_le(pm
->wid
, VD_VERSION
); /* client version */
556 h_u16_to_le(pm
->wbytes
, 0);
557 h_u16_to_le(pm
->rbytes
, 0);
558 h_u16_to_le(pm
->wwords
, 0);
559 h_u16_to_le(pm
->rwords
, 0);
560 vdebug_wait_server(hsock
, pm
);
561 LOG_DEBUG("type %0x", type
);
566 static int vdebug_wait(int hsock
, struct vd_shm
*pm
, uint32_t cycles
)
569 pm
->cmd
= VD_CMD_WAIT
;
570 h_u16_to_le(pm
->wbytes
, 0);
571 h_u16_to_le(pm
->rbytes
, 0);
572 h_u32_to_le(pm
->rwdata
, cycles
); /* clock sycles to wait */
573 int rc
= vdebug_wait_server(hsock
, pm
);
575 LOG_ERROR("0x%x waiting %" PRIx32
" cycles", rc
, cycles
);
578 LOG_DEBUG("%d cycles", cycles
);
584 static int vdebug_sig_set(int hsock
, struct vd_shm
*pm
, uint32_t write_mask
, uint32_t value
)
586 pm
->cmd
= VD_CMD_SIGSET
;
587 h_u16_to_le(pm
->wbytes
, 0);
588 h_u16_to_le(pm
->rbytes
, 0);
589 h_u32_to_le(pm
->rwdata
, (write_mask
<< 16) | (value
& 0xffff)); /* mask and value of signals to set */
590 int rc
= vdebug_wait_server(hsock
, pm
);
592 LOG_ERROR("0x%x setting signals %04" PRIx32
, rc
, write_mask
);
596 LOG_DEBUG("setting signals %04" PRIx32
" to %04" PRIx32
, write_mask
, value
);
601 static int vdebug_jtag_clock(int hsock
, struct vd_shm
*pm
, uint32_t value
)
603 pm
->cmd
= VD_CMD_JTAGCLOCK
;
604 h_u16_to_le(pm
->wbytes
, 0);
605 h_u16_to_le(pm
->rbytes
, 0);
606 h_u32_to_le(pm
->rwdata
, value
); /* divider value */
607 int rc
= vdebug_wait_server(hsock
, pm
);
609 LOG_ERROR("0x%x setting jtag_clock", rc
);
613 LOG_DEBUG("setting jtag clock divider to %" PRIx32
, value
);
618 static int vdebug_jtag_shift_tap(int hsock
, struct vd_shm
*pm
, uint8_t num_pre
,
619 const uint8_t tms_pre
, uint32_t num
, const uint8_t *tdi
,
620 uint8_t num_post
, const uint8_t tms_post
, uint8_t *tdo
,
623 const uint32_t tobits
= 8;
624 uint16_t bytes
, hwords
, anum
, words
, waddr
;
627 pm
->cmd
= VD_CMD_JTAGSHTAP
;
628 vdc
.trans_last
= f_last
|| (vdc
.trans_batch
== VD_BATCH_NO
);
630 waddr
= 0; /* reset buffer offset */
632 waddr
= le_to_h_u32(pm
->offseth
); /* continue from the previous transaction */
633 if (num_post
) /* actual number of bits to shift */
634 anum
= num
+ num_pre
+ num_post
- 1;
636 anum
= num
+ num_pre
;
637 hwords
= (anum
+ 4 * vdc
.buf_width
- 1) / (4 * vdc
.buf_width
); /* in 4B TDI/TMS words */
638 words
= (hwords
+ 1) / 2; /* in 8B TDO words to read */
639 bytes
= (num
+ 7) / 8; /* data only portion in bytes */
640 /* buffer overflow check and flush */
641 if (4 * waddr
+ sizeof(uint64_t) + 8 * hwords
+ 64 > VD_BUFFER_LEN
) {
642 vdc
.trans_last
= 1; /* force flush within 64B of buffer end */
643 } else if (4 * waddr
+ sizeof(uint64_t) + 8 * hwords
> VD_BUFFER_LEN
) {
644 /* this req does not fit, discard it */
645 LOG_ERROR("%04x L:%02d O:%05x @%04x too many bits to shift",
646 le_to_h_u16(pm
->wid
), anum
, (vdc
.trans_first
<< 14) | (vdc
.trans_last
<< 15), waddr
);
651 uint16_t i
, j
; /* portability requires to use bit operations for 8B JTAG header */
652 uint64_t jhdr
= (tdo
? ((uint64_t)(words
) << 48) : 0) + ((uint64_t)(hwords
) << 32) +
653 ((tdo
? 3UL : 1UL) << 30) + (num_pre
<< 27) + (num_post
<< 24) + anum
;
654 h_u64_to_le(&pm
->wd8
[4 * waddr
], jhdr
);
656 h_u16_to_le(pm
->wid
, le_to_h_u16(pm
->wid
) + 1); /* transaction ID */
657 waddr
+= 2; /* waddr past header */
658 /* TDI/TMS data follows as 32 bit word pairs {TMS,TDI} */
659 pm
->wd8
[4 * waddr
] = (tdi
? (tdi
[0] << num_pre
) : 0);
660 pm
->wd8
[4 * waddr
+ 4] = tms_pre
; /* init with tms_pre */
661 if (num
+ num_pre
<= 8) /* and tms_post for num <=4 */
662 pm
->wd8
[4 * waddr
+ 4] |= (tms_post
<< (num
+ num_pre
- 1));
663 for (i
= 1, j
= 4 * waddr
; i
< bytes
; i
++) {
664 if (i
== bytes
- 1 && num
+ num_pre
<= bytes
* tobits
)
665 pm
->wd8
[j
+ i
+ 4] = tms_post
<< ((num
+ num_pre
- 1) % 8);
667 pm
->wd8
[j
+ i
+ 4] = 0x0;/* placing 4 bytes of TMS bits into high word */
668 if (!tdi
) /* placing 4 bytes of TDI bits into low word */
669 pm
->wd8
[j
+ i
] = 0x0;
671 pm
->wd8
[j
+ i
] = (tdi
[i
] << num_pre
) | (tdi
[i
- 1] >> (8 - num_pre
));
677 if (num
+ num_pre
> bytes
* tobits
) /* in case 1 additional byte needed for TDI */
678 pm
->wd8
[j
+ i
] = (tdi
[i
- 1] >> (8 - num_pre
)); /* put last TDI bits there */
680 if (num
+ num_pre
<= bytes
* tobits
) { /* in case no or 1 additional byte needed */
681 pm
->wd8
[j
+ i
+ 4] = tms_post
>> (8 - (num
+ num_pre
- 1) % 8); /* may need to add higher part */
682 /* in case exactly 1 additional byte needed */
683 } else if (num
+ num_pre
> bytes
* tobits
&& anum
<= (bytes
+ 1) * tobits
) {
684 pm
->wd8
[j
+ i
+ 4] = tms_post
<< ((num
+ num_pre
- 1) % 8); /* add whole tms_post */
685 } else { /* in case 2 additional bytes, tms_post split */
686 pm
->wd8
[j
+ i
+ 4] = tms_post
<< ((num
+ num_pre
- 1) % 8);/* add lower part of tms_post */
687 if (i
% 4 == 3) /* next byte is in the next 32b word */
688 pm
->wd8
[j
+ i
+ 4 + 5] = tms_post
>> (8 - (num
+ num_pre
- 1) % 8); /* and higher part */
689 else /* next byte is in the same 32b word */
690 pm
->wd8
[j
+ i
+ 4 + 1] = tms_post
>> (8 - (num
+ num_pre
- 1) % 8); /* and higher part */
695 if (le_to_h_u16(pm
->rwords
) == 0) {
698 rd
= calloc(1, sizeof(struct vd_rdata
));
699 if (!rd
) /* check allocation for 24B */
701 list_add_tail(&rd
->lh
, &vdc
.rdataq
.lh
);
704 h_u16_to_le(pm
->rwords
, le_to_h_u16(pm
->rwords
) + words
);/* keep track of the words to read */
706 h_u16_to_le(pm
->wwords
, waddr
/ 2 + hwords
); /* payload size *2 to include both TDI and TMS data */
707 h_u16_to_le(pm
->waddr
, le_to_h_u16(pm
->waddr
) + 1);
710 if (!waddr
) /* flush issued, but buffer empty */
712 else if (!vdc
.trans_last
) /* buffered request */
713 h_u16_to_le(pm
->offseth
, waddr
+ hwords
* 2); /* offset for next transaction, must be even */
714 else /* execute batch of requests */
715 rc
= vdebug_run_jtag_queue(hsock
, pm
, le_to_h_u16(pm
->waddr
));
716 vdc
.trans_first
= vdc
.trans_last
; /* flush forces trans_first flag */
721 static int vdebug_reg_write(int hsock
, struct vd_shm
*pm
, const uint32_t reg
,
722 const uint32_t data
, uint8_t aspace
, uint8_t f_last
)
727 pm
->cmd
= VD_CMD_REGWRITE
;
728 vdc
.trans_last
= f_last
|| (vdc
.trans_batch
== VD_BATCH_NO
);
730 waddr
= 0; /* reset buffer offset */
732 waddr
= le_to_h_u16(pm
->offseth
); /* continue from the previous transaction */
734 if (4 * waddr
+ 2 * sizeof(uint64_t) + 4 > VD_BUFFER_LEN
)
735 vdc
.trans_last
= 1; /* force flush, no room for next request */
737 uint64_t rhdr
= ((uint64_t)reg
<< 32) + (1UL << 30) + (2UL << 27) + (1UL << 16) + aspace
;
738 h_u64_to_le(&pm
->wd8
[4 * waddr
], rhdr
);
739 h_u32_to_le(&pm
->wd8
[4 * (waddr
+ 2)], data
);
740 h_u16_to_le(pm
->wid
, le_to_h_u16(pm
->wid
) + 1);
741 h_u16_to_le(pm
->wwords
, waddr
+ 3);
742 h_u16_to_le(pm
->waddr
, le_to_h_u16(pm
->waddr
) + 1);
743 if (!vdc
.trans_last
) /* buffered request */
744 h_u16_to_le(pm
->offseth
, waddr
+ 3);
746 rc
= vdebug_run_reg_queue(hsock
, pm
, le_to_h_u16(pm
->waddr
));
747 vdc
.trans_first
= vdc
.trans_last
; /* flush forces trans_first flag */
752 static int vdebug_reg_read(int hsock
, struct vd_shm
*pm
, const uint32_t reg
,
753 uint32_t *data
, uint8_t aspace
, uint8_t f_last
)
758 pm
->cmd
= VD_CMD_REGREAD
;
759 vdc
.trans_last
= f_last
|| (vdc
.trans_batch
== VD_BATCH_NO
);
761 waddr
= 0; /* reset buffer offset */
763 waddr
= le_to_h_u16(pm
->offseth
); /* continue from the previous transaction */
765 if (4 * waddr
+ 2 * sizeof(uint64_t) + 4 > VD_BUFFER_LEN
)
766 vdc
.trans_last
= 1; /* force flush, no room for next request */
768 uint64_t rhdr
= ((uint64_t)reg
<< 32) + (2UL << 30) + (2UL << 27) + ((data
? 1UL : 0UL) << 16) + aspace
;
769 h_u64_to_le(&pm
->wd8
[4 * waddr
], rhdr
);
770 h_u16_to_le(pm
->wid
, le_to_h_u16(pm
->wid
) + 1);
773 if (le_to_h_u16(pm
->rwords
) == 0) {
776 rd
= calloc(1, sizeof(struct vd_rdata
));
777 if (!rd
) /* check allocation for 24B */
779 list_add_tail(&rd
->lh
, &vdc
.rdataq
.lh
);
781 rd
->rdata
= (uint8_t *)data
;
782 h_u16_to_le(pm
->rwords
, le_to_h_u16(pm
->rwords
) + 1);
784 h_u16_to_le(pm
->wwords
, waddr
+ 2);
785 h_u16_to_le(pm
->waddr
, le_to_h_u16(pm
->waddr
) + 1);
786 if (!vdc
.trans_last
) /* buffered request */
787 h_u16_to_le(pm
->offseth
, waddr
+ 2);
789 rc
= vdebug_run_reg_queue(hsock
, pm
, le_to_h_u16(pm
->waddr
));
790 vdc
.trans_first
= vdc
.trans_last
; /* flush forces trans_first flag */
795 static int vdebug_mem_open(int hsock
, struct vd_shm
*pm
, const char *path
, uint8_t ndx
)
802 pm
->cmd
= VD_CMD_MEMOPEN
;
803 h_u16_to_le(pm
->wbytes
, strlen(path
) + 1); /* includes terminating 0 */
804 h_u16_to_le(pm
->rbytes
, 8);
805 h_u16_to_le(pm
->wwords
, 0);
806 h_u16_to_le(pm
->rwords
, 0);
807 memcpy(pm
->wd8
, path
, le_to_h_u16(pm
->wbytes
));
808 rc
= vdebug_wait_server(hsock
, pm
);
810 LOG_ERROR("0x%x opening memory %s", rc
, path
);
811 } else if (ndx
!= pm
->rd8
[2]) {
812 LOG_WARNING("Invalid memory index %" PRIu16
" returned. Direct memory access disabled", pm
->rd8
[2]);
814 vdc
.mem_width
[ndx
] = le_to_h_u16(&pm
->rd8
[0]) / 8; /* memory width in bytes */
815 vdc
.mem_depth
[ndx
] = le_to_h_u32(&pm
->rd8
[4]); /* memory depth in words */
816 LOG_DEBUG("%" PRIx8
": %s memory %" PRIu32
"x%" PRIu32
"B, buffer %" PRIu32
"x%" PRIu32
"B", ndx
, path
,
817 vdc
.mem_depth
[ndx
], vdc
.mem_width
[ndx
], VD_BUFFER_LEN
/ vdc
.mem_width
[ndx
], vdc
.mem_width
[ndx
]);
823 static void vdebug_mem_close(int hsock
, struct vd_shm
*pm
, uint8_t ndx
)
825 pm
->cmd
= VD_CMD_MEMCLOSE
;
826 h_u32_to_le(pm
->rwdata
, ndx
); /* which memory */
827 h_u16_to_le(pm
->wbytes
, 0);
828 h_u16_to_le(pm
->rbytes
, 0);
829 h_u16_to_le(pm
->wwords
, 0);
830 h_u16_to_le(pm
->rwords
, 0);
831 vdebug_wait_server(hsock
, pm
);
832 LOG_DEBUG("%" PRIx8
": %s", ndx
, vdc
.mem_path
[ndx
]);
836 static int vdebug_init(void)
838 vdc
.hsocket
= vdebug_socket_open(vdc
.server_name
, vdc
.server_port
);
839 pbuf
= calloc(1, sizeof(struct vd_shm
));
841 close_socket(vdc
.hsocket
);
843 LOG_ERROR("cannot allocate %zu bytes", sizeof(struct vd_shm
));
846 if (vdc
.hsocket
<= 0) {
849 LOG_ERROR("cannot connect to vdebug server %s:%" PRIu16
,
850 vdc
.server_name
, vdc
.server_port
);
854 vdc
.poll_cycles
= vdc
.poll_max
;
855 uint32_t sig_mask
= VD_SIG_RESET
;
856 if (transport_is_jtag())
857 sig_mask
|= VD_SIG_TRST
| VD_SIG_TCKDIV
;
859 int rc
= vdebug_open(vdc
.hsocket
, pbuf
, vdc
.bfm_path
, vdc
.bfm_type
, vdc
.bfm_period
, sig_mask
);
861 LOG_ERROR("0x%x cannot connect to %s", rc
, vdc
.bfm_path
);
862 close_socket(vdc
.hsocket
);
867 for (uint8_t i
= 0; i
< vdc
.mem_ndx
; i
++) {
868 rc
= vdebug_mem_open(vdc
.hsocket
, pbuf
, vdc
.mem_path
[i
], i
);
870 LOG_ERROR("0x%x cannot connect to %s", rc
, vdc
.mem_path
[i
]);
873 LOG_INFO("vdebug %d connected to %s through %s:%" PRIu16
,
874 VD_VERSION
, vdc
.bfm_path
, vdc
.server_name
, vdc
.server_port
);
880 static int vdebug_quit(void)
882 for (uint8_t i
= 0; i
< vdc
.mem_ndx
; i
++)
883 if (vdc
.mem_width
[i
])
884 vdebug_mem_close(vdc
.hsocket
, pbuf
, i
);
885 int rc
= vdebug_close(vdc
.hsocket
, pbuf
, vdc
.bfm_type
);
886 LOG_INFO("vdebug %d disconnected from %s through %s:%" PRIu16
" rc:%d", VD_VERSION
,
887 vdc
.bfm_path
, vdc
.server_name
, vdc
.server_port
, rc
);
889 close_socket(vdc
.hsocket
);
896 static int vdebug_reset(int trst
, int srst
)
898 uint16_t sig_val
= 0xffff;
899 uint16_t sig_mask
= 0;
901 sig_mask
|= VD_SIG_RESET
;
903 sig_val
&= ~VD_SIG_RESET
;/* active low */
904 if (transport_is_jtag()) {
905 sig_mask
|= VD_SIG_TRST
;
907 sig_val
&= ~VD_SIG_TRST
; /* active low */
910 LOG_INFO("rst trst:%d srst:%d mask:%" PRIx16
" val:%" PRIx16
, trst
, srst
, sig_mask
, sig_val
);
911 int rc
= vdebug_sig_set(vdc
.hsocket
, pbuf
, sig_mask
, sig_val
);
913 rc
= vdebug_wait(vdc
.hsocket
, pbuf
, 20); /* 20 clock cycles pulse */
918 static int vdebug_jtag_tms_seq(const uint8_t *tms
, int num
, uint8_t f_flush
)
920 LOG_INFO("tms len:%d tms:%x", num
, *tms
);
922 return vdebug_jtag_shift_tap(vdc
.hsocket
, pbuf
, num
, *tms
, 0, NULL
, 0, 0, NULL
, f_flush
);
925 static int vdebug_jtag_path_move(struct pathmove_command
*cmd
, uint8_t f_flush
)
927 uint8_t tms
[DIV_ROUND_UP(cmd
->num_states
, 8)];
928 LOG_INFO("path num states %d", cmd
->num_states
);
930 memset(tms
, 0, DIV_ROUND_UP(cmd
->num_states
, 8));
932 for (uint8_t i
= 0; i
< cmd
->num_states
; i
++) {
933 if (tap_state_transition(tap_get_state(), true) == cmd
->path
[i
])
934 buf_set_u32(tms
, i
, 1, 1);
935 tap_set_state(cmd
->path
[i
]);
938 return vdebug_jtag_tms_seq(tms
, cmd
->num_states
, f_flush
);
941 static int vdebug_jtag_tlr(tap_state_t state
, uint8_t f_flush
)
945 tap_state_t cur
= tap_get_state();
946 uint8_t tms_pre
= tap_get_tms_path(cur
, state
);
947 uint8_t num_pre
= tap_get_tms_path_len(cur
, state
);
948 LOG_INFO("tlr from %x to %x", cur
, state
);
950 rc
= vdebug_jtag_shift_tap(vdc
.hsocket
, pbuf
, num_pre
, tms_pre
, 0, NULL
, 0, 0, NULL
, f_flush
);
951 tap_set_state(state
);
957 static int vdebug_jtag_scan(struct scan_command
*cmd
, uint8_t f_flush
)
961 tap_state_t cur
= tap_get_state();
962 uint8_t state
= cmd
->ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
;
963 uint8_t tms_pre
= tap_get_tms_path(cur
, state
);
964 uint8_t num_pre
= tap_get_tms_path_len(cur
, state
);
965 uint8_t tms_post
= tap_get_tms_path(state
, cmd
->end_state
);
966 uint8_t num_post
= tap_get_tms_path_len(state
, cmd
->end_state
);
967 int num_bits
= jtag_scan_size(cmd
);
968 LOG_DEBUG("scan len:%d fields:%d ir/!dr:%d state cur:%x end:%x",
969 num_bits
, cmd
->num_fields
, cmd
->ir_scan
, cur
, cmd
->end_state
);
970 for (int i
= 0; i
< cmd
->num_fields
; i
++) {
971 uint8_t cur_num_pre
= i
== 0 ? num_pre
: 0;
972 uint8_t cur_tms_pre
= i
== 0 ? tms_pre
: 0;
973 uint8_t cur_num_post
= i
== cmd
->num_fields
- 1 ? num_post
: 0;
974 uint8_t cur_tms_post
= i
== cmd
->num_fields
- 1 ? tms_post
: 0;
975 uint8_t cur_flush
= i
== cmd
->num_fields
- 1 ? f_flush
: 0;
976 rc
= vdebug_jtag_shift_tap(vdc
.hsocket
, pbuf
, cur_num_pre
, cur_tms_pre
,
977 cmd
->fields
[i
].num_bits
, cmd
->fields
[i
].out_value
, cur_num_post
, cur_tms_post
,
978 cmd
->fields
[i
].in_value
, cur_flush
);
983 if (cur
!= cmd
->end_state
)
984 tap_set_state(cmd
->end_state
);
989 static int vdebug_jtag_runtest(int cycles
, tap_state_t state
, uint8_t f_flush
)
991 tap_state_t cur
= tap_get_state();
992 uint8_t tms_pre
= tap_get_tms_path(cur
, state
);
993 uint8_t num_pre
= tap_get_tms_path_len(cur
, state
);
994 LOG_DEBUG("idle len:%d state cur:%x end:%x", cycles
, cur
, state
);
995 int rc
= vdebug_jtag_shift_tap(vdc
.hsocket
, pbuf
, num_pre
, tms_pre
, cycles
, NULL
, 0, 0, NULL
, f_flush
);
997 tap_set_state(state
);
1002 static int vdebug_jtag_stableclocks(int num
, uint8_t f_flush
)
1004 LOG_INFO("stab len:%d state cur:%x", num
, tap_get_state());
1006 return vdebug_jtag_shift_tap(vdc
.hsocket
, pbuf
, 0, 0, num
, NULL
, 0, 0, NULL
, f_flush
);
1009 static int vdebug_sleep(int us
)
1011 LOG_INFO("sleep %d us", us
);
1013 return vdebug_wait(vdc
.hsocket
, pbuf
, us
/ 1000);
1016 static int vdebug_jtag_speed(int speed
)
1018 unsigned int clkmax
= VD_SCALE_PSTOMS
/ (vdc
.bfm_period
* 2); /* kHz */
1019 unsigned int divval
= clkmax
/ speed
;
1020 LOG_INFO("jclk speed:%d kHz set, BFM divider %u", speed
, divval
);
1022 return vdebug_jtag_clock(vdc
.hsocket
, pbuf
, divval
);
1025 static int vdebug_jtag_khz(int khz
, int *jtag_speed
)
1027 unsigned int clkmax
= VD_SCALE_PSTOMS
/ (vdc
.bfm_period
* 2); /* kHz */
1028 unsigned int divval
= khz
? clkmax
/ khz
: 1;
1029 *jtag_speed
= clkmax
/ divval
;
1030 LOG_DEBUG("khz speed:%d from khz:%d", *jtag_speed
, khz
);
1035 static int vdebug_jtag_div(int speed
, int *khz
)
1038 LOG_DEBUG("div khz:%d from speed:%d", *khz
, speed
);
1043 static int vdebug_jtag_execute_queue(void)
1047 for (struct jtag_command
*cmd
= jtag_command_queue
; rc
== ERROR_OK
&& cmd
; cmd
= cmd
->next
) {
1048 switch (cmd
->type
) {
1050 rc
= vdebug_jtag_runtest(cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
, !cmd
->next
);
1052 case JTAG_STABLECLOCKS
:
1053 rc
= vdebug_jtag_stableclocks(cmd
->cmd
.stableclocks
->num_cycles
, !cmd
->next
);
1055 case JTAG_TLR_RESET
:
1056 rc
= vdebug_jtag_tlr(cmd
->cmd
.statemove
->end_state
, !cmd
->next
);
1059 rc
= vdebug_jtag_path_move(cmd
->cmd
.pathmove
, !cmd
->next
);
1062 rc
= vdebug_jtag_tms_seq(cmd
->cmd
.tms
->bits
, cmd
->cmd
.tms
->num_bits
, !cmd
->next
);
1065 rc
= vdebug_sleep(cmd
->cmd
.sleep
->us
);
1068 rc
= vdebug_jtag_scan(cmd
->cmd
.scan
, !cmd
->next
);
1071 LOG_ERROR("Unknown JTAG command type 0x%x encountered", cmd
->type
);
1079 static int vdebug_dap_connect(struct adiv5_dap
*dap
)
1081 return dap_dp_init(dap
);
1084 static int vdebug_dap_send_sequence(struct adiv5_dap
*dap
, enum swd_special_seq seq
)
1089 static int vdebug_dap_queue_dp_read(struct adiv5_dap
*dap
, unsigned int reg
, uint32_t *data
)
1091 return vdebug_reg_read(vdc
.hsocket
, pbuf
, (reg
& DP_SELECT_DPBANK
) >> 2, data
, VD_ASPACE_DP
, 0);
1094 static int vdebug_dap_queue_dp_write(struct adiv5_dap
*dap
, unsigned int reg
, uint32_t data
)
1096 return vdebug_reg_write(vdc
.hsocket
, pbuf
, (reg
& DP_SELECT_DPBANK
) >> 2, data
, VD_ASPACE_DP
, 0);
1099 static int vdebug_dap_queue_ap_read(struct adiv5_ap
*ap
, unsigned int reg
, uint32_t *data
)
1101 if ((reg
& ADIV5_DP_SELECT_APBANK
) != ap
->dap
->select
) {
1102 vdebug_reg_write(vdc
.hsocket
, pbuf
, DP_SELECT
>> 2, reg
& ADIV5_DP_SELECT_APBANK
, VD_ASPACE_DP
, 0);
1103 ap
->dap
->select
= reg
& ADIV5_DP_SELECT_APBANK
;
1106 vdebug_reg_read(vdc
.hsocket
, pbuf
, (reg
& DP_SELECT_DPBANK
) >> 2, NULL
, VD_ASPACE_AP
, 0);
1108 return vdebug_reg_read(vdc
.hsocket
, pbuf
, DP_RDBUFF
>> 2, data
, VD_ASPACE_DP
, 0);
1111 static int vdebug_dap_queue_ap_write(struct adiv5_ap
*ap
, unsigned int reg
, uint32_t data
)
1113 if ((reg
& ADIV5_DP_SELECT_APBANK
) != ap
->dap
->select
) {
1114 vdebug_reg_write(vdc
.hsocket
, pbuf
, DP_SELECT
>> 2, reg
& ADIV5_DP_SELECT_APBANK
, VD_ASPACE_DP
, 0);
1115 ap
->dap
->select
= reg
& ADIV5_DP_SELECT_APBANK
;
1118 return vdebug_reg_write(vdc
.hsocket
, pbuf
, (reg
& DP_SELECT_DPBANK
) >> 2, data
, VD_ASPACE_AP
, 0);
1121 static int vdebug_dap_queue_ap_abort(struct adiv5_dap
*dap
, uint8_t *ack
)
1123 return vdebug_reg_write(vdc
.hsocket
, pbuf
, 0, 0x1, VD_ASPACE_AB
, 0);
1126 static int vdebug_dap_run(struct adiv5_dap
*dap
)
1128 if (le_to_h_u16(pbuf
->waddr
))
1129 return vdebug_run_reg_queue(vdc
.hsocket
, pbuf
, le_to_h_u16(pbuf
->waddr
));
1134 COMMAND_HANDLER(vdebug_set_server
)
1136 if ((CMD_ARGC
!= 1) || !strchr(CMD_ARGV
[0], ':'))
1137 return ERROR_COMMAND_SYNTAX_ERROR
;
1139 char *pchar
= strchr(CMD_ARGV
[0], ':');
1141 strncpy(vdc
.server_name
, CMD_ARGV
[0], sizeof(vdc
.server_name
) - 1);
1142 int port
= atoi(++pchar
);
1143 if (port
< 0 || port
> UINT16_MAX
) {
1144 LOG_ERROR("invalid port number %d specified", port
);
1145 return ERROR_COMMAND_SYNTAX_ERROR
;
1147 vdc
.server_port
= port
;
1148 LOG_DEBUG("server: %s port %u", vdc
.server_name
, vdc
.server_port
);
1153 COMMAND_HANDLER(vdebug_set_bfm
)
1157 if ((CMD_ARGC
!= 2) || (sscanf(CMD_ARGV
[1], "%u%c", &vdc
.bfm_period
, &prefix
) != 2))
1158 return ERROR_COMMAND_SYNTAX_ERROR
;
1160 strncpy(vdc
.bfm_path
, CMD_ARGV
[0], sizeof(vdc
.bfm_path
) - 1);
1163 vdc
.bfm_period
*= 1000000;
1166 vdc
.bfm_period
*= 1000;
1172 if (transport_is_dapdirect_swd())
1173 vdc
.bfm_type
= VD_BFM_SWDP
;
1175 vdc
.bfm_type
= VD_BFM_JTAG
;
1176 LOG_DEBUG("bfm_path: %s clk_period %ups", vdc
.bfm_path
, vdc
.bfm_period
);
1181 COMMAND_HANDLER(vdebug_set_mem
)
1184 return ERROR_COMMAND_SYNTAX_ERROR
;
1186 if (vdc
.mem_ndx
>= VD_MAX_MEMORIES
) {
1187 LOG_ERROR("mem_path declared more than %d allowed times", VD_MAX_MEMORIES
);
1191 strncpy(vdc
.mem_path
[vdc
.mem_ndx
], CMD_ARGV
[0], sizeof(vdc
.mem_path
[vdc
.mem_ndx
]) - 1);
1192 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], vdc
.mem_base
[vdc
.mem_ndx
]);
1193 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], vdc
.mem_size
[vdc
.mem_ndx
]);
1194 LOG_DEBUG("mem_path: set %s @ 0x%08x+0x%08x", vdc
.mem_path
[vdc
.mem_ndx
],
1195 vdc
.mem_base
[vdc
.mem_ndx
], vdc
.mem_size
[vdc
.mem_ndx
]);
1201 COMMAND_HANDLER(vdebug_set_batching
)
1204 return ERROR_COMMAND_SYNTAX_ERROR
;
1206 if (isdigit((unsigned char)CMD_ARGV
[0][0]))
1207 vdc
.trans_batch
= (CMD_ARGV
[0][0] == '0' ? 0 : (CMD_ARGV
[0][0] == '1' ? 1 : 2));
1208 else if (CMD_ARGV
[0][0] == 'r')
1209 vdc
.trans_batch
= VD_BATCH_WR
;
1210 else if (CMD_ARGV
[0][0] == 'w')
1211 vdc
.trans_batch
= VD_BATCH_WO
;
1213 vdc
.trans_batch
= VD_BATCH_NO
;
1214 LOG_DEBUG("batching: set to %u", vdc
.trans_batch
);
1219 COMMAND_HANDLER(vdebug_set_polling
)
1222 return ERROR_COMMAND_SYNTAX_ERROR
;
1224 vdc
.poll_min
= atoi(CMD_ARGV
[0]);
1225 vdc
.poll_max
= atoi(CMD_ARGV
[1]);
1226 LOG_DEBUG("polling: set min %u max %u", vdc
.poll_min
, vdc
.poll_max
);
1231 static const struct command_registration vdebug_command_handlers
[] = {
1234 .handler
= &vdebug_set_server
,
1235 .mode
= COMMAND_CONFIG
,
1236 .help
= "set the vdebug server name or address",
1237 .usage
= "<host:port>",
1241 .handler
= &vdebug_set_bfm
,
1242 .mode
= COMMAND_CONFIG
,
1243 .help
= "set the vdebug BFM hierarchical path",
1244 .usage
= "<path> <clk_period[p|n|u]s>",
1248 .handler
= &vdebug_set_mem
,
1249 .mode
= COMMAND_CONFIG
,
1250 .help
= "set the design memory for the code load",
1251 .usage
= "<path> <base_address> <size>",
1255 .handler
= &vdebug_set_batching
,
1256 .mode
= COMMAND_CONFIG
,
1257 .help
= "set the transaction batching no|wr|rd [0|1|2]",
1262 .handler
= &vdebug_set_polling
,
1263 .mode
= COMMAND_CONFIG
,
1264 .help
= "set the polling pause, executing hardware cycles between min and max",
1265 .usage
= "<min cycles> <max cycles>",
1267 COMMAND_REGISTRATION_DONE
1270 static const struct command_registration vdebug_command
[] = {
1273 .chain
= vdebug_command_handlers
,
1274 .mode
= COMMAND_ANY
,
1275 .help
= "vdebug command group",
1278 COMMAND_REGISTRATION_DONE
1281 static struct jtag_interface vdebug_jtag_ops
= {
1282 .supported
= DEBUG_CAP_TMS_SEQ
,
1283 .execute_queue
= vdebug_jtag_execute_queue
,
1286 static const struct dap_ops vdebug_dap_ops
= {
1287 .connect
= vdebug_dap_connect
,
1288 .send_sequence
= vdebug_dap_send_sequence
,
1289 .queue_dp_read
= vdebug_dap_queue_dp_read
,
1290 .queue_dp_write
= vdebug_dap_queue_dp_write
,
1291 .queue_ap_read
= vdebug_dap_queue_ap_read
,
1292 .queue_ap_write
= vdebug_dap_queue_ap_write
,
1293 .queue_ap_abort
= vdebug_dap_queue_ap_abort
,
1294 .run
= vdebug_dap_run
,
1295 .sync
= NULL
, /* optional */
1296 .quit
= NULL
, /* optional */
1299 static const char *const vdebug_transports
[] = { "jtag", "dapdirect_swd", NULL
};
1301 struct adapter_driver vdebug_adapter_driver
= {
1303 .transports
= vdebug_transports
,
1304 .speed
= vdebug_jtag_speed
,
1305 .khz
= vdebug_jtag_khz
,
1306 .speed_div
= vdebug_jtag_div
,
1307 .commands
= vdebug_command
,
1308 .init
= vdebug_init
,
1309 .quit
= vdebug_quit
,
1310 .reset
= vdebug_reset
,
1311 .jtag_ops
= &vdebug_jtag_ops
,
1312 .dap_swd_ops
= &vdebug_dap_ops
,