Fix libusb-1.0.22 deprecated libusb_set_debug with libusb_set_option
[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 and disable debug messages */
369 (void)libusb_set_auto_detach_kernel_driver(dev, 1);
370 #if LIBUSB_API_VERSION >= 0x01000106
371 libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_NONE);
372 #else
373 libusb_set_debug(ctx, LIBUSB_LOG_LEVEL_NONE);
374 #endif
375 /* Claim the debug interface on the XDS110 */
376 result = libusb_claim_interface(dev, INTERFACE_DEBUG);
377 } else {
378 /* Couldn't find an XDS110, flag the error */
379 result = -1;
380 }
381
382 /* On an error, clean up what we can */
383 if (0 != result) {
384 if (NULL != dev) {
385 /* Release the debug and data interface on the XDS110 */
386 (void)libusb_release_interface(dev, INTERFACE_DEBUG);
387 libusb_close(dev);
388 }
389 if (NULL != ctx)
390 libusb_exit(ctx);
391 xds110.ctx = NULL;
392 xds110.dev = NULL;
393 }
394
395 /* Log the results */
396 if (0 == result)
397 LOG_INFO("XDS110: connected");
398 else
399 LOG_ERROR("XDS110: failed to connect");
400
401 return (0 == result) ? true : false;
402 }
403
404 static void usb_disconnect(void)
405 {
406 if (NULL != xds110.dev) {
407 /* Release the debug and data interface on the XDS110 */
408 (void)libusb_release_interface(xds110.dev, INTERFACE_DEBUG);
409 libusb_close(xds110.dev);
410 xds110.dev = NULL;
411 }
412 if (NULL != xds110.ctx) {
413 libusb_exit(xds110.ctx);
414 xds110.ctx = NULL;
415 }
416
417 LOG_INFO("XDS110: disconnected");
418 }
419
420 static bool usb_read(unsigned char *buffer, int size, int *bytes_read,
421 int timeout)
422 {
423 int result;
424
425 if (NULL == xds110.dev || NULL == buffer || NULL == bytes_read)
426 return false;
427
428 /* Force a non-zero timeout to prevent blocking */
429 if (0 == timeout)
430 timeout = DEFAULT_TIMEOUT;
431
432 result = libusb_bulk_transfer(xds110.dev, ENDPOINT_DEBUG_IN, buffer, size,
433 bytes_read, timeout);
434
435 return (0 == result) ? true : false;
436 }
437
438 static bool usb_write(unsigned char *buffer, int size, int *written)
439 {
440 int bytes_written = 0;
441 int result = LIBUSB_SUCCESS;
442 int retries = 0;
443
444 if (NULL == xds110.dev || NULL == buffer)
445 return false;
446
447 result = libusb_bulk_transfer(xds110.dev, ENDPOINT_DEBUG_OUT, buffer,
448 size, &bytes_written, 0);
449
450 while (LIBUSB_ERROR_PIPE == result && retries < 3) {
451 /* Try clearing the pipe stall and retry transfer */
452 libusb_clear_halt(xds110.dev, ENDPOINT_DEBUG_OUT);
453 result = libusb_bulk_transfer(xds110.dev, ENDPOINT_DEBUG_OUT, buffer,
454 size, &bytes_written, 0);
455 retries++;
456 }
457
458 if (NULL != written)
459 *written = bytes_written;
460
461 return (0 == result && size == bytes_written) ? true : false;
462 }
463
464 static bool usb_get_response(uint32_t *total_bytes_read, uint32_t timeout)
465 {
466 static unsigned char buffer[MAX_PACKET];
467 int bytes_read;
468 uint16_t size;
469 uint16_t count;
470 bool success;
471
472 size = 0;
473 success = true;
474 while (success) {
475 success = usb_read(buffer, sizeof(buffer), &bytes_read, timeout);
476 if (success) {
477 /*
478 * Validate that this appears to be a good response packet
479 * First check it contains enough data for header and error
480 * code, plus the first character is the start character
481 */
482 if (bytes_read >= 7 && '*' == buffer[0]) {
483 /* Extract the payload size */
484 size = xds110_get_u16(&buffer[1]);
485 /* Sanity test on payload size */
486 if (USB_PAYLOAD_SIZE >= size && 4 <= size) {
487 /* Check we didn't get more data than expected */
488 if ((bytes_read - 3) <= size) {
489 /* Packet appears to be valid, move on */
490 break;
491 }
492 }
493 }
494 }
495 /*
496 * Somehow received an invalid packet, retry till we
497 * time out or a valid response packet is received
498 */
499 }
500
501 /* Abort now if we didn't receive a valid response */
502 if (!success) {
503 if (NULL != total_bytes_read)
504 *total_bytes_read = 0;
505 return false;
506 }
507
508 /* Build the return payload into xds110.read_payload */
509
510 /* Copy over payload data from received buffer (skipping header) */
511 count = 0;
512 bytes_read -= 3;
513 memcpy((void *)&xds110.read_payload[count], (void *)&buffer[3], bytes_read);
514 count += bytes_read;
515 /*
516 * Drop timeout to just 1/2 second. Once the XDS110 starts sending
517 * a response, the remaining packets should arrive in short order
518 */
519 if (timeout > 500)
520 timeout = 500; /* ms */
521
522 /* If there's more data to retrieve, get it now */
523 while ((count < size) && success) {
524 success = usb_read(buffer, sizeof(buffer), &bytes_read, timeout);
525 if (success) {
526 if ((count + bytes_read) > size) {
527 /* Read too much data, not a valid packet, abort */
528 success = false;
529 } else {
530 /* Copy this data over to xds110.read_payload */
531 memcpy((void *)&xds110.read_payload[count], (void *)buffer,
532 bytes_read);
533 count += bytes_read;
534 }
535 }
536 }
537
538 if (!success)
539 count = 0;
540 if (NULL != total_bytes_read)
541 *total_bytes_read = count;
542
543 return success;
544 }
545
546 static bool usb_send_command(uint16_t size)
547 {
548 int written;
549 bool success = true;
550
551 /* Check the packet length */
552 if (size > USB_PAYLOAD_SIZE)
553 return false;
554
555 /* Place the start character into the packet buffer */
556 xds110.write_packet[0] = '*';
557
558 /* Place the payload size into the packet buffer */
559 xds110_set_u16(&xds110.write_packet[1], size);
560
561 /* Adjust size to include header */
562 size += 3;
563
564 /* Send the data via the USB connection */
565 success = usb_write(xds110.write_packet, (int)size, &written);
566
567 /* Check if the correct number of bytes was written */
568 if (written != (int)size)
569 success = false;
570
571 return success;
572 }
573
574 /***************************************************************************
575 * XDS110 firmware API routines *
576 * *
577 * The following functions handle calling into the XDS110 firmware to *
578 * perform requested debug actions. *
579 ***************************************************************************/
580
581 static bool xds_execute(uint32_t out_length, uint32_t in_length,
582 uint32_t attempts, uint32_t timeout)
583 {
584 bool done = false;
585 bool success = true;
586 int error = 0;
587 uint32_t bytes_read = 0;
588
589 if (NULL == xds110.dev)
590 return false;
591
592 while (!done && attempts > 0) {
593 attempts--;
594
595 /* Send command to XDS110 */
596 success = usb_send_command(out_length);
597
598 if (success) {
599 /* Get response from XDS110 */
600 success = usb_get_response(&bytes_read, timeout);
601 }
602
603 if (success) {
604 /* Check for valid response from XDS code handling */
605 if (bytes_read != in_length) {
606 /* Unexpected amount of data returned */
607 success = false;
608 } else {
609 /* Extract error code from return packet */
610 error = (int)xds110_get_u32(&xds110.read_payload[0]);
611 done = true;
612 }
613 }
614 }
615
616 if (!success)
617 error = SC_ERR_XDS110_FAIL;
618
619 if (0 != error)
620 success = false;
621
622 return success;
623 }
624
625 static bool xds_connect(void)
626 {
627 bool success;
628
629 xds110.write_payload[0] = XDS_CONNECT;
630
631 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,
632 DEFAULT_TIMEOUT);
633
634 return success;
635 }
636
637 static bool xds_disconnect(void)
638 {
639 bool success;
640
641 xds110.write_payload[0] = XDS_DISCONNECT;
642
643 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,
644 DEFAULT_TIMEOUT);
645
646 return success;
647 }
648
649 static bool xds_version(uint32_t *firmware_id, uint16_t *hardware_id)
650 {
651 uint8_t *fw_id_pntr = &xds110.read_payload[XDS_IN_LEN + 0]; /* 32-bits */
652 uint8_t *hw_id_pntr = &xds110.read_payload[XDS_IN_LEN + 4]; /* 16-bits */
653
654 bool success;
655
656 xds110.write_payload[0] = XDS_VERSION;
657
658 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN + 6, DEFAULT_ATTEMPTS,
659 DEFAULT_TIMEOUT);
660
661 if (success) {
662 if (NULL != firmware_id)
663 *firmware_id = xds110_get_u32(fw_id_pntr);
664 if (NULL != hardware_id)
665 *hardware_id = xds110_get_u16(hw_id_pntr);
666 }
667
668 return success;
669 }
670
671 static bool xds_set_tck_delay(uint32_t delay)
672 {
673 uint8_t *delay_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 32-bits */
674
675 bool success;
676
677 xds110.write_payload[0] = XDS_SET_TCK;
678
679 xds110_set_u32(delay_pntr, delay);
680
681 success = xds_execute(XDS_OUT_LEN + 4, XDS_IN_LEN, DEFAULT_ATTEMPTS,
682 DEFAULT_TIMEOUT);
683
684 return success;
685 }
686
687 static bool xds_set_trst(uint8_t trst)
688 {
689 uint8_t *trst_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 8-bits */
690
691 bool success;
692
693 xds110.write_payload[0] = XDS_SET_TRST;
694
695 *trst_pntr = trst;
696
697 success = xds_execute(XDS_OUT_LEN + 1, XDS_IN_LEN, DEFAULT_ATTEMPTS,
698 DEFAULT_TIMEOUT);
699
700 return success;
701 }
702
703 static bool xds_cycle_tck(uint32_t count)
704 {
705 uint8_t *count_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 32-bits */
706
707 bool success;
708
709 xds110.write_payload[0] = XDS_CYCLE_TCK;
710
711 xds110_set_u32(count_pntr, count);
712
713 success = xds_execute(XDS_OUT_LEN + 4, XDS_IN_LEN, DEFAULT_ATTEMPTS,
714 DEFAULT_TIMEOUT);
715
716 return success;
717 }
718
719 static bool xds_goto_state(uint32_t state)
720 {
721 uint8_t *state_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 32-bits */
722 uint8_t *transit_pntr = &xds110.write_payload[XDS_OUT_LEN+4]; /* 32-bits */
723
724 bool success;
725
726 xds110.write_payload[0] = XDS_GOTO_STATE;
727
728 xds110_set_u32(state_pntr, state);
729 xds110_set_u32(transit_pntr, XDS_JTAG_TRANSIT_QUICKEST);
730
731 success = xds_execute(XDS_OUT_LEN+8, XDS_IN_LEN, DEFAULT_ATTEMPTS,
732 DEFAULT_TIMEOUT);
733
734 return success;
735 }
736
737 static bool xds_jtag_scan(uint32_t shift_state, uint16_t shift_bits,
738 uint32_t end_state, uint8_t *data_out, uint8_t *data_in)
739 {
740 uint8_t *bits_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 16-bits */
741 uint8_t *path_pntr = &xds110.write_payload[XDS_OUT_LEN + 2]; /* 8-bits */
742 uint8_t *trans1_pntr = &xds110.write_payload[XDS_OUT_LEN + 3]; /* 8-bits */
743 uint8_t *end_pntr = &xds110.write_payload[XDS_OUT_LEN + 4]; /* 8-bits */
744 uint8_t *trans2_pntr = &xds110.write_payload[XDS_OUT_LEN + 5]; /* 8-bits */
745 uint8_t *pre_pntr = &xds110.write_payload[XDS_OUT_LEN + 6]; /* 16-bits */
746 uint8_t *pos_pntr = &xds110.write_payload[XDS_OUT_LEN + 8]; /* 16-bits */
747 uint8_t *delay_pntr = &xds110.write_payload[XDS_OUT_LEN + 10]; /* 16-bits */
748 uint8_t *rep_pntr = &xds110.write_payload[XDS_OUT_LEN + 12]; /* 16-bits */
749 uint8_t *out_pntr = &xds110.write_payload[XDS_OUT_LEN + 14]; /* 16-bits */
750 uint8_t *in_pntr = &xds110.write_payload[XDS_OUT_LEN + 16]; /* 16-bits */
751 uint8_t *data_out_pntr = &xds110.write_payload[XDS_OUT_LEN + 18];
752 uint8_t *data_in_pntr = &xds110.read_payload[XDS_IN_LEN+0];
753
754 uint16_t total_bytes = DIV_ROUND_UP(shift_bits, 8);
755
756 bool success;
757
758 xds110.write_payload[0] = XDS_JTAG_SCAN;
759
760 xds110_set_u16(bits_pntr, shift_bits); /* bits to scan */
761 *path_pntr = (uint8_t)(shift_state & 0xff); /* IR vs DR path */
762 *trans1_pntr = (uint8_t)XDS_JTAG_TRANSIT_QUICKEST; /* start state route */
763 *end_pntr = (uint8_t)(end_state & 0xff); /* JTAG state after scan */
764 *trans2_pntr = (uint8_t)XDS_JTAG_TRANSIT_QUICKEST; /* end state route */
765 xds110_set_u16(pre_pntr, 0); /* number of preamble bits */
766 xds110_set_u16(pos_pntr, 0); /* number of postamble bits */
767 xds110_set_u16(delay_pntr, 0); /* number of extra TCKs after scan */
768 xds110_set_u16(rep_pntr, 1); /* number of repetitions */
769 xds110_set_u16(out_pntr, total_bytes); /* out buffer offset (if repeats) */
770 xds110_set_u16(in_pntr, total_bytes); /* in buffer offset (if repeats) */
771
772 memcpy((void *)data_out_pntr, (void *)data_out, total_bytes);
773
774 success = xds_execute(XDS_OUT_LEN + 18 + total_bytes,
775 XDS_IN_LEN + total_bytes, DEFAULT_ATTEMPTS, DEFAULT_TIMEOUT);
776
777 if (success)
778 memcpy((void *)data_in, (void *)data_in_pntr, total_bytes);
779
780 return success;
781 }
782
783 static bool xds_set_srst(uint8_t srst)
784 {
785 uint8_t *srst_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 8-bits */
786
787 bool success;
788
789 xds110.write_payload[0] = XDS_SET_SRST;
790
791 *srst_pntr = srst;
792
793 success = xds_execute(XDS_OUT_LEN + 1, XDS_IN_LEN, DEFAULT_ATTEMPTS,
794 DEFAULT_TIMEOUT);
795
796 return success;
797 }
798
799 static bool cmapi_connect(uint32_t *idcode)
800 {
801 uint8_t *idcode_pntr = &xds110.read_payload[XDS_IN_LEN + 0]; /* 32-bits */
802
803 bool success;
804
805 xds110.write_payload[0] = CMAPI_CONNECT;
806
807 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN+4, DEFAULT_ATTEMPTS,
808 DEFAULT_TIMEOUT);
809
810 if (success) {
811 if (NULL != idcode)
812 *idcode = xds110_get_u32(idcode_pntr);
813 }
814
815 return success;
816 }
817
818 static bool cmapi_disconnect(void)
819 {
820 bool success;
821
822 xds110.write_payload[0] = CMAPI_DISCONNECT;
823
824 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,
825 DEFAULT_TIMEOUT);
826
827 return success;
828 }
829
830 static bool cmapi_acquire(void)
831 {
832 bool success;
833
834 xds110.write_payload[0] = CMAPI_ACQUIRE;
835
836 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,
837 DEFAULT_TIMEOUT);
838
839 return success;
840 }
841
842 static bool cmapi_release(void)
843 {
844 bool success;
845
846 xds110.write_payload[0] = CMAPI_RELEASE;
847
848 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,
849 DEFAULT_TIMEOUT);
850
851 return success;
852 }
853
854 static bool cmapi_read_dap_reg(uint32_t type, uint32_t ap_num,
855 uint32_t address, uint32_t *value)
856 {
857 uint8_t *type_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 8-bits */
858 uint8_t *ap_num_pntr = &xds110.write_payload[XDS_OUT_LEN + 1]; /* 8-bits */
859 uint8_t *address_pntr = &xds110.write_payload[XDS_OUT_LEN + 2]; /* 8-bits */
860 uint8_t *value_pntr = &xds110.read_payload[XDS_IN_LEN + 0]; /* 32-bits */
861
862 bool success;
863
864 xds110.write_payload[0] = CMAPI_REG_READ;
865
866 *type_pntr = (uint8_t)(type & 0xff);
867 *ap_num_pntr = (uint8_t)(ap_num & 0xff);
868 *address_pntr = (uint8_t)(address & 0xff);
869
870 success = xds_execute(XDS_OUT_LEN + 3, XDS_IN_LEN + 4, DEFAULT_ATTEMPTS,
871 DEFAULT_TIMEOUT);
872
873 if (success) {
874 if (NULL != value)
875 *value = xds110_get_u32(value_pntr);
876 }
877
878 return success;
879 }
880
881 static bool cmapi_write_dap_reg(uint32_t type, uint32_t ap_num,
882 uint32_t address, uint32_t *value)
883 {
884 uint8_t *type_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 8-bits */
885 uint8_t *ap_num_pntr = &xds110.write_payload[XDS_OUT_LEN + 1]; /* 8-bits */
886 uint8_t *address_pntr = &xds110.write_payload[XDS_OUT_LEN + 2]; /* 8-bits */
887 uint8_t *value_pntr = &xds110.write_payload[XDS_OUT_LEN + 3]; /* 32-bits */
888
889 bool success;
890
891 if (NULL == value)
892 return false;
893
894 xds110.write_payload[0] = CMAPI_REG_WRITE;
895
896 *type_pntr = (uint8_t)(type & 0xff);
897 *ap_num_pntr = (uint8_t)(ap_num & 0xff);
898 *address_pntr = (uint8_t)(address & 0xff);
899 xds110_set_u32(value_pntr, *value);
900
901 success = xds_execute(XDS_OUT_LEN + 7, XDS_IN_LEN, DEFAULT_ATTEMPTS,
902 DEFAULT_TIMEOUT);
903
904 return success;
905 }
906
907 static bool swd_connect(void)
908 {
909 bool success;
910
911 xds110.write_payload[0] = SWD_CONNECT;
912
913 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,
914 DEFAULT_TIMEOUT);
915
916 return success;
917 }
918
919 static bool swd_disconnect(void)
920 {
921 bool success;
922
923 xds110.write_payload[0] = SWD_DISCONNECT;
924
925 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,
926 DEFAULT_TIMEOUT);
927
928 return success;
929 }
930
931 static bool cjtag_connect(uint32_t format)
932 {
933 uint8_t *format_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 32-bits */
934
935 bool success;
936
937 xds110.write_payload[0] = CJTAG_CONNECT;
938
939 xds110_set_u32(format_pntr, format);
940
941 success = xds_execute(XDS_OUT_LEN + 4, XDS_IN_LEN, DEFAULT_ATTEMPTS,
942 DEFAULT_TIMEOUT);
943
944 return success;
945 }
946
947 static bool cjtag_disconnect(void)
948 {
949 bool success;
950
951 xds110.write_payload[0] = CJTAG_DISCONNECT;
952
953 success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,
954 DEFAULT_TIMEOUT);
955
956 return success;
957 }
958
959 static bool ocd_dap_request(uint8_t *dap_requests, uint32_t request_size,
960 uint32_t *dap_results, uint32_t result_count)
961 {
962 uint8_t *request_pntr = &xds110.write_payload[XDS_OUT_LEN + 0];
963 uint8_t *result_pntr = &xds110.read_payload[XDS_IN_LEN + 0];
964
965 bool success;
966
967 if (NULL == dap_requests || NULL == dap_results)
968 return false;
969
970 xds110.write_payload[0] = OCD_DAP_REQUEST;
971
972 memcpy((void *)request_pntr, (void *)dap_requests, request_size);
973
974 success = xds_execute(XDS_OUT_LEN + request_size,
975 XDS_IN_LEN + (result_count * 4), DEFAULT_ATTEMPTS,
976 DEFAULT_TIMEOUT);
977
978 if (success && (result_count > 0))
979 memcpy((void *)dap_results, (void *)result_pntr, result_count * 4);
980
981 return success;
982 }
983
984 static bool ocd_scan_request(uint8_t *scan_requests, uint32_t request_size,
985 uint8_t *scan_results, uint32_t result_size)
986 {
987 uint8_t *request_pntr = &xds110.write_payload[XDS_OUT_LEN + 0];
988 uint8_t *result_pntr = &xds110.read_payload[XDS_IN_LEN + 0];
989
990 bool success;
991
992 if (NULL == scan_requests || NULL == scan_results)
993 return false;
994
995 xds110.write_payload[0] = OCD_SCAN_REQUEST;
996
997 memcpy((void *)request_pntr, (void *)scan_requests, request_size);
998
999 success = xds_execute(XDS_OUT_LEN + request_size,
1000 XDS_IN_LEN + result_size, DEFAULT_ATTEMPTS,
1001 DEFAULT_TIMEOUT);
1002
1003 if (success && (result_size > 0))
1004 memcpy((void *)scan_results, (void *)result_pntr, result_size);
1005
1006 return success;
1007 }
1008
1009 static bool ocd_pathmove(uint32_t num_states, uint8_t *path)
1010 {
1011 uint8_t *num_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 32-bits */
1012 uint8_t *path_pntr = &xds110.write_payload[XDS_OUT_LEN + 4];
1013
1014 bool success;
1015
1016 if (NULL == path)
1017 return false;
1018
1019 xds110.write_payload[0] = OCD_PATHMOVE;
1020
1021 xds110_set_u32(num_pntr, num_states);
1022
1023 memcpy((void *)path_pntr, (void *)path, num_states);
1024
1025 success = xds_execute(XDS_OUT_LEN + 4 + num_states, XDS_IN_LEN,
1026 DEFAULT_ATTEMPTS, DEFAULT_TIMEOUT);
1027
1028 return success;
1029 }
1030
1031 /***************************************************************************
1032 * swd driver interface *
1033 * *
1034 * The following functions provide SWD support to OpenOCD. *
1035 ***************************************************************************/
1036
1037 static int xds110_swd_init(void)
1038 {
1039 xds110.is_swd_mode = true;
1040 return ERROR_OK;
1041 }
1042
1043 static int xds110_swd_switch_seq(enum swd_special_seq seq)
1044 {
1045 uint32_t idcode;
1046 bool success;
1047
1048 switch (seq) {
1049 case LINE_RESET:
1050 LOG_ERROR("Sequence SWD line reset (%d) not supported", seq);
1051 return ERROR_FAIL;
1052 case JTAG_TO_SWD:
1053 LOG_DEBUG("JTAG-to-SWD");
1054 xds110.is_swd_mode = false;
1055 xds110.is_cmapi_connected = false;
1056 xds110.is_cmapi_acquired = false;
1057 /* Run sequence to put target in SWD mode */
1058 success = swd_connect();
1059 /* Re-iniitialize CMAPI API for DAP access */
1060 if (success) {
1061 xds110.is_swd_mode = true;
1062 success = cmapi_connect(&idcode);
1063 if (success) {
1064 xds110.is_cmapi_connected = true;
1065 success = cmapi_acquire();
1066 }
1067 }
1068 break;
1069 case SWD_TO_JTAG:
1070 LOG_DEBUG("SWD-to-JTAG");
1071 xds110.is_swd_mode = false;
1072 xds110.is_cmapi_connected = false;
1073 xds110.is_cmapi_acquired = false;
1074 /* Run sequence to put target in JTAG mode */
1075 success = swd_disconnect();
1076 if (success) {
1077 /* Re-initialize JTAG interface */
1078 success = cjtag_connect(MODE_JTAG);
1079 }
1080 break;
1081 default:
1082 LOG_ERROR("Sequence %d not supported", seq);
1083 return ERROR_FAIL;
1084 }
1085
1086 if (success)
1087 return ERROR_OK;
1088 else
1089 return ERROR_FAIL;
1090 }
1091
1092 static bool xds110_legacy_read_reg(uint8_t cmd, uint32_t *value)
1093 {
1094 /* Make sure this is a read request */
1095 bool is_read_request = (0 != (SWD_CMD_RnW & cmd));
1096 /* Determine whether this is a DP or AP register access */
1097 uint32_t type = (0 != (SWD_CMD_APnDP & cmd)) ? DAP_AP : DAP_DP;
1098 /* Determine the AP number from cached SELECT value */
1099 uint32_t ap_num = (xds110.select & 0xff000000) >> 24;
1100 /* Extract register address from command */
1101 uint32_t address = ((cmd & SWD_CMD_A32) >> 1);
1102 /* Extract bank address from cached SELECT value */
1103 uint32_t bank = (xds110.select & 0x000000f0);
1104
1105 uint32_t reg_value = 0;
1106 uint32_t temp_value = 0;
1107
1108 bool success;
1109
1110 if (!is_read_request)
1111 return false;
1112
1113 if (DAP_AP == type) {
1114 /* Add bank address to register address for CMAPI call */
1115 address |= bank;
1116 }
1117
1118 if (DAP_DP == type && DAP_DP_RDBUFF == address && xds110.use_rdbuff) {
1119 /* If RDBUFF is cached and this is a DP RDBUFF read, use the cache */
1120 reg_value = xds110.rdbuff;
1121 success = true;
1122 } else if (DAP_AP == type && DAP_AP_DRW == address && xds110.use_rdbuff) {
1123 /* If RDBUFF is cached and this is an AP DRW read, use the cache, */
1124 /* but still call into the firmware to get the next read. */
1125 reg_value = xds110.rdbuff;
1126 success = cmapi_read_dap_reg(type, ap_num, address, &temp_value);
1127 } else {
1128 success = cmapi_read_dap_reg(type, ap_num, address, &temp_value);
1129 if (success)
1130 reg_value = temp_value;
1131 }
1132
1133 /* Mark that we have consumed or invalidated the RDBUFF cache */
1134 xds110.use_rdbuff = false;
1135
1136 /* Handle result of read attempt */
1137 if (!success)
1138 LOG_ERROR("XDS110: failed to read DAP register");
1139 else if (NULL != value)
1140 *value = reg_value;
1141
1142 if (success && DAP_AP == type) {
1143 /*
1144 * On a successful DAP AP read, we actually have the value from RDBUFF,
1145 * the firmware will have run the AP request and made the RDBUFF read
1146 */
1147 xds110.use_rdbuff = true;
1148 xds110.rdbuff = temp_value;
1149 }
1150
1151 return success;
1152 }
1153
1154 static bool xds110_legacy_write_reg(uint8_t cmd, uint32_t value)
1155 {
1156 /* Make sure this isn't a read request */
1157 bool is_read_request = (0 != (SWD_CMD_RnW & cmd));
1158 /* Determine whether this is a DP or AP register access */
1159 uint32_t type = (0 != (SWD_CMD_APnDP & cmd)) ? DAP_AP : DAP_DP;
1160 /* Determine the AP number from cached SELECT value */
1161 uint32_t ap_num = (xds110.select & 0xff000000) >> 24;
1162 /* Extract register address from command */
1163 uint32_t address = ((cmd & SWD_CMD_A32) >> 1);
1164 /* Extract bank address from cached SELECT value */
1165 uint32_t bank = (xds110.select & 0x000000f0);
1166
1167 bool success;
1168
1169 if (is_read_request)
1170 return false;
1171
1172 /* Invalidate the RDBUFF cache */
1173 xds110.use_rdbuff = false;
1174
1175 if (DAP_AP == type) {
1176 /* Add bank address to register address for CMAPI call */
1177 address |= bank;
1178 /* Any write to an AP register invalidates the firmware's cache */
1179 xds110.is_ap_dirty = true;
1180 } else if (DAP_DP_SELECT == address) {
1181 /* Any write to the SELECT register invalidates the firmware's cache */
1182 xds110.is_ap_dirty = true;
1183 }
1184
1185 success = cmapi_write_dap_reg(type, ap_num, address, &value);
1186
1187 if (!success) {
1188 LOG_ERROR("XDS110: failed to write DAP register");
1189 } else {
1190 /*
1191 * If the debugger wrote to SELECT, cache the value
1192 * to use to build the apNum and address values above
1193 */
1194 if ((DAP_DP == type) && (DAP_DP_SELECT == address))
1195 xds110.select = value;
1196 }
1197
1198 return success;
1199 }
1200
1201 static int xds110_swd_run_queue(void)
1202 {
1203 static uint32_t dap_results[MAX_RESULT_QUEUE];
1204 uint8_t cmd;
1205 uint32_t request;
1206 uint32_t result;
1207 uint32_t value;
1208 bool success = true;
1209
1210 if (0 == xds110.txn_request_size)
1211 return ERROR_OK;
1212
1213 /* Terminate request queue */
1214 xds110.txn_requests[xds110.txn_request_size++] = 0;
1215
1216 if (xds110.firmware >= OCD_FIRMWARE_VERSION) {
1217 /* XDS110 firmware has the API to directly handle the queue */
1218 success = ocd_dap_request(xds110.txn_requests,
1219 xds110.txn_request_size, dap_results, xds110.txn_result_count);
1220 } else {
1221 /* Legacy firmware needs to handle queue via discrete DAP calls */
1222 request = 0;
1223 result = 0;
1224 while (xds110.txn_requests[request] != 0) {
1225 cmd = xds110.txn_requests[request++];
1226 if (0 == (SWD_CMD_RnW & cmd)) {
1227 /* DAP register write command */
1228 value = (uint32_t)(xds110.txn_requests[request++]) << 0;
1229 value |= (uint32_t)(xds110.txn_requests[request++]) << 8;
1230 value |= (uint32_t)(xds110.txn_requests[request++]) << 16;
1231 value |= (uint32_t)(xds110.txn_requests[request++]) << 24;
1232 if (success)
1233 success = xds110_legacy_write_reg(cmd, value);
1234 } else {
1235 /* DAP register read command */
1236 value = 0;
1237 if (success)
1238 success = xds110_legacy_read_reg(cmd, &value);
1239 dap_results[result++] = value;
1240 }
1241 }
1242 }
1243
1244 /* Transfer results into caller's buffers */
1245 for (result = 0; result < xds110.txn_result_count; result++)
1246 if (0 != xds110.txn_dap_results[result])
1247 *xds110.txn_dap_results[result] = dap_results[result];
1248
1249 xds110.txn_request_size = 0;
1250 xds110.txn_result_size = 0;
1251 xds110.txn_result_count = 0;
1252
1253 return (success) ? ERROR_OK : ERROR_FAIL;
1254 }
1255
1256 static void xds110_swd_queue_cmd(uint8_t cmd, uint32_t *value)
1257 {
1258 /* Check if this is a read or write request */
1259 bool is_read_request = (0 != (SWD_CMD_RnW & cmd));
1260 /* Determine whether this is a DP or AP register access */
1261 uint32_t type = (0 != (SWD_CMD_APnDP & cmd)) ? DAP_AP : DAP_DP;
1262 /* Extract register address from command */
1263 uint32_t address = ((cmd & SWD_CMD_A32) >> 1);
1264 uint32_t request_size = (is_read_request) ? 1 : 5;
1265
1266 /* Check if new request would be too large to fit */
1267 if (((xds110.txn_request_size + request_size + 1) > MAX_DATA_BLOCK) ||
1268 ((xds110.txn_result_count + 1) > MAX_RESULT_QUEUE))
1269 xds110_swd_run_queue();
1270
1271 /* Set the START bit in cmd to ensure cmd is not zero */
1272 /* (a value of zero is used to terminate the buffer) */
1273 cmd |= SWD_CMD_START;
1274
1275 /* Add request to queue; queue is built marshalled for XDS110 call */
1276 if (is_read_request) {
1277 /* Queue read request, save pointer to pass back result */
1278 xds110.txn_requests[xds110.txn_request_size++] = cmd;
1279 xds110.txn_dap_results[xds110.txn_result_count++] = value;
1280 xds110.txn_result_size += 4;
1281 } else {
1282 /* Check for and prevent sticky overrun detection */
1283 if (DAP_DP == type && DAP_DP_CTRL == address &&
1284 (*value & CORUNDETECT)) {
1285 LOG_DEBUG("XDS110: refusing to enable sticky overrun detection");
1286 *value &= ~CORUNDETECT;
1287 }
1288 /* Queue write request, add value directly to queue buffer */
1289 xds110.txn_requests[xds110.txn_request_size++] = cmd;
1290 xds110.txn_requests[xds110.txn_request_size++] = (*value >> 0) & 0xff;
1291 xds110.txn_requests[xds110.txn_request_size++] = (*value >> 8) & 0xff;
1292 xds110.txn_requests[xds110.txn_request_size++] = (*value >> 16) & 0xff;
1293 xds110.txn_requests[xds110.txn_request_size++] = (*value >> 24) & 0xff;
1294 }
1295 }
1296
1297 static void xds110_swd_read_reg(uint8_t cmd, uint32_t *value,
1298 uint32_t ap_delay_clk)
1299 {
1300 xds110_swd_queue_cmd(cmd, value);
1301 }
1302 static void xds110_swd_write_reg(uint8_t cmd, uint32_t value,
1303 uint32_t ap_delay_clk)
1304 {
1305 xds110_swd_queue_cmd(cmd, &value);
1306 }
1307
1308 /***************************************************************************
1309 * jtag interface *
1310 * *
1311 * The following functions provide XDS110 interface to OpenOCD. *
1312 ***************************************************************************/
1313
1314 static void xds110_show_info(void)
1315 {
1316 uint32_t firmware = xds110.firmware;
1317
1318 LOG_INFO("XDS110: firmware version = %d.%d.%d.%d",
1319 (((firmware >> 28) & 0xf) * 10) + ((firmware >> 24) & 0xf),
1320 (((firmware >> 20) & 0xf) * 10) + ((firmware >> 16) & 0xf),
1321 (((firmware >> 12) & 0xf) * 10) + ((firmware >> 8) & 0xf),
1322 (((firmware >> 4) & 0xf) * 10) + ((firmware >> 0) & 0xf));
1323 LOG_INFO("XDS110: hardware version = 0x%04x", xds110.hardware);
1324 if (0 != xds110.serial[0])
1325 LOG_INFO("XDS110: serial number = %s)", xds110.serial);
1326 if (xds110.is_swd_mode) {
1327 LOG_INFO("XDS110: connected to target via SWD");
1328 LOG_INFO("XDS110: SWCLK set to %d kHz", xds110.speed);
1329 } else {
1330 LOG_INFO("XDS110: connected to target via JTAG");
1331 LOG_INFO("XDS110: TCK set to %d kHz", xds110.speed);
1332 }
1333
1334 /* Alert user that there's a better firmware to use */
1335 if (firmware < OCD_FIRMWARE_VERSION) {
1336 LOG_WARNING("XDS110: the firmware is not optimized for OpenOCD");
1337 LOG_WARNING(OCD_FIRMWARE_UPGRADE);
1338 }
1339 }
1340
1341 static int xds110_quit(void)
1342 {
1343 if (xds110.is_cmapi_acquired) {
1344 (void)cmapi_release();
1345 xds110.is_cmapi_acquired = false;
1346 }
1347 if (xds110.is_cmapi_connected) {
1348 (void)cmapi_disconnect();
1349 xds110.is_cmapi_connected = false;
1350 }
1351 if (xds110.is_connected) {
1352 if (xds110.is_swd_mode) {
1353 /* Switch out of SWD mode */
1354 (void)swd_disconnect();
1355 } else {
1356 /* Switch out of cJTAG mode */
1357 (void)cjtag_disconnect();
1358 }
1359 /* Tell firmware we're disconnecting */
1360 (void)xds_disconnect();
1361 xds110.is_connected = false;
1362 }
1363 /* Close down the USB connection to the XDS110 debug probe */
1364 usb_disconnect();
1365
1366 return ERROR_OK;
1367 }
1368
1369 static int xds110_init(void)
1370 {
1371 bool success;
1372
1373 /* Establish USB connection to the XDS110 debug probe */
1374 success = usb_connect();
1375
1376 if (success) {
1377 /* Send connect message to XDS110 firmware */
1378 success = xds_connect();
1379 if (success)
1380 xds110.is_connected = true;
1381 }
1382
1383 if (success) {
1384 uint32_t firmware;
1385 uint16_t hardware;
1386
1387 /* Retrieve version IDs from firmware */
1388 /* Version numbers are stored in BCD format */
1389 success = xds_version(&firmware, &hardware);
1390 if (success) {
1391 /* Save the firmware and hardware version */
1392 xds110.firmware = firmware;
1393 xds110.hardware = hardware;
1394 }
1395 }
1396
1397 if (success) {
1398 success = xds_set_trst(0);
1399 if (success)
1400 success = xds_cycle_tck(50);
1401 if (success)
1402 success = xds_set_trst(1);
1403 if (success)
1404 success = xds_cycle_tck(50);
1405 }
1406
1407 if (success) {
1408 if (xds110.is_swd_mode) {
1409 /* Switch to SWD if needed */
1410 success = swd_connect();
1411 } else {
1412 success = cjtag_connect(MODE_JTAG);
1413 }
1414 }
1415
1416 if (success && xds110.is_swd_mode) {
1417 uint32_t idcode;
1418
1419 /* Connect to CMAPI interface in XDS110 */
1420 success = cmapi_connect(&idcode);
1421
1422 /* Acquire exclusive access to CMAPI interface */
1423 if (success) {
1424 xds110.is_cmapi_connected = true;
1425 success = cmapi_acquire();
1426 if (success)
1427 xds110.is_cmapi_acquired = true;
1428 }
1429 }
1430
1431 if (!success)
1432 xds110_quit();
1433
1434 if (success)
1435 xds110_show_info();
1436
1437 return (success) ? ERROR_OK : ERROR_FAIL;
1438 }
1439
1440 static void xds110_legacy_scan(uint32_t shift_state, uint32_t total_bits,
1441 uint32_t end_state, uint8_t *data_out, uint8_t *data_in)
1442 {
1443 (void)xds_jtag_scan(shift_state, total_bits, end_state, data_out, data_in);
1444 }
1445
1446 static void xds110_legacy_runtest(uint32_t clocks, uint32_t end_state)
1447 {
1448 xds_goto_state(XDS_JTAG_STATE_IDLE);
1449 xds_cycle_tck(clocks);
1450 xds_goto_state(end_state);
1451 }
1452
1453 static void xds110_legacy_stableclocks(uint32_t clocks)
1454 {
1455 xds_cycle_tck(clocks);
1456 }
1457
1458 static void xds110_flush(void)
1459 {
1460 uint8_t command;
1461 uint32_t clocks;
1462 uint32_t shift_state;
1463 uint32_t end_state;
1464 uint32_t bits;
1465 uint32_t bytes;
1466 uint32_t request;
1467 uint32_t result;
1468 uint8_t *data_out;
1469 uint8_t data_in[MAX_DATA_BLOCK];
1470 uint8_t *data_pntr;
1471
1472 if (0 == xds110.txn_request_size)
1473 return;
1474
1475 /* Terminate request queue */
1476 xds110.txn_requests[xds110.txn_request_size++] = 0;
1477
1478 if (xds110.firmware >= OCD_FIRMWARE_VERSION) {
1479 /* Updated firmware has the API to directly handle the queue */
1480 (void)ocd_scan_request(xds110.txn_requests, xds110.txn_request_size,
1481 data_in, xds110.txn_result_size);
1482 } else {
1483 /* Legacy firmware needs to handle queue via discrete JTAG calls */
1484 request = 0;
1485 result = 0;
1486 while (xds110.txn_requests[request] != 0) {
1487 command = xds110.txn_requests[request++];
1488 switch (command) {
1489 case CMD_IR_SCAN:
1490 case CMD_DR_SCAN:
1491 if (command == CMD_IR_SCAN)
1492 shift_state = XDS_JTAG_STATE_SHIFT_IR;
1493 else
1494 shift_state = XDS_JTAG_STATE_SHIFT_DR;
1495 end_state = (uint32_t)(xds110.txn_requests[request++]);
1496 bits = (uint32_t)(xds110.txn_requests[request++]) << 0;
1497 bits |= (uint32_t)(xds110.txn_requests[request++]) << 8;
1498 data_out = &xds110.txn_requests[request];
1499 bytes = DIV_ROUND_UP(bits, 8);
1500 xds110_legacy_scan(shift_state, bits, end_state, data_out,
1501 &data_in[result]);
1502 result += bytes;
1503 request += bytes;
1504 break;
1505 case CMD_RUNTEST:
1506 clocks = (uint32_t)(xds110.txn_requests[request++]) << 0;
1507 clocks |= (uint32_t)(xds110.txn_requests[request++]) << 8;
1508 clocks |= (uint32_t)(xds110.txn_requests[request++]) << 16;
1509 clocks |= (uint32_t)(xds110.txn_requests[request++]) << 24;
1510 end_state = (uint32_t)xds110.txn_requests[request++];
1511 xds110_legacy_runtest(clocks, end_state);
1512 break;
1513 case CMD_STABLECLOCKS:
1514 clocks = (uint32_t)(xds110.txn_requests[request++]) << 0;
1515 clocks |= (uint32_t)(xds110.txn_requests[request++]) << 8;
1516 clocks |= (uint32_t)(xds110.txn_requests[request++]) << 16;
1517 clocks |= (uint32_t)(xds110.txn_requests[request++]) << 24;
1518 xds110_legacy_stableclocks(clocks);
1519 break;
1520 default:
1521 LOG_ERROR("BUG: unknown JTAG command type 0x%x encountered",
1522 command);
1523 exit(-1);
1524 break;
1525 }
1526 }
1527 }
1528
1529 /* Transfer results into caller's buffers from data_in buffer */
1530 bits = 0; /* Bit offset into current scan result */
1531 data_pntr = data_in;
1532 for (result = 0; result < xds110.txn_result_count; result++) {
1533 if (xds110.txn_scan_results[result].first) {
1534 if (bits != 0) {
1535 bytes = DIV_ROUND_UP(bits, 8);
1536 data_pntr += bytes;
1537 }
1538 bits = 0;
1539 }
1540 if (xds110.txn_scan_results[result].buffer != 0)
1541 bit_copy(xds110.txn_scan_results[result].buffer, 0, data_pntr,
1542 bits, xds110.txn_scan_results[result].num_bits);
1543 bits += xds110.txn_scan_results[result].num_bits;
1544 }
1545
1546 xds110.txn_request_size = 0;
1547 xds110.txn_result_size = 0;
1548 xds110.txn_result_count = 0;
1549 }
1550
1551 static void xds110_execute_reset(struct jtag_command *cmd)
1552 {
1553 char trst;
1554 char srst;
1555
1556 if (cmd->cmd.reset->trst != -1) {
1557 if (cmd->cmd.reset->trst == 0) {
1558 /* Deassert nTRST (active low) */
1559 trst = 1;
1560 } else {
1561 /* Assert nTRST (active low) */
1562 trst = 0;
1563 }
1564 (void)xds_set_trst(trst);
1565 }
1566
1567 if (cmd->cmd.reset->srst != -1) {
1568 if (cmd->cmd.reset->srst == 0) {
1569 /* Deassert nSRST (active low) */
1570 srst = 1;
1571 } else {
1572 /* Assert nSRST (active low) */
1573 srst = 0;
1574 }
1575 (void)xds_set_srst(srst);
1576 }
1577 }
1578
1579 static void xds110_execute_sleep(struct jtag_command *cmd)
1580 {
1581 jtag_sleep(cmd->cmd.sleep->us);
1582 return;
1583 }
1584
1585 static void xds110_execute_tlr_reset(struct jtag_command *cmd)
1586 {
1587 (void)xds_goto_state(XDS_JTAG_STATE_RESET);
1588
1589 return;
1590 }
1591
1592 static void xds110_execute_pathmove(struct jtag_command *cmd)
1593 {
1594 uint32_t i;
1595 uint32_t num_states;
1596 uint8_t *path;
1597
1598 num_states = (uint32_t)cmd->cmd.pathmove->num_states;
1599
1600 if (num_states == 0)
1601 return;
1602
1603 path = (uint8_t *)malloc(num_states * sizeof(uint8_t));
1604 if (path == 0) {
1605 LOG_ERROR("XDS110: unable to allocate memory");
1606 return;
1607 }
1608
1609 /* Convert requested path states into XDS API states */
1610 for (i = 0; i < num_states; i++)
1611 path[i] = (uint8_t)xds_jtag_state[cmd->cmd.pathmove->path[i]];
1612
1613 if (xds110.firmware >= OCD_FIRMWARE_VERSION) {
1614 /* Updated firmware fully supports pathmove */
1615 (void)ocd_pathmove(num_states, path);
1616 } else {
1617 /* Notify user that legacy firmware simply cannot handle pathmove */
1618 LOG_ERROR("XDS110: the firmware does not support pathmove command");
1619 LOG_ERROR(OCD_FIRMWARE_UPGRADE);
1620 /* If pathmove is required, then debug is not possible */
1621 exit(-1);
1622 }
1623
1624 free((void *)path);
1625
1626 return;
1627 }
1628
1629 static void xds110_queue_scan(struct jtag_command *cmd)
1630 {
1631 int i;
1632 uint32_t offset;
1633 uint32_t total_fields;
1634 uint32_t total_bits;
1635 uint32_t total_bytes;
1636 uint8_t end_state;
1637 uint8_t *buffer;
1638
1639 /* Calculate the total number of bits to scan */
1640 total_bits = 0;
1641 total_fields = 0;
1642 for (i = 0; i < cmd->cmd.scan->num_fields; i++) {
1643 total_fields++;
1644 total_bits += (uint32_t)cmd->cmd.scan->fields[i].num_bits;
1645 }
1646
1647 if (total_bits == 0)
1648 return;
1649
1650 total_bytes = DIV_ROUND_UP(total_bits, 8);
1651
1652 /* Check if new request would be too large to fit */
1653 if (((xds110.txn_request_size + 1 + total_bytes + sizeof(end_state) + 1)
1654 > MAX_DATA_BLOCK) || ((xds110.txn_result_count + total_fields) >
1655 MAX_RESULT_QUEUE))
1656 xds110_flush();
1657
1658 /* Check if this single request is too large to fit */
1659 if ((1 + total_bytes + sizeof(end_state) + 1) > MAX_DATA_BLOCK) {
1660 LOG_ERROR("BUG: JTAG scan request is too large to handle (%d bits)",
1661 total_bits);
1662 /* Failing to run this scan mucks up debug on this target */
1663 exit(-1);
1664 }
1665
1666 if (cmd->cmd.scan->ir_scan)
1667 xds110.txn_requests[xds110.txn_request_size++] = CMD_IR_SCAN;
1668 else
1669 xds110.txn_requests[xds110.txn_request_size++] = CMD_DR_SCAN;
1670
1671 end_state = (uint8_t)xds_jtag_state[cmd->cmd.scan->end_state];
1672 xds110.txn_requests[xds110.txn_request_size++] = end_state;
1673
1674 xds110.txn_requests[xds110.txn_request_size++] = (total_bits >> 0) & 0xff;
1675 xds110.txn_requests[xds110.txn_request_size++] = (total_bits >> 8) & 0xff;
1676
1677 /* Build request data by flattening fields into single buffer */
1678 /* also populate the results array to return the results when run */
1679 offset = 0;
1680 buffer = &xds110.txn_requests[xds110.txn_request_size];
1681 /* Clear data out buffer to default value of all zeros */
1682 memset((void *)buffer, 0x00, total_bytes);
1683 for (i = 0; i < cmd->cmd.scan->num_fields; i++) {
1684 if (cmd->cmd.scan->fields[i].out_value != 0) {
1685 /* Copy over data to scan out into request buffer */
1686 bit_copy(buffer, offset, cmd->cmd.scan->fields[i].out_value, 0,
1687 cmd->cmd.scan->fields[i].num_bits);
1688 }
1689 offset += cmd->cmd.scan->fields[i].num_bits;
1690 xds110.txn_scan_results[xds110.txn_result_count].first = (i == 0);
1691 xds110.txn_scan_results[xds110.txn_result_count].num_bits =
1692 cmd->cmd.scan->fields[i].num_bits;
1693 xds110.txn_scan_results[xds110.txn_result_count++].buffer =
1694 cmd->cmd.scan->fields[i].in_value;
1695 }
1696 xds110.txn_request_size += total_bytes;
1697 xds110.txn_result_size += total_bytes;
1698
1699 return;
1700 }
1701
1702 static void xds110_queue_runtest(struct jtag_command *cmd)
1703 {
1704 uint32_t clocks = (uint32_t)cmd->cmd.stableclocks->num_cycles;
1705 uint8_t end_state = (uint8_t)xds_jtag_state[cmd->cmd.runtest->end_state];
1706
1707 /* Check if new request would be too large to fit */
1708 if ((xds110.txn_request_size + 1 + sizeof(clocks) + sizeof(end_state) + 1)
1709 > MAX_DATA_BLOCK)
1710 xds110_flush();
1711
1712 /* Queue request and cycle count directly to queue buffer */
1713 xds110.txn_requests[xds110.txn_request_size++] = CMD_RUNTEST;
1714 xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 0) & 0xff;
1715 xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 8) & 0xff;
1716 xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 16) & 0xff;
1717 xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 24) & 0xff;
1718 xds110.txn_requests[xds110.txn_request_size++] = end_state;
1719
1720 return;
1721 }
1722
1723 static void xds110_queue_stableclocks(struct jtag_command *cmd)
1724 {
1725 uint32_t clocks = (uint32_t)cmd->cmd.stableclocks->num_cycles;
1726
1727 /* Check if new request would be too large to fit */
1728 if ((xds110.txn_request_size + 1 + sizeof(clocks) + 1) > MAX_DATA_BLOCK)
1729 xds110_flush();
1730
1731 /* Queue request and cycle count directly to queue buffer */
1732 xds110.txn_requests[xds110.txn_request_size++] = CMD_STABLECLOCKS;
1733 xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 0) & 0xff;
1734 xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 8) & 0xff;
1735 xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 16) & 0xff;
1736 xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 24) & 0xff;
1737
1738 return;
1739 }
1740
1741 static void xds110_execute_command(struct jtag_command *cmd)
1742 {
1743 switch (cmd->type) {
1744 case JTAG_RESET:
1745 xds110_flush();
1746 xds110_execute_reset(cmd);
1747 break;
1748 case JTAG_SLEEP:
1749 xds110_flush();
1750 xds110_execute_sleep(cmd);
1751 break;
1752 case JTAG_TLR_RESET:
1753 xds110_flush();
1754 xds110_execute_tlr_reset(cmd);
1755 break;
1756 case JTAG_PATHMOVE:
1757 xds110_flush();
1758 xds110_execute_pathmove(cmd);
1759 break;
1760 case JTAG_SCAN:
1761 xds110_queue_scan(cmd);
1762 break;
1763 case JTAG_RUNTEST:
1764 xds110_queue_runtest(cmd);
1765 break;
1766 case JTAG_STABLECLOCKS:
1767 xds110_queue_stableclocks(cmd);
1768 break;
1769 case JTAG_TMS:
1770 default:
1771 LOG_ERROR("BUG: unknown JTAG command type 0x%x encountered",
1772 cmd->type);
1773 exit(-1);
1774 }
1775 }
1776
1777 static int xds110_execute_queue(void)
1778 {
1779 struct jtag_command *cmd = jtag_command_queue;
1780
1781 while (cmd != NULL) {
1782 xds110_execute_command(cmd);
1783 cmd = cmd->next;
1784 }
1785
1786 xds110_flush();
1787
1788 return ERROR_OK;
1789 }
1790
1791 static int xds110_speed(int speed)
1792 {
1793 bool success;
1794
1795 if (speed == 0) {
1796 LOG_INFO("XDS110: RTCK not supported");
1797 return ERROR_JTAG_NOT_IMPLEMENTED;
1798 }
1799
1800 if (speed > XDS110_MAX_TCK_SPEED) {
1801 LOG_INFO("XDS110: reduce speed request: %dkHz to %dkHz maximum",
1802 speed, XDS110_MAX_TCK_SPEED);
1803 speed = XDS110_MAX_TCK_SPEED;
1804 }
1805
1806 if (speed < XDS110_MIN_TCK_SPEED) {
1807 LOG_INFO("XDS110: increase speed request: %dkHz to %dkHz minimum",
1808 speed, XDS110_MIN_TCK_SPEED);
1809 speed = XDS110_MIN_TCK_SPEED;
1810 }
1811
1812 /* The default is the maximum frequency the XDS110 can support */
1813 uint32_t freq_to_use = XDS110_MAX_TCK_SPEED * 1000; /* Hz */
1814 uint32_t delay_count = 0;
1815
1816 if (XDS110_MAX_TCK_SPEED != speed) {
1817 freq_to_use = speed * 1000; /* Hz */
1818
1819 /* Calculate the delay count value */
1820 double one_giga = 1000000000;
1821 /* Get the pulse duration for the maximum frequency supported in ns */
1822 double max_freq_pulse_duration = one_giga /
1823 (XDS110_MAX_TCK_SPEED * 1000);
1824
1825 /* Convert frequency to pulse duration */
1826 double freq_to_pulse_width_in_ns = one_giga / freq_to_use;
1827
1828 /*
1829 * Start with the pulse duration for the maximum frequency. Keep
1830 * decrementing the time added by each count value till the requested
1831 * frequency pulse is less than the calculated value.
1832 */
1833 double current_value = max_freq_pulse_duration;
1834
1835 while (current_value < freq_to_pulse_width_in_ns) {
1836 current_value += XDS110_TCK_PULSE_INCREMENT;
1837 ++delay_count;
1838 }
1839
1840 /*
1841 * Determine which delay count yields the best match.
1842 * The one obtained above or one less.
1843 */
1844 if (delay_count) {
1845 double diff_freq_1 = freq_to_use -
1846 (one_giga / (max_freq_pulse_duration +
1847 (XDS110_TCK_PULSE_INCREMENT * delay_count)));
1848 double diff_freq_2 = (one_giga / (max_freq_pulse_duration +
1849 (XDS110_TCK_PULSE_INCREMENT * (delay_count - 1)))) -
1850 freq_to_use;
1851
1852 /* One less count value yields a better match */
1853 if (diff_freq_1 > diff_freq_2)
1854 --delay_count;
1855 }
1856 }
1857
1858 /* Send the delay count to the XDS110 firmware */
1859 success = xds_set_tck_delay(delay_count);
1860
1861 if (success) {
1862 xds110.delay_count = delay_count;
1863 xds110.speed = speed;
1864 }
1865
1866 return (success) ? ERROR_OK : ERROR_FAIL;
1867 }
1868
1869 static int xds110_speed_div(int speed, int *khz)
1870 {
1871 *khz = speed;
1872 return ERROR_OK;
1873 }
1874
1875 static int xds110_khz(int khz, int *jtag_speed)
1876 {
1877 *jtag_speed = khz;
1878 return ERROR_OK;
1879 }
1880
1881 static int_least32_t xds110_swd_frequency(int_least32_t hz)
1882 {
1883 if (hz > 0)
1884 xds110_speed(hz / 1000);
1885 return hz;
1886 }
1887
1888 COMMAND_HANDLER(xds110_handle_info_command)
1889 {
1890 xds110_show_info();
1891 return ERROR_OK;
1892 }
1893
1894 COMMAND_HANDLER(xds110_handle_serial_command)
1895 {
1896 wchar_t serial[XDS110_SERIAL_LEN + 1];
1897
1898 xds110.serial[0] = 0;
1899
1900 if (CMD_ARGC == 1) {
1901 size_t len = mbstowcs(0, CMD_ARGV[0], 0);
1902 if (len > XDS110_SERIAL_LEN) {
1903 LOG_ERROR("XDS110: serial number is limited to %d characters",
1904 XDS110_SERIAL_LEN);
1905 return ERROR_FAIL;
1906 }
1907 if ((size_t)-1 == mbstowcs(serial, CMD_ARGV[0], len + 1)) {
1908 LOG_ERROR("XDS110: unable to convert serial number");
1909 return ERROR_FAIL;
1910 }
1911
1912 for (uint32_t i = 0; i < len; i++)
1913 xds110.serial[i] = (char)serial[i];
1914
1915 xds110.serial[len] = 0;
1916 } else {
1917 LOG_ERROR("XDS110: expected exactly one argument to xds110_serial "
1918 "<serial-number>");
1919 return ERROR_FAIL;
1920 }
1921
1922 return ERROR_OK;
1923 }
1924
1925 static const struct command_registration xds110_subcommand_handlers[] = {
1926 {
1927 .name = "info",
1928 .handler = &xds110_handle_info_command,
1929 .mode = COMMAND_EXEC,
1930 .usage = "",
1931 .help = "show XDS110 info",
1932 },
1933 COMMAND_REGISTRATION_DONE
1934 };
1935
1936 static const struct command_registration xds110_command_handlers[] = {
1937 {
1938 .name = "xds110",
1939 .mode = COMMAND_ANY,
1940 .help = "perform XDS110 management",
1941 .usage = "<cmd>",
1942 .chain = xds110_subcommand_handlers,
1943 },
1944 {
1945 .name = "xds110_serial",
1946 .handler = &xds110_handle_serial_command,
1947 .mode = COMMAND_CONFIG,
1948 .help = "set the XDS110 probe serial number",
1949 .usage = "serial_string",
1950 },
1951 COMMAND_REGISTRATION_DONE
1952 };
1953
1954 static const struct swd_driver xds110_swd_driver = {
1955 .init = xds110_swd_init,
1956 .frequency = xds110_swd_frequency,
1957 .switch_seq = xds110_swd_switch_seq,
1958 .read_reg = xds110_swd_read_reg,
1959 .write_reg = xds110_swd_write_reg,
1960 .run = xds110_swd_run_queue,
1961 };
1962
1963 static const char * const xds110_transport[] = { "swd", "jtag", NULL };
1964
1965 struct jtag_interface xds110_interface = {
1966 .name = "xds110",
1967 .commands = xds110_command_handlers,
1968 .swd = &xds110_swd_driver,
1969 .transports = xds110_transport,
1970
1971 .execute_queue = xds110_execute_queue,
1972 .speed = xds110_speed,
1973 .speed_div = xds110_speed_div,
1974 .khz = xds110_khz,
1975 .init = xds110_init,
1976 .quit = xds110_quit,
1977 };

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)