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
, NULL
, &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(struct jtag_command
*cmd_queue
)
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
= cmd_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
,