target: Do not use LOG_USER() for error messages
[openocd.git] / src / jtag / drivers / osbdm.c
blob8d4fc90d8847761ec62cbbf9fa373d71f95e5683
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2012 by Jan Dakinevich *
5 * jan.dakinevich@gmail.com *
6 ***************************************************************************/
7 #ifdef HAVE_CONFIG_H
8 # include "config.h"
9 #endif
11 #include <helper/log.h>
12 #include <helper/binarybuffer.h>
13 #include <helper/command.h>
14 #include <jtag/interface.h>
15 #include "libusb_helper.h"
17 struct sequence {
18 int len;
19 void *tms;
20 void *tdo;
21 const void *tdi;
22 struct sequence *next;
25 struct queue {
26 struct sequence *head;
27 struct sequence *tail;
30 static struct sequence *queue_add_tail(struct queue *queue, int len)
32 if (len <= 0) {
33 LOG_ERROR("BUG: sequences with zero length are not allowed");
34 return NULL;
37 struct sequence *next;
38 next = malloc(sizeof(*next));
39 if (next) {
40 next->tms = calloc(1, DIV_ROUND_UP(len, 8));
41 if (next->tms) {
42 next->len = len;
43 next->tdo = NULL;
44 next->tdi = NULL;
45 next->next = NULL;
47 if (!queue->head) {
48 /* Queue is empty at the moment */
49 queue->head = next;
50 } else {
51 /* Queue already contains at least one sequence */
52 queue->tail->next = next;
55 queue->tail = next;
56 } else {
57 free(next);
58 next = NULL;
62 if (!next)
63 LOG_ERROR("Not enough memory");
65 return next;
68 static void queue_drop_head(struct queue *queue)
70 struct sequence *head = queue->head->next; /* New head */
71 free(queue->head->tms);
72 free(queue->head);
73 queue->head = head;
76 static void queue_free(struct queue *queue)
78 if (queue) {
79 while (queue->head)
80 queue_drop_head(queue);
82 free(queue);
86 static struct queue *queue_alloc(void)
88 struct queue *queue = malloc(sizeof(*queue));
89 if (queue)
90 queue->head = NULL;
91 else
92 LOG_ERROR("Not enough memory");
94 return queue;
97 /* Size of usb communication buffer */
98 #define OSBDM_USB_BUFSIZE 64
99 /* Timeout for USB transfer, ms */
100 #define OSBDM_USB_TIMEOUT 1000
101 /* Write end point */
102 #define OSBDM_USB_EP_WRITE 0x01
103 /* Read end point */
104 #define OSBDM_USB_EP_READ 0x82
106 /* Initialize OSBDM device */
107 #define OSBDM_CMD_INIT 0x11
108 /* Execute special, not-BDM command. But only this
109 * command is used for JTAG operation */
110 #define OSBDM_CMD_SPECIAL 0x27
111 /* Execute JTAG swap (tms/tdi -> tdo) */
112 #define OSBDM_CMD_SPECIAL_SWAP 0x05
113 /* Reset control */
114 #define OSBDM_CMD_SPECIAL_SRST 0x01
115 /* Maximum bit-length in one swap */
116 #define OSBDM_SWAP_MAX (((OSBDM_USB_BUFSIZE - 6) / 5) * 16)
118 /* Lists of valid VID/PID pairs
120 static const uint16_t osbdm_vid[] = { 0x15a2, 0x15a2, 0x15a2, 0 };
121 static const uint16_t osbdm_pid[] = { 0x0042, 0x0058, 0x005e, 0 };
123 struct osbdm {
124 struct libusb_device_handle *devh; /* USB handle */
125 uint8_t buffer[OSBDM_USB_BUFSIZE]; /* Data to send and receive */
126 int count; /* Count data to send and to read */
129 /* osbdm instance
131 static struct osbdm osbdm_context;
133 static int osbdm_send_and_recv(struct osbdm *osbdm)
135 /* Send request */
136 int count, ret;
138 ret = jtag_libusb_bulk_write(osbdm->devh, OSBDM_USB_EP_WRITE,
139 (char *)osbdm->buffer, osbdm->count,
140 OSBDM_USB_TIMEOUT, &count);
141 if (ret || count != osbdm->count) {
142 LOG_ERROR("OSBDM communication error: can't write");
143 return ERROR_FAIL;
146 /* Save command code for next checking */
147 uint8_t cmd_saved = osbdm->buffer[0];
149 /* Reading answer */
150 ret = jtag_libusb_bulk_read(osbdm->devh, OSBDM_USB_EP_READ,
151 (char *)osbdm->buffer, OSBDM_USB_BUFSIZE,
152 OSBDM_USB_TIMEOUT, &osbdm->count);
153 /* Now perform basic checks for data sent by BDM device
155 if (ret) {
156 LOG_ERROR("OSBDM communication error: can't read");
157 return ERROR_FAIL;
160 if (osbdm->count < 2) {
161 LOG_ERROR("OSBDM communication error: reply too small");
162 return ERROR_FAIL;
165 if (osbdm->count != osbdm->buffer[1]) {
166 LOG_ERROR("OSBDM communication error: reply size mismatch");
167 return ERROR_FAIL;
170 if (cmd_saved != osbdm->buffer[0]) {
171 LOG_ERROR("OSBDM communication error: reply command mismatch");
172 return ERROR_FAIL;
175 return ERROR_OK;
178 static int osbdm_srst(struct osbdm *osbdm, int srst)
180 osbdm->count = 0;
181 (void)memset(osbdm->buffer, 0, OSBDM_USB_BUFSIZE);
183 /* Composing request
185 osbdm->buffer[osbdm->count++] = OSBDM_CMD_SPECIAL; /* Command */
186 osbdm->buffer[osbdm->count++] = OSBDM_CMD_SPECIAL_SRST; /* Subcommand */
187 /* Length in bytes - not used */
188 osbdm->buffer[osbdm->count++] = 0;
189 osbdm->buffer[osbdm->count++] = 0;
190 /* SRST state */
191 osbdm->buffer[osbdm->count++] = (srst ? 0 : 0x08);
193 /* Sending data
195 if (osbdm_send_and_recv(osbdm) != ERROR_OK)
196 return ERROR_FAIL;
198 return ERROR_OK;
201 static int osbdm_swap(struct osbdm *osbdm, void *tms, void *tdi,
202 void *tdo, int length)
204 if (length > OSBDM_SWAP_MAX) {
205 LOG_ERROR("BUG: bit sequence too long");
206 return ERROR_FAIL;
209 if (length <= 0) {
210 LOG_ERROR("BUG: bit sequence equal or less than 0");
211 return ERROR_FAIL;
214 int swap_count = DIV_ROUND_UP(length, 16);
216 /* cleanup */
217 osbdm->count = 0;
218 (void)memset(osbdm->buffer, 0, OSBDM_USB_BUFSIZE);
220 /* Composing request
223 osbdm->buffer[osbdm->count++] = OSBDM_CMD_SPECIAL; /* Command */
224 osbdm->buffer[osbdm->count++] = OSBDM_CMD_SPECIAL_SWAP; /* Subcommand */
225 /* Length in bytes - not used */
226 osbdm->buffer[osbdm->count++] = 0;
227 osbdm->buffer[osbdm->count++] = 0;
228 /* Swap count */
229 osbdm->buffer[osbdm->count++] = 0;
230 osbdm->buffer[osbdm->count++] = (uint8_t)swap_count;
232 for (int bit_idx = 0; bit_idx < length; ) {
233 /* Bit count in swap */
234 int bit_count = length - bit_idx;
235 if (bit_count > 16)
236 bit_count = 16;
238 osbdm->buffer[osbdm->count++] = (uint8_t)bit_count;
240 /* Copying TMS and TDI data to output buffer */
241 uint32_t tms_data = buf_get_u32(tms, bit_idx, bit_count);
242 uint32_t tdi_data = buf_get_u32(tdi, bit_idx, bit_count);
243 osbdm->buffer[osbdm->count++] = (uint8_t)(tdi_data >> 8);
244 osbdm->buffer[osbdm->count++] = (uint8_t)tdi_data;
245 osbdm->buffer[osbdm->count++] = (uint8_t)(tms_data >> 8);
246 osbdm->buffer[osbdm->count++] = (uint8_t)tms_data;
248 /* Next bit offset */
249 bit_idx += bit_count;
252 assert(osbdm->count <= OSBDM_USB_BUFSIZE);
254 /* Sending data
256 if (osbdm_send_and_recv(osbdm) != ERROR_OK)
257 return ERROR_FAIL;
259 /* Extra check
261 if (((osbdm->buffer[2] << 8) | osbdm->buffer[3]) != 2 * swap_count) {
262 LOG_ERROR("OSBDM communication error: invalid swap command reply");
263 return ERROR_FAIL;
266 /* Copy TDO response
268 uint8_t *buffer = osbdm->buffer + 4;
269 for (int bit_idx = 0; bit_idx < length; ) {
270 int bit_count = length - bit_idx;
271 if (bit_count > 16)
272 bit_count = 16;
274 /* Prepare data */
275 uint32_t tdo_data = 0;
276 tdo_data |= (*buffer++) << 8;
277 tdo_data |= (*buffer++);
278 tdo_data >>= (16 - bit_count);
280 /* Copy TDO to return */
281 buf_set_u32(tdo, bit_idx, bit_count, tdo_data);
283 bit_idx += bit_count;
286 return ERROR_OK;
289 static int osbdm_flush(struct osbdm *osbdm, struct queue *queue)
291 uint8_t tms[DIV_ROUND_UP(OSBDM_SWAP_MAX, 8)];
292 uint8_t tdi[DIV_ROUND_UP(OSBDM_SWAP_MAX, 8)];
293 uint8_t tdo[DIV_ROUND_UP(OSBDM_SWAP_MAX, 8)];
295 int seq_back_len = 0;
297 while (queue->head) {
298 (void)memset(tms, 0, sizeof(tms));
299 (void)memset(tdi, 0, sizeof(tdi));
300 (void)memset(tdo, 0, sizeof(tdo));
302 int seq_len;
303 int swap_len;
304 struct sequence *seq;
306 /* Copy from queue to tms/tdi streams
308 seq = queue->head;
309 seq_len = seq_back_len;
310 swap_len = 0;
312 while (seq && swap_len != OSBDM_SWAP_MAX) {
313 /* Count bit for copy at this iteration.
314 * len should fit into remaining space
315 * in tms/tdo bitstreams
317 int len = seq->len - seq_len;
318 if (len > OSBDM_SWAP_MAX - swap_len)
319 len = OSBDM_SWAP_MAX - swap_len;
321 /* Set tms data */
322 buf_set_buf(seq->tms, seq_len, tms, swap_len, len);
324 /* Set tdi data if they exists */
325 if (seq->tdi)
326 buf_set_buf(seq->tdi, seq_len, tdi, swap_len, len);
328 swap_len += len;
329 seq_len += len;
330 if (seq_len == seq->len) {
331 seq = seq->next; /* Move to next sequence */
332 seq_len = 0;
336 if (osbdm_swap(osbdm, tms, tdi, tdo, swap_len))
337 return ERROR_FAIL;
339 /* Copy from tdo stream to queue
342 for (int swap_back_len = 0; swap_back_len < swap_len; ) {
343 int len = queue->head->len - seq_back_len;
344 if (len > swap_len - swap_back_len)
345 len = swap_len - swap_back_len;
347 if (queue->head->tdo)
348 buf_set_buf(tdo, swap_back_len, queue->head->tdo, seq_back_len, len);
350 swap_back_len += len;
351 seq_back_len += len;
352 if (seq_back_len == queue->head->len) {
353 queue_drop_head(queue);
354 seq_back_len = 0;
359 return ERROR_OK;
362 /* Basic operation for opening USB device */
363 static int osbdm_open(struct osbdm *osbdm)
365 (void)memset(osbdm, 0, sizeof(*osbdm));
366 if (jtag_libusb_open(osbdm_vid, osbdm_pid, NULL, &osbdm->devh, NULL) != ERROR_OK)
367 return ERROR_FAIL;
369 if (libusb_claim_interface(osbdm->devh, 0) != ERROR_OK)
370 return ERROR_FAIL;
372 return ERROR_OK;
375 static int osbdm_quit(void)
377 jtag_libusb_close(osbdm_context.devh);
378 return ERROR_OK;
381 static int osbdm_add_pathmove(
382 struct queue *queue,
383 tap_state_t *path,
384 int num_states)
386 assert(num_states <= 32);
388 struct sequence *next = queue_add_tail(queue, num_states);
389 if (!next) {
390 LOG_ERROR("BUG: can't allocate bit sequence");
391 return ERROR_FAIL;
394 uint32_t tms = 0;
395 for (int i = 0; i < num_states; i++) {
396 if (tap_state_transition(tap_get_state(), 1) == path[i]) {
397 tms |= (1 << i);
398 } else if (tap_state_transition(tap_get_state(), 0) == path[i]) {
399 tms &= ~(1 << i); /* This line not so needed */
400 } else {
401 LOG_ERROR("BUG: %s -> %s isn't a valid TAP state transition",
402 tap_state_name(tap_get_state()),
403 tap_state_name(path[i]));
404 return ERROR_FAIL;
407 tap_set_state(path[i]);
410 buf_set_u32(next->tms, 0, num_states, tms);
411 tap_set_end_state(tap_get_state());
413 return ERROR_OK;
416 static int osbdm_add_statemove(
417 struct queue *queue,
418 tap_state_t new_state,
419 int skip_first)
421 int len = 0;
422 int tms = 0;
424 tap_set_end_state(new_state);
425 if (tap_get_end_state() == TAP_RESET) {
426 /* Ignore current state */
427 tms = 0xff;
428 len = 5;
429 } else if (tap_get_state() != tap_get_end_state()) {
430 tms = tap_get_tms_path(tap_get_state(), new_state);
431 len = tap_get_tms_path_len(tap_get_state(), new_state);
434 if (len && skip_first) {
435 len--;
436 tms >>= 1;
439 if (len) {
440 struct sequence *next = queue_add_tail(queue, len);
441 if (!next) {
442 LOG_ERROR("BUG: can't allocate bit sequence");
443 return ERROR_FAIL;
445 buf_set_u32(next->tms, 0, len, tms);
448 tap_set_state(tap_get_end_state());
449 return ERROR_OK;
452 static int osbdm_add_stableclocks(
453 struct queue *queue,
454 int count)
456 if (!tap_is_state_stable(tap_get_state())) {
457 LOG_ERROR("BUG: current state (%s) is not stable",
458 tap_state_name(tap_get_state()));
459 return ERROR_FAIL;
462 struct sequence *next = queue_add_tail(queue, count);
463 if (!next) {
464 LOG_ERROR("BUG: can't allocate bit sequence");
465 return ERROR_FAIL;
468 if (tap_get_state() == TAP_RESET)
469 (void)memset(next->tms, 0xff, DIV_ROUND_UP(count, 8));
471 return ERROR_OK;
474 static int osbdm_add_tms(
475 struct queue *queue,
476 const uint8_t *tms,
477 int num_bits)
479 struct sequence *next = queue_add_tail(queue, num_bits);
480 if (!next) {
481 LOG_ERROR("BUG: can't allocate bit sequence");
482 return ERROR_FAIL;
484 buf_set_buf(tms, 0, next->tms, 0, num_bits);
486 return ERROR_OK;
489 static int osbdm_add_scan(
490 struct queue *queue,
491 struct scan_field *fields,
492 int num_fields,
493 tap_state_t end_state,
494 bool ir_scan)
496 /* Move to desired shift state */
497 if (ir_scan) {
498 if (tap_get_state() != TAP_IRSHIFT) {
499 if (osbdm_add_statemove(queue, TAP_IRSHIFT, 0) != ERROR_OK)
500 return ERROR_FAIL;
502 } else {
503 if (tap_get_state() != TAP_DRSHIFT) {
504 if (osbdm_add_statemove(queue, TAP_DRSHIFT, 0) != ERROR_OK)
505 return ERROR_FAIL;
509 /* Add scan */
510 tap_set_end_state(end_state);
511 for (int idx = 0; idx < num_fields; idx++) {
512 struct sequence *next = queue_add_tail(queue, fields[idx].num_bits);
513 if (!next) {
514 LOG_ERROR("Can't allocate bit sequence");
515 return ERROR_FAIL;
518 (void)memset(next->tms, 0, DIV_ROUND_UP(fields[idx].num_bits, 8));
519 next->tdi = fields[idx].out_value;
520 next->tdo = fields[idx].in_value;
523 /* Move to end state
525 if (tap_get_state() != tap_get_end_state()) {
526 /* Exit from IRSHIFT/DRSHIFT */
527 buf_set_u32(queue->tail->tms, queue->tail->len - 1, 1, 1);
529 /* Move with skip_first flag */
530 if (osbdm_add_statemove(queue, tap_get_end_state(), 1) != ERROR_OK)
531 return ERROR_FAIL;
534 return ERROR_OK;
537 static int osbdm_add_runtest(
538 struct queue *queue,
539 int num_cycles,
540 tap_state_t end_state)
542 if (osbdm_add_statemove(queue, TAP_IDLE, 0) != ERROR_OK)
543 return ERROR_FAIL;
545 if (osbdm_add_stableclocks(queue, num_cycles) != ERROR_OK)
546 return ERROR_FAIL;
548 if (osbdm_add_statemove(queue, end_state, 0) != ERROR_OK)
549 return ERROR_FAIL;
551 return ERROR_OK;
554 static int osbdm_execute_command(
555 struct osbdm *osbdm,
556 struct queue *queue,
557 struct jtag_command *cmd)
559 int retval = ERROR_OK;
561 switch (cmd->type) {
562 case JTAG_RESET:
563 if (cmd->cmd.reset->trst) {
564 LOG_ERROR("BUG: nTRST signal is not supported");
565 retval = ERROR_FAIL;
566 } else {
567 retval = osbdm_flush(osbdm, queue);
568 if (retval == ERROR_OK)
569 retval = osbdm_srst(osbdm, cmd->cmd.reset->srst);
571 break;
573 case JTAG_PATHMOVE:
574 retval = osbdm_add_pathmove(
575 queue,
576 cmd->cmd.pathmove->path,
577 cmd->cmd.pathmove->num_states);
578 break;
580 case JTAG_TLR_RESET:
581 retval = osbdm_add_statemove(
582 queue,
583 cmd->cmd.statemove->end_state,
585 break;
587 case JTAG_STABLECLOCKS:
588 retval = osbdm_add_stableclocks(
589 queue,
590 cmd->cmd.stableclocks->num_cycles);
591 break;
593 case JTAG_TMS:
594 retval = osbdm_add_tms(
595 queue,
596 cmd->cmd.tms->bits,
597 cmd->cmd.tms->num_bits);
598 break;
600 case JTAG_SCAN:
601 retval = osbdm_add_scan(
602 queue,
603 cmd->cmd.scan->fields,
604 cmd->cmd.scan->num_fields,
605 cmd->cmd.scan->end_state,
606 cmd->cmd.scan->ir_scan);
607 break;
609 case JTAG_SLEEP:
610 retval = osbdm_flush(osbdm, queue);
611 if (retval == ERROR_OK)
612 jtag_sleep(cmd->cmd.sleep->us);
613 break;
615 case JTAG_RUNTEST:
616 retval = osbdm_add_runtest(
617 queue,
618 cmd->cmd.runtest->num_cycles,
619 cmd->cmd.runtest->end_state);
620 break;
622 default:
623 LOG_ERROR("BUG: unknown JTAG command type encountered");
624 retval = ERROR_FAIL;
625 break;
628 return retval;
631 static int osbdm_execute_queue(struct jtag_command *cmd_queue)
633 int retval = ERROR_OK;
635 struct queue *queue = queue_alloc();
636 if (!queue) {
637 LOG_ERROR("BUG: can't allocate bit queue");
638 retval = ERROR_FAIL;
639 } else {
640 struct jtag_command *cmd = cmd_queue;
642 while (retval == ERROR_OK && cmd) {
643 retval = osbdm_execute_command(&osbdm_context, queue, cmd);
644 cmd = cmd->next;
647 if (retval == ERROR_OK)
648 retval = osbdm_flush(&osbdm_context, queue);
650 queue_free(queue);
653 if (retval != ERROR_OK) {
654 LOG_ERROR("FATAL: can't execute jtag command");
655 exit(-1);
658 return retval;
661 static int osbdm_init(void)
663 /* Open device */
664 if (osbdm_open(&osbdm_context) != ERROR_OK) {
665 LOG_ERROR("Can't open OSBDM device");
666 return ERROR_FAIL;
667 } else {
668 /* Device successfully opened */
669 LOG_DEBUG("OSBDM init");
672 /* Perform initialize command */
673 osbdm_context.count = 0;
674 osbdm_context.buffer[osbdm_context.count++] = OSBDM_CMD_INIT;
675 if (osbdm_send_and_recv(&osbdm_context) != ERROR_OK)
676 return ERROR_FAIL;
678 return ERROR_OK;
681 static struct jtag_interface osbdm_interface = {
682 .execute_queue = osbdm_execute_queue,
685 struct adapter_driver osbdm_adapter_driver = {
686 .name = "osbdm",
687 .transports = jtag_only,
689 .init = osbdm_init,
690 .quit = osbdm_quit,
692 .jtag_ops = &osbdm_interface,