1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /***************************************************************************
4 * Copyright (C) 2012 by Jan Dakinevich *
5 * jan.dakinevich@gmail.com *
6 ***************************************************************************/
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"
22 struct sequence *next;
26 struct sequence *head;
27 struct sequence *tail;
30 static struct sequence *queue_add_tail(struct queue *queue, int len)
33 LOG_ERROR("BUG: sequences with zero length are not allowed");
37 struct sequence *next;
38 next = malloc(sizeof(*next));
40 next->tms = calloc(1, DIV_ROUND_UP(len, 8));
48 /* Queue is empty at the moment */
51 /* Queue already contains at least one sequence */
52 queue->tail->next = next;
63 LOG_ERROR("Not enough memory");
68 static void queue_drop_head(struct queue *queue)
70 struct sequence *head = queue->head->next; /* New head */
71 free(queue->head->tms);
76 static void queue_free(struct queue *queue)
80 queue_drop_head(queue);
86 static struct queue *queue_alloc(void)
88 struct queue *queue = malloc(sizeof(*queue));
92 LOG_ERROR("Not enough memory");
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
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
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 };
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 */
131 static struct osbdm osbdm_context;
133 static int osbdm_send_and_recv(struct osbdm *osbdm)
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");
146 /* Save command code for next checking */
147 uint8_t cmd_saved = osbdm->buffer[0];
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
156 LOG_ERROR("OSBDM communication error: can't read");
160 if (osbdm->count < 2) {
161 LOG_ERROR("OSBDM communication error: reply too small");
165 if (osbdm->count != osbdm->buffer[1]) {
166 LOG_ERROR("OSBDM communication error: reply size mismatch");
170 if (cmd_saved != osbdm->buffer[0]) {
171 LOG_ERROR("OSBDM communication error: reply command mismatch");
178 static int osbdm_srst(struct osbdm *osbdm, int srst)
181 (void)memset(osbdm->buffer, 0, OSBDM_USB_BUFSIZE);
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;
191 osbdm->buffer[osbdm->count++] = (srst ? 0 : 0x08);
195 if (osbdm_send_and_recv(osbdm) != 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");
210 LOG_ERROR("BUG: bit sequence equal or less than 0");
214 int swap_count = DIV_ROUND_UP(length, 16);
218 (void)memset(osbdm->buffer, 0, OSBDM_USB_BUFSIZE);
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;
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;
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);
256 if (osbdm_send_and_recv(osbdm) != ERROR_OK)
261 if (((osbdm->buffer[2] << 8) | osbdm->buffer[3]) != 2 * swap_count) {
262 LOG_ERROR("OSBDM communication error: invalid swap command reply");
268 uint8_t *buffer = osbdm->buffer + 4;
269 for (int bit_idx = 0; bit_idx < length; ) {
270 int bit_count = length - bit_idx;
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;
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));
304 struct sequence *seq;
306 /* Copy from queue to tms/tdi streams
309 seq_len = seq_back_len;
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;
322 buf_set_buf(seq->tms, seq_len, tms, swap_len, len);
324 /* Set tdi data if they exists */
326 buf_set_buf(seq->tdi, seq_len, tdi, swap_len, len);
330 if (seq_len == seq->len) {
331 seq = seq->next; /* Move to next sequence */
336 if (osbdm_swap(osbdm, tms, tdi, tdo, swap_len))
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;
352 if (seq_back_len == queue->head->len) {
353 queue_drop_head(queue);
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, &osbdm->devh, NULL) != ERROR_OK)
369 if (libusb_claim_interface(osbdm->devh, 0) != ERROR_OK)
375 static int osbdm_quit(void)
377 jtag_libusb_close(osbdm_context.devh);
381 static int osbdm_add_pathmove(
386 assert(num_states <= 32);
388 struct sequence *next = queue_add_tail(queue, num_states);
390 LOG_ERROR("BUG: can't allocate bit sequence");
395 for (int i = 0; i < num_states; i++) {
396 if (tap_state_transition(tap_get_state(), 1) == path[i]) {
398 } else if (tap_state_transition(tap_get_state(), 0) == path[i]) {
399 tms &= ~(1 << i); /* This line not so needed */
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]));
407 tap_set_state(path[i]);
410 buf_set_u32(next->tms, 0, num_states, tms);
411 tap_set_end_state(tap_get_state());
416 static int osbdm_add_statemove(
418 tap_state_t new_state,
424 tap_set_end_state(new_state);
425 if (tap_get_end_state() == TAP_RESET) {
426 /* Ignore current state */
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) {
440 struct sequence *next = queue_add_tail(queue, len);
442 LOG_ERROR("BUG: can't allocate bit sequence");
445 buf_set_u32(next->tms, 0, len, tms);
448 tap_set_state(tap_get_end_state());
452 static int osbdm_add_stableclocks(
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()));
462 struct sequence *next = queue_add_tail(queue, count);
464 LOG_ERROR("BUG: can't allocate bit sequence");
468 if (tap_get_state() == TAP_RESET)
469 (void)memset(next->tms, 0xff, DIV_ROUND_UP(count, 8));
474 static int osbdm_add_tms(
479 struct sequence *next = queue_add_tail(queue, num_bits);
481 LOG_ERROR("BUG: can't allocate bit sequence");
484 buf_set_buf(tms, 0, next->tms, 0, num_bits);
489 static int osbdm_add_scan(
491 struct scan_field *fields,
493 tap_state_t end_state,
496 /* Move to desired shift state */
498 if (tap_get_state() != TAP_IRSHIFT) {
499 if (osbdm_add_statemove(queue, TAP_IRSHIFT, 0) != ERROR_OK)
503 if (tap_get_state() != TAP_DRSHIFT) {
504 if (osbdm_add_statemove(queue, TAP_DRSHIFT, 0) != ERROR_OK)
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);
514 LOG_ERROR("Can't allocate bit sequence");
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;
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)
537 static int osbdm_add_runtest(
540 tap_state_t end_state)
542 if (osbdm_add_statemove(queue, TAP_IDLE, 0) != ERROR_OK)
545 if (osbdm_add_stableclocks(queue, num_cycles) != ERROR_OK)
548 if (osbdm_add_statemove(queue, end_state, 0) != ERROR_OK)
554 static int osbdm_execute_command(
557 struct jtag_command *cmd)
559 int retval = ERROR_OK;
563 if (cmd->cmd.reset->trst) {
564 LOG_ERROR("BUG: nTRST signal is not supported");
567 retval = osbdm_flush(osbdm, queue);
568 if (retval == ERROR_OK)
569 retval = osbdm_srst(osbdm, cmd->cmd.reset->srst);
574 retval = osbdm_add_pathmove(
576 cmd->cmd.pathmove->path,
577 cmd->cmd.pathmove->num_states);
581 retval = osbdm_add_statemove(
583 cmd->cmd.statemove->end_state,
587 case JTAG_STABLECLOCKS:
588 retval = osbdm_add_stableclocks(
590 cmd->cmd.stableclocks->num_cycles);
594 retval = osbdm_add_tms(
597 cmd->cmd.tms->num_bits);
601 retval = osbdm_add_scan(
603 cmd->cmd.scan->fields,
604 cmd->cmd.scan->num_fields,
605 cmd->cmd.scan->end_state,
606 cmd->cmd.scan->ir_scan);
610 retval = osbdm_flush(osbdm, queue);
611 if (retval == ERROR_OK)
612 jtag_sleep(cmd->cmd.sleep->us);
616 retval = osbdm_add_runtest(
618 cmd->cmd.runtest->num_cycles,
619 cmd->cmd.runtest->end_state);
623 LOG_ERROR("BUG: unknown JTAG command type encountered");
631 static int osbdm_execute_queue(void)
633 int retval = ERROR_OK;
635 struct queue *queue = queue_alloc();
637 LOG_ERROR("BUG: can't allocate bit queue");
640 struct jtag_command *cmd = jtag_command_queue;
642 while (retval == ERROR_OK && cmd) {
643 retval = osbdm_execute_command(&osbdm_context, queue, cmd);
647 if (retval == ERROR_OK)
648 retval = osbdm_flush(&osbdm_context, queue);
653 if (retval != ERROR_OK) {
654 LOG_ERROR("FATAL: can't execute jtag command");
661 static int osbdm_init(void)
664 if (osbdm_open(&osbdm_context) != ERROR_OK) {
665 LOG_ERROR("Can't open OSBDM device");
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)
681 static struct jtag_interface osbdm_interface = {
682 .execute_queue = osbdm_execute_queue,
685 struct adapter_driver osbdm_adapter_driver = {
687 .transports = jtag_only,
692 .jtag_ops = &osbdm_interface,