1 /***************************************************************************
2 * Copyright (C) 2017 by Texas Instruments, Inc. *
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. *
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. *
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 ***************************************************************************/
22 #include <transport/transport.h>
24 #include <jtag/interface.h>
25 #include <jtag/commands.h>
29 /* XDS110 USB serial number length */
30 #define XDS110_SERIAL_LEN 8
32 /* XDS110 stand-alone probe voltage supply limits */
33 #define XDS110_MIN_VOLTAGE 1800
34 #define XDS110_MAX_VOLTAGE 3600
36 /* XDS110 stand-alone probe hardware ID */
37 #define XDS110_STAND_ALONE_ID 0x21
39 /* Firmware version that introduced OpenOCD support via block accesses */
40 #define OCD_FIRMWARE_VERSION 0x02030011
41 #define OCD_FIRMWARE_UPGRADE \
42 "XDS110: upgrade to version 2.3.0.11+ for improved support"
44 /* Firmware version that introduced improved TCK performance */
45 #define FAST_TCK_FIRMWARE_VERSION 0x03000000
47 /* Firmware version that introduced 10 MHz and 12 MHz TCK support */
48 #define FAST_TCK_PLUS_FIRMWARE_VERSION 0x03000003
50 /***************************************************************************
51 * USB Connection Buffer Definitions *
52 ***************************************************************************/
54 /* Max USB packet size for up to USB 3.0 */
55 #define MAX_PACKET 1024
58 * Maximum data payload that can be handled in a single call
59 * Limitation is the size of the buffers in the XDS110 firmware
61 #define MAX_DATA_BLOCK 4096
63 #ifndef USB_PAYLOAD_SIZE
64 /* Largest data block plus parameters */
65 #define USB_PAYLOAD_SIZE (MAX_DATA_BLOCK + 60)
67 #define MAX_RESULT_QUEUE (MAX_DATA_BLOCK / 4)
69 /***************************************************************************
70 * USB Connection Endpoints *
71 ***************************************************************************/
73 /* Bulk endpoints used by the XDS110 debug interface */
74 #define INTERFACE_DEBUG (2)
75 #define ENDPOINT_DEBUG_IN (3 | LIBUSB_ENDPOINT_IN)
76 #define ENDPOINT_DEBUG_OUT (2 | LIBUSB_ENDPOINT_OUT)
78 /***************************************************************************
79 * XDS110 Firmware API Definitions *
80 ***************************************************************************/
83 * Default values controlling how the host communicates commands
84 * with XDS110 firmware (automatic retry count and wait timeout)
86 #define DEFAULT_ATTEMPTS (1)
87 #define DEFAULT_TIMEOUT (4000)
89 /* XDS110 API error codes */
91 #define SC_ERR_XDS110_FAIL -261
92 #define SC_ERR_SWD_WAIT -613
93 #define SC_ERR_SWD_FAULT -614
94 #define SC_ERR_SWD_PROTOCOL -615
95 #define SC_ERR_SWD_PARITY -616
96 #define SC_ERR_SWD_DEVICE_ID -617
98 /* TCK frequency limits */
99 #define XDS110_MIN_TCK_SPEED 100 /* kHz */
100 #define XDS110_MAX_SLOW_TCK_SPEED 2500 /* kHz */
101 #define XDS110_MAX_FAST_TCK_SPEED 14000 /* kHz */
102 #define XDS110_DEFAULT_TCK_SPEED 2500 /* kHz */
104 /* Fixed TCK delay values for "Fast" TCK frequencies */
105 #define FAST_TCK_DELAY_14000_KHZ 0
106 #define FAST_TCK_DELAY_10000_KHZ 0xfffffffd
107 #define FAST_TCK_DELAY_12000_KHZ 0xfffffffe
108 #define FAST_TCK_DELAY_8500_KHZ 1
109 #define FAST_TCK_DELAY_5500_KHZ 2
110 /* For TCK frequencies below 5500 kHz, use calculated delay */
112 /* Scan mode on connect */
115 /* XDS110 API JTAG state definitions */
116 #define XDS_JTAG_STATE_RESET 1
117 #define XDS_JTAG_STATE_IDLE 2
118 #define XDS_JTAG_STATE_SHIFT_DR 3
119 #define XDS_JTAG_STATE_SHIFT_IR 4
120 #define XDS_JTAG_STATE_PAUSE_DR 5
121 #define XDS_JTAG_STATE_PAUSE_IR 6
122 #define XDS_JTAG_STATE_EXIT1_DR 8
123 #define XDS_JTAG_STATE_EXIT1_IR 9
124 #define XDS_JTAG_STATE_EXIT2_DR 10
125 #define XDS_JTAG_STATE_EXIT2_IR 11
126 #define XDS_JTAG_STATE_SELECT_DR 12
127 #define XDS_JTAG_STATE_SELECT_IR 13
128 #define XDS_JTAG_STATE_UPDATE_DR 14
129 #define XDS_JTAG_STATE_UPDATE_IR 15
130 #define XDS_JTAG_STATE_CAPTURE_DR 16
131 #define XDS_JTAG_STATE_CAPTURE_IR 17
133 /* XDS110 API JTAG transit definitions */
134 #define XDS_JTAG_TRANSIT_QUICKEST 1
135 #define XDS_JTAG_TRANSIT_VIA_CAPTURE 2
136 #define XDS_JTAG_TRANSIT_VIA_IDLE 3
138 /* DAP register definitions as used by XDS110 APIs */
140 #define DAP_AP 0 /* DAP AP register type */
141 #define DAP_DP 1 /* DAP DP register type */
143 #define DAP_DP_IDCODE 0x0 /* DAP DP IDCODE register (read only) */
144 #define DAP_DP_ABORT 0x0 /* DAP DP ABORT register (write only) */
145 #define DAP_DP_STAT 0x4 /* DAP DP STAT register (for read only) */
146 #define DAP_DP_CTRL 0x4 /* DAP DP CTRL register (for write only) */
147 #define DAP_DP_ADDR 0x8 /* DAP DP SELECT register (legacy name) */
148 #define DAP_DP_RESEND 0x8 /* DAP DP RESEND register (read only) */
149 #define DAP_DP_SELECT 0x8 /* DAP DP SELECT register (write only) */
150 #define DAP_DP_RDBUFF 0xc /* DAP DP RDBUFF Read Buffer register */
152 #define DAP_AP_CSW 0x00 /* DAP AP Control Status Word */
153 #define DAP_AP_TAR 0x04 /* DAP AP Transfer Address */
154 #define DAP_AP_DRW 0x0C /* DAP AP Data Read/Write */
155 #define DAP_AP_BD0 0x10 /* DAP AP Banked Data 0 */
156 #define DAP_AP_BD1 0x14 /* DAP AP Banked Data 1 */
157 #define DAP_AP_BD2 0x18 /* DAP AP Banked Data 2 */
158 #define DAP_AP_BD3 0x1C /* DAP AP Banked Data 3 */
159 #define DAP_AP_RTBL 0xF8 /* DAP AP Debug ROM Table */
160 #define DAP_AP_IDR 0xFC /* DAP AP Identification Register */
162 /* Command packet definitions */
164 #define XDS_OUT_LEN 1 /* command (byte) */
165 #define XDS_IN_LEN 4 /* error code (int) */
167 /* XDS API Commands */
168 #define XDS_CONNECT 0x01 /* Connect JTAG connection */
169 #define XDS_DISCONNECT 0x02 /* Disconnect JTAG connection */
170 #define XDS_VERSION 0x03 /* Get firmware version and hardware ID */
171 #define XDS_SET_TCK 0x04 /* Set TCK delay (to set TCK frequency) */
172 #define XDS_SET_TRST 0x05 /* Assert or deassert nTRST signal */
173 #define XDS_CYCLE_TCK 0x07 /* Toggle TCK for a number of cycles */
174 #define XDS_GOTO_STATE 0x09 /* Go to requested JTAG state */
175 #define XDS_JTAG_SCAN 0x0c /* Send and receive JTAG scan */
176 #define XDS_SET_SRST 0x0e /* Assert or deassert nSRST signal */
177 #define CMAPI_CONNECT 0x0f /* CMAPI connect */
178 #define CMAPI_DISCONNECT 0x10 /* CMAPI disconnect */
179 #define CMAPI_ACQUIRE 0x11 /* CMAPI acquire */
180 #define CMAPI_RELEASE 0x12 /* CMAPI release */
181 #define CMAPI_REG_READ 0x15 /* CMAPI DAP register read */
182 #define CMAPI_REG_WRITE 0x16 /* CMAPI DAP register write */
183 #define SWD_CONNECT 0x17 /* Switch from JTAG to SWD connection */
184 #define SWD_DISCONNECT 0x18 /* Switch from SWD to JTAG connection */
185 #define CJTAG_CONNECT 0x2b /* Switch from JTAG to cJTAG connection */
186 #define CJTAG_DISCONNECT 0x2c /* Switch from cJTAG to JTAG connection */
187 #define XDS_SET_SUPPLY 0x32 /* Set up stand-alone probe upply voltage */
188 #define OCD_DAP_REQUEST 0x3a /* Handle block of DAP requests */
189 #define OCD_SCAN_REQUEST 0x3b /* Handle block of JTAG scan requests */
190 #define OCD_PATHMOVE 0x3c /* Handle PATHMOVE to navigate JTAG states */
192 #define CMD_IR_SCAN 1
193 #define CMD_DR_SCAN 2
194 #define CMD_RUNTEST 3
195 #define CMD_STABLECLOCKS 4
197 /* Array to convert from OpenOCD tap_state_t to XDS JTAG state */
198 const uint32_t xds_jtag_state
[] = {
199 XDS_JTAG_STATE_EXIT2_DR
, /* TAP_DREXIT2 = 0x0 */
200 XDS_JTAG_STATE_EXIT1_DR
, /* TAP_DREXIT1 = 0x1 */
201 XDS_JTAG_STATE_SHIFT_DR
, /* TAP_DRSHIFT = 0x2 */
202 XDS_JTAG_STATE_PAUSE_DR
, /* TAP_DRPAUSE = 0x3 */
203 XDS_JTAG_STATE_SELECT_IR
, /* TAP_IRSELECT = 0x4 */
204 XDS_JTAG_STATE_UPDATE_DR
, /* TAP_DRUPDATE = 0x5 */
205 XDS_JTAG_STATE_CAPTURE_DR
, /* TAP_DRCAPTURE = 0x6 */
206 XDS_JTAG_STATE_SELECT_DR
, /* TAP_DRSELECT = 0x7 */
207 XDS_JTAG_STATE_EXIT2_IR
, /* TAP_IREXIT2 = 0x8 */
208 XDS_JTAG_STATE_EXIT1_IR
, /* TAP_IREXIT1 = 0x9 */
209 XDS_JTAG_STATE_SHIFT_IR
, /* TAP_IRSHIFT = 0xa */
210 XDS_JTAG_STATE_PAUSE_IR
, /* TAP_IRPAUSE = 0xb */
211 XDS_JTAG_STATE_IDLE
, /* TAP_IDLE = 0xc */
212 XDS_JTAG_STATE_UPDATE_IR
, /* TAP_IRUPDATE = 0xd */
213 XDS_JTAG_STATE_CAPTURE_IR
, /* TAP_IRCAPTURE = 0xe */
214 XDS_JTAG_STATE_RESET
, /* TAP_RESET = 0xf */
224 /* USB connection handles and data buffers */
226 libusb_device_handle
*dev
;
227 unsigned char read_payload
[USB_PAYLOAD_SIZE
];
228 unsigned char write_packet
[3];
229 unsigned char write_payload
[USB_PAYLOAD_SIZE
];
232 bool is_cmapi_connected
;
233 bool is_cmapi_acquired
;
236 /* DAP register caches */
240 /* TCK speed and delay count*/
242 uint32_t delay_count
;
243 /* XDS110 serial number */
244 char serial
[XDS110_SERIAL_LEN
+ 1];
245 /* XDS110 voltage supply setting */
247 /* XDS110 firmware and hardware version */
250 /* Transaction queues */
251 unsigned char txn_requests
[MAX_DATA_BLOCK
];
252 uint32_t *txn_dap_results
[MAX_DATA_BLOCK
/ 4];
253 struct scan_result txn_scan_results
[MAX_DATA_BLOCK
/ 4];
254 uint32_t txn_request_size
;
255 uint32_t txn_result_size
;
256 uint32_t txn_result_count
;
259 static struct xds110_info xds110
= {
262 .is_connected
= false,
263 .is_cmapi_connected
= false,
264 .is_cmapi_acquired
= false,
265 .is_swd_mode
= false,
266 .is_ap_dirty
= false,
267 .speed
= XDS110_DEFAULT_TCK_SPEED
,
273 .txn_request_size
= 0,
274 .txn_result_size
= 0,
275 .txn_result_count
= 0
278 static inline void xds110_set_u32(uint8_t *buffer
, uint32_t value
)
280 buffer
[3] = (value
>> 24) & 0xff;
281 buffer
[2] = (value
>> 16) & 0xff;
282 buffer
[1] = (value
>> 8) & 0xff;
283 buffer
[0] = (value
>> 0) & 0xff;
286 static inline void xds110_set_u16(uint8_t *buffer
, uint16_t value
)
288 buffer
[1] = (value
>> 8) & 0xff;
289 buffer
[0] = (value
>> 0) & 0xff;
292 static inline uint32_t xds110_get_u32(uint8_t *buffer
)
294 uint32_t value
= (((uint32_t)buffer
[3]) << 24) |
295 (((uint32_t)buffer
[2]) << 16) |
296 (((uint32_t)buffer
[1]) << 8) |
297 (((uint32_t)buffer
[0]) << 0);
301 static inline uint16_t xds110_get_u16(uint8_t *buffer
)
303 uint16_t value
= (((uint32_t)buffer
[1]) << 8) |
304 (((uint32_t)buffer
[0]) << 0);
308 /***************************************************************************
309 * usb connection routines *
311 * The following functions handle connecting, reading, and writing to *
312 * the XDS110 over USB using the libusb library. *
313 ***************************************************************************/
315 static bool usb_connect(void)
317 libusb_context
*ctx
= NULL
;
318 libusb_device
**list
= NULL
;
319 libusb_device_handle
*dev
= NULL
;
321 struct libusb_device_descriptor desc
;
323 uint16_t vid
= 0x0451;
324 uint16_t pid
= 0xbef3;
330 /* Initialize libusb context */
331 result
= libusb_init(&ctx
);
334 /* Get list of USB devices attached to system */
335 count
= libusb_get_device_list(ctx
, &list
);
343 /* Scan through list of devices for any XDS110s */
344 for (i
= 0; i
< count
; i
++) {
345 /* Check for device VID/PID match */
346 libusb_get_device_descriptor(list
[i
], &desc
);
347 if (desc
.idVendor
== vid
&& desc
.idProduct
== pid
) {
348 result
= libusb_open(list
[i
], &dev
);
350 const int MAX_DATA
= 256;
351 unsigned char data
[MAX_DATA
+ 1];
354 /* May be the requested device if serial number matches */
355 if (0 == xds110
.serial
[0]) {
356 /* No serial number given; match first XDS110 found */
360 /* Get the device's serial number string */
361 result
= libusb_get_string_descriptor_ascii(dev
,
362 desc
.iSerialNumber
, data
, MAX_DATA
);
364 0 == strcmp((char *)data
, (char *)xds110
.serial
)) {
370 /* If we fall though to here, we don't want this device */
379 * We can fall through the for() loop with two possible exit conditions:
380 * 1) found the right XDS110, and that device is open
381 * 2) didn't find the XDS110, and no devices are currently open
385 /* Free the device list, we're done with it */
386 libusb_free_device_list(list
, 1);
390 /* Save the context and device handles */
394 /* Set libusb to auto detach kernel */
395 (void)libusb_set_auto_detach_kernel_driver(dev
, 1);
397 /* Claim the debug interface on the XDS110 */
398 result
= libusb_claim_interface(dev
, INTERFACE_DEBUG
);
400 /* Couldn't find an XDS110, flag the error */
404 /* On an error, clean up what we can */
407 /* Release the debug and data interface on the XDS110 */
408 (void)libusb_release_interface(dev
, INTERFACE_DEBUG
);
417 /* Log the results */
419 LOG_INFO("XDS110: connected");
421 LOG_ERROR("XDS110: failed to connect");
423 return (0 == result
) ? true : false;
426 static void usb_disconnect(void)
428 if (NULL
!= xds110
.dev
) {
429 /* Release the debug and data interface on the XDS110 */
430 (void)libusb_release_interface(xds110
.dev
, INTERFACE_DEBUG
);
431 libusb_close(xds110
.dev
);
434 if (NULL
!= xds110
.ctx
) {
435 libusb_exit(xds110
.ctx
);
439 LOG_INFO("XDS110: disconnected");
442 static bool usb_read(unsigned char *buffer
, int size
, int *bytes_read
,
447 if (NULL
== xds110
.dev
|| NULL
== buffer
|| NULL
== bytes_read
)
450 /* Force a non-zero timeout to prevent blocking */
452 timeout
= DEFAULT_TIMEOUT
;
454 result
= libusb_bulk_transfer(xds110
.dev
, ENDPOINT_DEBUG_IN
, buffer
, size
,
455 bytes_read
, timeout
);
457 return (0 == result
) ? true : false;
460 static bool usb_write(unsigned char *buffer
, int size
, int *written
)
462 int bytes_written
= 0;
463 int result
= LIBUSB_SUCCESS
;
466 if (NULL
== xds110
.dev
|| NULL
== buffer
)
469 result
= libusb_bulk_transfer(xds110
.dev
, ENDPOINT_DEBUG_OUT
, buffer
,
470 size
, &bytes_written
, 0);
472 while (LIBUSB_ERROR_PIPE
== result
&& retries
< 3) {
473 /* Try clearing the pipe stall and retry transfer */
474 libusb_clear_halt(xds110
.dev
, ENDPOINT_DEBUG_OUT
);
475 result
= libusb_bulk_transfer(xds110
.dev
, ENDPOINT_DEBUG_OUT
, buffer
,
476 size
, &bytes_written
, 0);
481 *written
= bytes_written
;
483 return (0 == result
&& size
== bytes_written
) ? true : false;
486 static bool usb_get_response(uint32_t *total_bytes_read
, uint32_t timeout
)
488 static unsigned char buffer
[MAX_PACKET
];
497 success
= usb_read(buffer
, sizeof(buffer
), &bytes_read
, timeout
);
500 * Validate that this appears to be a good response packet
501 * First check it contains enough data for header and error
502 * code, plus the first character is the start character
504 if (bytes_read
>= 7 && '*' == buffer
[0]) {
505 /* Extract the payload size */
506 size
= xds110_get_u16(&buffer
[1]);
507 /* Sanity test on payload size */
508 if (USB_PAYLOAD_SIZE
>= size
&& 4 <= size
) {
509 /* Check we didn't get more data than expected */
510 if ((bytes_read
- 3) <= size
) {
511 /* Packet appears to be valid, move on */
518 * Somehow received an invalid packet, retry till we
519 * time out or a valid response packet is received
523 /* Abort now if we didn't receive a valid response */
525 if (NULL
!= total_bytes_read
)
526 *total_bytes_read
= 0;
530 /* Build the return payload into xds110.read_payload */
532 /* Copy over payload data from received buffer (skipping header) */
535 memcpy((void *)&xds110
.read_payload
[count
], (void *)&buffer
[3], bytes_read
);
538 * Drop timeout to just 1/2 second. Once the XDS110 starts sending
539 * a response, the remaining packets should arrive in short order
542 timeout
= 500; /* ms */
544 /* If there's more data to retrieve, get it now */
545 while ((count
< size
) && success
) {
546 success
= usb_read(buffer
, sizeof(buffer
), &bytes_read
, timeout
);
548 if ((count
+ bytes_read
) > size
) {
549 /* Read too much data, not a valid packet, abort */
552 /* Copy this data over to xds110.read_payload */
553 memcpy((void *)&xds110
.read_payload
[count
], (void *)buffer
,
562 if (NULL
!= total_bytes_read
)
563 *total_bytes_read
= count
;
568 static bool usb_send_command(uint16_t size
)
573 /* Check the packet length */
574 if (size
> USB_PAYLOAD_SIZE
)
577 /* Place the start character into the packet buffer */
578 xds110
.write_packet
[0] = '*';
580 /* Place the payload size into the packet buffer */
581 xds110_set_u16(&xds110
.write_packet
[1], size
);
583 /* Adjust size to include header */
586 /* Send the data via the USB connection */
587 success
= usb_write(xds110
.write_packet
, (int)size
, &written
);
589 /* Check if the correct number of bytes was written */
590 if (written
!= (int)size
)
596 /***************************************************************************
597 * XDS110 firmware API routines *
599 * The following functions handle calling into the XDS110 firmware to *
600 * perform requested debug actions. *
601 ***************************************************************************/
603 static bool xds_execute(uint32_t out_length
, uint32_t in_length
,
604 uint32_t attempts
, uint32_t timeout
)
609 uint32_t bytes_read
= 0;
611 if (NULL
== xds110
.dev
)
614 while (!done
&& attempts
> 0) {
617 /* Send command to XDS110 */
618 success
= usb_send_command(out_length
);
621 /* Get response from XDS110 */
622 success
= usb_get_response(&bytes_read
, timeout
);
626 /* Check for valid response from XDS code handling */
627 if (bytes_read
!= in_length
) {
628 /* Unexpected amount of data returned */
630 LOG_DEBUG("XDS110: command 0x%02x return %d bytes, expected %d",
631 xds110
.write_payload
[0], bytes_read
, in_length
);
633 /* Extract error code from return packet */
634 error
= (int)xds110_get_u32(&xds110
.read_payload
[0]);
636 if (SC_ERR_NONE
!= error
)
637 LOG_DEBUG("XDS110: command 0x%02x returned error %d",
638 xds110
.write_payload
[0], error
);
644 error
= SC_ERR_XDS110_FAIL
;
652 static bool xds_connect(void)
656 xds110
.write_payload
[0] = XDS_CONNECT
;
658 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
664 static bool xds_disconnect(void)
668 xds110
.write_payload
[0] = XDS_DISCONNECT
;
670 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
676 static bool xds_version(uint32_t *firmware_id
, uint16_t *hardware_id
)
678 uint8_t *fw_id_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+ 0]; /* 32-bits */
679 uint8_t *hw_id_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+ 4]; /* 16-bits */
683 xds110
.write_payload
[0] = XDS_VERSION
;
685 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
+ 6, DEFAULT_ATTEMPTS
,
689 if (NULL
!= firmware_id
)
690 *firmware_id
= xds110_get_u32(fw_id_pntr
);
691 if (NULL
!= hardware_id
)
692 *hardware_id
= xds110_get_u16(hw_id_pntr
);
698 static bool xds_set_tck_delay(uint32_t delay
)
700 uint8_t *delay_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
704 xds110
.write_payload
[0] = XDS_SET_TCK
;
706 xds110_set_u32(delay_pntr
, delay
);
708 success
= xds_execute(XDS_OUT_LEN
+ 4, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
714 static bool xds_set_trst(uint8_t trst
)
716 uint8_t *trst_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 8-bits */
720 xds110
.write_payload
[0] = XDS_SET_TRST
;
724 success
= xds_execute(XDS_OUT_LEN
+ 1, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
730 static bool xds_cycle_tck(uint32_t count
)
732 uint8_t *count_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
736 xds110
.write_payload
[0] = XDS_CYCLE_TCK
;
738 xds110_set_u32(count_pntr
, count
);
740 success
= xds_execute(XDS_OUT_LEN
+ 4, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
746 static bool xds_goto_state(uint32_t state
)
748 uint8_t *state_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
749 uint8_t *transit_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+4]; /* 32-bits */
753 xds110
.write_payload
[0] = XDS_GOTO_STATE
;
755 xds110_set_u32(state_pntr
, state
);
756 xds110_set_u32(transit_pntr
, XDS_JTAG_TRANSIT_QUICKEST
);
758 success
= xds_execute(XDS_OUT_LEN
+8, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
764 static bool xds_jtag_scan(uint32_t shift_state
, uint16_t shift_bits
,
765 uint32_t end_state
, uint8_t *data_out
, uint8_t *data_in
)
767 uint8_t *bits_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 16-bits */
768 uint8_t *path_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 2]; /* 8-bits */
769 uint8_t *trans1_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 3]; /* 8-bits */
770 uint8_t *end_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 4]; /* 8-bits */
771 uint8_t *trans2_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 5]; /* 8-bits */
772 uint8_t *pre_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 6]; /* 16-bits */
773 uint8_t *pos_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 8]; /* 16-bits */
774 uint8_t *delay_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 10]; /* 16-bits */
775 uint8_t *rep_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 12]; /* 16-bits */
776 uint8_t *out_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 14]; /* 16-bits */
777 uint8_t *in_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 16]; /* 16-bits */
778 uint8_t *data_out_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 18];
779 uint8_t *data_in_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+0];
781 uint16_t total_bytes
= DIV_ROUND_UP(shift_bits
, 8);
785 xds110
.write_payload
[0] = XDS_JTAG_SCAN
;
787 xds110_set_u16(bits_pntr
, shift_bits
); /* bits to scan */
788 *path_pntr
= (uint8_t)(shift_state
& 0xff); /* IR vs DR path */
789 *trans1_pntr
= (uint8_t)XDS_JTAG_TRANSIT_QUICKEST
; /* start state route */
790 *end_pntr
= (uint8_t)(end_state
& 0xff); /* JTAG state after scan */
791 *trans2_pntr
= (uint8_t)XDS_JTAG_TRANSIT_QUICKEST
; /* end state route */
792 xds110_set_u16(pre_pntr
, 0); /* number of preamble bits */
793 xds110_set_u16(pos_pntr
, 0); /* number of postamble bits */
794 xds110_set_u16(delay_pntr
, 0); /* number of extra TCKs after scan */
795 xds110_set_u16(rep_pntr
, 1); /* number of repetitions */
796 xds110_set_u16(out_pntr
, total_bytes
); /* out buffer offset (if repeats) */
797 xds110_set_u16(in_pntr
, total_bytes
); /* in buffer offset (if repeats) */
799 memcpy((void *)data_out_pntr
, (void *)data_out
, total_bytes
);
801 success
= xds_execute(XDS_OUT_LEN
+ 18 + total_bytes
,
802 XDS_IN_LEN
+ total_bytes
, DEFAULT_ATTEMPTS
, DEFAULT_TIMEOUT
);
805 memcpy((void *)data_in
, (void *)data_in_pntr
, total_bytes
);
810 static bool xds_set_srst(uint8_t srst
)
812 uint8_t *srst_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 8-bits */
816 xds110
.write_payload
[0] = XDS_SET_SRST
;
820 success
= xds_execute(XDS_OUT_LEN
+ 1, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
826 static bool cmapi_connect(uint32_t *idcode
)
828 uint8_t *idcode_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+ 0]; /* 32-bits */
832 xds110
.write_payload
[0] = CMAPI_CONNECT
;
834 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
+4, DEFAULT_ATTEMPTS
,
839 *idcode
= xds110_get_u32(idcode_pntr
);
845 static bool cmapi_disconnect(void)
849 xds110
.write_payload
[0] = CMAPI_DISCONNECT
;
851 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
857 static bool cmapi_acquire(void)
861 xds110
.write_payload
[0] = CMAPI_ACQUIRE
;
863 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
869 static bool cmapi_release(void)
873 xds110
.write_payload
[0] = CMAPI_RELEASE
;
875 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
881 static bool cmapi_read_dap_reg(uint32_t type
, uint32_t ap_num
,
882 uint32_t address
, uint32_t *value
)
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
.read_payload
[XDS_IN_LEN
+ 0]; /* 32-bits */
891 xds110
.write_payload
[0] = CMAPI_REG_READ
;
893 *type_pntr
= (uint8_t)(type
& 0xff);
894 *ap_num_pntr
= (uint8_t)(ap_num
& 0xff);
895 *address_pntr
= (uint8_t)(address
& 0xff);
897 success
= xds_execute(XDS_OUT_LEN
+ 3, XDS_IN_LEN
+ 4, DEFAULT_ATTEMPTS
,
902 *value
= xds110_get_u32(value_pntr
);
908 static bool cmapi_write_dap_reg(uint32_t type
, uint32_t ap_num
,
909 uint32_t address
, uint32_t *value
)
911 uint8_t *type_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 8-bits */
912 uint8_t *ap_num_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 1]; /* 8-bits */
913 uint8_t *address_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 2]; /* 8-bits */
914 uint8_t *value_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 3]; /* 32-bits */
921 xds110
.write_payload
[0] = CMAPI_REG_WRITE
;
923 *type_pntr
= (uint8_t)(type
& 0xff);
924 *ap_num_pntr
= (uint8_t)(ap_num
& 0xff);
925 *address_pntr
= (uint8_t)(address
& 0xff);
926 xds110_set_u32(value_pntr
, *value
);
928 success
= xds_execute(XDS_OUT_LEN
+ 7, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
934 static bool swd_connect(void)
938 xds110
.write_payload
[0] = SWD_CONNECT
;
940 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
946 static bool swd_disconnect(void)
950 xds110
.write_payload
[0] = SWD_DISCONNECT
;
952 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
958 static bool cjtag_connect(uint32_t format
)
960 uint8_t *format_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
964 xds110
.write_payload
[0] = CJTAG_CONNECT
;
966 xds110_set_u32(format_pntr
, format
);
968 success
= xds_execute(XDS_OUT_LEN
+ 4, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
974 static bool cjtag_disconnect(void)
978 xds110
.write_payload
[0] = CJTAG_DISCONNECT
;
980 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
986 static bool xds_set_supply(uint32_t voltage
)
988 uint8_t *volts_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
989 uint8_t *source_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 4]; /* 8-bits */
993 xds110
.write_payload
[0] = XDS_SET_SUPPLY
;
995 xds110_set_u32(volts_pntr
, voltage
);
996 *source_pntr
= (uint8_t)(0 != voltage
? 1 : 0);
998 success
= xds_execute(XDS_OUT_LEN
+ 5, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
1004 static bool ocd_dap_request(uint8_t *dap_requests
, uint32_t request_size
,
1005 uint32_t *dap_results
, uint32_t result_count
)
1007 uint8_t *request_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0];
1008 uint8_t *result_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+ 0];
1012 if (NULL
== dap_requests
|| NULL
== dap_results
)
1015 xds110
.write_payload
[0] = OCD_DAP_REQUEST
;
1017 memcpy((void *)request_pntr
, (void *)dap_requests
, request_size
);
1019 success
= xds_execute(XDS_OUT_LEN
+ request_size
,
1020 XDS_IN_LEN
+ (result_count
* 4), DEFAULT_ATTEMPTS
,
1023 if (success
&& (result_count
> 0))
1024 memcpy((void *)dap_results
, (void *)result_pntr
, result_count
* 4);
1029 static bool ocd_scan_request(uint8_t *scan_requests
, uint32_t request_size
,
1030 uint8_t *scan_results
, uint32_t result_size
)
1032 uint8_t *request_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0];
1033 uint8_t *result_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+ 0];
1037 if (NULL
== scan_requests
|| NULL
== scan_results
)
1040 xds110
.write_payload
[0] = OCD_SCAN_REQUEST
;
1042 memcpy((void *)request_pntr
, (void *)scan_requests
, request_size
);
1044 success
= xds_execute(XDS_OUT_LEN
+ request_size
,
1045 XDS_IN_LEN
+ result_size
, DEFAULT_ATTEMPTS
,
1048 if (success
&& (result_size
> 0))
1049 memcpy((void *)scan_results
, (void *)result_pntr
, result_size
);
1054 static bool ocd_pathmove(uint32_t num_states
, uint8_t *path
)
1056 uint8_t *num_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
1057 uint8_t *path_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 4];
1064 xds110
.write_payload
[0] = OCD_PATHMOVE
;
1066 xds110_set_u32(num_pntr
, num_states
);
1068 memcpy((void *)path_pntr
, (void *)path
, num_states
);
1070 success
= xds_execute(XDS_OUT_LEN
+ 4 + num_states
, XDS_IN_LEN
,
1071 DEFAULT_ATTEMPTS
, DEFAULT_TIMEOUT
);
1076 /***************************************************************************
1077 * swd driver interface *
1079 * The following functions provide SWD support to OpenOCD. *
1080 ***************************************************************************/
1082 static int xds110_swd_init(void)
1084 xds110
.is_swd_mode
= true;
1088 static int xds110_swd_switch_seq(enum swd_special_seq seq
)
1095 LOG_ERROR("Sequence SWD line reset (%d) not supported", seq
);
1098 LOG_DEBUG("JTAG-to-SWD");
1099 xds110
.is_swd_mode
= false;
1100 xds110
.is_cmapi_connected
= false;
1101 xds110
.is_cmapi_acquired
= false;
1102 /* Run sequence to put target in SWD mode */
1103 success
= swd_connect();
1104 /* Re-iniitialize CMAPI API for DAP access */
1106 xds110
.is_swd_mode
= true;
1107 success
= cmapi_connect(&idcode
);
1109 xds110
.is_cmapi_connected
= true;
1110 success
= cmapi_acquire();
1115 LOG_DEBUG("SWD-to-JTAG");
1116 xds110
.is_swd_mode
= false;
1117 xds110
.is_cmapi_connected
= false;
1118 xds110
.is_cmapi_acquired
= false;
1119 /* Run sequence to put target in JTAG mode */
1120 success
= swd_disconnect();
1122 /* Re-initialize JTAG interface */
1123 success
= cjtag_connect(MODE_JTAG
);
1127 LOG_ERROR("Sequence %d not supported", seq
);
1137 static bool xds110_legacy_read_reg(uint8_t cmd
, uint32_t *value
)
1139 /* Make sure this is a read request */
1140 bool is_read_request
= (0 != (SWD_CMD_RnW
& cmd
));
1141 /* Determine whether this is a DP or AP register access */
1142 uint32_t type
= (0 != (SWD_CMD_APnDP
& cmd
)) ? DAP_AP
: DAP_DP
;
1143 /* Determine the AP number from cached SELECT value */
1144 uint32_t ap_num
= (xds110
.select
& 0xff000000) >> 24;
1145 /* Extract register address from command */
1146 uint32_t address
= ((cmd
& SWD_CMD_A32
) >> 1);
1147 /* Extract bank address from cached SELECT value */
1148 uint32_t bank
= (xds110
.select
& 0x000000f0);
1150 uint32_t reg_value
= 0;
1151 uint32_t temp_value
= 0;
1155 if (!is_read_request
)
1158 if (DAP_AP
== type
) {
1159 /* Add bank address to register address for CMAPI call */
1163 if (DAP_DP
== type
&& DAP_DP_RDBUFF
== address
&& xds110
.use_rdbuff
) {
1164 /* If RDBUFF is cached and this is a DP RDBUFF read, use the cache */
1165 reg_value
= xds110
.rdbuff
;
1167 } else if (DAP_AP
== type
&& DAP_AP_DRW
== address
&& xds110
.use_rdbuff
) {
1168 /* If RDBUFF is cached and this is an AP DRW read, use the cache, */
1169 /* but still call into the firmware to get the next read. */
1170 reg_value
= xds110
.rdbuff
;
1171 success
= cmapi_read_dap_reg(type
, ap_num
, address
, &temp_value
);
1173 success
= cmapi_read_dap_reg(type
, ap_num
, address
, &temp_value
);
1175 reg_value
= temp_value
;
1178 /* Mark that we have consumed or invalidated the RDBUFF cache */
1179 xds110
.use_rdbuff
= false;
1181 /* Handle result of read attempt */
1183 LOG_ERROR("XDS110: failed to read DAP register");
1184 else if (NULL
!= value
)
1187 if (success
&& DAP_AP
== type
) {
1189 * On a successful DAP AP read, we actually have the value from RDBUFF,
1190 * the firmware will have run the AP request and made the RDBUFF read
1192 xds110
.use_rdbuff
= true;
1193 xds110
.rdbuff
= temp_value
;
1199 static bool xds110_legacy_write_reg(uint8_t cmd
, uint32_t value
)
1201 /* Make sure this isn't a read request */
1202 bool is_read_request
= (0 != (SWD_CMD_RnW
& cmd
));
1203 /* Determine whether this is a DP or AP register access */
1204 uint32_t type
= (0 != (SWD_CMD_APnDP
& cmd
)) ? DAP_AP
: DAP_DP
;
1205 /* Determine the AP number from cached SELECT value */
1206 uint32_t ap_num
= (xds110
.select
& 0xff000000) >> 24;
1207 /* Extract register address from command */
1208 uint32_t address
= ((cmd
& SWD_CMD_A32
) >> 1);
1209 /* Extract bank address from cached SELECT value */
1210 uint32_t bank
= (xds110
.select
& 0x000000f0);
1214 if (is_read_request
)
1217 /* Invalidate the RDBUFF cache */
1218 xds110
.use_rdbuff
= false;
1220 if (DAP_AP
== type
) {
1221 /* Add bank address to register address for CMAPI call */
1223 /* Any write to an AP register invalidates the firmware's cache */
1224 xds110
.is_ap_dirty
= true;
1225 } else if (DAP_DP_SELECT
== address
) {
1226 /* Any write to the SELECT register invalidates the firmware's cache */
1227 xds110
.is_ap_dirty
= true;
1230 success
= cmapi_write_dap_reg(type
, ap_num
, address
, &value
);
1233 LOG_ERROR("XDS110: failed to write DAP register");
1236 * If the debugger wrote to SELECT, cache the value
1237 * to use to build the apNum and address values above
1239 if ((DAP_DP
== type
) && (DAP_DP_SELECT
== address
))
1240 xds110
.select
= value
;
1246 static int xds110_swd_run_queue(void)
1248 static uint32_t dap_results
[MAX_RESULT_QUEUE
];
1253 bool success
= true;
1255 if (0 == xds110
.txn_request_size
)
1258 /* Terminate request queue */
1259 xds110
.txn_requests
[xds110
.txn_request_size
++] = 0;
1261 if (xds110
.firmware
>= OCD_FIRMWARE_VERSION
) {
1262 /* XDS110 firmware has the API to directly handle the queue */
1263 success
= ocd_dap_request(xds110
.txn_requests
,
1264 xds110
.txn_request_size
, dap_results
, xds110
.txn_result_count
);
1266 /* Legacy firmware needs to handle queue via discrete DAP calls */
1269 while (xds110
.txn_requests
[request
] != 0) {
1270 cmd
= xds110
.txn_requests
[request
++];
1271 if (0 == (SWD_CMD_RnW
& cmd
)) {
1272 /* DAP register write command */
1273 value
= (uint32_t)(xds110
.txn_requests
[request
++]) << 0;
1274 value
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 8;
1275 value
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 16;
1276 value
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 24;
1278 success
= xds110_legacy_write_reg(cmd
, value
);
1280 /* DAP register read command */
1283 success
= xds110_legacy_read_reg(cmd
, &value
);
1284 dap_results
[result
++] = value
;
1289 /* Transfer results into caller's buffers */
1290 for (result
= 0; result
< xds110
.txn_result_count
; result
++)
1291 if (0 != xds110
.txn_dap_results
[result
])
1292 *xds110
.txn_dap_results
[result
] = dap_results
[result
];
1294 xds110
.txn_request_size
= 0;
1295 xds110
.txn_result_size
= 0;
1296 xds110
.txn_result_count
= 0;
1298 return (success
) ? ERROR_OK
: ERROR_FAIL
;
1301 static void xds110_swd_queue_cmd(uint8_t cmd
, uint32_t *value
)
1303 /* Check if this is a read or write request */
1304 bool is_read_request
= (0 != (SWD_CMD_RnW
& cmd
));
1305 /* Determine whether this is a DP or AP register access */
1306 uint32_t type
= (0 != (SWD_CMD_APnDP
& cmd
)) ? DAP_AP
: DAP_DP
;
1307 /* Extract register address from command */
1308 uint32_t address
= ((cmd
& SWD_CMD_A32
) >> 1);
1309 uint32_t request_size
= (is_read_request
) ? 1 : 5;
1311 /* Check if new request would be too large to fit */
1312 if (((xds110
.txn_request_size
+ request_size
+ 1) > MAX_DATA_BLOCK
) ||
1313 ((xds110
.txn_result_count
+ 1) > MAX_RESULT_QUEUE
))
1314 xds110_swd_run_queue();
1316 /* Set the START bit in cmd to ensure cmd is not zero */
1317 /* (a value of zero is used to terminate the buffer) */
1318 cmd
|= SWD_CMD_START
;
1320 /* Add request to queue; queue is built marshalled for XDS110 call */
1321 if (is_read_request
) {
1322 /* Queue read request, save pointer to pass back result */
1323 xds110
.txn_requests
[xds110
.txn_request_size
++] = cmd
;
1324 xds110
.txn_dap_results
[xds110
.txn_result_count
++] = value
;
1325 xds110
.txn_result_size
+= 4;
1327 /* Check for and prevent sticky overrun detection */
1328 if (DAP_DP
== type
&& DAP_DP_CTRL
== address
&&
1329 (*value
& CORUNDETECT
)) {
1330 LOG_DEBUG("XDS110: refusing to enable sticky overrun detection");
1331 *value
&= ~CORUNDETECT
;
1333 /* Queue write request, add value directly to queue buffer */
1334 xds110
.txn_requests
[xds110
.txn_request_size
++] = cmd
;
1335 xds110
.txn_requests
[xds110
.txn_request_size
++] = (*value
>> 0) & 0xff;
1336 xds110
.txn_requests
[xds110
.txn_request_size
++] = (*value
>> 8) & 0xff;
1337 xds110
.txn_requests
[xds110
.txn_request_size
++] = (*value
>> 16) & 0xff;
1338 xds110
.txn_requests
[xds110
.txn_request_size
++] = (*value
>> 24) & 0xff;
1342 static void xds110_swd_read_reg(uint8_t cmd
, uint32_t *value
,
1343 uint32_t ap_delay_clk
)
1345 xds110_swd_queue_cmd(cmd
, value
);
1347 static void xds110_swd_write_reg(uint8_t cmd
, uint32_t value
,
1348 uint32_t ap_delay_clk
)
1350 xds110_swd_queue_cmd(cmd
, &value
);
1353 /***************************************************************************
1356 * The following functions provide XDS110 interface to OpenOCD. *
1357 ***************************************************************************/
1359 static void xds110_show_info(void)
1361 uint32_t firmware
= xds110
.firmware
;
1363 LOG_INFO("XDS110: firmware version = %d.%d.%d.%d",
1364 (((firmware
>> 28) & 0xf) * 10) + ((firmware
>> 24) & 0xf),
1365 (((firmware
>> 20) & 0xf) * 10) + ((firmware
>> 16) & 0xf),
1366 (((firmware
>> 12) & 0xf) * 10) + ((firmware
>> 8) & 0xf),
1367 (((firmware
>> 4) & 0xf) * 10) + ((firmware
>> 0) & 0xf));
1368 LOG_INFO("XDS110: hardware version = 0x%04x", xds110
.hardware
);
1369 if (0 != xds110
.serial
[0])
1370 LOG_INFO("XDS110: serial number = %s", xds110
.serial
);
1371 if (xds110
.is_swd_mode
) {
1372 LOG_INFO("XDS110: connected to target via SWD");
1373 LOG_INFO("XDS110: SWCLK set to %d kHz", xds110
.speed
);
1375 LOG_INFO("XDS110: connected to target via JTAG");
1376 LOG_INFO("XDS110: TCK set to %d kHz", xds110
.speed
);
1379 /* Alert user that there's a better firmware to use */
1380 if (firmware
< OCD_FIRMWARE_VERSION
) {
1381 LOG_WARNING("XDS110: the firmware is not optimized for OpenOCD");
1382 LOG_WARNING(OCD_FIRMWARE_UPGRADE
);
1386 static int xds110_quit(void)
1388 if (xds110
.is_cmapi_acquired
) {
1389 (void)cmapi_release();
1390 xds110
.is_cmapi_acquired
= false;
1392 if (xds110
.is_cmapi_connected
) {
1393 (void)cmapi_disconnect();
1394 xds110
.is_cmapi_connected
= false;
1396 if (xds110
.is_connected
) {
1397 if (xds110
.is_swd_mode
) {
1398 /* Switch out of SWD mode */
1399 (void)swd_disconnect();
1401 /* Switch out of cJTAG mode */
1402 (void)cjtag_disconnect();
1404 /* Tell firmware we're disconnecting */
1405 (void)xds_disconnect();
1406 xds110
.is_connected
= false;
1408 /* Close down the USB connection to the XDS110 debug probe */
1414 static int xds110_init(void)
1418 /* Establish USB connection to the XDS110 debug probe */
1419 success
= usb_connect();
1422 /* Send connect message to XDS110 firmware */
1423 success
= xds_connect();
1425 xds110
.is_connected
= true;
1432 /* Retrieve version IDs from firmware */
1433 /* Version numbers are stored in BCD format */
1434 success
= xds_version(&firmware
, &hardware
);
1436 /* Save the firmware and hardware version */
1437 xds110
.firmware
= firmware
;
1438 xds110
.hardware
= hardware
;
1443 /* Set supply voltage for stand-alone probes */
1444 if (XDS110_STAND_ALONE_ID
== xds110
.hardware
) {
1445 success
= xds_set_supply(xds110
.voltage
);
1446 /* Allow time for target device to power up */
1447 /* (CC32xx takes up to 1300 ms before debug is enabled) */
1449 } else if (0 != xds110
.voltage
) {
1450 /* Voltage supply not a feature of embedded probes */
1452 "XDS110: ignoring supply voltage, not supported on this probe");
1457 success
= xds_set_trst(0);
1459 success
= xds_cycle_tck(50);
1461 success
= xds_set_trst(1);
1463 success
= xds_cycle_tck(50);
1467 if (xds110
.is_swd_mode
) {
1468 /* Switch to SWD if needed */
1469 success
= swd_connect();
1471 success
= cjtag_connect(MODE_JTAG
);
1475 if (success
&& xds110
.is_swd_mode
) {
1478 /* Connect to CMAPI interface in XDS110 */
1479 success
= cmapi_connect(&idcode
);
1481 /* Acquire exclusive access to CMAPI interface */
1483 xds110
.is_cmapi_connected
= true;
1484 success
= cmapi_acquire();
1486 xds110
.is_cmapi_acquired
= true;
1496 return (success
) ? ERROR_OK
: ERROR_FAIL
;
1499 static void xds110_legacy_scan(uint32_t shift_state
, uint32_t total_bits
,
1500 uint32_t end_state
, uint8_t *data_out
, uint8_t *data_in
)
1502 (void)xds_jtag_scan(shift_state
, total_bits
, end_state
, data_out
, data_in
);
1505 static void xds110_legacy_runtest(uint32_t clocks
, uint32_t end_state
)
1507 xds_goto_state(XDS_JTAG_STATE_IDLE
);
1508 xds_cycle_tck(clocks
);
1509 xds_goto_state(end_state
);
1512 static void xds110_legacy_stableclocks(uint32_t clocks
)
1514 xds_cycle_tck(clocks
);
1517 static void xds110_flush(void)
1521 uint32_t shift_state
;
1528 uint8_t data_in
[MAX_DATA_BLOCK
];
1531 if (0 == xds110
.txn_request_size
)
1534 /* Terminate request queue */
1535 xds110
.txn_requests
[xds110
.txn_request_size
++] = 0;
1537 if (xds110
.firmware
>= OCD_FIRMWARE_VERSION
) {
1538 /* Updated firmware has the API to directly handle the queue */
1539 (void)ocd_scan_request(xds110
.txn_requests
, xds110
.txn_request_size
,
1540 data_in
, xds110
.txn_result_size
);
1542 /* Legacy firmware needs to handle queue via discrete JTAG calls */
1545 while (xds110
.txn_requests
[request
] != 0) {
1546 command
= xds110
.txn_requests
[request
++];
1550 if (command
== CMD_IR_SCAN
)
1551 shift_state
= XDS_JTAG_STATE_SHIFT_IR
;
1553 shift_state
= XDS_JTAG_STATE_SHIFT_DR
;
1554 end_state
= (uint32_t)(xds110
.txn_requests
[request
++]);
1555 bits
= (uint32_t)(xds110
.txn_requests
[request
++]) << 0;
1556 bits
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 8;
1557 data_out
= &xds110
.txn_requests
[request
];
1558 bytes
= DIV_ROUND_UP(bits
, 8);
1559 xds110_legacy_scan(shift_state
, bits
, end_state
, data_out
,
1565 clocks
= (uint32_t)(xds110
.txn_requests
[request
++]) << 0;
1566 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 8;
1567 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 16;
1568 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 24;
1569 end_state
= (uint32_t)xds110
.txn_requests
[request
++];
1570 xds110_legacy_runtest(clocks
, end_state
);
1572 case CMD_STABLECLOCKS
:
1573 clocks
= (uint32_t)(xds110
.txn_requests
[request
++]) << 0;
1574 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 8;
1575 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 16;
1576 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 24;
1577 xds110_legacy_stableclocks(clocks
);
1580 LOG_ERROR("BUG: unknown JTAG command type 0x%x encountered",
1588 /* Transfer results into caller's buffers from data_in buffer */
1589 bits
= 0; /* Bit offset into current scan result */
1590 data_pntr
= data_in
;
1591 for (result
= 0; result
< xds110
.txn_result_count
; result
++) {
1592 if (xds110
.txn_scan_results
[result
].first
) {
1594 bytes
= DIV_ROUND_UP(bits
, 8);
1599 if (xds110
.txn_scan_results
[result
].buffer
!= 0)
1600 bit_copy(xds110
.txn_scan_results
[result
].buffer
, 0, data_pntr
,
1601 bits
, xds110
.txn_scan_results
[result
].num_bits
);
1602 bits
+= xds110
.txn_scan_results
[result
].num_bits
;
1605 xds110
.txn_request_size
= 0;
1606 xds110
.txn_result_size
= 0;
1607 xds110
.txn_result_count
= 0;
1610 static int xds110_reset(int trst
, int srst
)
1614 int retval
= ERROR_OK
;
1618 /* Deassert nTRST (active low) */
1621 /* Assert nTRST (active low) */
1624 success
= xds_set_trst(value
);
1626 retval
= ERROR_FAIL
;
1631 /* Deassert nSRST (active low) */
1634 /* Assert nSRST (active low) */
1637 success
= xds_set_srst(value
);
1639 retval
= ERROR_FAIL
;
1641 /* Toggle TCK to trigger HIB on CC13x/CC26x devices */
1642 if (success
&& !xds110
.is_swd_mode
) {
1643 /* Toggle TCK for about 50 ms */
1644 success
= xds_cycle_tck(xds110
.speed
* 50);
1648 retval
= ERROR_FAIL
;
1654 static void xds110_execute_sleep(struct jtag_command
*cmd
)
1656 jtag_sleep(cmd
->cmd
.sleep
->us
);
1660 static void xds110_execute_tlr_reset(struct jtag_command
*cmd
)
1662 (void)xds_goto_state(XDS_JTAG_STATE_RESET
);
1667 static void xds110_execute_pathmove(struct jtag_command
*cmd
)
1670 uint32_t num_states
;
1673 num_states
= (uint32_t)cmd
->cmd
.pathmove
->num_states
;
1675 if (num_states
== 0)
1678 path
= (uint8_t *)malloc(num_states
* sizeof(uint8_t));
1680 LOG_ERROR("XDS110: unable to allocate memory");
1684 /* Convert requested path states into XDS API states */
1685 for (i
= 0; i
< num_states
; i
++)
1686 path
[i
] = (uint8_t)xds_jtag_state
[cmd
->cmd
.pathmove
->path
[i
]];
1688 if (xds110
.firmware
>= OCD_FIRMWARE_VERSION
) {
1689 /* Updated firmware fully supports pathmove */
1690 (void)ocd_pathmove(num_states
, path
);
1692 /* Notify user that legacy firmware simply cannot handle pathmove */
1693 LOG_ERROR("XDS110: the firmware does not support pathmove command");
1694 LOG_ERROR(OCD_FIRMWARE_UPGRADE
);
1695 /* If pathmove is required, then debug is not possible */
1704 static void xds110_queue_scan(struct jtag_command
*cmd
)
1708 uint32_t total_fields
;
1709 uint32_t total_bits
;
1710 uint32_t total_bytes
;
1714 /* Calculate the total number of bits to scan */
1717 for (i
= 0; i
< cmd
->cmd
.scan
->num_fields
; i
++) {
1719 total_bits
+= (uint32_t)cmd
->cmd
.scan
->fields
[i
].num_bits
;
1722 if (total_bits
== 0)
1725 total_bytes
= DIV_ROUND_UP(total_bits
, 8);
1727 /* Check if new request would be too large to fit */
1728 if (((xds110
.txn_request_size
+ 1 + total_bytes
+ sizeof(end_state
) + 1)
1729 > MAX_DATA_BLOCK
) || ((xds110
.txn_result_count
+ total_fields
) >
1733 /* Check if this single request is too large to fit */
1734 if ((1 + total_bytes
+ sizeof(end_state
) + 1) > MAX_DATA_BLOCK
) {
1735 LOG_ERROR("BUG: JTAG scan request is too large to handle (%d bits)",
1737 /* Failing to run this scan mucks up debug on this target */
1741 if (cmd
->cmd
.scan
->ir_scan
)
1742 xds110
.txn_requests
[xds110
.txn_request_size
++] = CMD_IR_SCAN
;
1744 xds110
.txn_requests
[xds110
.txn_request_size
++] = CMD_DR_SCAN
;
1746 end_state
= (uint8_t)xds_jtag_state
[cmd
->cmd
.scan
->end_state
];
1747 xds110
.txn_requests
[xds110
.txn_request_size
++] = end_state
;
1749 xds110
.txn_requests
[xds110
.txn_request_size
++] = (total_bits
>> 0) & 0xff;
1750 xds110
.txn_requests
[xds110
.txn_request_size
++] = (total_bits
>> 8) & 0xff;
1752 /* Build request data by flattening fields into single buffer */
1753 /* also populate the results array to return the results when run */
1755 buffer
= &xds110
.txn_requests
[xds110
.txn_request_size
];
1756 /* Clear data out buffer to default value of all zeros */
1757 memset((void *)buffer
, 0x00, total_bytes
);
1758 for (i
= 0; i
< cmd
->cmd
.scan
->num_fields
; i
++) {
1759 if (cmd
->cmd
.scan
->fields
[i
].out_value
!= 0) {
1760 /* Copy over data to scan out into request buffer */
1761 bit_copy(buffer
, offset
, cmd
->cmd
.scan
->fields
[i
].out_value
, 0,
1762 cmd
->cmd
.scan
->fields
[i
].num_bits
);
1764 offset
+= cmd
->cmd
.scan
->fields
[i
].num_bits
;
1765 xds110
.txn_scan_results
[xds110
.txn_result_count
].first
= (i
== 0);
1766 xds110
.txn_scan_results
[xds110
.txn_result_count
].num_bits
=
1767 cmd
->cmd
.scan
->fields
[i
].num_bits
;
1768 xds110
.txn_scan_results
[xds110
.txn_result_count
++].buffer
=
1769 cmd
->cmd
.scan
->fields
[i
].in_value
;
1771 xds110
.txn_request_size
+= total_bytes
;
1772 xds110
.txn_result_size
+= total_bytes
;
1777 static void xds110_queue_runtest(struct jtag_command
*cmd
)
1779 uint32_t clocks
= (uint32_t)cmd
->cmd
.stableclocks
->num_cycles
;
1780 uint8_t end_state
= (uint8_t)xds_jtag_state
[cmd
->cmd
.runtest
->end_state
];
1782 /* Check if new request would be too large to fit */
1783 if ((xds110
.txn_request_size
+ 1 + sizeof(clocks
) + sizeof(end_state
) + 1)
1787 /* Queue request and cycle count directly to queue buffer */
1788 xds110
.txn_requests
[xds110
.txn_request_size
++] = CMD_RUNTEST
;
1789 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 0) & 0xff;
1790 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 8) & 0xff;
1791 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 16) & 0xff;
1792 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 24) & 0xff;
1793 xds110
.txn_requests
[xds110
.txn_request_size
++] = end_state
;
1798 static void xds110_queue_stableclocks(struct jtag_command
*cmd
)
1800 uint32_t clocks
= (uint32_t)cmd
->cmd
.stableclocks
->num_cycles
;
1802 /* Check if new request would be too large to fit */
1803 if ((xds110
.txn_request_size
+ 1 + sizeof(clocks
) + 1) > MAX_DATA_BLOCK
)
1806 /* Queue request and cycle count directly to queue buffer */
1807 xds110
.txn_requests
[xds110
.txn_request_size
++] = CMD_STABLECLOCKS
;
1808 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 0) & 0xff;
1809 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 8) & 0xff;
1810 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 16) & 0xff;
1811 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 24) & 0xff;
1816 static void xds110_execute_command(struct jtag_command
*cmd
)
1818 switch (cmd
->type
) {
1821 xds110_execute_sleep(cmd
);
1823 case JTAG_TLR_RESET
:
1825 xds110_execute_tlr_reset(cmd
);
1829 xds110_execute_pathmove(cmd
);
1832 xds110_queue_scan(cmd
);
1835 xds110_queue_runtest(cmd
);
1837 case JTAG_STABLECLOCKS
:
1838 xds110_queue_stableclocks(cmd
);
1842 LOG_ERROR("BUG: unknown JTAG command type 0x%x encountered",
1848 static int xds110_execute_queue(void)
1850 struct jtag_command
*cmd
= jtag_command_queue
;
1852 while (cmd
!= NULL
) {
1853 xds110_execute_command(cmd
);
1862 static int xds110_speed(int speed
)
1865 uint32_t delay_count
;
1869 LOG_INFO("XDS110: RTCK not supported");
1870 return ERROR_JTAG_NOT_IMPLEMENTED
;
1873 if (speed
< XDS110_MIN_TCK_SPEED
) {
1874 LOG_INFO("XDS110: increase speed request: %d kHz to %d kHz minimum",
1875 speed
, XDS110_MIN_TCK_SPEED
);
1876 speed
= XDS110_MIN_TCK_SPEED
;
1879 /* Older XDS110 firmware had inefficient scan routines and could only */
1880 /* achieve a peak TCK frequency of about 2500 kHz */
1881 if (xds110
.firmware
< FAST_TCK_FIRMWARE_VERSION
) {
1883 /* Check for request for top speed or higher */
1884 if (speed
>= XDS110_MAX_SLOW_TCK_SPEED
) {
1886 /* Inform user that speed was adjusted down to max possible */
1887 if (speed
> XDS110_MAX_SLOW_TCK_SPEED
) {
1889 "XDS110: reduce speed request: %d kHz to %d kHz maximum",
1890 speed
, XDS110_MAX_SLOW_TCK_SPEED
);
1891 speed
= XDS110_MAX_SLOW_TCK_SPEED
;
1897 const double XDS110_TCK_PULSE_INCREMENT
= 66.0;
1898 freq_to_use
= speed
* 1000; /* Hz */
1901 /* Calculate the delay count value */
1902 double one_giga
= 1000000000;
1903 /* Get the pulse duration for the max frequency supported in ns */
1904 double max_freq_pulse_duration
= one_giga
/
1905 (XDS110_MAX_SLOW_TCK_SPEED
* 1000);
1907 /* Convert frequency to pulse duration */
1908 double freq_to_pulse_width_in_ns
= one_giga
/ freq_to_use
;
1911 * Start with the pulse duration for the maximum frequency. Keep
1912 * decrementing time added by each count value till the requested
1913 * frequency pulse is less than the calculated value.
1915 double current_value
= max_freq_pulse_duration
;
1917 while (current_value
< freq_to_pulse_width_in_ns
) {
1918 current_value
+= XDS110_TCK_PULSE_INCREMENT
;
1923 * Determine which delay count yields the best match.
1924 * The one obtained above or one less.
1927 double diff_freq_1
= freq_to_use
-
1928 (one_giga
/ (max_freq_pulse_duration
+
1929 (XDS110_TCK_PULSE_INCREMENT
* delay_count
)));
1930 double diff_freq_2
= (one_giga
/ (max_freq_pulse_duration
+
1931 (XDS110_TCK_PULSE_INCREMENT
* (delay_count
- 1)))) -
1934 /* One less count value yields a better match */
1935 if (diff_freq_1
> diff_freq_2
)
1940 /* Newer firmware has reworked TCK routines that are much more efficient */
1941 /* and can now achieve a peak TCK frequency of 14000 kHz */
1944 if (speed
>= XDS110_MAX_FAST_TCK_SPEED
) {
1945 if (speed
> XDS110_MAX_FAST_TCK_SPEED
) {
1947 "XDS110: reduce speed request: %d kHz to %d kHz maximum",
1948 speed
, XDS110_MAX_FAST_TCK_SPEED
);
1949 speed
= XDS110_MAX_FAST_TCK_SPEED
;
1952 } else if (speed
>= 12000 && xds110
.firmware
>=
1953 FAST_TCK_PLUS_FIRMWARE_VERSION
) {
1954 delay_count
= FAST_TCK_DELAY_12000_KHZ
;
1955 } else if (speed
>= 10000 && xds110
.firmware
>=
1956 FAST_TCK_PLUS_FIRMWARE_VERSION
) {
1957 delay_count
= FAST_TCK_DELAY_10000_KHZ
;
1958 } else if (speed
>= 8500) {
1959 delay_count
= FAST_TCK_DELAY_8500_KHZ
;
1960 } else if (speed
>= 5500) {
1961 delay_count
= FAST_TCK_DELAY_5500_KHZ
;
1963 /* Calculate the delay count to set the frequency */
1964 /* Formula determined by measuring the waveform on Saeleae logic */
1965 /* analyzer using known values for delay count */
1966 const double m
= 17100000.0; /* slope */
1967 const double b
= -1.02; /* y-intercept */
1969 freq_to_use
= speed
* 1000; /* Hz */
1970 double period
= 1.0/freq_to_use
;
1971 double delay
= m
* period
+ b
;
1976 delay_count
= (uint32_t)delay
;
1980 /* Send the delay count to the XDS110 firmware */
1981 success
= xds_set_tck_delay(delay_count
);
1984 xds110
.delay_count
= delay_count
;
1985 xds110
.speed
= speed
;
1988 return (success
) ? ERROR_OK
: ERROR_FAIL
;
1991 static int xds110_speed_div(int speed
, int *khz
)
1997 static int xds110_khz(int khz
, int *jtag_speed
)
2003 COMMAND_HANDLER(xds110_handle_info_command
)
2009 COMMAND_HANDLER(xds110_handle_serial_command
)
2011 wchar_t serial
[XDS110_SERIAL_LEN
+ 1];
2013 xds110
.serial
[0] = 0;
2015 if (CMD_ARGC
== 1) {
2016 size_t len
= mbstowcs(0, CMD_ARGV
[0], 0);
2017 if (len
> XDS110_SERIAL_LEN
) {
2018 LOG_ERROR("XDS110: serial number is limited to %d characters",
2022 if ((size_t)-1 == mbstowcs(serial
, CMD_ARGV
[0], len
+ 1)) {
2023 LOG_ERROR("XDS110: unable to convert serial number");
2027 for (uint32_t i
= 0; i
< len
; i
++)
2028 xds110
.serial
[i
] = (char)serial
[i
];
2030 xds110
.serial
[len
] = 0;
2032 return ERROR_COMMAND_SYNTAX_ERROR
;
2037 COMMAND_HANDLER(xds110_handle_supply_voltage_command
)
2039 uint32_t voltage
= 0;
2041 if (CMD_ARGC
== 1) {
2042 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], voltage
);
2043 if (voltage
== 0 || (voltage
>= XDS110_MIN_VOLTAGE
&& voltage
2044 <= XDS110_MAX_VOLTAGE
)) {
2045 /* Requested voltage is in range */
2046 xds110
.voltage
= voltage
;
2048 LOG_ERROR("XDS110: voltage must be 0 or between %d and %d "
2049 "millivolts", XDS110_MIN_VOLTAGE
, XDS110_MAX_VOLTAGE
);
2052 xds110
.voltage
= voltage
;
2054 return ERROR_COMMAND_SYNTAX_ERROR
;
2059 static const struct command_registration xds110_subcommand_handlers
[] = {
2062 .handler
= &xds110_handle_info_command
,
2063 .mode
= COMMAND_EXEC
,
2064 .help
= "show XDS110 info",
2069 .handler
= &xds110_handle_serial_command
,
2070 .mode
= COMMAND_CONFIG
,
2071 .help
= "set the XDS110 probe serial number",
2072 .usage
= "serial_string",
2076 .handler
= &xds110_handle_supply_voltage_command
,
2077 .mode
= COMMAND_CONFIG
,
2078 .help
= "set the XDS110 probe supply voltage",
2079 .usage
= "voltage_in_millivolts",
2081 COMMAND_REGISTRATION_DONE
2084 static const struct command_registration xds110_command_handlers
[] = {
2087 .mode
= COMMAND_ANY
,
2088 .help
= "perform XDS110 management",
2090 .chain
= xds110_subcommand_handlers
,
2092 COMMAND_REGISTRATION_DONE
2095 static const struct swd_driver xds110_swd_driver
= {
2096 .init
= xds110_swd_init
,
2097 .switch_seq
= xds110_swd_switch_seq
,
2098 .read_reg
= xds110_swd_read_reg
,
2099 .write_reg
= xds110_swd_write_reg
,
2100 .run
= xds110_swd_run_queue
,
2103 static const char * const xds110_transport
[] = { "swd", "jtag", NULL
};
2105 static struct jtag_interface xds110_interface
= {
2106 .execute_queue
= xds110_execute_queue
,
2109 struct adapter_driver xds110_adapter_driver
= {
2111 .transports
= xds110_transport
,
2112 .commands
= xds110_command_handlers
,
2114 .init
= xds110_init
,
2115 .quit
= xds110_quit
,
2116 .reset
= xds110_reset
,
2117 .speed
= xds110_speed
,
2119 .speed_div
= xds110_speed_div
,
2121 .jtag_ops
= &xds110_interface
,
2122 .swd_ops
= &xds110_swd_driver
,
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)