hla: cleanup read/write api
[fw/openocd] / src / jtag / drivers / ti_icdi_usb.c
1 /***************************************************************************
2  *                                                                         *
3  *   Copyright (C) 2012 by Spencer Oliver                                  *
4  *   spen@spen-soft.co.uk                                                  *
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  *   This program is distributed in the hope that it will be useful,       *
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14  *   GNU General Public License for more details.                          *
15  *                                                                         *
16  *   You should have received a copy of the GNU General Public License     *
17  *   along with this program; if not, write to the                         *
18  *   Free Software Foundation, Inc.,                                       *
19  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
20  ***************************************************************************/
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 /* project specific includes */
27 #include <helper/binarybuffer.h>
28 #include <jtag/interface.h>
29 #include <jtag/hla/hla_layout.h>
30 #include <jtag/hla/hla_transport.h>
31 #include <jtag/hla/hla_interface.h>
32 #include <target/target.h>
33
34 #include <target/cortex_m.h>
35
36 #include <libusb.h>
37
38 #define ICDI_WRITE_ENDPOINT 0x02
39 #define ICDI_READ_ENDPOINT 0x83
40
41 #define ICDI_WRITE_TIMEOUT 1000
42 #define ICDI_READ_TIMEOUT 1000
43 #define ICDI_PACKET_SIZE 2048
44
45 #define PACKET_START "$"
46 #define PACKET_END "#"
47
48 struct icdi_usb_handle_s {
49         libusb_context *usb_ctx;
50         libusb_device_handle *usb_dev;
51
52         char *read_buffer;
53         char *write_buffer;
54         int max_packet;
55         int read_count;
56 };
57
58 static int icdi_usb_read_mem(void *handle, uint32_t addr, uint32_t size,
59                 uint32_t count, uint8_t *buffer);
60 static int icdi_usb_write_mem(void *handle, uint32_t addr, uint32_t size,
61                 uint32_t count, const uint8_t *buffer);
62
63 static int remote_escape_output(const char *buffer, int len, char *out_buf, int *out_len, int out_maxlen)
64 {
65         int input_index, output_index;
66
67         output_index = 0;
68
69         for (input_index = 0; input_index < len; input_index++) {
70
71                 char b = buffer[input_index];
72
73                 if (b == '$' || b == '#' || b == '}' || b == '*') {
74                         /* These must be escaped.  */
75                         if (output_index + 2 > out_maxlen)
76                                 break;
77                         out_buf[output_index++] = '}';
78                         out_buf[output_index++] = b ^ 0x20;
79                 } else {
80                         if (output_index + 1 > out_maxlen)
81                                 break;
82                         out_buf[output_index++] = b;
83                 }
84         }
85
86         *out_len = input_index;
87         return output_index;
88 }
89
90 static int remote_unescape_input(const char *buffer, int len, char *out_buf, int out_maxlen)
91 {
92         int input_index, output_index;
93         int escaped;
94
95         output_index = 0;
96         escaped = 0;
97
98         for (input_index = 0; input_index < len; input_index++) {
99
100                 char b = buffer[input_index];
101
102                 if (output_index + 1 > out_maxlen)
103                         LOG_ERROR("Received too much data from the target.");
104
105                 if (escaped) {
106                         out_buf[output_index++] = b ^ 0x20;
107                         escaped = 0;
108                 } else if (b == '}')
109                         escaped = 1;
110                 else
111                         out_buf[output_index++] = b;
112         }
113
114         if (escaped)
115                 LOG_ERROR("Unmatched escape character in target response.");
116
117         return output_index;
118 }
119
120 static int icdi_send_packet(void *handle, int len)
121 {
122         unsigned char cksum = 0;
123         struct icdi_usb_handle_s *h;
124         int result, retry = 0;
125         int transferred = 0;
126
127         assert(handle != NULL);
128         h = (struct icdi_usb_handle_s *)handle;
129
130         /* check we have a large enough buffer for checksum "#00" */
131         if (len + 3 > h->max_packet) {
132                 LOG_ERROR("packet buffer too small");
133                 return ERROR_FAIL;
134         }
135
136         /* calculate checksum - offset start of packet */
137         for (int i = 1; i < len; i++)
138                 cksum += h->write_buffer[i];
139
140         len += sprintf(&h->write_buffer[len], PACKET_END "%02x", cksum);
141
142 #ifdef _DEBUG_USB_COMMS_
143         char buffer[50];
144         char ch = h->write_buffer[1];
145         if (ch == 'x' || ch == 'X')
146                 LOG_DEBUG("writing packet: <binary>");
147         else {
148                 memcpy(buffer, h->write_buffer, len >= 50 ? 50-1 : len);
149                 buffer[len] = 0;
150                 LOG_DEBUG("writing packet: %s", buffer);
151         }
152 #endif
153
154         while (1) {
155
156                 result = libusb_bulk_transfer(h->usb_dev, ICDI_WRITE_ENDPOINT, (unsigned char *)h->write_buffer, len,
157                                 &transferred, ICDI_WRITE_TIMEOUT);
158                 if (result != 0 || transferred != len) {
159                         LOG_DEBUG("Error TX Data %d", result);
160                         return ERROR_FAIL;
161                 }
162
163                 /* check that the client got the message ok, or shall we resend */
164                 result = libusb_bulk_transfer(h->usb_dev, ICDI_READ_ENDPOINT, (unsigned char *)h->read_buffer, h->max_packet,
165                                         &transferred, ICDI_READ_TIMEOUT);
166                 if (result != 0 || transferred < 1) {
167                         LOG_DEBUG("Error RX Data %d", result);
168                         return ERROR_FAIL;
169                 }
170
171 #ifdef _DEBUG_USB_COMMS_
172                 LOG_DEBUG("received reply: '%c' : count %d", h->read_buffer[0], transferred);
173 #endif
174
175                 if (h->read_buffer[0] == '-') {
176                         LOG_DEBUG("Resending packet %d", ++retry);
177                 } else {
178                         if (h->read_buffer[0] != '+')
179                                 LOG_DEBUG("Unexpected Reply from ICDI: %c", h->read_buffer[0]);
180                         break;
181                 }
182
183                 if (retry == 3) {
184                         LOG_DEBUG("maximum nack retries attempted");
185                         return ERROR_FAIL;
186                 }
187         }
188
189         retry = 0;
190         h->read_count = transferred;
191
192         while (1) {
193
194                 /* read reply from icdi */
195                 result = libusb_bulk_transfer(h->usb_dev, ICDI_READ_ENDPOINT, (unsigned char *)h->read_buffer + h->read_count,
196                                 h->max_packet - h->read_count, &transferred, ICDI_READ_TIMEOUT);
197
198 #ifdef _DEBUG_USB_COMMS_
199                 LOG_DEBUG("received data: count %d", transferred);
200 #endif
201
202                 /* check for errors but retry for timeout */
203                 if (result != 0) {
204
205                         if (result == LIBUSB_ERROR_TIMEOUT) {
206                                 LOG_DEBUG("Error RX timeout %d", result);
207                         } else {
208                                 LOG_DEBUG("Error RX Data %d", result);
209                                 return ERROR_FAIL;
210                         }
211                 }
212
213                 h->read_count += transferred;
214
215                 /* we need to make sure we have a full packet, including checksum */
216                 if (h->read_count > 5) {
217
218                         /* check that we have received an packet delimiter
219                          * we do not validate the checksum
220                          * reply should contain $...#AA - so we check for # */
221                         if (h->read_buffer[h->read_count - 3] == '#')
222                                 return ERROR_OK;
223                 }
224
225                 if (retry++ == 3) {
226                         LOG_DEBUG("maximum data retries attempted");
227                         break;
228                 }
229         }
230
231         return ERROR_FAIL;
232 }
233
234 static int icdi_send_cmd(void *handle, const char *cmd)
235 {
236         struct icdi_usb_handle_s *h;
237         h = (struct icdi_usb_handle_s *)handle;
238
239         int cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START "%s", cmd);
240         return icdi_send_packet(handle, cmd_len);
241 }
242
243 static int icdi_send_remote_cmd(void *handle, const char *data)
244 {
245         struct icdi_usb_handle_s *h;
246         h = (struct icdi_usb_handle_s *)handle;
247
248         size_t cmd_len = sprintf(h->write_buffer, PACKET_START "qRcmd,");
249         cmd_len += hexify(h->write_buffer + cmd_len, data, 0, h->max_packet - cmd_len);
250
251         return icdi_send_packet(handle, cmd_len);
252 }
253
254 static int icdi_get_cmd_result(void *handle)
255 {
256         struct icdi_usb_handle_s *h;
257         int offset = 0;
258         char ch;
259
260         assert(handle != NULL);
261         h = (struct icdi_usb_handle_s *)handle;
262
263         do {
264                 ch = h->read_buffer[offset++];
265                 if (offset > h->read_count)
266                         return ERROR_FAIL;
267         } while (ch != '$');
268
269         if (memcmp("OK", h->read_buffer + offset, 2) == 0)
270                 return ERROR_OK;
271
272         if (h->read_buffer[offset] == 'E') {
273                 /* get error code */
274                 char result;
275                 if (unhexify(&result, h->read_buffer + offset + 1, 1) != 1)
276                         return ERROR_FAIL;
277                 return result;
278         }
279
280         /* for now we assume everything else is ok */
281         return ERROR_OK;
282 }
283
284 static int icdi_usb_idcode(void *handle, uint32_t *idcode)
285 {
286         return ERROR_OK;
287 }
288
289 static int icdi_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val)
290 {
291         return icdi_usb_write_mem(handle, addr, 4, 1, (uint8_t *)&val);
292 }
293
294 static enum target_state icdi_usb_state(void *handle)
295 {
296         int result;
297         struct icdi_usb_handle_s *h;
298         uint32_t dhcsr;
299
300         h = (struct icdi_usb_handle_s *)handle;
301
302         result = icdi_usb_read_mem(h, DCB_DHCSR, 4, 1, (uint8_t *)&dhcsr);
303         if (result != ERROR_OK)
304                 return TARGET_UNKNOWN;
305
306         if (dhcsr & S_HALT)
307                 return TARGET_HALTED;
308
309         return TARGET_RUNNING;
310 }
311
312 static int icdi_usb_version(void *handle)
313 {
314         struct icdi_usb_handle_s *h;
315         h = (struct icdi_usb_handle_s *)handle;
316
317         char version[20];
318
319         /* get info about icdi */
320         int result = icdi_send_remote_cmd(handle, "version");
321         if (result != ERROR_OK)
322                 return result;
323
324         if (h->read_count < 8) {
325                 LOG_ERROR("Invalid Reply Received");
326                 return ERROR_FAIL;
327         }
328
329         /* convert reply */
330         if (unhexify(version, h->read_buffer + 2, 4) != 4) {
331                 LOG_WARNING("unable to get ICDI version");
332                 return ERROR_OK;
333         }
334
335         /* null terminate and print info */
336         version[4] = 0;
337
338         LOG_INFO("ICDI Firmware version: %s", version);
339
340         return ERROR_OK;
341 }
342
343 static int icdi_usb_query(void *handle)
344 {
345         int result;
346
347         struct icdi_usb_handle_s *h;
348         h = (struct icdi_usb_handle_s *)handle;
349
350         result = icdi_send_cmd(handle, "qSupported");
351         if (result != ERROR_OK)
352                 return result;
353
354         /* check result */
355         result = icdi_get_cmd_result(handle);
356         if (result != ERROR_OK) {
357                 LOG_ERROR("query supported failed: 0x%x", result);
358                 return ERROR_FAIL;
359         }
360
361         /* from this we can get the max packet supported */
362
363         /* query packet buffer size */
364         char *offset = strstr(h->read_buffer, "PacketSize");
365         if (offset) {
366                 char *separator;
367                 int max_packet;
368
369                 max_packet = strtoul(offset + 11, &separator, 16);
370                 if (!max_packet)
371                         LOG_ERROR("invalid max packet, using defaults");
372                 else
373                         h->max_packet = max_packet;
374                 LOG_DEBUG("max packet supported : %" PRIu32 " bytes", h->max_packet);
375         }
376
377
378         /* if required re allocate packet buffer */
379         if (h->max_packet != ICDI_PACKET_SIZE) {
380                 h->read_buffer = realloc(h->read_buffer, h->max_packet);
381                 h->write_buffer = realloc(h->write_buffer, h->max_packet);
382                 if (h->read_buffer == 0 || h->write_buffer == 0) {
383                         LOG_ERROR("unable to reallocate memory");
384                         return ERROR_FAIL;
385                 }
386         }
387
388         /* set extended mode */
389         result = icdi_send_cmd(handle, "!");
390         if (result != ERROR_OK)
391                 return result;
392
393         /* check result */
394         result = icdi_get_cmd_result(handle);
395         if (result != ERROR_OK) {
396                 LOG_ERROR("unable to enable extended mode: 0x%x", result);
397                 return ERROR_FAIL;
398         }
399
400         return ERROR_OK;
401 }
402
403 static int icdi_usb_reset(void *handle)
404 {
405         /* we do this in hla_target.c */
406         return ERROR_OK;
407 }
408
409 static int icdi_usb_assert_srst(void *handle, int srst)
410 {
411         /* TODO not supported yet */
412         return ERROR_COMMAND_NOTFOUND;
413 }
414
415 static int icdi_usb_run(void *handle)
416 {
417         int result;
418
419         /* resume target at current address */
420         result = icdi_send_cmd(handle, "c");
421         if (result != ERROR_OK)
422                 return result;
423
424         /* check result */
425         result = icdi_get_cmd_result(handle);
426         if (result != ERROR_OK) {
427                 LOG_ERROR("continue failed: 0x%x", result);
428                 return ERROR_FAIL;
429         }
430
431         return result;
432 }
433
434 static int icdi_usb_halt(void *handle)
435 {
436         int result;
437
438         /* this query halts the target ?? */
439         result = icdi_send_cmd(handle, "?");
440         if (result != ERROR_OK)
441                 return result;
442
443         /* check result */
444         result = icdi_get_cmd_result(handle);
445         if (result != ERROR_OK) {
446                 LOG_ERROR("halt failed: 0x%x", result);
447                 return ERROR_FAIL;
448         }
449
450         return result;
451 }
452
453 static int icdi_usb_step(void *handle)
454 {
455         int result;
456
457         /* step target at current address */
458         result = icdi_send_cmd(handle, "s");
459         if (result != ERROR_OK)
460                 return result;
461
462         /* check result */
463         result = icdi_get_cmd_result(handle);
464         if (result != ERROR_OK) {
465                 LOG_ERROR("step failed: 0x%x", result);
466                 return ERROR_FAIL;
467         }
468
469         return result;
470 }
471
472 static int icdi_usb_read_regs(void *handle)
473 {
474         /* currently unsupported */
475         return ERROR_OK;
476 }
477
478 static int icdi_usb_read_reg(void *handle, int num, uint32_t *val)
479 {
480         int result;
481         struct icdi_usb_handle_s *h;
482         char cmd[10];
483
484         h = (struct icdi_usb_handle_s *)handle;
485
486         snprintf(cmd, sizeof(cmd), "p%x", num);
487         result = icdi_send_cmd(handle, cmd);
488         if (result != ERROR_OK)
489                 return result;
490
491         /* check result */
492         result = icdi_get_cmd_result(handle);
493         if (result != ERROR_OK) {
494                 LOG_ERROR("register read failed: 0x%x", result);
495                 return ERROR_FAIL;
496         }
497
498         /* convert result */
499         if (unhexify((char *)val, h->read_buffer + 2, 4) != 4) {
500                 LOG_ERROR("failed to convert result");
501                 return ERROR_FAIL;
502         }
503
504         return result;
505 }
506
507 static int icdi_usb_write_reg(void *handle, int num, uint32_t val)
508 {
509         int result;
510         char cmd[20];
511
512         int cmd_len = snprintf(cmd, sizeof(cmd), "P%x=", num);
513         hexify(cmd + cmd_len, (char *)&val, 4, sizeof(cmd));
514
515         result = icdi_send_cmd(handle, cmd);
516         if (result != ERROR_OK)
517                 return result;
518
519         /* check result */
520         result = icdi_get_cmd_result(handle);
521         if (result != ERROR_OK) {
522                 LOG_ERROR("register write failed: 0x%x", result);
523                 return ERROR_FAIL;
524         }
525
526         return result;
527 }
528
529 static int icdi_usb_read_mem_int(void *handle, uint32_t addr, uint32_t len, uint8_t *buffer)
530 {
531         int result;
532         struct icdi_usb_handle_s *h;
533         char cmd[20];
534
535         h = (struct icdi_usb_handle_s *)handle;
536
537         snprintf(cmd, sizeof(cmd), "x%x,%x", addr, len);
538         result = icdi_send_cmd(handle, cmd);
539         if (result != ERROR_OK)
540                 return result;
541
542         /* check result */
543         result = icdi_get_cmd_result(handle);
544         if (result != ERROR_OK) {
545                 LOG_ERROR("memory read failed: 0x%x", result);
546                 return ERROR_FAIL;
547         }
548
549         /* unescape input */
550         int read_len = remote_unescape_input(h->read_buffer + 5, h->read_count - 8, (char *)buffer, len);
551         if (read_len != (int)len) {
552                 LOG_ERROR("read more bytes than expected: actual 0x%" PRIx32 " expected 0x%" PRIx32, read_len, len);
553                 return ERROR_FAIL;
554         }
555
556         return ERROR_OK;
557 }
558
559 static int icdi_usb_write_mem_int(void *handle, uint32_t addr, uint32_t len, const uint8_t *buffer)
560 {
561         int result;
562         struct icdi_usb_handle_s *h;
563
564         h = (struct icdi_usb_handle_s *)handle;
565
566         size_t cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START "X%x,%x:", addr, len);
567
568         int out_len;
569         cmd_len += remote_escape_output((char *)buffer, len, h->write_buffer + cmd_len,
570                         &out_len, h->max_packet - cmd_len);
571
572         if (out_len < (int)len) {
573                 /* for now issue a error as we have no way of allocating a larger buffer */
574                 LOG_ERROR("memory buffer too small: requires 0x%" PRIx32 " actual 0x%" PRIx32, out_len, len);
575                 return ERROR_FAIL;
576         }
577
578         result = icdi_send_packet(handle, cmd_len);
579         if (result != ERROR_OK)
580                 return result;
581
582         /* check result */
583         result = icdi_get_cmd_result(handle);
584         if (result != ERROR_OK) {
585                 LOG_ERROR("memory write failed: 0x%x", result);
586                 return ERROR_FAIL;
587         }
588
589         return ERROR_OK;
590 }
591
592 static int icdi_usb_read_mem(void *handle, uint32_t addr, uint32_t size,
593                 uint32_t count, uint8_t *buffer)
594 {
595         if (size == 4)
596                 count *= size;
597         return icdi_usb_read_mem_int(handle, addr, count, buffer);
598 }
599
600 static int icdi_usb_write_mem(void *handle, uint32_t addr, uint32_t size,
601                 uint32_t count, const uint8_t *buffer)
602 {
603         if (size == 4)
604                 count *= size;
605         return icdi_usb_write_mem_int(handle, addr, count, buffer);
606 }
607
608 static int icdi_usb_close(void *handle)
609 {
610         struct icdi_usb_handle_s *h;
611
612         h = (struct icdi_usb_handle_s *)handle;
613
614         if (h->usb_dev)
615                 libusb_close(h->usb_dev);
616
617         if (h->usb_ctx)
618                 libusb_exit(h->usb_ctx);
619
620         if (h->read_buffer)
621                 free(h->read_buffer);
622
623         if (h->write_buffer)
624                 free(h->write_buffer);
625
626         free(handle);
627
628         return ERROR_OK;
629 }
630
631 static int icdi_usb_open(struct hl_interface_param_s *param, void **fd)
632 {
633         int retval;
634         struct icdi_usb_handle_s *h;
635
636         LOG_DEBUG("icdi_usb_open");
637
638         h = calloc(1, sizeof(struct icdi_usb_handle_s));
639
640         if (h == 0) {
641                 LOG_ERROR("unable to allocate memory");
642                 return ERROR_FAIL;
643         }
644
645         LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x", param->transport,
646                 param->vid, param->pid);
647
648         if (libusb_init(&h->usb_ctx) != 0) {
649                 LOG_ERROR("libusb init failed");
650                 goto error_open;
651         }
652
653         h->usb_dev = libusb_open_device_with_vid_pid(h->usb_ctx, param->vid, param->pid);
654         if (!h->usb_dev) {
655                 LOG_ERROR("open failed");
656                 goto error_open;
657         }
658
659         if (libusb_claim_interface(h->usb_dev, 2)) {
660                 LOG_DEBUG("claim interface failed");
661                 goto error_open;
662         }
663
664         /* check if mode is supported */
665         retval = ERROR_OK;
666
667         switch (param->transport) {
668 #if 0
669                 /* TODO place holder as swd is not currently supported */
670                 case HL_TRANSPORT_SWD:
671 #endif
672                 case HL_TRANSPORT_JTAG:
673                         break;
674                 default:
675                         retval = ERROR_FAIL;
676                         break;
677         }
678
679         if (retval != ERROR_OK) {
680                 LOG_ERROR("mode (transport) not supported by device");
681                 goto error_open;
682         }
683
684         /* allocate buffer */
685         h->read_buffer = malloc(ICDI_PACKET_SIZE);
686         h->write_buffer = malloc(ICDI_PACKET_SIZE);
687         h->max_packet = ICDI_PACKET_SIZE;
688
689         if (h->read_buffer == 0 || h->write_buffer == 0) {
690                 LOG_DEBUG("malloc failed");
691                 goto error_open;
692         }
693
694         /* query icdi version etc */
695         retval = icdi_usb_version(h);
696         if (retval != ERROR_OK)
697                 goto error_open;
698
699         /* query icdi support */
700         retval = icdi_usb_query(h);
701         if (retval != ERROR_OK)
702                 goto error_open;
703
704         *fd = h;
705
706         /* set the max target read/write buffer in bytes
707          * as we are using gdb binary packets to transfer memory we have to
708          * reserve half the buffer for any possible escape chars plus
709          * at least 64 bytes for the gdb packet header */
710         param->max_buffer = (((h->max_packet - 64) / 4) * 4) / 2;
711
712         return ERROR_OK;
713
714 error_open:
715         icdi_usb_close(h);
716
717         return ERROR_FAIL;
718 }
719
720 struct hl_layout_api_s icdi_usb_layout_api = {
721         .open = icdi_usb_open,
722         .close = icdi_usb_close,
723         .idcode = icdi_usb_idcode,
724         .state = icdi_usb_state,
725         .reset = icdi_usb_reset,
726         .assert_srst = icdi_usb_assert_srst,
727         .run = icdi_usb_run,
728         .halt = icdi_usb_halt,
729         .step = icdi_usb_step,
730         .read_regs = icdi_usb_read_regs,
731         .read_reg = icdi_usb_read_reg,
732         .write_reg = icdi_usb_write_reg,
733         .read_mem = icdi_usb_read_mem,
734         .write_mem = icdi_usb_write_mem,
735         .write_debug_reg = icdi_usb_write_debug_reg
736 };