1 /***************************************************************************
2 * Copyright (C) 2012 by Jan Dakinevich *
3 * jan.dakinevich@gmail.com *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
22 #include <helper/log.h>
23 #include <helper/binarybuffer.h>
24 #include <helper/command.h>
25 #include <jtag/interface.h>
26 #include "libusb_common.h"
33 struct sequence
*next
;
37 struct sequence
*head
;
38 struct sequence
*tail
;
41 static struct sequence
*queue_add_tail(struct queue
*queue
, int len
)
44 LOG_ERROR("BUG: sequences with zero length are not allowed");
48 struct sequence
*next
;
49 next
= malloc(sizeof(*next
));
51 next
->tms
= calloc(1, DIV_ROUND_UP(len
, 8));
59 /* Queue is empty at the moment */
62 /* Queue already contains at least one sequence */
63 queue
->tail
->next
= next
;
74 LOG_ERROR("Not enough memory");
79 static void queue_drop_head(struct queue
*queue
)
81 struct sequence
*head
= queue
->head
->next
; /* New head */
82 free(queue
->head
->tms
);
87 static void queue_free(struct queue
*queue
)
91 queue_drop_head(queue
);
97 static struct queue
*queue_alloc(void)
99 struct queue
*queue
= malloc(sizeof(*queue
));
103 LOG_ERROR("Not enough memory");
108 /* Size of usb communication buffer */
109 #define OSBDM_USB_BUFSIZE 64
110 /* Timeout for USB transfer, ms */
111 #define OSBDM_USB_TIMEOUT 1000
112 /* Write end point */
113 #define OSBDM_USB_EP_WRITE 0x01
115 #define OSBDM_USB_EP_READ 0x82
117 /* Initialize OSBDM device */
118 #define OSBDM_CMD_INIT 0x11
119 /* Execute special, not-BDM command. But only this
120 * command is used for JTAG operation */
121 #define OSBDM_CMD_SPECIAL 0x27
122 /* Execute JTAG swap (tms/tdi -> tdo) */
123 #define OSBDM_CMD_SPECIAL_SWAP 0x05
125 #define OSBDM_CMD_SPECIAL_SRST 0x01
126 /* Maximum bit-length in one swap */
127 #define OSBDM_SWAP_MAX (((OSBDM_USB_BUFSIZE - 6) / 5) * 16)
129 /* Lists of valid VID/PID pairs
131 static const uint16_t osbdm_vid
[] = { 0x15a2, 0x15a2, 0x15a2, 0 };
132 static const uint16_t osbdm_pid
[] = { 0x0042, 0x0058, 0x005e, 0 };
135 struct jtag_libusb_device_handle
*devh
; /* USB handle */
136 uint8_t buffer
[OSBDM_USB_BUFSIZE
]; /* Data to send and receive */
137 int count
; /* Count data to send and to read */
142 static struct osbdm osbdm_context
;
144 static int osbdm_send_and_recv(struct osbdm
*osbdm
)
147 int count
= jtag_libusb_bulk_write(osbdm
->devh
, OSBDM_USB_EP_WRITE
,
148 (char *)osbdm
->buffer
, osbdm
->count
, OSBDM_USB_TIMEOUT
);
150 if (count
!= osbdm
->count
) {
151 LOG_ERROR("OSBDM communication error: can't write");
155 /* Save command code for next checking */
156 uint8_t cmd_saved
= osbdm
->buffer
[0];
159 osbdm
->count
= jtag_libusb_bulk_read(osbdm
->devh
, OSBDM_USB_EP_READ
,
160 (char *)osbdm
->buffer
, OSBDM_USB_BUFSIZE
, OSBDM_USB_TIMEOUT
);
162 /* Now perform basic checks for data sent by BDM device
165 if (osbdm
->count
< 0) {
166 LOG_ERROR("OSBDM communication error: can't read");
170 if (osbdm
->count
< 2) {
171 LOG_ERROR("OSBDM communication error: reply too small");
175 if (osbdm
->count
!= osbdm
->buffer
[1]) {
176 LOG_ERROR("OSBDM communication error: reply size mismatch");
180 if (cmd_saved
!= osbdm
->buffer
[0]) {
181 LOG_ERROR("OSBDM communication error: reply command mismatch");
188 static int osbdm_srst(struct osbdm
*osbdm
, int srst
)
191 (void)memset(osbdm
->buffer
, 0, OSBDM_USB_BUFSIZE
);
195 osbdm
->buffer
[osbdm
->count
++] = OSBDM_CMD_SPECIAL
; /* Command */
196 osbdm
->buffer
[osbdm
->count
++] = OSBDM_CMD_SPECIAL_SRST
; /* Subcommand */
197 /* Length in bytes - not used */
198 osbdm
->buffer
[osbdm
->count
++] = 0;
199 osbdm
->buffer
[osbdm
->count
++] = 0;
201 osbdm
->buffer
[osbdm
->count
++] = (srst
? 0 : 0x08);
205 if (osbdm_send_and_recv(osbdm
) != ERROR_OK
)
211 static int osbdm_swap(struct osbdm
*osbdm
, void *tms
, void *tdi
,
212 void *tdo
, int length
)
214 if (length
> OSBDM_SWAP_MAX
) {
215 LOG_ERROR("BUG: bit sequence too long");
220 LOG_ERROR("BUG: bit sequence equal or less than 0");
224 int swap_count
= DIV_ROUND_UP(length
, 16);
228 (void)memset(osbdm
->buffer
, 0, OSBDM_USB_BUFSIZE
);
233 osbdm
->buffer
[osbdm
->count
++] = OSBDM_CMD_SPECIAL
; /* Command */
234 osbdm
->buffer
[osbdm
->count
++] = OSBDM_CMD_SPECIAL_SWAP
; /* Subcommand */
235 /* Length in bytes - not used */
236 osbdm
->buffer
[osbdm
->count
++] = 0;
237 osbdm
->buffer
[osbdm
->count
++] = 0;
239 osbdm
->buffer
[osbdm
->count
++] = 0;
240 osbdm
->buffer
[osbdm
->count
++] = (uint8_t)swap_count
;
242 for (int bit_idx
= 0; bit_idx
< length
; ) {
243 /* Bit count in swap */
244 int bit_count
= length
- bit_idx
;
248 osbdm
->buffer
[osbdm
->count
++] = (uint8_t)bit_count
;
250 /* Copying TMS and TDI data to output buffer */
251 uint32_t tms_data
= buf_get_u32(tms
, bit_idx
, bit_count
);
252 uint32_t tdi_data
= buf_get_u32(tdi
, bit_idx
, bit_count
);
253 osbdm
->buffer
[osbdm
->count
++] = (uint8_t)(tdi_data
>> 8);
254 osbdm
->buffer
[osbdm
->count
++] = (uint8_t)tdi_data
;
255 osbdm
->buffer
[osbdm
->count
++] = (uint8_t)(tms_data
>> 8);
256 osbdm
->buffer
[osbdm
->count
++] = (uint8_t)tms_data
;
258 /* Next bit offset */
259 bit_idx
+= bit_count
;
262 assert(osbdm
->count
<= OSBDM_USB_BUFSIZE
);
266 if (osbdm_send_and_recv(osbdm
) != ERROR_OK
)
271 if (((osbdm
->buffer
[2] << 8) | osbdm
->buffer
[3]) != 2 * swap_count
) {
272 LOG_ERROR("OSBDM communication error: invalid swap command reply");
278 uint8_t *buffer
= osbdm
->buffer
+ 4;
279 for (int bit_idx
= 0; bit_idx
< length
; ) {
280 int bit_count
= length
- bit_idx
;
285 uint32_t tdo_data
= 0;
286 tdo_data
|= (*buffer
++) << 8;
287 tdo_data
|= (*buffer
++);
288 tdo_data
>>= (16 - bit_count
);
290 /* Copy TDO to return */
291 buf_set_u32(tdo
, bit_idx
, bit_count
, tdo_data
);
293 bit_idx
+= bit_count
;
299 static int osbdm_flush(struct osbdm
*osbdm
, struct queue
* queue
)
301 uint8_t tms
[DIV_ROUND_UP(OSBDM_SWAP_MAX
, 8)];
302 uint8_t tdi
[DIV_ROUND_UP(OSBDM_SWAP_MAX
, 8)];
303 uint8_t tdo
[DIV_ROUND_UP(OSBDM_SWAP_MAX
, 8)];
305 int seq_back_len
= 0;
307 while (queue
->head
) {
308 (void)memset(tms
, 0, sizeof(tms
));
309 (void)memset(tdi
, 0, sizeof(tdi
));
310 (void)memset(tdo
, 0, sizeof(tdo
));
314 struct sequence
*seq
;
316 /* Copy from queue to tms/tdi streams
319 seq_len
= seq_back_len
;
322 while (seq
&& swap_len
!= OSBDM_SWAP_MAX
) {
323 /* Count bit for copy at this iteration.
324 * len should fit into remaining space
325 * in tms/tdo bitstreams
327 int len
= seq
->len
- seq_len
;
328 if (len
> OSBDM_SWAP_MAX
- swap_len
)
329 len
= OSBDM_SWAP_MAX
- swap_len
;
332 buf_set_buf(seq
->tms
, seq_len
, tms
, swap_len
, len
);
334 /* Set tdi data if they exists */
336 buf_set_buf(seq
->tdi
, seq_len
, tdi
, swap_len
, len
);
340 if (seq_len
== seq
->len
) {
341 seq
= seq
->next
; /* Move to next sequence */
346 if (osbdm_swap(osbdm
, tms
, tdi
, tdo
, swap_len
))
349 /* Copy from tdo stream to queue
352 for (int swap_back_len
= 0; swap_back_len
< swap_len
; ) {
353 int len
= queue
->head
->len
- seq_back_len
;
354 if (len
> swap_len
- swap_back_len
)
355 len
= swap_len
- swap_back_len
;
357 if (queue
->head
->tdo
)
358 buf_set_buf(tdo
, swap_back_len
, queue
->head
->tdo
, seq_back_len
, len
);
360 swap_back_len
+= len
;
362 if (seq_back_len
== queue
->head
->len
) {
363 queue_drop_head(queue
);
372 /* Basic operation for opening USB device */
373 static int osbdm_open(struct osbdm
*osbdm
)
375 (void)memset(osbdm
, 0, sizeof(*osbdm
));
376 if (jtag_libusb_open(osbdm_vid
, osbdm_pid
, NULL
, &osbdm
->devh
) != ERROR_OK
)
379 if (jtag_libusb_claim_interface(osbdm
->devh
, 0) != ERROR_OK
)
385 static int osbdm_quit(void)
387 jtag_libusb_close(osbdm_context
.devh
);
391 static int osbdm_add_pathmove(
396 assert(num_states
<= 32);
398 struct sequence
*next
= queue_add_tail(queue
, num_states
);
400 LOG_ERROR("BUG: can't allocate bit sequence");
405 for (int i
= 0; i
< num_states
; i
++) {
406 if (tap_state_transition(tap_get_state(), 1) == path
[i
]) {
408 } else if (tap_state_transition(tap_get_state(), 0) == path
[i
]) {
409 tms
&= ~(1 << i
); /* This line not so needed */
411 LOG_ERROR("BUG: %s -> %s isn't a valid TAP state transition",
412 tap_state_name(tap_get_state()),
413 tap_state_name(path
[i
]));
417 tap_set_state(path
[i
]);
420 buf_set_u32(next
->tms
, 0, num_states
, tms
);
421 tap_set_end_state(tap_get_state());
426 static int osbdm_add_statemove(
428 tap_state_t new_state
,
434 tap_set_end_state(new_state
);
435 if (tap_get_end_state() == TAP_RESET
) {
436 /* Ignore current state */
439 } else if (tap_get_state() != tap_get_end_state()) {
440 tms
= tap_get_tms_path(tap_get_state(), new_state
);
441 len
= tap_get_tms_path_len(tap_get_state(), new_state
);
444 if (len
&& skip_first
) {
450 struct sequence
*next
= queue_add_tail(queue
, len
);
452 LOG_ERROR("BUG: can't allocate bit sequence");
455 buf_set_u32(next
->tms
, 0, len
, tms
);
458 tap_set_state(tap_get_end_state());
462 static int osbdm_add_stableclocks(
466 if (!tap_is_state_stable(tap_get_state())) {
467 LOG_ERROR("BUG: current state (%s) is not stable",
468 tap_state_name(tap_get_state()));
472 struct sequence
*next
= queue_add_tail(queue
, count
);
474 LOG_ERROR("BUG: can't allocate bit sequence");
478 if (tap_get_state() == TAP_RESET
)
479 (void)memset(next
->tms
, 0xff, DIV_ROUND_UP(count
, 8));
484 static int osbdm_add_tms(
489 struct sequence
*next
= queue_add_tail(queue
, num_bits
);
491 LOG_ERROR("BUG: can't allocate bit sequence");
494 buf_set_buf(tms
, 0, next
->tms
, 0, num_bits
);
499 static int osbdm_add_scan(
501 struct scan_field
*fields
,
503 tap_state_t end_state
,
506 /* Move to desired shift state */
508 if (tap_get_state() != TAP_IRSHIFT
) {
509 if (osbdm_add_statemove(queue
, TAP_IRSHIFT
, 0) != ERROR_OK
)
513 if (tap_get_state() != TAP_DRSHIFT
) {
514 if (osbdm_add_statemove(queue
, TAP_DRSHIFT
, 0) != ERROR_OK
)
520 tap_set_end_state(end_state
);
521 for (int idx
= 0; idx
< num_fields
; idx
++) {
522 struct sequence
*next
= queue_add_tail(queue
, fields
[idx
].num_bits
);
524 LOG_ERROR("Can't allocate bit sequence");
528 (void)memset(next
->tms
, 0, DIV_ROUND_UP(fields
[idx
].num_bits
, 8));
529 next
->tdi
= fields
[idx
].out_value
;
530 next
->tdo
= fields
[idx
].in_value
;
535 if (tap_get_state() != tap_get_end_state()) {
536 /* Exit from IRSHIFT/DRSHIFT */
537 buf_set_u32(queue
->tail
->tms
, queue
->tail
->len
- 1, 1, 1);
539 /* Move with skip_first flag */
540 if (osbdm_add_statemove(queue
, tap_get_end_state(), 1) != ERROR_OK
)
547 static int osbdm_add_runtest(
550 tap_state_t end_state
)
552 if (osbdm_add_statemove(queue
, TAP_IDLE
, 0) != ERROR_OK
)
555 if (osbdm_add_stableclocks(queue
, num_cycles
) != ERROR_OK
)
558 if (osbdm_add_statemove(queue
, end_state
, 0) != ERROR_OK
)
564 static int osbdm_execute_command(
567 struct jtag_command
*cmd
)
569 int retval
= ERROR_OK
;
573 if (cmd
->cmd
.reset
->trst
) {
574 LOG_ERROR("BUG: nTRST signal is not supported");
577 retval
= osbdm_flush(osbdm
, queue
);
578 if (retval
== ERROR_OK
)
579 retval
= osbdm_srst(osbdm
, cmd
->cmd
.reset
->srst
);
584 retval
= osbdm_add_pathmove(
586 cmd
->cmd
.pathmove
->path
,
587 cmd
->cmd
.pathmove
->num_states
);
591 retval
= osbdm_add_statemove(
593 cmd
->cmd
.statemove
->end_state
,
597 case JTAG_STABLECLOCKS
:
598 retval
= osbdm_add_stableclocks(
600 cmd
->cmd
.stableclocks
->num_cycles
);
604 retval
= osbdm_add_tms(
607 cmd
->cmd
.tms
->num_bits
);
611 retval
= osbdm_add_scan(
613 cmd
->cmd
.scan
->fields
,
614 cmd
->cmd
.scan
->num_fields
,
615 cmd
->cmd
.scan
->end_state
,
616 cmd
->cmd
.scan
->ir_scan
);
620 retval
= osbdm_flush(osbdm
, queue
);
621 if (retval
== ERROR_OK
)
622 jtag_sleep(cmd
->cmd
.sleep
->us
);
626 retval
= osbdm_add_runtest(
628 cmd
->cmd
.runtest
->num_cycles
,
629 cmd
->cmd
.runtest
->end_state
);
633 LOG_ERROR("BUG: unknown JTAG command type encountered");
641 static int osbdm_execute_queue(void)
643 int retval
= ERROR_OK
;
645 struct queue
*queue
= queue_alloc();
647 LOG_ERROR("BUG: can't allocate bit queue");
650 struct jtag_command
*cmd
= jtag_command_queue
;
652 while (retval
== ERROR_OK
&& cmd
) {
653 retval
= osbdm_execute_command(&osbdm_context
, queue
, cmd
);
657 if (retval
== ERROR_OK
)
658 retval
= osbdm_flush(&osbdm_context
, queue
);
663 if (retval
!= ERROR_OK
) {
664 LOG_ERROR("FATAL: can't execute jtag command");
671 static int osbdm_init(void)
674 if (osbdm_open(&osbdm_context
) != ERROR_OK
) {
675 LOG_ERROR("Can't open OSBDM device");
678 /* Device successfully opened */
679 LOG_DEBUG("OSBDM init");
682 /* Perform initialize command */
683 osbdm_context
.count
= 0;
684 osbdm_context
.buffer
[osbdm_context
.count
++] = OSBDM_CMD_INIT
;
685 if (osbdm_send_and_recv(&osbdm_context
) != ERROR_OK
)
691 struct jtag_interface osbdm_interface
= {
694 .transports
= jtag_only
,
695 .execute_queue
= osbdm_execute_queue
,
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)