1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /***************************************************************************
5 * Copyright (C) 2012 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 ***************************************************************************/
13 /* project specific includes */
14 #include <helper/binarybuffer.h>
15 #include <jtag/adapter.h>
16 #include <jtag/interface.h>
17 #include <jtag/hla/hla_layout.h>
18 #include <jtag/hla/hla_transport.h>
19 #include <jtag/hla/hla_interface.h>
20 #include <target/target.h>
22 #include <target/cortex_m.h>
24 #include "libusb_helper.h"
26 #define ICDI_WRITE_ENDPOINT 0x02
27 #define ICDI_READ_ENDPOINT 0x83
29 #define ICDI_WRITE_TIMEOUT (LIBUSB_TIMEOUT_MS)
30 #define ICDI_READ_TIMEOUT (LIBUSB_TIMEOUT_MS)
31 #define ICDI_PACKET_SIZE 2048
33 #define PACKET_START "$"
34 #define PACKET_END "#"
36 struct icdi_usb_handle_s {
37 struct libusb_device_handle *usb_dev;
43 uint32_t max_rw_packet; /* max X packet (read/write memory) transfers */
46 static int icdi_usb_read_mem(void *handle, uint32_t addr, uint32_t size,
47 uint32_t count, uint8_t *buffer);
48 static int icdi_usb_write_mem(void *handle, uint32_t addr, uint32_t size,
49 uint32_t count, const uint8_t *buffer);
51 static int remote_escape_output(const char *buffer, int len, char *out_buf, int *out_len, int out_maxlen)
53 int input_index, output_index;
57 for (input_index = 0; input_index < len; input_index++) {
59 char b = buffer[input_index];
61 if (b == '$' || b == '#' || b == '}' || b == '*') {
62 /* These must be escaped. */
63 if (output_index + 2 > out_maxlen)
65 out_buf[output_index++] = '}';
66 out_buf[output_index++] = b ^ 0x20;
68 if (output_index + 1 > out_maxlen)
70 out_buf[output_index++] = b;
74 *out_len = input_index;
78 static int remote_unescape_input(const char *buffer, int len, char *out_buf, int out_maxlen)
80 int input_index, output_index;
86 for (input_index = 0; input_index < len; input_index++) {
88 char b = buffer[input_index];
90 if (output_index + 1 > out_maxlen)
91 LOG_ERROR("Received too much data from the target.");
94 out_buf[output_index++] = b ^ 0x20;
99 out_buf[output_index++] = b;
103 LOG_ERROR("Unmatched escape character in target response.");
108 static int icdi_send_packet(void *handle, int len)
110 unsigned char cksum = 0;
111 struct icdi_usb_handle_s *h = handle;
112 int result, retry = 0;
117 /* check we have a large enough buffer for checksum "#00" */
118 if (len + 3 > h->max_packet) {
119 LOG_ERROR("packet buffer too small");
123 /* calculate checksum - offset start of packet */
124 for (int i = 1; i < len; i++)
125 cksum += h->write_buffer[i];
127 len += sprintf(&h->write_buffer[len], PACKET_END "%02x", cksum);
129 #ifdef _DEBUG_USB_COMMS_
131 char ch = h->write_buffer[1];
132 if (ch == 'x' || ch == 'X')
133 LOG_DEBUG("writing packet: <binary>");
135 memcpy(buffer, h->write_buffer, len >= 50 ? 50-1 : len);
137 LOG_DEBUG("writing packet: %s", buffer);
143 result = libusb_bulk_transfer(h->usb_dev, ICDI_WRITE_ENDPOINT, (unsigned char *)h->write_buffer, len,
144 &transferred, ICDI_WRITE_TIMEOUT);
145 if (result != 0 || transferred != len) {
146 LOG_DEBUG("Error TX Data %d", result);
150 /* check that the client got the message ok, or shall we resend */
151 result = libusb_bulk_transfer(h->usb_dev, ICDI_READ_ENDPOINT, (unsigned char *)h->read_buffer, h->max_packet,
152 &transferred, ICDI_READ_TIMEOUT);
153 if (result != 0 || transferred < 1) {
154 LOG_DEBUG("Error RX Data %d", result);
158 #ifdef _DEBUG_USB_COMMS_
159 LOG_DEBUG("received reply: '%c' : count %d", h->read_buffer[0], transferred);
162 if (h->read_buffer[0] == '-') {
163 LOG_DEBUG("Resending packet %d", ++retry);
165 if (h->read_buffer[0] != '+')
166 LOG_DEBUG("Unexpected Reply from ICDI: %c", h->read_buffer[0]);
171 LOG_DEBUG("maximum nack retries attempted");
177 h->read_count = transferred;
181 /* read reply from icdi */
182 result = libusb_bulk_transfer(h->usb_dev, ICDI_READ_ENDPOINT, (unsigned char *)h->read_buffer + h->read_count,
183 h->max_packet - h->read_count, &transferred, ICDI_READ_TIMEOUT);
185 #ifdef _DEBUG_USB_COMMS_
186 LOG_DEBUG("received data: count %d", transferred);
189 /* check for errors but retry for timeout */
192 if (result == LIBUSB_ERROR_TIMEOUT) {
193 LOG_DEBUG("Error RX timeout %d", result);
195 LOG_DEBUG("Error RX Data %d", result);
200 h->read_count += transferred;
202 /* we need to make sure we have a full packet, including checksum */
203 if (h->read_count > 5) {
205 /* check that we have received an packet delimiter
206 * we do not validate the checksum
207 * reply should contain $...#AA - so we check for # */
208 if (h->read_buffer[h->read_count - 3] == '#')
213 LOG_DEBUG("maximum data retries attempted");
221 static int icdi_send_cmd(void *handle, const char *cmd)
223 struct icdi_usb_handle_s *h = handle;
225 int cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START "%s", cmd);
226 return icdi_send_packet(handle, cmd_len);
229 static int icdi_send_remote_cmd(void *handle, const char *data)
231 struct icdi_usb_handle_s *h = handle;
233 size_t cmd_len = sprintf(h->write_buffer, PACKET_START "qRcmd,");
234 cmd_len += hexify(h->write_buffer + cmd_len, (const uint8_t *)data,
235 strlen(data), h->max_packet - cmd_len);
237 return icdi_send_packet(handle, cmd_len);
240 static int icdi_get_cmd_result(void *handle)
242 struct icdi_usb_handle_s *h = handle;
249 ch = h->read_buffer[offset++];
250 if (offset > h->read_count)
254 if (memcmp("OK", h->read_buffer + offset, 2) == 0)
257 if (h->read_buffer[offset] == 'E') {
260 if (unhexify(&result, h->read_buffer + offset + 1, 1) != 1)
265 /* for now we assume everything else is ok */
269 static int icdi_usb_idcode(void *handle, uint32_t *idcode)
275 static int icdi_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val)
278 /* REVISIT: There's no target pointer here so there's no way to use target_buffer_set_u32().
279 * I guess all supported chips are little-endian anyway. */
280 h_u32_to_le(buf, val);
281 return icdi_usb_write_mem(handle, addr, 4, 1, buf);
284 static enum target_state icdi_usb_state(void *handle)
287 struct icdi_usb_handle_s *h = handle;
291 result = icdi_usb_read_mem(h, DCB_DHCSR, 4, 1, buf);
292 if (result != ERROR_OK)
293 return TARGET_UNKNOWN;
295 /* REVISIT: There's no target pointer here so there's no way to use target_buffer_get_u32().
296 * I guess all supported chips are little-endian anyway. */
297 dhcsr = le_to_h_u32(buf);
299 return TARGET_HALTED;
301 return TARGET_RUNNING;
304 static int icdi_usb_version(void *handle)
306 struct icdi_usb_handle_s *h = handle;
310 /* get info about icdi */
311 int result = icdi_send_remote_cmd(handle, "version");
312 if (result != ERROR_OK)
315 if (h->read_count < 8) {
316 LOG_ERROR("Invalid Reply Received");
321 if (unhexify((uint8_t *)version, h->read_buffer + 2, 4) != 4) {
322 LOG_WARNING("unable to get ICDI version");
326 /* null terminate and print info */
329 LOG_INFO("ICDI Firmware version: %s", version);
334 static int icdi_usb_query(void *handle)
338 struct icdi_usb_handle_s *h = handle;
340 result = icdi_send_cmd(handle, "qSupported");
341 if (result != ERROR_OK)
345 result = icdi_get_cmd_result(handle);
346 if (result != ERROR_OK) {
347 LOG_ERROR("query supported failed: 0x%x", result);
351 /* from this we can get the max packet supported */
353 /* query packet buffer size */
354 char *offset = strstr(h->read_buffer, "PacketSize");
359 max_packet = strtol(offset + 11, &separator, 16);
361 LOG_ERROR("invalid max packet, using defaults");
363 h->max_packet = max_packet;
364 LOG_DEBUG("max packet supported : %i bytes", h->max_packet);
368 /* if required re allocate packet buffer */
369 if (h->max_packet != ICDI_PACKET_SIZE) {
370 h->read_buffer = realloc(h->read_buffer, h->max_packet);
371 h->write_buffer = realloc(h->write_buffer, h->max_packet);
372 if (h->read_buffer == 0 || h->write_buffer == 0) {
373 LOG_ERROR("unable to reallocate memory");
378 /* set extended mode */
379 result = icdi_send_cmd(handle, "!");
380 if (result != ERROR_OK)
384 result = icdi_get_cmd_result(handle);
385 if (result != ERROR_OK) {
386 LOG_ERROR("unable to enable extended mode: 0x%x", result);
393 static int icdi_usb_reset(void *handle)
395 /* we do this in hla_target.c */
399 static int icdi_usb_assert_srst(void *handle, int srst)
401 /* TODO not supported yet */
402 return ERROR_COMMAND_NOTFOUND;
405 static int icdi_usb_run(void *handle)
409 /* resume target at current address */
410 result = icdi_send_cmd(handle, "c");
411 if (result != ERROR_OK)
415 result = icdi_get_cmd_result(handle);
416 if (result != ERROR_OK) {
417 LOG_ERROR("continue failed: 0x%x", result);
424 static int icdi_usb_halt(void *handle)
428 /* this query halts the target ?? */
429 result = icdi_send_cmd(handle, "?");
430 if (result != ERROR_OK)
434 result = icdi_get_cmd_result(handle);
435 if (result != ERROR_OK) {
436 LOG_ERROR("halt failed: 0x%x", result);
443 static int icdi_usb_step(void *handle)
447 /* step target at current address */
448 result = icdi_send_cmd(handle, "s");
449 if (result != ERROR_OK)
453 result = icdi_get_cmd_result(handle);
454 if (result != ERROR_OK) {
455 LOG_ERROR("step failed: 0x%x", result);
462 static int icdi_usb_read_regs(void *handle)
464 /* currently unsupported */
468 static int icdi_usb_read_reg(void *handle, unsigned int regsel, uint32_t *val)
471 struct icdi_usb_handle_s *h = handle;
474 snprintf(cmd, sizeof(cmd), "p%x", regsel);
475 result = icdi_send_cmd(handle, cmd);
476 if (result != ERROR_OK)
480 result = icdi_get_cmd_result(handle);
481 if (result != ERROR_OK) {
482 LOG_ERROR("register read failed: 0x%x", result);
488 if (unhexify(buf, h->read_buffer + 2, 4) != 4) {
489 LOG_ERROR("failed to convert result");
492 *val = le_to_h_u32(buf);
497 static int icdi_usb_write_reg(void *handle, unsigned int regsel, uint32_t val)
502 h_u32_to_le(buf, val);
504 int cmd_len = snprintf(cmd, sizeof(cmd), "P%x=", regsel);
505 hexify(cmd + cmd_len, buf, 4, sizeof(cmd));
507 result = icdi_send_cmd(handle, cmd);
508 if (result != ERROR_OK)
512 result = icdi_get_cmd_result(handle);
513 if (result != ERROR_OK) {
514 LOG_ERROR("register write failed: 0x%x", result);
521 static int icdi_usb_read_mem_int(void *handle, uint32_t addr, uint32_t len, uint8_t *buffer)
524 struct icdi_usb_handle_s *h = handle;
527 snprintf(cmd, sizeof(cmd), "x%" PRIx32 ",%" PRIx32, addr, len);
528 result = icdi_send_cmd(handle, cmd);
529 if (result != ERROR_OK)
533 result = icdi_get_cmd_result(handle);
534 if (result != ERROR_OK) {
535 LOG_ERROR("memory read failed: 0x%x", result);
540 int read_len = remote_unescape_input(h->read_buffer + 5, h->read_count - 8, (char *)buffer, len);
541 if (read_len != (int)len) {
542 LOG_ERROR("read more bytes than expected: actual 0x%x expected 0x%" PRIx32, read_len, len);
549 static int icdi_usb_write_mem_int(void *handle, uint32_t addr, uint32_t len, const uint8_t *buffer)
552 struct icdi_usb_handle_s *h = handle;
554 size_t cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START "X%" PRIx32 ",%" PRIx32 ":", addr, len);
557 cmd_len += remote_escape_output((const char *)buffer, len, h->write_buffer + cmd_len,
558 &out_len, h->max_packet - cmd_len);
560 if (out_len < (int)len) {
561 /* for now issue a error as we have no way of allocating a larger buffer */
562 LOG_ERROR("memory buffer too small: requires 0x%x actual 0x%" PRIx32, out_len, len);
566 result = icdi_send_packet(handle, cmd_len);
567 if (result != ERROR_OK)
571 result = icdi_get_cmd_result(handle);
572 if (result != ERROR_OK) {
573 LOG_ERROR("memory write failed: 0x%x", result);
580 static int icdi_usb_read_mem(void *handle, uint32_t addr, uint32_t size,
581 uint32_t count, uint8_t *buffer)
583 int retval = ERROR_OK;
584 struct icdi_usb_handle_s *h = handle;
585 uint32_t bytes_remaining;
587 /* calculate byte count */
592 bytes_remaining = h->max_rw_packet;
593 if (count < bytes_remaining)
594 bytes_remaining = count;
596 retval = icdi_usb_read_mem_int(handle, addr, bytes_remaining, buffer);
597 if (retval != ERROR_OK)
600 buffer += bytes_remaining;
601 addr += bytes_remaining;
602 count -= bytes_remaining;
608 static int icdi_usb_write_mem(void *handle, uint32_t addr, uint32_t size,
609 uint32_t count, const uint8_t *buffer)
611 int retval = ERROR_OK;
612 struct icdi_usb_handle_s *h = handle;
613 uint32_t bytes_remaining;
615 /* calculate byte count */
620 bytes_remaining = h->max_rw_packet;
621 if (count < bytes_remaining)
622 bytes_remaining = count;
624 retval = icdi_usb_write_mem_int(handle, addr, bytes_remaining, buffer);
625 if (retval != ERROR_OK)
628 buffer += bytes_remaining;
629 addr += bytes_remaining;
630 count -= bytes_remaining;
636 static int icdi_usb_override_target(const char *targetname)
638 return !strcmp(targetname, "cortex_m");
641 static int icdi_usb_close(void *handle)
643 struct icdi_usb_handle_s *h = handle;
649 jtag_libusb_close(h->usb_dev);
651 free(h->read_buffer);
652 free(h->write_buffer);
657 static int icdi_usb_open(struct hl_interface_param_s *param, void **fd)
659 /* TODO: Convert remaining libusb_ calls to jtag_libusb_ */
661 struct icdi_usb_handle_s *h;
663 LOG_DEBUG("icdi_usb_open");
665 h = calloc(1, sizeof(struct icdi_usb_handle_s));
668 LOG_ERROR("unable to allocate memory");
672 for (uint8_t i = 0; param->vid[i] && param->pid[i]; ++i)
673 LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x serial: %s", param->transport,
674 param->vid[i], param->pid[i], adapter_get_required_serial() ? adapter_get_required_serial() : "");
676 /* TI (Stellaris) ICDI provides its serial number in the USB descriptor;
677 no need to provide a callback here. */
678 jtag_libusb_open(param->vid, param->pid, &h->usb_dev, NULL);
681 LOG_ERROR("open failed");
685 if (libusb_claim_interface(h->usb_dev, 2)) {
686 LOG_DEBUG("claim interface failed");
690 /* check if mode is supported */
693 switch (param->transport) {
695 /* TODO place holder as swd is not currently supported */
696 case HL_TRANSPORT_SWD:
698 case HL_TRANSPORT_JTAG:
705 if (retval != ERROR_OK) {
706 LOG_ERROR("mode (transport) not supported by device");
710 /* allocate buffer */
711 h->read_buffer = malloc(ICDI_PACKET_SIZE);
712 h->write_buffer = malloc(ICDI_PACKET_SIZE);
713 h->max_packet = ICDI_PACKET_SIZE;
715 if (h->read_buffer == 0 || h->write_buffer == 0) {
716 LOG_DEBUG("malloc failed");
720 /* query icdi version etc */
721 retval = icdi_usb_version(h);
722 if (retval != ERROR_OK)
725 /* query icdi support */
726 retval = icdi_usb_query(h);
727 if (retval != ERROR_OK)
732 /* set the max target read/write buffer in bytes
733 * as we are using gdb binary packets to transfer memory we have to
734 * reserve half the buffer for any possible escape chars plus
735 * at least 64 bytes for the gdb packet header */
736 h->max_rw_packet = (((h->max_packet - 64) / 4) * 4) / 2;
746 struct hl_layout_api_s icdi_usb_layout_api = {
747 .open = icdi_usb_open,
748 .close = icdi_usb_close,
749 .idcode = icdi_usb_idcode,
750 .state = icdi_usb_state,
751 .reset = icdi_usb_reset,
752 .assert_srst = icdi_usb_assert_srst,
754 .halt = icdi_usb_halt,
755 .step = icdi_usb_step,
756 .read_regs = icdi_usb_read_regs,
757 .read_reg = icdi_usb_read_reg,
758 .write_reg = icdi_usb_write_reg,
759 .read_mem = icdi_usb_read_mem,
760 .write_mem = icdi_usb_write_mem,
761 .write_debug_reg = icdi_usb_write_debug_reg,
762 .override_target = icdi_usb_override_target,
763 .custom_command = icdi_send_remote_cmd,