drivers/cmsis-dap: speed up sending multiple HID requests
[openocd.git] / src / jtag / drivers / xds110.c
1 /***************************************************************************
2 * Copyright (C) 2017 by Texas Instruments, Inc. *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
16 ***************************************************************************/
17
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21
22 #include <transport/transport.h>
23 #include <jtag/swd.h>
24 #include <jtag/interface.h>
25 #include <jtag/commands.h>
26 #include <jtag/tcl.h>
27 #include <libusb.h>
28
29 /* XDS110 USB serial number length */
30 #define XDS110_SERIAL_LEN 8
31
32 /* Firmware version that introduced OpenOCD support via block accesses */
33 #define OCD_FIRMWARE_VERSION 0x02030011
34 #define OCD_FIRMWARE_UPGRADE \
35 "XDS110: upgrade to version 2.3.0.11+ for improved support"
36
37 /***************************************************************************
38 * USB Connection Buffer Definitions *
39 ***************************************************************************/
40
41 /* Max USB packet size for up to USB 3.0 */
42 #define MAX_PACKET 1024
43
44 /*
45 * Maximum data payload that can be handled in a single call
46 * Limitation is the size of the buffers in the XDS110 firmware
47 */
48 #define MAX_DATA_BLOCK 4096
49
50 #ifndef USB_PAYLOAD_SIZE
51 /* Largest data block plus parameters */
52 #define USB_PAYLOAD_SIZE (MAX_DATA_BLOCK + 60)
53 #endif
54 #define MAX_RESULT_QUEUE (MAX_DATA_BLOCK / 4)
55
56 /***************************************************************************
57 * USB Connection Endpoints *
58 ***************************************************************************/
59
60 /* Bulk endpoints used by the XDS110 debug interface */
61 #define INTERFACE_DEBUG (2)
62 #define ENDPOINT_DEBUG_IN (3 | LIBUSB_ENDPOINT_IN)
63 #define ENDPOINT_DEBUG_OUT (2 | LIBUSB_ENDPOINT_OUT)
64
65 /***************************************************************************
66 * XDS110 Firmware API Definitions *
67 ***************************************************************************/
68
69 /*
70 * Default values controlling how the host communicates commands
71 * with XDS110 firmware (automatic retry count and wait timeout)
72 */
73 #define DEFAULT_ATTEMPTS (1)
74 #define DEFAULT_TIMEOUT (4000)
75
76 /* XDS110 API error codes */
77 #define SC_ERR_NONE 0
78 #define SC_ERR_XDS110_FAIL -261
79 #define SC_ERR_SWD_WAIT -613
80 #define SC_ERR_SWD_FAULT -614
81 #define SC_ERR_SWD_PROTOCOL -615
82 #define SC_ERR_SWD_PARITY -616
83 #define SC_ERR_SWD_DEVICE_ID -617
84
85 /* TCK frequency limits */
86 #define XDS110_MIN_TCK_SPEED 100 /* kHz */
87 #define XDS110_MAX_TCK_SPEED 2500 /* kHz */
88 #define XDS110_TCK_PULSE_INCREMENT 66.0
89
90 /* Scan mode on connect */
91 #define MODE_JTAG 1
92
93 /* XDS110 API JTAG state definitions */
94 #define XDS_JTAG_STATE_RESET 1
95 #define XDS_JTAG_STATE_IDLE 2
96 #define XDS_JTAG_STATE_SHIFT_DR 3
97 #define XDS_JTAG_STATE_SHIFT_IR 4
98 #define XDS_JTAG_STATE_PAUSE_DR 5
99 #define XDS_JTAG_STATE_PAUSE_IR 6
100 #define XDS_JTAG_STATE_EXIT1_DR 8
101 #define XDS_JTAG_STATE_EXIT1_IR 9
102 #define XDS_JTAG_STATE_EXIT2_DR 10
103 #define XDS_JTAG_STATE_EXIT2_IR 11
104 #define XDS_JTAG_STATE_SELECT_DR 12
105 #define XDS_JTAG_STATE_SELECT_IR 13
106 #define XDS_JTAG_STATE_UPDATE_DR 14
107 #define XDS_JTAG_STATE_UPDATE_IR 15
108 #define XDS_JTAG_STATE_CAPTURE_DR 16
109 #define XDS_JTAG_STATE_CAPTURE_IR 17
110
111 /* XDS110 API JTAG transit definitions */
112 #define XDS_JTAG_TRANSIT_QUICKEST 1
113 #define XDS_JTAG_TRANSIT_VIA_CAPTURE 2
114 #define XDS_JTAG_TRANSIT_VIA_IDLE 3
115
116 /* DAP register definitions as used by XDS110 APIs */
117
118 #define DAP_AP 0 /* DAP AP register type */
119 #define DAP_DP 1 /* DAP DP register type */
120
121 #define DAP_DP_IDCODE 0x0 /* DAP DP IDCODE register (read only) */
122 #define DAP_DP_ABORT 0x0 /* DAP DP ABORT register (write only) */
123 #define DAP_DP_STAT 0x4 /* DAP DP STAT register (for read only) */
124 #define DAP_DP_CTRL 0x4 /* DAP DP CTRL register (for write only) */
125 #define DAP_DP_ADDR 0x8 /* DAP DP SELECT register (legacy name) */
126 #define DAP_DP_RESEND 0x8 /* DAP DP RESEND register (read only) */
127 #define DAP_DP_SELECT 0x8 /* DAP DP SELECT register (write only) */
128 #define DAP_DP_RDBUFF 0xc /* DAP DP RDBUFF Read Buffer register */
129
130 #define DAP_AP_CSW 0x00 /* DAP AP Control Status Word */
131 #define DAP_AP_TAR 0x04 /* DAP AP Transfer Address */
132 #define DAP_AP_DRW 0x0C /* DAP AP Data Read/Write */
133 #define DAP_AP_BD0 0x10 /* DAP AP Banked Data 0 */
134 #define DAP_AP_BD1 0x14 /* DAP AP Banked Data 1 */
135 #define DAP_AP_BD2 0x18 /* DAP AP Banked Data 2 */
136 #define DAP_AP_BD3 0x1C /* DAP AP Banked Data 3 */
137 #define DAP_AP_RTBL 0xF8 /* DAP AP Debug ROM Table */
138 #define DAP_AP_IDR 0xFC /* DAP AP Identification Register */
139
140 /* Command packet definitions */
141
142 #define XDS_OUT_LEN 1 /* command (byte) */
143 #define XDS_IN_LEN 4 /* error code (int) */
144
145 /* XDS API Commands */
146 #define XDS_CONNECT 0x01 /* Connect JTAG connection */
147 #define XDS_DISCONNECT 0x02 /* Disconnect JTAG connection */
148 #define XDS_VERSION 0x03 /* Get firmware version and hardware ID */
149 #define XDS_SET_TCK 0x04 /* Set TCK delay (to set TCK frequency) */
150 #define XDS_SET_TRST 0x05 /* Assert or deassert nTRST signal */
151 #define XDS_CYCLE_TCK 0x07 /* Toggle TCK for a number of cycles */
152 #define XDS_GOTO_STATE 0x09 /* Go to requested JTAG state */
153 #define XDS_JTAG_SCAN 0x0c /* Send and receive JTAG scan */
154 #define XDS_SET_SRST 0x0e /* Assert or deassert nSRST signal */
155 #define CMAPI_CONNECT 0x0f /* CMAPI connect */
156 #define CMAPI_DISCONNECT 0x10 /* CMAPI disconnect */
157 #define CMAPI_ACQUIRE 0x11 /* CMAPI acquire */
158 #define CMAPI_RELEASE 0x12 /* CMAPI release */
159 #define CMAPI_REG_READ 0x15 /* CMAPI DAP register read */
160 #define CMAPI_REG_WRITE 0x16 /* CMAPI DAP register write */
161 #define SWD_CONNECT 0x17 /* Switch from JTAG to SWD connection */
162 #define SWD_DISCONNECT 0x18 /* Switch from SWD to JTAG connection */
163 #define CJTAG_CONNECT 0x2b /* Switch from JTAG to cJTAG connection */
164 #define CJTAG_DISCONNECT 0x2c /* Switch from cJTAG to JTAG connection */
165 #define OCD_DAP_REQUEST 0x3a /* Handle block of DAP requests */
166 #define OCD_SCAN_REQUEST 0x3b /* Handle block of JTAG scan requests */
167 #define OCD_PATHMOVE 0x3c /* Handle PATHMOVE to navigate JTAG states */
168
169 #define CMD_IR_SCAN 1
170 #define CMD_DR_SCAN 2
171 #define CMD_RUNTEST 3
172 #define CMD_STABLECLOCKS 4
173
174 /* Array to convert from OpenOCD tap_state_t to XDS JTAG state */
175 const uint32_t xds_jtag_state[] = {
176 XDS_JTAG_STATE_EXIT2_DR, /* TAP_DREXIT2 = 0x0 */
177 XDS_JTAG_STATE_EXIT1_DR, /* TAP_DREXIT1 = 0x1 */
178 XDS_JTAG_STATE_SHIFT_DR, /* TAP_DRSHIFT = 0x2 */
179 XDS_JTAG_STATE_PAUSE_DR, /* TAP_DRPAUSE = 0x3 */
180 XDS_JTAG_STATE_SELECT_IR, /* TAP_IRSELECT = 0x4 */
181 XDS_JTAG_STATE_UPDATE_DR, /* TAP_DRUPDATE = 0x5 */
182 XDS_JTAG_STATE_CAPTURE_DR, /* TAP_DRCAPTURE = 0x6 */
183 XDS_JTAG_STATE_SELECT_DR, /* TAP_DRSELECT = 0x7 */
184 XDS_JTAG_STATE_EXIT2_IR, /* TAP_IREXIT2 = 0x8 */
185 XDS_JTAG_STATE_EXIT1_IR, /* TAP_IREXIT1 = 0x9 */
186 XDS_JTAG_STATE_SHIFT_IR, /* TAP_IRSHIFT = 0xa */
187 XDS_JTAG_STATE_PAUSE_IR, /* TAP_IRPAUSE = 0xb */
188 XDS_JTAG_STATE_IDLE, /* TAP_IDLE = 0xc */
189 XDS_JTAG_STATE_UPDATE_IR, /* TAP_IRUPDATE = 0xd */
190 XDS_JTAG_STATE_CAPTURE_IR, /* TAP_IRCAPTURE = 0xe */
191 XDS_JTAG_STATE_RESET, /* TAP_RESET = 0xf */
192 };
193
194 struct scan_result {
195 bool first;
196 uint8_t *buffer;
197 uint32_t num_bits;
198 };
199
200 struct xds110_info {
201 /* USB connection handles and data buffers */
202 libusb_context *ctx;
203 libusb_device_handle *dev;
204 unsigned char read_payload[USB_PAYLOAD_SIZE];
205 unsigned char write_packet[3];
206 unsigned char write_payload[USB_PAYLOAD_SIZE];
207 /* Status flags */
208 bool is_connected;
209 bool is_cmapi_connected;
210 bool is_cmapi_acquired;
211 bool is_swd_mode;
212 bool is_ap_dirty;
213 /* DAP register caches */
214 uint32_t select;
215 uint32_t rdbuff;
216 bool use_rdbuff;
217 /* TCK speed and delay count*/
218 uint32_t speed;
219 uint32_t delay_count;
220 /* XDS110 serial number */
221 char serial[XDS110_SERIAL_LEN + 1];
222 /* XDS110 firmware and hardware version */
223 uint32_t firmware;
224 uint16_t hardware;
225 /* Transaction queues */
226 unsigned char txn_requests[MAX_DATA_BLOCK];
227 uint32_t *txn_dap_results[MAX_DATA_BLOCK / 4];
228 struct scan_result txn_scan_results[MAX_DATA_BLOCK / 4];
229 uint32_t txn_request_size;
230 uint32_t txn_result_size;
231 uint32_t txn_result_count;
232 };
233
234 static struct xds110_info xds110 = {
235 .ctx = NULL,
236 .dev = NULL,
237 .is_connected = false,
238 .is_cmapi_connected = false,
239 .is_cmapi_acquired = false,
240 .is_swd_mode = false,
241 .is_ap_dirty = false,
242 .speed = XDS110_MAX_TCK_SPEED,
243 .delay_count = 0,
244 .serial = {0},
245 .firmware = 0,
246 .hardware = 0,
247 .txn_request_size = 0,
248 .txn_result_size = 0,
249 .txn_result_count = 0
250 };
251
252 static inline void xds110_set_u32(uint8_t *buffer, uint32_t value)
253 {
254 buffer[3] = (value >> 24) & 0xff;
255 buffer[2] = (value >> 16) & 0xff;
256 buffer[1] = (value >> 8) & 0xff;
257 buffer[0] = (value >> 0) & 0xff;
258 }
259
260 static inline void xds110_set_u16(uint8_t *buffer, uint16_t value)
261 {
262 buffer[1] = (value >> 8) & 0xff;
263 buffer[0] = (value >> 0) & 0xff;
264 }
265
266 static inline uint32_t xds110_get_u32(uint8_t *buffer)
267 {
268 uint32_t value = (((uint32_t)buffer[3]) << 24) |
269 (((uint32_t)buffer[2]) << 16) |
270 (((uint32_t)buffer[1]) << 8) |
271 (((uint32_t)buffer[0]) << 0);
272 return value;
273 }
274
275 static inline uint16_t xds110_get_u16(uint8_t *buffer)
276 {
277 uint16_t value = (((uint32_t)buffer[1]) << 8) |
278 (((uint32_t)buffer[0]) << 0);
279 return value;
280 }
281
282 /***************************************************************************
283 * usb connection routines *
284 * *
285 * The following functions handle connecting, reading, and writing to *
286 * the XDS110 over USB using the libusb library. *
287 ***************************************************************************/
288
289 static bool usb_connect(void)
290 {
291 libusb_context *ctx = NULL;
292 libusb_device **list = NULL;
293 libusb_device_handle *dev = NULL;
294
295 struct libusb_device_descriptor desc;
296
297 uint16_t vid = 0x0451;
298 uint16_t pid = 0xbef3;
299 ssize_t count = 0;
300 ssize_t i = 0;
301 int result = 0;
302 bool found = false;
303
304 /* Initialize libusb context */
305 result = libusb_init(&ctx);
306
307 if (0 == result) {
308 /* Get list of USB devices attached to system */
309 count = libusb_get_device_list(ctx, &list);
310 if (count <= 0) {
311 result = -1;
312 list = NULL;
313 }
314 }
315
316 if (0 == result) {
317 /* Scan through list of devices for any XDS110s */
318 for (i = 0; i < count; i++) {
319 /* Check for device VID/PID match */
320 libusb_get_device_descriptor(list[i], &desc);
321 if (desc.idVendor == vid && desc.idProduct == pid) {
322 result = libusb_open(list[i], &dev);
323 if (0 == result) {
324 const int MAX_DATA = 256;
325 unsigned char data[MAX_DATA + 1];
326 *data = '\0';
327
328 /* May be the requested device if serial number matches */
329 if (0 == xds110.serial[0]) {
330 /* No serial number given; match first XDS110 found */
331 found = true;
332 break;
333 } else {
334 /* Get the device's serial number string */
335 result = libusb_get_string_descriptor_ascii(dev,
336 desc.iSerialNumber, data, MAX_DATA);
337 if (0 < result &&
338 0 == strcmp((char *)data, (char *)xds110.serial)) {
339 found = true;
340 break;
341 }
342 }
343
344 /* If we fall though to here, we don't want this device */
345 libusb_close(dev);
346 dev = NULL;
347 }
348 }
349 }
350 }
351
352 /*
353 * We can fall through the for() loop with two possible exit conditions:
354 * 1) found the right XDS110, and that device is open
355 * 2) didn't find the XDS110, and no devices are currently open
356 */
357
358 if (NULL != list) {
359 /* Free the device list, we're done with it */
360 libusb_free_device_list(list, 1);
361 }
362
363 if (found) {
364 /* Save the context and device handles */
365 xds110.ctx = ctx;
366 xds110.dev = dev;
367
368 /* Set libusb to auto detach kernel */
369 (void)libusb_set_auto_detach_kernel_driver(dev, 1);
370
371 /* Claim the debug interface on the XDS110 */
372 result = libusb_claim_interface(dev, INTERFACE_DEBUG);
373 } else {
374 /* Couldn't find an XDS110, flag the error */
375 result = -1;
376 }
377
378 /* On an error, clean up what we can */
379 if (0 != result) {
380 if (NULL != dev) {
381 /* Release the debug and data interface on the XDS110 */
382 (void)libusb_release_interface(dev, INTERFACE_DEBUG);
383 libusb_close(dev);
384 }
385 if (NULL != ctx)
386 libusb_exit(ctx);
387 xds110.ctx = NULL;
388 xds110.dev = NULL;
389 }
390
391 /* Log the results */
392 if (0 == result)
393 LOG_INFO("XDS110: connected");
394 else
395 LOG_ERROR("XDS110: failed to connect");
396
397 return (0 == result) ? true : false;
398 }
399
400 static void usb_disconnect(void)
401 {
402 if (NULL != xds110.dev) {
403 /* Release the debug and data interface on the XDS110 */
404 (void)libusb_release_interface(xds110.dev, INTERFACE_DEBUG);
405 libusb_close(xds110.dev);
406 xds110.dev = NULL;
407 }
408 if (NULL != xds110.ctx) {
409 libusb_exit(xds110.ctx);
410 xds110.ctx = NULL;
411 }
412
413 LOG_INFO("XDS110: disconnected");
414 }
415
416 static bool usb_read(unsigned char *buffer, int size, int *bytes_read,
417 int timeout)
418 {
419 int result;
420
421 if (NULL == xds110.dev || NULL == buffer || NULL == bytes_read)
422 return false;
423
424 /* Force a non-zero timeout to prevent blocking */
425 if (0 == timeout)
426 timeout = DEFAULT_TIMEOUT;
427
428 result = libusb_bulk_transfer(xds110.dev, ENDPOINT_DEBUG_IN, buffer, size,
429 bytes_read, timeout);
430
431 return (0 == result) ? true : false;
432 }
433
434 static bool usb_write(unsigned char *buffer, int size, int *written)
435 {
436 int bytes_written = 0;
437 int result = LIBUSB_SUCCESS;
438 int retries = 0;
439
440 if (NULL == xds110.dev || NULL == buffer)
441 return false;
442
443 result = libusb_bulk_transfer(xds110.dev, ENDPOINT_DEBUG_OUT, buffer,
444 size, &bytes_written, 0);
445
446 while (LIBUSB_ERROR_PIPE == result && retries < 3) {
447 /* Try clearing the pipe stall and retry transfer */
448 libusb_clear_halt(xds110.dev, ENDPOINT_DEBUG_OUT);
449 result = libusb_bulk_transfer(xds110.dev, ENDPOINT_DEBUG_OUT, buffer,
450 size, &bytes_written, 0);
451 retries++;
452 }
453
454 if (NULL != written)
455 *written = bytes_written;
456
457 return (0 == result && size == bytes_written) ? true : false;
458 }
459
460 static bool usb_get_response(uint32_t *total_bytes_read, uint32_t timeout)
461 {
462 static unsigned char buffer[MAX_PACKET];
463 int bytes_read;
464 uint16_t size;
465 uint16_t count;
466 bool success;
467
468 size = 0;
469 success = true;
470 while (success) {
471 success = usb_read(buffer, sizeof(buffer), &bytes_read, timeout);
472 if (success) {
473 /*
474 * Validate that this appears to be a good response packet
475 * First check it contains enough data for header and error
476 * code, plus the first character is the start character
477 */
478 if (bytes_read >= 7 && '*' == buffer[0]) {
479 /* Extract the payload size */
480 size = xds110_get_u16(&buffer[1]);
481 /* Sanity test on payload size */
482 if (USB_PAYLOAD_SIZE >= size && 4 <= size) {
483 /* Check we didn't get more data than expected */
484 if ((bytes_read - 3) <= size) {
485 /* Packet appears to be valid, move on */
486 break;
487 }
488 }
489 }
490 }
491 /*
492 * Somehow received an invalid packet, retry till we
493 * time out or a valid response packet is received
494 */
495 }
496
497 /* Abort now if we didn't receive a valid response */
498 if (!success) {
499 if (NULL != total_bytes_read)
500 *total_bytes_read = 0;
501 return false;
502 }
503
504 /* Build the return payload into xds110.read_payload */
505
506 /* Copy over payload data from received buffer (skipping header) */
507 count = 0;
508 bytes_read -= 3;
509 memcpy((void *)&xds110.read_payload[count], (void *)&buffer[3], bytes_read);
510 count += bytes_read;
511 /*
512 * Drop timeout to just 1/2 second. Once the XDS110 starts sending
513 * a response, the remaining packets should arrive in short order
514 */
515 if (timeout > 500)
516 timeout = 500; /* ms */
517
518 /* If there's more data to retrieve, get it now */
519 while ((count < size) && success) {
520 success = usb_read(buffer, sizeof(buffer), &bytes_read, timeout);
521 if (success) {
522 if ((count + bytes_read) > size) {
523 /* Read too much data, not a valid packet, abort */
524 success = false;
525 } else {
526 /* Copy this data over to xds110.read_payload */
527 memcpy((void *)&xds110.read_payload[count], (void *)buffer,
528 bytes_read);
529 count += bytes_read;
530 }
531 }
532 }
533
534 if (!success)
535 count = 0;
536 if (NULL != total_bytes_read)
537 *total_bytes_read = count;
538
539 return success;
540 }
541
542 static bool usb_send_command(uint16_t size)
543 {
544 int written;
545 bool success = true;
546
547 /* Check the packet length */
548 if (size > USB_PAYLOAD_SIZE)
549 return false;
550
551 /* Place the start character into the packet buffer */
552 xds110.write_packet[0] = '*';
553
554 /* Place the payload size into the packet buffer */
555 xds110_set_u16(&xds110.write_packet[1], size);
556
557 /* Adjust size to include header */
558 size += 3;
559
560 /* Send the data via the USB connection */
561 success = usb_write(xds110.write_packet, (int)size, &written);
562
563 /* Check if the correct number of bytes was written */
564 if (written != (int)size)
565 success = false;
566
567 return success;
568 }
569
570 /***************************************************************************
571 * XDS110 firmware API routines *
572 * *
573 * The following functions handle calling into the XDS110 firmware to *
574 * perform requested debug actions. *
575 ***************************************************************************/
576
577 static bool xds_execute(uint32_t out_length, uint32_t in_length,
578 uint32_t attempts, uint32_t timeout)
579 {
580 bool done = false;
581 bool success = true;
582 int error = 0;
583 uint32_t bytes_read = 0;
584
585 if (NULL == xds110.dev)
586 return false;
587
588 while (!done && attempts > 0) {
589 attempts--;
590
591 /* Send command to XDS110 */
592 success = usb_send_command(out_length);
593
594 if (success) {
595 /* Get response from XDS110 */
596 success = usb_get_response(&bytes_read, timeout);
597 }
598
599 if (success) {
600 /* Check for valid response from XDS code handling */
601 if (bytes_read != in_length) {
602 /* Unexpected amount of data returned */
603 success = false;
604 } else {
605 /* Extract error code from return packet */
606 error = (int)xds110_get_u32(&xds110.read_payload[0]);
607 done = true;
608 }
609 }
610 }
611
612 if (!success)
613 error = SC_ERR_XDS110_FAIL;
614
615 if (0 != error)
616 success = false;
617
618 return success;
619 }
620
621 static bool xds_connect(void)
622 {
623 bool success;
624
625 xds110.write_payload[0] = XDS_CONNECT;
626
627 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,
628 DEFAULT_TIMEOUT);
629
630 return success;
631 }
632
633 static bool xds_disconnect(void)
634 {
635 bool success;
636
637 xds110.write_payload[0] = XDS_DISCONNECT;
638
639 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,
640 DEFAULT_TIMEOUT);
641
642 return success;
643 }
644
645 static bool xds_version(uint32_t *firmware_id, uint16_t *hardware_id)
646 {
647 uint8_t *fw_id_pntr = &xds110.read_payload[XDS_IN_LEN + 0]; /* 32-bits */
648 uint8_t *hw_id_pntr = &xds110.read_payload[XDS_IN_LEN + 4]; /* 16-bits */
649
650 bool success;
651
652 xds110.write_payload[0] = XDS_VERSION;
653
654 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN + 6, DEFAULT_ATTEMPTS,
655 DEFAULT_TIMEOUT);
656
657 if (success) {
658 if (NULL != firmware_id)
659 *firmware_id = xds110_get_u32(fw_id_pntr);
660 if (NULL != hardware_id)
661 *hardware_id = xds110_get_u16(hw_id_pntr);
662 }
663
664 return success;
665 }
666
667 static bool xds_set_tck_delay(uint32_t delay)
668 {
669 uint8_t *delay_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 32-bits */
670
671 bool success;
672
673 xds110.write_payload[0] = XDS_SET_TCK;
674
675 xds110_set_u32(delay_pntr, delay);
676
677 success = xds_execute(XDS_OUT_LEN + 4, XDS_IN_LEN, DEFAULT_ATTEMPTS,
678 DEFAULT_TIMEOUT);
679
680 return success;
681 }
682
683 static bool xds_set_trst(uint8_t trst)
684 {
685 uint8_t *trst_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 8-bits */
686
687 bool success;
688
689 xds110.write_payload[0] = XDS_SET_TRST;
690
691 *trst_pntr = trst;
692
693 success = xds_execute(XDS_OUT_LEN + 1, XDS_IN_LEN, DEFAULT_ATTEMPTS,
694 DEFAULT_TIMEOUT);
695
696 return success;
697 }
698
699 static bool xds_cycle_tck(uint32_t count)
700 {
701 uint8_t *count_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 32-bits */
702
703 bool success;
704
705 xds110.write_payload[0] = XDS_CYCLE_TCK;
706
707 xds110_set_u32(count_pntr, count);
708
709 success = xds_execute(XDS_OUT_LEN + 4, XDS_IN_LEN, DEFAULT_ATTEMPTS,
710 DEFAULT_TIMEOUT);
711
712 return success;
713 }
714
715 static bool xds_goto_state(uint32_t state)
716 {
717 uint8_t *state_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 32-bits */
718 uint8_t *transit_pntr = &xds110.write_payload[XDS_OUT_LEN+4]; /* 32-bits */
719
720 bool success;
721
722 xds110.write_payload[0] = XDS_GOTO_STATE;
723
724 xds110_set_u32(state_pntr, state);
725 xds110_set_u32(transit_pntr, XDS_JTAG_TRANSIT_QUICKEST);
726
727 success = xds_execute(XDS_OUT_LEN+8, XDS_IN_LEN, DEFAULT_ATTEMPTS,
728 DEFAULT_TIMEOUT);
729
730 return success;
731 }
732
733 static bool xds_jtag_scan(uint32_t shift_state, uint16_t shift_bits,
734 uint32_t end_state, uint8_t *data_out, uint8_t *data_in)
735 {
736 uint8_t *bits_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 16-bits */
737 uint8_t *path_pntr = &xds110.write_payload[XDS_OUT_LEN + 2]; /* 8-bits */
738 uint8_t *trans1_pntr = &xds110.write_payload[XDS_OUT_LEN + 3]; /* 8-bits */
739 uint8_t *end_pntr = &xds110.write_payload[XDS_OUT_LEN + 4]; /* 8-bits */
740 uint8_t *trans2_pntr = &xds110.write_payload[XDS_OUT_LEN + 5]; /* 8-bits */
741 uint8_t *pre_pntr = &xds110.write_payload[XDS_OUT_LEN + 6]; /* 16-bits */
742 uint8_t *pos_pntr = &xds110.write_payload[XDS_OUT_LEN + 8]; /* 16-bits */
743 uint8_t *delay_pntr = &xds110.write_payload[XDS_OUT_LEN + 10]; /* 16-bits */
744 uint8_t *rep_pntr = &xds110.write_payload[XDS_OUT_LEN + 12]; /* 16-bits */
745 uint8_t *out_pntr = &xds110.write_payload[XDS_OUT_LEN + 14]; /* 16-bits */
746 uint8_t *in_pntr = &xds110.write_payload[XDS_OUT_LEN + 16]; /* 16-bits */
747 uint8_t *data_out_pntr = &xds110.write_payload[XDS_OUT_LEN + 18];
748 uint8_t *data_in_pntr = &xds110.read_payload[XDS_IN_LEN+0];
749
750 uint16_t total_bytes = DIV_ROUND_UP(shift_bits, 8);
751
752 bool success;
753
754 xds110.write_payload[0] = XDS_JTAG_SCAN;
755
756 xds110_set_u16(bits_pntr, shift_bits); /* bits to scan */
757 *path_pntr = (uint8_t)(shift_state & 0xff); /* IR vs DR path */
758 *trans1_pntr = (uint8_t)XDS_JTAG_TRANSIT_QUICKEST; /* start state route */
759 *end_pntr = (uint8_t)(end_state & 0xff); /* JTAG state after scan */
760 *trans2_pntr = (uint8_t)XDS_JTAG_TRANSIT_QUICKEST; /* end state route */
761 xds110_set_u16(pre_pntr, 0); /* number of preamble bits */
762 xds110_set_u16(pos_pntr, 0); /* number of postamble bits */
763 xds110_set_u16(delay_pntr, 0); /* number of extra TCKs after scan */
764 xds110_set_u16(rep_pntr, 1); /* number of repetitions */
765 xds110_set_u16(out_pntr, total_bytes); /* out buffer offset (if repeats) */
766 xds110_set_u16(in_pntr, total_bytes); /* in buffer offset (if repeats) */
767
768 memcpy((void *)data_out_pntr, (void *)data_out, total_bytes);
769
770 success = xds_execute(XDS_OUT_LEN + 18 + total_bytes,
771 XDS_IN_LEN + total_bytes, DEFAULT_ATTEMPTS, DEFAULT_TIMEOUT);
772
773 if (success)
774 memcpy((void *)data_in, (void *)data_in_pntr, total_bytes);
775
776 return success;
777 }
778
779 static bool xds_set_srst(uint8_t srst)
780 {
781 uint8_t *srst_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 8-bits */
782
783 bool success;
784
785 xds110.write_payload[0] = XDS_SET_SRST;
786
787 *srst_pntr = srst;
788
789 success = xds_execute(XDS_OUT_LEN + 1, XDS_IN_LEN, DEFAULT_ATTEMPTS,
790 DEFAULT_TIMEOUT);
791
792 return success;
793 }
794
795 static bool cmapi_connect(uint32_t *idcode)
796 {
797 uint8_t *idcode_pntr = &xds110.read_payload[XDS_IN_LEN + 0]; /* 32-bits */
798
799 bool success;
800
801 xds110.write_payload[0] = CMAPI_CONNECT;
802
803 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN+4, DEFAULT_ATTEMPTS,
804 DEFAULT_TIMEOUT);
805
806 if (success) {
807 if (NULL != idcode)
808 *idcode = xds110_get_u32(idcode_pntr);
809 }
810
811 return success;
812 }
813
814 static bool cmapi_disconnect(void)
815 {
816 bool success;
817
818 xds110.write_payload[0] = CMAPI_DISCONNECT;
819
820 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,
821 DEFAULT_TIMEOUT);
822
823 return success;
824 }
825
826 static bool cmapi_acquire(void)
827 {
828 bool success;
829
830 xds110.write_payload[0] = CMAPI_ACQUIRE;
831
832 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,
833 DEFAULT_TIMEOUT);
834
835 return success;
836 }
837
838 static bool cmapi_release(void)
839 {
840 bool success;
841
842 xds110.write_payload[0] = CMAPI_RELEASE;
843
844 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,
845 DEFAULT_TIMEOUT);
846
847 return success;
848 }
849
850 static bool cmapi_read_dap_reg(uint32_t type, uint32_t ap_num,
851 uint32_t address, uint32_t *value)
852 {
853 uint8_t *type_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 8-bits */
854 uint8_t *ap_num_pntr = &xds110.write_payload[XDS_OUT_LEN + 1]; /* 8-bits */
855 uint8_t *address_pntr = &xds110.write_payload[XDS_OUT_LEN + 2]; /* 8-bits */
856 uint8_t *value_pntr = &xds110.read_payload[XDS_IN_LEN + 0]; /* 32-bits */
857
858 bool success;
859
860 xds110.write_payload[0] = CMAPI_REG_READ;
861
862 *type_pntr = (uint8_t)(type & 0xff);
863 *ap_num_pntr = (uint8_t)(ap_num & 0xff);
864 *address_pntr = (uint8_t)(address & 0xff);
865
866 success = xds_execute(XDS_OUT_LEN + 3, XDS_IN_LEN + 4, DEFAULT_ATTEMPTS,
867 DEFAULT_TIMEOUT);
868
869 if (success) {
870 if (NULL != value)
871 *value = xds110_get_u32(value_pntr);
872 }
873
874 return success;
875 }
876
877 static bool cmapi_write_dap_reg(uint32_t type, uint32_t ap_num,
878 uint32_t address, uint32_t *value)
879 {
880 uint8_t *type_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 8-bits */
881 uint8_t *ap_num_pntr = &xds110.write_payload[XDS_OUT_LEN + 1]; /* 8-bits */
882 uint8_t *address_pntr = &xds110.write_payload[XDS_OUT_LEN + 2]; /* 8-bits */
883 uint8_t *value_pntr = &xds110.write_payload[XDS_OUT_LEN + 3]; /* 32-bits */
884
885 bool success;
886
887 if (NULL == value)
888 return false;
889
890 xds110.write_payload[0] = CMAPI_REG_WRITE;
891
892 *type_pntr = (uint8_t)(type & 0xff);
893 *ap_num_pntr = (uint8_t)(ap_num & 0xff);
894 *address_pntr = (uint8_t)(address & 0xff);
895 xds110_set_u32(value_pntr, *value);
896
897 success = xds_execute(XDS_OUT_LEN + 7, XDS_IN_LEN, DEFAULT_ATTEMPTS,
898 DEFAULT_TIMEOUT);
899
900 return success;
901 }
902
903 static bool swd_connect(void)
904 {
905 bool success;
906
907 xds110.write_payload[0] = SWD_CONNECT;
908
909 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,
910 DEFAULT_TIMEOUT);
911
912 return success;
913 }
914
915 static bool swd_disconnect(void)
916 {
917 bool success;
918
919 xds110.write_payload[0] = SWD_DISCONNECT;
920
921 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,
922 DEFAULT_TIMEOUT);
923
924 return success;
925 }
926
927 static bool cjtag_connect(uint32_t format)
928 {
929 uint8_t *format_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 32-bits */
930
931 bool success;
932
933 xds110.write_payload[0] = CJTAG_CONNECT;
934
935 xds110_set_u32(format_pntr, format);
936
937 success = xds_execute(XDS_OUT_LEN + 4, XDS_IN_LEN, DEFAULT_ATTEMPTS,
938 DEFAULT_TIMEOUT);
939
940 return success;
941 }
942
943 static bool cjtag_disconnect(void)
944 {
945 bool success;
946
947 xds110.write_payload[0] = CJTAG_DISCONNECT;
948
949 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,
950 DEFAULT_TIMEOUT);
951
952 return success;
953 }
954
955 static bool ocd_dap_request(uint8_t *dap_requests, uint32_t request_size,
956 uint32_t *dap_results, uint32_t result_count)
957 {
958 uint8_t *request_pntr = &xds110.write_payload[XDS_OUT_LEN + 0];
959 uint8_t *result_pntr = &xds110.read_payload[XDS_IN_LEN + 0];
960
961 bool success;
962
963 if (NULL == dap_requests || NULL == dap_results)
964 return false;
965
966 xds110.write_payload[0] = OCD_DAP_REQUEST;
967
968 memcpy((void *)request_pntr, (void *)dap_requests, request_size);
969
970 success = xds_execute(XDS_OUT_LEN + request_size,
971 XDS_IN_LEN + (result_count * 4), DEFAULT_ATTEMPTS,
972 DEFAULT_TIMEOUT);
973
974 if (success && (result_count > 0))
975 memcpy((void *)dap_results, (void *)result_pntr, result_count * 4);
976
977 return success;
978 }
979
980 static bool ocd_scan_request(uint8_t *scan_requests, uint32_t request_size,
981 uint8_t *scan_results, uint32_t result_size)
982 {
983 uint8_t *request_pntr = &xds110.write_payload[XDS_OUT_LEN + 0];
984 uint8_t *result_pntr = &xds110.read_payload[XDS_IN_LEN + 0];
985
986 bool success;
987
988 if (NULL == scan_requests || NULL == scan_results)
989 return false;
990
991 xds110.write_payload[0] = OCD_SCAN_REQUEST;
992
993 memcpy((void *)request_pntr, (void *)scan_requests, request_size);
994
995 success = xds_execute(XDS_OUT_LEN + request_size,
996 XDS_IN_LEN + result_size, DEFAULT_ATTEMPTS,
997 DEFAULT_TIMEOUT);
998
999 if (success && (result_size > 0))
1000 memcpy((void *)scan_results, (void *)result_pntr, result_size);
1001
1002 return success;
1003 }
1004
1005 static bool ocd_pathmove(uint32_t num_states, uint8_t *path)
1006 {
1007 uint8_t *num_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 32-bits */
1008 uint8_t *path_pntr = &xds110.write_payload[XDS_OUT_LEN + 4];
1009
1010 bool success;
1011
1012 if (NULL == path)
1013 return false;
1014
1015 xds110.write_payload[0] = OCD_PATHMOVE;
1016
1017 xds110_set_u32(num_pntr, num_states);
1018
1019 memcpy((void *)path_pntr, (void *)path, num_states);
1020
1021 success = xds_execute(XDS_OUT_LEN + 4 + num_states, XDS_IN_LEN,
1022 DEFAULT_ATTEMPTS, DEFAULT_TIMEOUT);
1023
1024 return success;
1025 }
1026
1027 /***************************************************************************
1028 * swd driver interface *
1029 * *
1030 * The following functions provide SWD support to OpenOCD. *
1031 ***************************************************************************/
1032
1033 static int xds110_swd_init(void)
1034 {
1035 xds110.is_swd_mode = true;
1036 return ERROR_OK;
1037 }
1038
1039 static int xds110_swd_switch_seq(enum swd_special_seq seq)
1040 {
1041 uint32_t idcode;
1042 bool success;
1043
1044 switch (seq) {
1045 case LINE_RESET:
1046 LOG_ERROR("Sequence SWD line reset (%d) not supported", seq);
1047 return ERROR_FAIL;
1048 case JTAG_TO_SWD:
1049 LOG_DEBUG("JTAG-to-SWD");
1050 xds110.is_swd_mode = false;
1051 xds110.is_cmapi_connected = false;
1052 xds110.is_cmapi_acquired = false;
1053 /* Run sequence to put target in SWD mode */
1054 success = swd_connect();
1055 /* Re-iniitialize CMAPI API for DAP access */
1056 if (success) {
1057 xds110.is_swd_mode = true;
1058 success = cmapi_connect(&idcode);
1059 if (success) {
1060 xds110.is_cmapi_connected = true;
1061 success = cmapi_acquire();
1062 }
1063 }
1064 break;
1065 case SWD_TO_JTAG:
1066 LOG_DEBUG("SWD-to-JTAG");
1067 xds110.is_swd_mode = false;
1068 xds110.is_cmapi_connected = false;
1069 xds110.is_cmapi_acquired = false;
1070 /* Run sequence to put target in JTAG mode */
1071 success = swd_disconnect();
1072 if (success) {
1073 /* Re-initialize JTAG interface */
1074 success = cjtag_connect(MODE_JTAG);
1075 }
1076 break;
1077 default:
1078 LOG_ERROR("Sequence %d not supported", seq);
1079 return ERROR_FAIL;
1080 }
1081
1082 if (success)
1083 return ERROR_OK;
1084 else
1085 return ERROR_FAIL;
1086 }
1087
1088 static bool xds110_legacy_read_reg(uint8_t cmd, uint32_t *value)
1089 {
1090 /* Make sure this is a read request */
1091 bool is_read_request = (0 != (SWD_CMD_RnW & cmd));
1092 /* Determine whether this is a DP or AP register access */
1093 uint32_t type = (0 != (SWD_CMD_APnDP & cmd)) ? DAP_AP : DAP_DP;
1094 /* Determine the AP number from cached SELECT value */
1095 uint32_t ap_num = (xds110.select & 0xff000000) >> 24;
1096 /* Extract register address from command */
1097 uint32_t address = ((cmd & SWD_CMD_A32) >> 1);
1098 /* Extract bank address from cached SELECT value */
1099 uint32_t bank = (xds110.select & 0x000000f0);
1100
1101 uint32_t reg_value = 0;
1102 uint32_t temp_value = 0;
1103
1104 bool success;
1105
1106 if (!is_read_request)
1107 return false;
1108
1109 if (DAP_AP == type) {
1110 /* Add bank address to register address for CMAPI call */
1111 address |= bank;
1112 }
1113
1114 if (DAP_DP == type && DAP_DP_RDBUFF == address && xds110.use_rdbuff) {
1115 /* If RDBUFF is cached and this is a DP RDBUFF read, use the cache */
1116 reg_value = xds110.rdbuff;
1117 success = true;
1118 } else if (DAP_AP == type && DAP_AP_DRW == address && xds110.use_rdbuff) {
1119 /* If RDBUFF is cached and this is an AP DRW read, use the cache, */
1120 /* but still call into the firmware to get the next read. */
1121 reg_value = xds110.rdbuff;
1122 success = cmapi_read_dap_reg(type, ap_num, address, &temp_value);
1123 } else {
1124 success = cmapi_read_dap_reg(type, ap_num, address, &temp_value);
1125 if (success)
1126 reg_value = temp_value;
1127 }
1128
1129 /* Mark that we have consumed or invalidated the RDBUFF cache */
1130 xds110.use_rdbuff = false;
1131
1132 /* Handle result of read attempt */
1133 if (!success)
1134 LOG_ERROR("XDS110: failed to read DAP register");
1135 else if (NULL != value)
1136 *value = reg_value;
1137
1138 if (success && DAP_AP == type) {
1139 /*
1140 * On a successful DAP AP read, we actually have the value from RDBUFF,
1141 * the firmware will have run the AP request and made the RDBUFF read
1142 */
1143 xds110.use_rdbuff = true;
1144 xds110.rdbuff = temp_value;
1145 }
1146
1147 return success;
1148 }
1149
1150 static bool xds110_legacy_write_reg(uint8_t cmd, uint32_t value)
1151 {
1152 /* Make sure this isn't a read request */
1153 bool is_read_request = (0 != (SWD_CMD_RnW & cmd));
1154 /* Determine whether this is a DP or AP register access */
1155 uint32_t type = (0 != (SWD_CMD_APnDP & cmd)) ? DAP_AP : DAP_DP;
1156 /* Determine the AP number from cached SELECT value */
1157 uint32_t ap_num = (xds110.select & 0xff000000) >> 24;
1158 /* Extract register address from command */
1159 uint32_t address = ((cmd & SWD_CMD_A32) >> 1);
1160 /* Extract bank address from cached SELECT value */
1161 uint32_t bank = (xds110.select & 0x000000f0);
1162
1163 bool success;
1164
1165 if (is_read_request)
1166 return false;
1167
1168 /* Invalidate the RDBUFF cache */
1169 xds110.use_rdbuff = false;
1170
1171 if (DAP_AP == type) {
1172 /* Add bank address to register address for CMAPI call */
1173 address |= bank;
1174 /* Any write to an AP register invalidates the firmware's cache */
1175 xds110.is_ap_dirty = true;
1176 } else if (DAP_DP_SELECT == address) {
1177 /* Any write to the SELECT register invalidates the firmware's cache */
1178 xds110.is_ap_dirty = true;
1179 }
1180
1181 success = cmapi_write_dap_reg(type, ap_num, address, &value);
1182
1183 if (!success) {
1184 LOG_ERROR("XDS110: failed to write DAP register");
1185 } else {
1186 /*
1187 * If the debugger wrote to SELECT, cache the value
1188 * to use to build the apNum and address values above
1189 */
1190 if ((DAP_DP == type) && (DAP_DP_SELECT == address))
1191 xds110.select = value;
1192 }
1193
1194 return success;
1195 }
1196
1197 static int xds110_swd_run_queue(void)
1198 {
1199 static uint32_t dap_results[MAX_RESULT_QUEUE];
1200 uint8_t cmd;
1201 uint32_t request;
1202 uint32_t result;
1203 uint32_t value;
1204 bool success = true;
1205
1206 if (0 == xds110.txn_request_size)
1207 return ERROR_OK;
1208
1209 /* Terminate request queue */
1210 xds110.txn_requests[xds110.txn_request_size++] = 0;
1211
1212 if (xds110.firmware >= OCD_FIRMWARE_VERSION) {
1213 /* XDS110 firmware has the API to directly handle the queue */
1214 success = ocd_dap_request(xds110.txn_requests,
1215 xds110.txn_request_size, dap_results, xds110.txn_result_count);
1216 } else {
1217 /* Legacy firmware needs to handle queue via discrete DAP calls */
1218 request = 0;
1219 result = 0;
1220 while (xds110.txn_requests[request] != 0) {
1221 cmd = xds110.txn_requests[request++];
1222 if (0 == (SWD_CMD_RnW & cmd)) {
1223 /* DAP register write command */
1224 value = (uint32_t)(xds110.txn_requests[request++]) << 0;
1225 value |= (uint32_t)(xds110.txn_requests[request++]) << 8;
1226 value |= (uint32_t)(xds110.txn_requests[request++]) << 16;
1227 value |= (uint32_t)(xds110.txn_requests[request++]) << 24;
1228 if (success)
1229 success = xds110_legacy_write_reg(cmd, value);
1230 } else {
1231 /* DAP register read command */
1232 value = 0;
1233 if (success)
1234 success = xds110_legacy_read_reg(cmd, &value);
1235 dap_results[result++] = value;
1236 }
1237 }
1238 }
1239
1240 /* Transfer results into caller's buffers */
1241 for (result = 0; result < xds110.txn_result_count; result++)
1242 if (0 != xds110.txn_dap_results[result])
1243 *xds110.txn_dap_results[result] = dap_results[result];
1244
1245 xds110.txn_request_size = 0;
1246 xds110.txn_result_size = 0;
1247 xds110.txn_result_count = 0;
1248
1249 return (success) ? ERROR_OK : ERROR_FAIL;
1250 }
1251
1252 static void xds110_swd_queue_cmd(uint8_t cmd, uint32_t *value)
1253 {
1254 /* Check if this is a read or write request */
1255 bool is_read_request = (0 != (SWD_CMD_RnW & cmd));
1256 /* Determine whether this is a DP or AP register access */
1257 uint32_t type = (0 != (SWD_CMD_APnDP & cmd)) ? DAP_AP : DAP_DP;
1258 /* Extract register address from command */
1259 uint32_t address = ((cmd & SWD_CMD_A32) >> 1);
1260 uint32_t request_size = (is_read_request) ? 1 : 5;
1261
1262 /* Check if new request would be too large to fit */
1263 if (((xds110.txn_request_size + request_size + 1) > MAX_DATA_BLOCK) ||
1264 ((xds110.txn_result_count + 1) > MAX_RESULT_QUEUE))
1265 xds110_swd_run_queue();
1266
1267 /* Set the START bit in cmd to ensure cmd is not zero */
1268 /* (a value of zero is used to terminate the buffer) */
1269 cmd |= SWD_CMD_START;
1270
1271 /* Add request to queue; queue is built marshalled for XDS110 call */
1272 if (is_read_request) {
1273 /* Queue read request, save pointer to pass back result */
1274 xds110.txn_requests[xds110.txn_request_size++] = cmd;
1275 xds110.txn_dap_results[xds110.txn_result_count++] = value;
1276 xds110.txn_result_size += 4;
1277 } else {
1278 /* Check for and prevent sticky overrun detection */
1279 if (DAP_DP == type && DAP_DP_CTRL == address &&
1280 (*value & CORUNDETECT)) {
1281 LOG_DEBUG("XDS110: refusing to enable sticky overrun detection");
1282 *value &= ~CORUNDETECT;
1283 }
1284 /* Queue write request, add value directly to queue buffer */
1285 xds110.txn_requests[xds110.txn_request_size++] = cmd;
1286 xds110.txn_requests[xds110.txn_request_size++] = (*value >> 0) & 0xff;
1287 xds110.txn_requests[xds110.txn_request_size++] = (*value >> 8) & 0xff;
1288 xds110.txn_requests[xds110.txn_request_size++] = (*value >> 16) & 0xff;
1289 xds110.txn_requests[xds110.txn_request_size++] = (*value >> 24) & 0xff;
1290 }
1291 }
1292
1293 static void xds110_swd_read_reg(uint8_t cmd, uint32_t *value,
1294 uint32_t ap_delay_clk)
1295 {
1296 xds110_swd_queue_cmd(cmd, value);
1297 }
1298 static void xds110_swd_write_reg(uint8_t cmd, uint32_t value,
1299 uint32_t ap_delay_clk)
1300 {
1301 xds110_swd_queue_cmd(cmd, &value);
1302 }
1303
1304 /***************************************************************************
1305 * jtag interface *
1306 * *
1307 * The following functions provide XDS110 interface to OpenOCD. *
1308 ***************************************************************************/
1309
1310 static void xds110_show_info(void)
1311 {
1312 uint32_t firmware = xds110.firmware;
1313
1314 LOG_INFO("XDS110: firmware version = %d.%d.%d.%d",
1315 (((firmware >> 28) & 0xf) * 10) + ((firmware >> 24) & 0xf),
1316 (((firmware >> 20) & 0xf) * 10) + ((firmware >> 16) & 0xf),
1317 (((firmware >> 12) & 0xf) * 10) + ((firmware >> 8) & 0xf),
1318 (((firmware >> 4) & 0xf) * 10) + ((firmware >> 0) & 0xf));
1319 LOG_INFO("XDS110: hardware version = 0x%04x", xds110.hardware);
1320 if (0 != xds110.serial[0])
1321 LOG_INFO("XDS110: serial number = %s)", xds110.serial);
1322 if (xds110.is_swd_mode) {
1323 LOG_INFO("XDS110: connected to target via SWD");
1324 LOG_INFO("XDS110: SWCLK set to %d kHz", xds110.speed);
1325 } else {
1326 LOG_INFO("XDS110: connected to target via JTAG");
1327 LOG_INFO("XDS110: TCK set to %d kHz", xds110.speed);
1328 }
1329
1330 /* Alert user that there's a better firmware to use */
1331 if (firmware < OCD_FIRMWARE_VERSION) {
1332 LOG_WARNING("XDS110: the firmware is not optimized for OpenOCD");
1333 LOG_WARNING(OCD_FIRMWARE_UPGRADE);
1334 }
1335 }
1336
1337 static int xds110_quit(void)
1338 {
1339 if (xds110.is_cmapi_acquired) {
1340 (void)cmapi_release();
1341 xds110.is_cmapi_acquired = false;
1342 }
1343 if (xds110.is_cmapi_connected) {
1344 (void)cmapi_disconnect();
1345 xds110.is_cmapi_connected = false;
1346 }
1347 if (xds110.is_connected) {
1348 if (xds110.is_swd_mode) {
1349 /* Switch out of SWD mode */
1350 (void)swd_disconnect();
1351 } else {
1352 /* Switch out of cJTAG mode */
1353 (void)cjtag_disconnect();
1354 }
1355 /* Tell firmware we're disconnecting */
1356 (void)xds_disconnect();
1357 xds110.is_connected = false;
1358 }
1359 /* Close down the USB connection to the XDS110 debug probe */
1360 usb_disconnect();
1361
1362 return ERROR_OK;
1363 }
1364
1365 static int xds110_init(void)
1366 {
1367 bool success;
1368
1369 /* Establish USB connection to the XDS110 debug probe */
1370 success = usb_connect();
1371
1372 if (success) {
1373 /* Send connect message to XDS110 firmware */
1374 success = xds_connect();
1375 if (success)
1376 xds110.is_connected = true;
1377 }
1378
1379 if (success) {
1380 uint32_t firmware;
1381 uint16_t hardware;
1382
1383 /* Retrieve version IDs from firmware */
1384 /* Version numbers are stored in BCD format */
1385 success = xds_version(&firmware, &hardware);
1386 if (success) {
1387 /* Save the firmware and hardware version */
1388 xds110.firmware = firmware;
1389 xds110.hardware = hardware;
1390 }
1391 }
1392
1393 if (success) {
1394 success = xds_set_trst(0);
1395 if (success)
1396 success = xds_cycle_tck(50);
1397 if (success)
1398 success = xds_set_trst(1);
1399 if (success)
1400 success = xds_cycle_tck(50);
1401 }
1402
1403 if (success) {
1404 if (xds110.is_swd_mode) {
1405 /* Switch to SWD if needed */
1406 success = swd_connect();
1407 } else {
1408 success = cjtag_connect(MODE_JTAG);
1409 }
1410 }
1411
1412 if (success && xds110.is_swd_mode) {
1413 uint32_t idcode;
1414
1415 /* Connect to CMAPI interface in XDS110 */
1416 success = cmapi_connect(&idcode);
1417
1418 /* Acquire exclusive access to CMAPI interface */
1419 if (success) {
1420 xds110.is_cmapi_connected = true;
1421 success = cmapi_acquire();
1422 if (success)
1423 xds110.is_cmapi_acquired = true;
1424 }
1425 }
1426
1427 if (!success)
1428 xds110_quit();
1429
1430 if (success)
1431 xds110_show_info();
1432
1433 return (success) ? ERROR_OK : ERROR_FAIL;
1434 }
1435
1436 static void xds110_legacy_scan(uint32_t shift_state, uint32_t total_bits,
1437 uint32_t end_state, uint8_t *data_out, uint8_t *data_in)
1438 {
1439 (void)xds_jtag_scan(shift_state, total_bits, end_state, data_out, data_in);
1440 }
1441
1442 static void xds110_legacy_runtest(uint32_t clocks, uint32_t end_state)
1443 {
1444 xds_goto_state(XDS_JTAG_STATE_IDLE);
1445 xds_cycle_tck(clocks);
1446 xds_goto_state(end_state);
1447 }
1448
1449 static void xds110_legacy_stableclocks(uint32_t clocks)
1450 {
1451 xds_cycle_tck(clocks);
1452 }
1453
1454 static void xds110_flush(void)
1455 {
1456 uint8_t command;
1457 uint32_t clocks;
1458 uint32_t shift_state;
1459 uint32_t end_state;
1460 uint32_t bits;
1461 uint32_t bytes;
1462 uint32_t request;
1463 uint32_t result;
1464 uint8_t *data_out;
1465 uint8_t data_in[MAX_DATA_BLOCK];
1466 uint8_t *data_pntr;
1467
1468 if (0 == xds110.txn_request_size)
1469 return;
1470
1471 /* Terminate request queue */
1472 xds110.txn_requests[xds110.txn_request_size++] = 0;
1473
1474 if (xds110.firmware >= OCD_FIRMWARE_VERSION) {
1475 /* Updated firmware has the API to directly handle the queue */
1476 (void)ocd_scan_request(xds110.txn_requests, xds110.txn_request_size,
1477 data_in, xds110.txn_result_size);
1478 } else {
1479 /* Legacy firmware needs to handle queue via discrete JTAG calls */
1480 request = 0;
1481 result = 0;
1482 while (xds110.txn_requests[request] != 0) {
1483 command = xds110.txn_requests[request++];
1484 switch (command) {
1485 case CMD_IR_SCAN:
1486 case CMD_DR_SCAN:
1487 if (command == CMD_IR_SCAN)
1488 shift_state = XDS_JTAG_STATE_SHIFT_IR;
1489 else
1490 shift_state = XDS_JTAG_STATE_SHIFT_DR;
1491 end_state = (uint32_t)(xds110.txn_requests[request++]);
1492 bits = (uint32_t)(xds110.txn_requests[request++]) << 0;
1493 bits |= (uint32_t)(xds110.txn_requests[request++]) << 8;
1494 data_out = &xds110.txn_requests[request];
1495 bytes = DIV_ROUND_UP(bits, 8);
1496 xds110_legacy_scan(shift_state, bits, end_state, data_out,
1497 &data_in[result]);
1498 result += bytes;
1499 request += bytes;
1500 break;
1501 case CMD_RUNTEST:
1502 clocks = (uint32_t)(xds110.txn_requests[request++]) << 0;
1503 clocks |= (uint32_t)(xds110.txn_requests[request++]) << 8;
1504 clocks |= (uint32_t)(xds110.txn_requests[request++]) << 16;
1505 clocks |= (uint32_t)(xds110.txn_requests[request++]) << 24;
1506 end_state = (uint32_t)xds110.txn_requests[request++];
1507 xds110_legacy_runtest(clocks, end_state);
1508 break;
1509 case CMD_STABLECLOCKS:
1510 clocks = (uint32_t)(xds110.txn_requests[request++]) << 0;
1511 clocks |= (uint32_t)(xds110.txn_requests[request++]) << 8;
1512 clocks |= (uint32_t)(xds110.txn_requests[request++]) << 16;
1513 clocks |= (uint32_t)(xds110.txn_requests[request++]) << 24;
1514 xds110_legacy_stableclocks(clocks);
1515 break;
1516 default:
1517 LOG_ERROR("BUG: unknown JTAG command type 0x%x encountered",
1518 command);
1519 exit(-1);
1520 break;
1521 }
1522 }
1523 }
1524
1525 /* Transfer results into caller's buffers from data_in buffer */
1526 bits = 0; /* Bit offset into current scan result */
1527 data_pntr = data_in;
1528 for (result = 0; result < xds110.txn_result_count; result++) {
1529 if (xds110.txn_scan_results[result].first) {
1530 if (bits != 0) {
1531 bytes = DIV_ROUND_UP(bits, 8);
1532 data_pntr += bytes;
1533 }
1534 bits = 0;
1535 }
1536 if (xds110.txn_scan_results[result].buffer != 0)
1537 bit_copy(xds110.txn_scan_results[result].buffer, 0, data_pntr,
1538 bits, xds110.txn_scan_results[result].num_bits);
1539 bits += xds110.txn_scan_results[result].num_bits;
1540 }
1541
1542 xds110.txn_request_size = 0;
1543 xds110.txn_result_size = 0;
1544 xds110.txn_result_count = 0;
1545 }
1546
1547 static void xds110_execute_reset(struct jtag_command *cmd)
1548 {
1549 char trst;
1550 char srst;
1551
1552 if (cmd->cmd.reset->trst != -1) {
1553 if (cmd->cmd.reset->trst == 0) {
1554 /* Deassert nTRST (active low) */
1555 trst = 1;
1556 } else {
1557 /* Assert nTRST (active low) */
1558 trst = 0;
1559 }
1560 (void)xds_set_trst(trst);
1561 }
1562
1563 if (cmd->cmd.reset->srst != -1) {
1564 if (cmd->cmd.reset->srst == 0) {
1565 /* Deassert nSRST (active low) */
1566 srst = 1;
1567 } else {
1568 /* Assert nSRST (active low) */
1569 srst = 0;
1570 }
1571 (void)xds_set_srst(srst);
1572 }
1573 }
1574
1575 static void xds110_execute_sleep(struct jtag_command *cmd)
1576 {
1577 jtag_sleep(cmd->cmd.sleep->us);
1578 return;
1579 }
1580
1581 static void xds110_execute_tlr_reset(struct jtag_command *cmd)
1582 {
1583 (void)xds_goto_state(XDS_JTAG_STATE_RESET);
1584
1585 return;
1586 }
1587
1588 static void xds110_execute_pathmove(struct jtag_command *cmd)
1589 {
1590 uint32_t i;
1591 uint32_t num_states;
1592 uint8_t *path;
1593
1594 num_states = (uint32_t)cmd->cmd.pathmove->num_states;
1595
1596 if (num_states == 0)
1597 return;
1598
1599 path = (uint8_t *)malloc(num_states * sizeof(uint8_t));
1600 if (path == 0) {
1601 LOG_ERROR("XDS110: unable to allocate memory");
1602 return;
1603 }
1604
1605 /* Convert requested path states into XDS API states */
1606 for (i = 0; i < num_states; i++)
1607 path[i] = (uint8_t)xds_jtag_state[cmd->cmd.pathmove->path[i]];
1608
1609 if (xds110.firmware >= OCD_FIRMWARE_VERSION) {
1610 /* Updated firmware fully supports pathmove */
1611 (void)ocd_pathmove(num_states, path);
1612 } else {
1613 /* Notify user that legacy firmware simply cannot handle pathmove */
1614 LOG_ERROR("XDS110: the firmware does not support pathmove command");
1615 LOG_ERROR(OCD_FIRMWARE_UPGRADE);
1616 /* If pathmove is required, then debug is not possible */
1617 exit(-1);
1618 }
1619
1620 free((void *)path);
1621
1622 return;
1623 }
1624
1625 static void xds110_queue_scan(struct jtag_command *cmd)
1626 {
1627 int i;
1628 uint32_t offset;
1629 uint32_t total_fields;
1630 uint32_t total_bits;
1631 uint32_t total_bytes;
1632 uint8_t end_state;
1633 uint8_t *buffer;
1634
1635 /* Calculate the total number of bits to scan */
1636 total_bits = 0;
1637 total_fields = 0;
1638 for (i = 0; i < cmd->cmd.scan->num_fields; i++) {
1639 total_fields++;
1640 total_bits += (uint32_t)cmd->cmd.scan->fields[i].num_bits;
1641 }
1642
1643 if (total_bits == 0)
1644 return;
1645
1646 total_bytes = DIV_ROUND_UP(total_bits, 8);
1647
1648 /* Check if new request would be too large to fit */
1649 if (((xds110.txn_request_size + 1 + total_bytes + sizeof(end_state) + 1)
1650 > MAX_DATA_BLOCK) || ((xds110.txn_result_count + total_fields) >
1651 MAX_RESULT_QUEUE))
1652 xds110_flush();
1653
1654 /* Check if this single request is too large to fit */
1655 if ((1 + total_bytes + sizeof(end_state) + 1) > MAX_DATA_BLOCK) {
1656 LOG_ERROR("BUG: JTAG scan request is too large to handle (%d bits)",
1657 total_bits);
1658 /* Failing to run this scan mucks up debug on this target */
1659 exit(-1);
1660 }
1661
1662 if (cmd->cmd.scan->ir_scan)
1663 xds110.txn_requests[xds110.txn_request_size++] = CMD_IR_SCAN;
1664 else
1665 xds110.txn_requests[xds110.txn_request_size++] = CMD_DR_SCAN;
1666
1667 end_state = (uint8_t)xds_jtag_state[cmd->cmd.scan->end_state];
1668 xds110.txn_requests[xds110.txn_request_size++] = end_state;
1669
1670 xds110.txn_requests[xds110.txn_request_size++] = (total_bits >> 0) & 0xff;
1671 xds110.txn_requests[xds110.txn_request_size++] = (total_bits >> 8) & 0xff;
1672
1673 /* Build request data by flattening fields into single buffer */
1674 /* also populate the results array to return the results when run */
1675 offset = 0;
1676 buffer = &xds110.txn_requests[xds110.txn_request_size];
1677 /* Clear data out buffer to default value of all zeros */
1678 memset((void *)buffer, 0x00, total_bytes);
1679 for (i = 0; i < cmd->cmd.scan->num_fields; i++) {
1680 if (cmd->cmd.scan->fields[i].out_value != 0) {
1681 /* Copy over data to scan out into request buffer */
1682 bit_copy(buffer, offset, cmd->cmd.scan->fields[i].out_value, 0,
1683 cmd->cmd.scan->fields[i].num_bits);
1684 }
1685 offset += cmd->cmd.scan->fields[i].num_bits;
1686 xds110.txn_scan_results[xds110.txn_result_count].first = (i == 0);
1687 xds110.txn_scan_results[xds110.txn_result_count].num_bits =
1688 cmd->cmd.scan->fields[i].num_bits;
1689 xds110.txn_scan_results[xds110.txn_result_count++].buffer =
1690 cmd->cmd.scan->fields[i].in_value;
1691 }
1692 xds110.txn_request_size += total_bytes;
1693 xds110.txn_result_size += total_bytes;
1694
1695 return;
1696 }
1697
1698 static void xds110_queue_runtest(struct jtag_command *cmd)
1699 {
1700 uint32_t clocks = (uint32_t)cmd->cmd.stableclocks->num_cycles;
1701 uint8_t end_state = (uint8_t)xds_jtag_state[cmd->cmd.runtest->end_state];
1702
1703 /* Check if new request would be too large to fit */
1704 if ((xds110.txn_request_size + 1 + sizeof(clocks) + sizeof(end_state) + 1)
1705 > MAX_DATA_BLOCK)
1706 xds110_flush();
1707
1708 /* Queue request and cycle count directly to queue buffer */
1709 xds110.txn_requests[xds110.txn_request_size++] = CMD_RUNTEST;
1710 xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 0) & 0xff;
1711 xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 8) & 0xff;
1712 xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 16) & 0xff;
1713 xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 24) & 0xff;
1714 xds110.txn_requests[xds110.txn_request_size++] = end_state;
1715
1716 return;
1717 }
1718
1719 static void xds110_queue_stableclocks(struct jtag_command *cmd)
1720 {
1721 uint32_t clocks = (uint32_t)cmd->cmd.stableclocks->num_cycles;
1722
1723 /* Check if new request would be too large to fit */
1724 if ((xds110.txn_request_size + 1 + sizeof(clocks) + 1) > MAX_DATA_BLOCK)
1725 xds110_flush();
1726
1727 /* Queue request and cycle count directly to queue buffer */
1728 xds110.txn_requests[xds110.txn_request_size++] = CMD_STABLECLOCKS;
1729 xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 0) & 0xff;
1730 xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 8) & 0xff;
1731 xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 16) & 0xff;
1732 xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 24) & 0xff;
1733
1734 return;
1735 }
1736
1737 static void xds110_execute_command(struct jtag_command *cmd)
1738 {
1739 switch (cmd->type) {
1740 case JTAG_RESET:
1741 xds110_flush();
1742 xds110_execute_reset(cmd);
1743 break;
1744 case JTAG_SLEEP:
1745 xds110_flush();
1746 xds110_execute_sleep(cmd);
1747 break;
1748 case JTAG_TLR_RESET:
1749 xds110_flush();
1750 xds110_execute_tlr_reset(cmd);
1751 break;
1752 case JTAG_PATHMOVE:
1753 xds110_flush();
1754 xds110_execute_pathmove(cmd);
1755 break;
1756 case JTAG_SCAN:
1757 xds110_queue_scan(cmd);
1758 break;
1759 case JTAG_RUNTEST:
1760 xds110_queue_runtest(cmd);
1761 break;
1762 case JTAG_STABLECLOCKS:
1763 xds110_queue_stableclocks(cmd);
1764 break;
1765 case JTAG_TMS:
1766 default:
1767 LOG_ERROR("BUG: unknown JTAG command type 0x%x encountered",
1768 cmd->type);
1769 exit(-1);
1770 }
1771 }
1772
1773 static int xds110_execute_queue(void)
1774 {
1775 struct jtag_command *cmd = jtag_command_queue;
1776
1777 while (cmd != NULL) {
1778 xds110_execute_command(cmd);
1779 cmd = cmd->next;
1780 }
1781
1782 xds110_flush();
1783
1784 return ERROR_OK;
1785 }
1786
1787 static int xds110_speed(int speed)
1788 {
1789 bool success;
1790
1791 if (speed == 0) {
1792 LOG_INFO("XDS110: RTCK not supported");
1793 return ERROR_JTAG_NOT_IMPLEMENTED;
1794 }
1795
1796 if (speed > XDS110_MAX_TCK_SPEED) {
1797 LOG_INFO("XDS110: reduce speed request: %dkHz to %dkHz maximum",
1798 speed, XDS110_MAX_TCK_SPEED);
1799 speed = XDS110_MAX_TCK_SPEED;
1800 }
1801
1802 if (speed < XDS110_MIN_TCK_SPEED) {
1803 LOG_INFO("XDS110: increase speed request: %dkHz to %dkHz minimum",
1804 speed, XDS110_MIN_TCK_SPEED);
1805 speed = XDS110_MIN_TCK_SPEED;
1806 }
1807
1808 /* The default is the maximum frequency the XDS110 can support */
1809 uint32_t freq_to_use = XDS110_MAX_TCK_SPEED * 1000; /* Hz */
1810 uint32_t delay_count = 0;
1811
1812 if (XDS110_MAX_TCK_SPEED != speed) {
1813 freq_to_use = speed * 1000; /* Hz */
1814
1815 /* Calculate the delay count value */
1816 double one_giga = 1000000000;
1817 /* Get the pulse duration for the maximum frequency supported in ns */
1818 double max_freq_pulse_duration = one_giga /
1819 (XDS110_MAX_TCK_SPEED * 1000);
1820
1821 /* Convert frequency to pulse duration */
1822 double freq_to_pulse_width_in_ns = one_giga / freq_to_use;
1823
1824 /*
1825 * Start with the pulse duration for the maximum frequency. Keep
1826 * decrementing the time added by each count value till the requested
1827 * frequency pulse is less than the calculated value.
1828 */
1829 double current_value = max_freq_pulse_duration;
1830
1831 while (current_value < freq_to_pulse_width_in_ns) {
1832 current_value += XDS110_TCK_PULSE_INCREMENT;
1833 ++delay_count;
1834 }
1835
1836 /*
1837 * Determine which delay count yields the best match.
1838 * The one obtained above or one less.
1839 */
1840 if (delay_count) {
1841 double diff_freq_1 = freq_to_use -
1842 (one_giga / (max_freq_pulse_duration +
1843 (XDS110_TCK_PULSE_INCREMENT * delay_count)));
1844 double diff_freq_2 = (one_giga / (max_freq_pulse_duration +
1845 (XDS110_TCK_PULSE_INCREMENT * (delay_count - 1)))) -
1846 freq_to_use;
1847
1848 /* One less count value yields a better match */
1849 if (diff_freq_1 > diff_freq_2)
1850 --delay_count;
1851 }
1852 }
1853
1854 /* Send the delay count to the XDS110 firmware */
1855 success = xds_set_tck_delay(delay_count);
1856
1857 if (success) {
1858 xds110.delay_count = delay_count;
1859 xds110.speed = speed;
1860 }
1861
1862 return (success) ? ERROR_OK : ERROR_FAIL;
1863 }
1864
1865 static int xds110_speed_div(int speed, int *khz)
1866 {
1867 *khz = speed;
1868 return ERROR_OK;
1869 }
1870
1871 static int xds110_khz(int khz, int *jtag_speed)
1872 {
1873 *jtag_speed = khz;
1874 return ERROR_OK;
1875 }
1876
1877 static int_least32_t xds110_swd_frequency(int_least32_t hz)
1878 {
1879 if (hz > 0)
1880 xds110_speed(hz / 1000);
1881 return hz;
1882 }
1883
1884 COMMAND_HANDLER(xds110_handle_info_command)
1885 {
1886 xds110_show_info();
1887 return ERROR_OK;
1888 }
1889
1890 COMMAND_HANDLER(xds110_handle_serial_command)
1891 {
1892 wchar_t serial[XDS110_SERIAL_LEN + 1];
1893
1894 xds110.serial[0] = 0;
1895
1896 if (CMD_ARGC == 1) {
1897 size_t len = mbstowcs(0, CMD_ARGV[0], 0);
1898 if (len > XDS110_SERIAL_LEN) {
1899 LOG_ERROR("XDS110: serial number is limited to %d characters",
1900 XDS110_SERIAL_LEN);
1901 return ERROR_FAIL;
1902 }
1903 if ((size_t)-1 == mbstowcs(serial, CMD_ARGV[0], len + 1)) {
1904 LOG_ERROR("XDS110: unable to convert serial number");
1905 return ERROR_FAIL;
1906 }
1907
1908 for (uint32_t i = 0; i < len; i++)
1909 xds110.serial[i] = (char)serial[i];
1910
1911 xds110.serial[len] = 0;
1912 } else {
1913 LOG_ERROR("XDS110: expected exactly one argument to xds110_serial "
1914 "<serial-number>");
1915 return ERROR_FAIL;
1916 }
1917
1918 return ERROR_OK;
1919 }
1920
1921 static const struct command_registration xds110_subcommand_handlers[] = {
1922 {
1923 .name = "info",
1924 .handler = &xds110_handle_info_command,
1925 .mode = COMMAND_EXEC,
1926 .usage = "",
1927 .help = "show XDS110 info",
1928 },
1929 COMMAND_REGISTRATION_DONE
1930 };
1931
1932 static const struct command_registration xds110_command_handlers[] = {
1933 {
1934 .name = "xds110",
1935 .mode = COMMAND_ANY,
1936 .help = "perform XDS110 management",
1937 .usage = "<cmd>",
1938 .chain = xds110_subcommand_handlers,
1939 },
1940 {
1941 .name = "xds110_serial",
1942 .handler = &xds110_handle_serial_command,
1943 .mode = COMMAND_CONFIG,
1944 .help = "set the XDS110 probe serial number",
1945 .usage = "serial_string",
1946 },
1947 COMMAND_REGISTRATION_DONE
1948 };
1949
1950 static const struct swd_driver xds110_swd_driver = {
1951 .init = xds110_swd_init,
1952 .frequency = xds110_swd_frequency,
1953 .switch_seq = xds110_swd_switch_seq,
1954 .read_reg = xds110_swd_read_reg,
1955 .write_reg = xds110_swd_write_reg,
1956 .run = xds110_swd_run_queue,
1957 };
1958
1959 static const char * const xds110_transport[] = { "swd", "jtag", NULL };
1960
1961 struct jtag_interface xds110_interface = {
1962 .name = "xds110",
1963 .commands = xds110_command_handlers,
1964 .swd = &xds110_swd_driver,
1965 .transports = xds110_transport,
1966
1967 .execute_queue = xds110_execute_queue,
1968 .speed = xds110_speed,
1969 .speed_div = xds110_speed_div,
1970 .khz = xds110_khz,
1971 .init = xds110_init,
1972 .quit = xds110_quit,
1973 };

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)