jtag/stlink: add STLINK-V3PWR support
[openocd.git] / src / jtag / drivers / vdebug.c
1 // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
2
3 /* Copyright 2020-2022 Cadence Design Systems, Inc. */
4
5 /*!
6 * @file
7 *
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
12 *
13 */
14
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif
18
19 #ifdef _WIN32
20 #define WIN32_LEAN_AND_MEAN
21 #include <windows.h>
22 #else
23 #ifdef HAVE_UNISTD_H
24 #include <unistd.h> /* close */
25 #endif
26 #ifdef HAVE_SYS_SOCKET_H
27 #include <sys/socket.h>
28 #endif
29 #ifdef HAVE_ARPA_INET_H
30 #include <arpa/inet.h>
31 #endif
32 #ifdef HAVE_NETDB_H
33 #include <netdb.h>
34 #endif
35 #endif
36 #include <stdio.h>
37 #ifdef HAVE_STDINT_H
38 #include <stdint.h>
39 #endif
40 #ifdef HAVE_STDLIB_H
41 #include <stdlib.h>
42 #endif
43 #include <stdarg.h>
44 #include <string.h>
45 #include <errno.h>
46
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"
55
56 #define VD_VERSION 46
57 #define VD_BUFFER_LEN 4024
58 #define VD_CHEADER_LEN 24
59 #define VD_SHEADER_LEN 16
60
61 #define VD_MAX_MEMORIES 20
62 #define VD_POLL_INTERVAL 500
63 #define VD_SCALE_PSTOMS 1000000000
64
65 /**
66 * @brief List of transactor types
67 */
68 enum {
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 */
76 };
77
78 /**
79 * @brief List of signals that can be read or written by the debugger
80 */
81 enum {
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 */
91 };
92
93 /**
94 * @brief List of errors
95 */
96 enum {
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 */
122 };
123
124 enum {
125 VD_CMD_OPEN = 0x01,
126 VD_CMD_CLOSE = 0x02,
127 VD_CMD_CONNECT = 0x04,
128 VD_CMD_DISCONNECT = 0x05,
129 VD_CMD_WAIT = 0x09,
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,
139 };
140
141 enum {
142 VD_ASPACE_AP = 0x01,
143 VD_ASPACE_DP = 0x02,
144 VD_ASPACE_ID = 0x03,
145 VD_ASPACE_AB = 0x04,
146 };
147
148 enum {
149 VD_BATCH_NO = 0,
150 VD_BATCH_WO = 1,
151 VD_BATCH_WR = 2,
152 };
153
154 struct vd_shm {
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*/
167 };
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; */
174 };
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));
180
181 struct vd_rdata {
182 struct list_head lh;
183 uint8_t *rdata;
184 };
185
186 struct vd_client {
187 uint8_t trans_batch;
188 bool trans_first;
189 bool trans_last;
190 uint8_t mem_ndx;
191 uint8_t buf_width;
192 uint8_t addr_bits;
193 uint8_t bfm_type;
194 uint16_t sig_read;
195 uint16_t sig_write;
196 uint32_t bfm_period;
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;
203 uint32_t poll_min;
204 uint32_t poll_max;
205 uint32_t targ_time;
206 int hsocket;
207 char server_name[32];
208 char bfm_path[128];
209 char mem_path[VD_MAX_MEMORIES][128];
210 struct vd_rdata rdataq;
211 };
212
213 struct vd_jtag_hdr {
214 uint64_t tlen:24;
215 uint64_t post:3;
216 uint64_t pre:3;
217 uint64_t cmd:2;
218 uint64_t wlen:16;
219 uint64_t rlen:16;
220 };
221
222 struct vd_reg_hdr {
223 uint64_t prot:3;
224 uint64_t nonincr:1;
225 uint64_t haddr:12;
226 uint64_t tlen:11;
227 uint64_t asize:3;
228 uint64_t cmd:2;
229 uint64_t addr:32;
230 };
231
232 static struct vd_shm *pbuf;
233 static struct vd_client vdc;
234
235 static int vdebug_socket_error(void)
236 {
237 #ifdef _WIN32
238 return WSAGetLastError();
239 #else
240 return errno;
241 #endif
242 }
243
244 static int vdebug_socket_open(char *server_addr, uint32_t port)
245 {
246 int hsock;
247 int rc = 0;
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 };
251
252 #ifdef _WIN32
253 hsock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
254 if (hsock == INVALID_SOCKET)
255 rc = vdebug_socket_error();
256 #else
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);
259 if (hsock < 0)
260 rc = errno;
261 else if (setsockopt(hsock, SOL_SOCKET, SO_RCVLOWAT, &rcvwat, sizeof(rcvwat)) < 0)
262 rc = errno;
263 #endif
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();
268
269 if (rc) {
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;
274 } else {
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;
279 }
280 }
281
282 if (rc) {
283 close_socket(hsock);
284 hsock = 0;
285 }
286
287 if (ainfo)
288 freeaddrinfo(ainfo);
289
290 return hsock;
291 }
292
293 static int vdebug_socket_receive(int hsock, struct vd_shm *pmem)
294 {
295 int rc;
296 int dreceived = 0;
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;
300
301 do {
302 rc = recv(hsock, pb + offset, to_receive, 0);
303 if (rc <= 0) {
304 LOG_WARNING("socket_receive: recv failed, error %d", rc < 0 ? vdebug_socket_error() : 0);
305 return rc;
306 }
307 to_receive -= rc;
308 offset += rc;
309 LOG_DEBUG_IO("socket_receive: received %d, to receive %d", rc, to_receive);
310 dreceived += rc;
311 } while (to_receive);
312
313 return dreceived;
314 }
315
316 static int vdebug_socket_send(int hsock, struct vd_shm *pmem)
317 {
318 int rc = send(hsock, (const char *)&pmem->cmd, VD_CHEADER_LEN + le_to_h_u16(pmem->wbytes), 0);
319 if (rc <= 0)
320 LOG_WARNING("socket_send: send failed, error %d", vdebug_socket_error());
321 else
322 LOG_DEBUG_IO("socket_send: sent %d, to send 0", rc);
323
324 return rc;
325 }
326
327 static uint32_t vdebug_wait_server(int hsock, struct vd_shm *pmem)
328 {
329 if (!hsock)
330 return VD_ERR_SOC_OPEN;
331
332 int st = vdebug_socket_send(hsock, pmem);
333 if (st <= 0)
334 return VD_ERR_SOC_SEND;
335
336 int rd = vdebug_socket_receive(hsock, pmem);
337 if (rd <= 0)
338 return VD_ERR_SOC_RECV;
339
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);
343
344 return rc;
345 }
346
347 static int vdebug_run_jtag_queue(int hsock, struct vd_shm *pm, unsigned int count)
348 {
349 uint8_t num_pre, num_post, tdi, tms;
350 unsigned int num, anum, bytes, hwords, words;
351 unsigned int req, waddr, rwords;
352 int64_t ts, te;
353 uint8_t *tdo;
354 int rc;
355 uint64_t jhdr;
356 struct vd_rdata *rd;
357
358 req = 0; /* beginning of request */
359 waddr = 0;
360 rwords = 0;
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);
363 ts = timeval_ms();
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]);
367 words = jhdr >> 48;
368 hwords = (jhdr >> 32) & 0xffff;
369 anum = jhdr & 0xffffff;
370 num_pre = (jhdr >> 27) & 0x7;
371 num_post = (jhdr >> 24) & 0x7;
372 if (num_post)
373 num = anum - num_pre - num_post + 1;
374 else
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 */
380 if (!rwords) {
381 rd = &vdc.rdataq;
382 tdo = rd->rdata;
383 } else {
384 rd = list_first_entry(&vdc.rdataq.lh, struct vd_rdata, lh);
385 tdo = rd->rdata;
386 list_del(&rd->lh);
387 free(rd);
388 }
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]);
392 }
393 rwords += words; /* read data offset */
394 } else {
395 tdo = NULL;
396 }
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 */
404 req += 1;
405 }
406
407 if (rc) {
408 LOG_ERROR("0x%x executing transaction", rc);
409 rc = ERROR_FAIL;
410 }
411
412 te = timeval_ms();
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 */
419
420 return rc;
421 }
422
423 static int vdebug_run_reg_queue(int hsock, struct vd_shm *pm, unsigned int count)
424 {
425 unsigned int num, awidth, wwidth;
426 unsigned int req, waddr, rwords;
427 uint8_t aspace;
428 uint32_t addr;
429 int64_t ts, te;
430 uint8_t *data;
431 int rc;
432 uint64_t rhdr;
433 struct vd_rdata *rd;
434
435 req = 0; /* beginning of request */
436 waddr = 0;
437 rwords = 0;
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);
440 ts = timeval_ms();
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;
446 aspace = rhdr & 0x3;
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 */
452 if (num) {
453 if (!rwords) {
454 rd = &vdc.rdataq;
455 data = rd->rdata;
456 } else {
457 rd = list_first_entry(&vdc.rdataq.lh, struct vd_rdata, lh);
458 data = rd->rdata;
459 list_del(&rd->lh);
460 free(rd);
461 }
462 for (unsigned int j = 0; j < num; j++)
463 memcpy(&data[j * awidth], &pm->rd8[(rwords + j) * awidth], awidth);
464 }
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 */
470 } else {
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;
475 }
476 req += 1;
477 }
478
479 if (rc) {
480 LOG_ERROR("0x%x executing transaction", rc);
481 rc = ERROR_FAIL;
482 }
483
484 te = timeval_ms();
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 */
491
492 return rc;
493 }
494
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)
497 {
498 int rc = VD_ERR_NOT_OPEN;
499
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);
513 rc = VD_ERR_VERSION;
514 } else {
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 */
530 }
531
532 if (rc) {
533 LOG_ERROR("0x%x connecting to BFM %s", rc, path);
534 return ERROR_FAIL;
535 }
536
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);
541
542 return ERROR_OK;
543 }
544
545 static int vdebug_close(int hsock, struct vd_shm *pm, uint8_t type)
546 {
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);
562
563 return ERROR_OK;
564 }
565
566 static int vdebug_wait(int hsock, struct vd_shm *pm, uint32_t cycles)
567 {
568 if (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);
574 if (rc) {
575 LOG_ERROR("0x%x waiting %" PRIx32 " cycles", rc, cycles);
576 return ERROR_FAIL;
577 }
578 LOG_DEBUG("%d cycles", cycles);
579 }
580
581 return ERROR_OK;
582 }
583
584 static int vdebug_sig_set(int hsock, struct vd_shm *pm, uint32_t write_mask, uint32_t value)
585 {
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);
591 if (rc) {
592 LOG_ERROR("0x%x setting signals %04" PRIx32, rc, write_mask);
593 return ERROR_FAIL;
594 }
595
596 LOG_DEBUG("setting signals %04" PRIx32 " to %04" PRIx32, write_mask, value);
597
598 return ERROR_OK;
599 }
600
601 static int vdebug_jtag_clock(int hsock, struct vd_shm *pm, uint32_t value)
602 {
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);
608 if (rc) {
609 LOG_ERROR("0x%x setting jtag_clock", rc);
610 return ERROR_FAIL;
611 }
612
613 LOG_DEBUG("setting jtag clock divider to %" PRIx32, value);
614
615 return ERROR_OK;
616 }
617
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,
621 uint8_t f_last)
622 {
623 const uint32_t tobits = 8;
624 uint16_t bytes, hwords, anum, words, waddr;
625 int rc = 0;
626
627 pm->cmd = VD_CMD_JTAGSHTAP;
628 vdc.trans_last = f_last || (vdc.trans_batch == VD_BATCH_NO);
629 if (vdc.trans_first)
630 waddr = 0; /* reset buffer offset */
631 else
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;
635 else
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);
647 rc = ERROR_FAIL;
648 }
649
650 if (!rc && anum) {
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);
655
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);
666 else
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;
670 else
671 pm->wd8[j + i] = (tdi[i] << num_pre) | (tdi[i - 1] >> (8 - num_pre));
672 if (i % 4 == 3)
673 j += 4;
674 }
675
676 if (tdi)
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 */
679
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 */
691 }
692
693 if (tdo) {
694 struct vd_rdata *rd;
695 if (le_to_h_u16(pm->rwords) == 0) {
696 rd = &vdc.rdataq;
697 } else {
698 rd = calloc(1, sizeof(struct vd_rdata));
699 if (!rd) /* check allocation for 24B */
700 return ERROR_FAIL;
701 list_add_tail(&rd->lh, &vdc.rdataq.lh);
702 }
703 rd->rdata = tdo;
704 h_u16_to_le(pm->rwords, le_to_h_u16(pm->rwords) + words);/* keep track of the words to read */
705 }
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);
708 }
709
710 if (!waddr) /* flush issued, but buffer empty */
711 ;
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 */
717
718 return rc;
719 }
720
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)
723 {
724 uint32_t waddr;
725 int rc = ERROR_OK;
726
727 pm->cmd = VD_CMD_REGWRITE;
728 vdc.trans_last = f_last || (vdc.trans_batch == VD_BATCH_NO);
729 if (vdc.trans_first)
730 waddr = 0; /* reset buffer offset */
731 else
732 waddr = le_to_h_u16(pm->offseth); /* continue from the previous transaction */
733
734 if (4 * waddr + 2 * sizeof(uint64_t) + 4 > VD_BUFFER_LEN)
735 vdc.trans_last = 1; /* force flush, no room for next request */
736
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);
745 else
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 */
748
749 return rc;
750 }
751
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)
754 {
755 uint32_t waddr;
756 int rc = ERROR_OK;
757
758 pm->cmd = VD_CMD_REGREAD;
759 vdc.trans_last = f_last || (vdc.trans_batch == VD_BATCH_NO);
760 if (vdc.trans_first)
761 waddr = 0; /* reset buffer offset */
762 else
763 waddr = le_to_h_u16(pm->offseth); /* continue from the previous transaction */
764
765 if (4 * waddr + 2 * sizeof(uint64_t) + 4 > VD_BUFFER_LEN)
766 vdc.trans_last = 1; /* force flush, no room for next request */
767
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);
771 if (data) {
772 struct vd_rdata *rd;
773 if (le_to_h_u16(pm->rwords) == 0) {
774 rd = &vdc.rdataq;
775 } else {
776 rd = calloc(1, sizeof(struct vd_rdata));
777 if (!rd) /* check allocation for 24B */
778 return ERROR_FAIL;
779 list_add_tail(&rd->lh, &vdc.rdataq.lh);
780 }
781 rd->rdata = (uint8_t *)data;
782 h_u16_to_le(pm->rwords, le_to_h_u16(pm->rwords) + 1);
783 }
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);
788 else
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 */
791
792 return rc;
793 }
794
795 static int vdebug_mem_open(int hsock, struct vd_shm *pm, const char *path, uint8_t ndx)
796 {
797 int rc;
798
799 if (!path)
800 return ERROR_OK;
801
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);
809 if (rc) {
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]);
813 } else {
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]);
818 }
819
820 return ERROR_OK;
821 }
822
823 static void vdebug_mem_close(int hsock, struct vd_shm *pm, uint8_t ndx)
824 {
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]);
833 }
834
835
836 static int vdebug_init(void)
837 {
838 vdc.hsocket = vdebug_socket_open(vdc.server_name, vdc.server_port);
839 pbuf = calloc(1, sizeof(struct vd_shm));
840 if (!pbuf) {
841 close_socket(vdc.hsocket);
842 vdc.hsocket = 0;
843 LOG_ERROR("cannot allocate %zu bytes", sizeof(struct vd_shm));
844 return ERROR_FAIL;
845 }
846 if (vdc.hsocket <= 0) {
847 free(pbuf);
848 pbuf = NULL;
849 LOG_ERROR("cannot connect to vdebug server %s:%" PRIu16,
850 vdc.server_name, vdc.server_port);
851 return ERROR_FAIL;
852 }
853 vdc.trans_first = 1;
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;
858
859 int rc = vdebug_open(vdc.hsocket, pbuf, vdc.bfm_path, vdc.bfm_type, vdc.bfm_period, sig_mask);
860 if (rc != 0) {
861 LOG_ERROR("0x%x cannot connect to %s", rc, vdc.bfm_path);
862 close_socket(vdc.hsocket);
863 vdc.hsocket = 0;
864 free(pbuf);
865 pbuf = NULL;
866 } else {
867 for (uint8_t i = 0; i < vdc.mem_ndx; i++) {
868 rc = vdebug_mem_open(vdc.hsocket, pbuf, vdc.mem_path[i], i);
869 if (rc != 0)
870 LOG_ERROR("0x%x cannot connect to %s", rc, vdc.mem_path[i]);
871 }
872
873 LOG_INFO("vdebug %d connected to %s through %s:%" PRIu16,
874 VD_VERSION, vdc.bfm_path, vdc.server_name, vdc.server_port);
875 }
876
877 return rc;
878 }
879
880 static int vdebug_quit(void)
881 {
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);
888 if (vdc.hsocket)
889 close_socket(vdc.hsocket);
890 free(pbuf);
891 pbuf = NULL;
892
893 return ERROR_OK;
894 }
895
896 static int vdebug_reset(int trst, int srst)
897 {
898 uint16_t sig_val = 0xffff;
899 uint16_t sig_mask = 0;
900
901 sig_mask |= VD_SIG_RESET;
902 if (srst)
903 sig_val &= ~VD_SIG_RESET;/* active low */
904 if (transport_is_jtag()) {
905 sig_mask |= VD_SIG_TRST;
906 if (trst)
907 sig_val &= ~VD_SIG_TRST; /* active low */
908 }
909
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);
912 if (rc == 0)
913 rc = vdebug_wait(vdc.hsocket, pbuf, 20); /* 20 clock cycles pulse */
914
915 return rc;
916 }
917
918 static int vdebug_jtag_tms_seq(const uint8_t *tms, int num, uint8_t f_flush)
919 {
920 LOG_INFO("tms len:%d tms:%x", num, *tms);
921
922 return vdebug_jtag_shift_tap(vdc.hsocket, pbuf, num, *tms, 0, NULL, 0, 0, NULL, f_flush);
923 }
924
925 static int vdebug_jtag_path_move(struct pathmove_command *cmd, uint8_t f_flush)
926 {
927 uint8_t tms[DIV_ROUND_UP(cmd->num_states, 8)];
928 LOG_INFO("path num states %d", cmd->num_states);
929
930 memset(tms, 0, DIV_ROUND_UP(cmd->num_states, 8));
931
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]);
936 }
937
938 return vdebug_jtag_tms_seq(tms, cmd->num_states, f_flush);
939 }
940
941 static int vdebug_jtag_tlr(tap_state_t state, uint8_t f_flush)
942 {
943 int rc = ERROR_OK;
944
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);
949 if (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);
952 }
953
954 return rc;
955 }
956
957 static int vdebug_jtag_scan(struct scan_command *cmd, uint8_t f_flush)
958 {
959 int rc = ERROR_OK;
960
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);
979 if (rc)
980 break;
981 }
982
983 if (cur != cmd->end_state)
984 tap_set_state(cmd->end_state);
985
986 return rc;
987 }
988
989 static int vdebug_jtag_runtest(int cycles, tap_state_t state, uint8_t f_flush)
990 {
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);
996 if (cur != state)
997 tap_set_state(state);
998
999 return rc;
1000 }
1001
1002 static int vdebug_jtag_stableclocks(int num, uint8_t f_flush)
1003 {
1004 LOG_INFO("stab len:%d state cur:%x", num, tap_get_state());
1005
1006 return vdebug_jtag_shift_tap(vdc.hsocket, pbuf, 0, 0, num, NULL, 0, 0, NULL, f_flush);
1007 }
1008
1009 static int vdebug_sleep(int us)
1010 {
1011 LOG_INFO("sleep %d us", us);
1012
1013 return vdebug_wait(vdc.hsocket, pbuf, us / 1000);
1014 }
1015
1016 static int vdebug_jtag_speed(int speed)
1017 {
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);
1021
1022 return vdebug_jtag_clock(vdc.hsocket, pbuf, divval);
1023 }
1024
1025 static int vdebug_jtag_khz(int khz, int *jtag_speed)
1026 {
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);
1031
1032 return ERROR_OK;
1033 }
1034
1035 static int vdebug_jtag_div(int speed, int *khz)
1036 {
1037 *khz = speed;
1038 LOG_DEBUG("div khz:%d from speed:%d", *khz, speed);
1039
1040 return ERROR_OK;
1041 }
1042
1043 static int vdebug_jtag_execute_queue(void)
1044 {
1045 int rc = ERROR_OK;
1046
1047 for (struct jtag_command *cmd = jtag_command_queue; rc == ERROR_OK && cmd; cmd = cmd->next) {
1048 switch (cmd->type) {
1049 case JTAG_RUNTEST:
1050 rc = vdebug_jtag_runtest(cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state, !cmd->next);
1051 break;
1052 case JTAG_STABLECLOCKS:
1053 rc = vdebug_jtag_stableclocks(cmd->cmd.stableclocks->num_cycles, !cmd->next);
1054 break;
1055 case JTAG_TLR_RESET:
1056 rc = vdebug_jtag_tlr(cmd->cmd.statemove->end_state, !cmd->next);
1057 break;
1058 case JTAG_PATHMOVE:
1059 rc = vdebug_jtag_path_move(cmd->cmd.pathmove, !cmd->next);
1060 break;
1061 case JTAG_TMS:
1062 rc = vdebug_jtag_tms_seq(cmd->cmd.tms->bits, cmd->cmd.tms->num_bits, !cmd->next);
1063 break;
1064 case JTAG_SLEEP:
1065 rc = vdebug_sleep(cmd->cmd.sleep->us);
1066 break;
1067 case JTAG_SCAN:
1068 rc = vdebug_jtag_scan(cmd->cmd.scan, !cmd->next);
1069 break;
1070 default:
1071 LOG_ERROR("Unknown JTAG command type 0x%x encountered", cmd->type);
1072 rc = ERROR_FAIL;
1073 }
1074 }
1075
1076 return rc;
1077 }
1078
1079 static int vdebug_dap_connect(struct adiv5_dap *dap)
1080 {
1081 return dap_dp_init(dap);
1082 }
1083
1084 static int vdebug_dap_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)
1085 {
1086 return ERROR_OK;
1087 }
1088
1089 static int vdebug_dap_queue_dp_read(struct adiv5_dap *dap, unsigned int reg, uint32_t *data)
1090 {
1091 return vdebug_reg_read(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, data, VD_ASPACE_DP, 0);
1092 }
1093
1094 static int vdebug_dap_queue_dp_write(struct adiv5_dap *dap, unsigned int reg, uint32_t data)
1095 {
1096 return vdebug_reg_write(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, data, VD_ASPACE_DP, 0);
1097 }
1098
1099 static int vdebug_dap_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, uint32_t *data)
1100 {
1101 if ((reg & DP_SELECT_APBANK) != ap->dap->select) {
1102 vdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, reg & DP_SELECT_APBANK, VD_ASPACE_DP, 0);
1103 ap->dap->select = reg & DP_SELECT_APBANK;
1104 }
1105
1106 vdebug_reg_read(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, NULL, VD_ASPACE_AP, 0);
1107
1108 return vdebug_reg_read(vdc.hsocket, pbuf, DP_RDBUFF >> 2, data, VD_ASPACE_DP, 0);
1109 }
1110
1111 static int vdebug_dap_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, uint32_t data)
1112 {
1113 if ((reg & DP_SELECT_APBANK) != ap->dap->select) {
1114 vdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, reg & DP_SELECT_APBANK, VD_ASPACE_DP, 0);
1115 ap->dap->select = reg & DP_SELECT_APBANK;
1116 }
1117
1118 return vdebug_reg_write(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, data, VD_ASPACE_AP, 0);
1119 }
1120
1121 static int vdebug_dap_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)
1122 {
1123 return vdebug_reg_write(vdc.hsocket, pbuf, 0, 0x1, VD_ASPACE_AB, 0);
1124 }
1125
1126 static int vdebug_dap_run(struct adiv5_dap *dap)
1127 {
1128 if (le_to_h_u16(pbuf->waddr))
1129 return vdebug_run_reg_queue(vdc.hsocket, pbuf, le_to_h_u16(pbuf->waddr));
1130
1131 return ERROR_OK;
1132 }
1133
1134 COMMAND_HANDLER(vdebug_set_server)
1135 {
1136 if ((CMD_ARGC != 1) || !strchr(CMD_ARGV[0], ':'))
1137 return ERROR_COMMAND_SYNTAX_ERROR;
1138
1139 char *pchar = strchr(CMD_ARGV[0], ':');
1140 *pchar = '\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;
1146 }
1147 vdc.server_port = port;
1148 LOG_DEBUG("server: %s port %u", vdc.server_name, vdc.server_port);
1149
1150 return ERROR_OK;
1151 }
1152
1153 COMMAND_HANDLER(vdebug_set_bfm)
1154 {
1155 char prefix;
1156
1157 if ((CMD_ARGC != 2) || (sscanf(CMD_ARGV[1], "%u%c", &vdc.bfm_period, &prefix) != 2))
1158 return ERROR_COMMAND_SYNTAX_ERROR;
1159
1160 strncpy(vdc.bfm_path, CMD_ARGV[0], sizeof(vdc.bfm_path) - 1);
1161 switch (prefix) {
1162 case 'u':
1163 vdc.bfm_period *= 1000000;
1164 break;
1165 case 'n':
1166 vdc.bfm_period *= 1000;
1167 break;
1168 case 'p':
1169 default:
1170 break;
1171 }
1172 if (transport_is_dapdirect_swd())
1173 vdc.bfm_type = VD_BFM_SWDP;
1174 else
1175 vdc.bfm_type = VD_BFM_JTAG;
1176 LOG_DEBUG("bfm_path: %s clk_period %ups", vdc.bfm_path, vdc.bfm_period);
1177
1178 return ERROR_OK;
1179 }
1180
1181 COMMAND_HANDLER(vdebug_set_mem)
1182 {
1183 if (CMD_ARGC != 3)
1184 return ERROR_COMMAND_SYNTAX_ERROR;
1185
1186 if (vdc.mem_ndx >= VD_MAX_MEMORIES) {
1187 LOG_ERROR("mem_path declared more than %d allowed times", VD_MAX_MEMORIES);
1188 return ERROR_FAIL;
1189 }
1190
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]);
1196 vdc.mem_ndx++;
1197
1198 return ERROR_OK;
1199 }
1200
1201 COMMAND_HANDLER(vdebug_set_batching)
1202 {
1203 if (CMD_ARGC != 1)
1204 return ERROR_COMMAND_SYNTAX_ERROR;
1205
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;
1212 else
1213 vdc.trans_batch = VD_BATCH_NO;
1214 LOG_DEBUG("batching: set to %u", vdc.trans_batch);
1215
1216 return ERROR_OK;
1217 }
1218
1219 COMMAND_HANDLER(vdebug_set_polling)
1220 {
1221 if (CMD_ARGC != 2)
1222 return ERROR_COMMAND_SYNTAX_ERROR;
1223
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);
1227
1228 return ERROR_OK;
1229 }
1230
1231 static const struct command_registration vdebug_command_handlers[] = {
1232 {
1233 .name = "server",
1234 .handler = &vdebug_set_server,
1235 .mode = COMMAND_CONFIG,
1236 .help = "set the vdebug server name or address",
1237 .usage = "<host:port>",
1238 },
1239 {
1240 .name = "bfm_path",
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>",
1245 },
1246 {
1247 .name = "mem_path",
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>",
1252 },
1253 {
1254 .name = "batching",
1255 .handler = &vdebug_set_batching,
1256 .mode = COMMAND_CONFIG,
1257 .help = "set the transaction batching no|wr|rd [0|1|2]",
1258 .usage = "<level>",
1259 },
1260 {
1261 .name = "polling",
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>",
1266 },
1267 COMMAND_REGISTRATION_DONE
1268 };
1269
1270 static const struct command_registration vdebug_command[] = {
1271 {
1272 .name = "vdebug",
1273 .chain = vdebug_command_handlers,
1274 .mode = COMMAND_ANY,
1275 .help = "vdebug command group",
1276 .usage = "",
1277 },
1278 COMMAND_REGISTRATION_DONE
1279 };
1280
1281 static struct jtag_interface vdebug_jtag_ops = {
1282 .supported = DEBUG_CAP_TMS_SEQ,
1283 .execute_queue = vdebug_jtag_execute_queue,
1284 };
1285
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 */
1297 };
1298
1299 static const char *const vdebug_transports[] = { "jtag", "dapdirect_swd", NULL };
1300
1301 struct adapter_driver vdebug_adapter_driver = {
1302 .name = "vdebug",
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,
1313 };

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)