1 /***************************************************************************
2 * Copyright (C) 2007 by Pavel Chromy *
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, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
26 /* project specific includes */
30 #include "configuration.h"
41 bitq_interface_t
*bitq_interface
; /* low level bit queue interface */
43 bitq_state_t bitq_in_state
; /* state of input queue */
45 u8
*bitq_in_buffer
; /* buffer dynamically reallocated as needed */
46 unsigned long bitq_in_bufsize
=32; /* min. buffer size */
50 * input queue processing does not use jtag_read_buffer() to avoid unnecessary overhead
51 * also the buffer for incomming data is reallocated only if necessary
52 * no parameters, makes use of stored state information
54 void bitq_in_proc(void)
56 /* static information preserved between calls to increase performance */
57 static u8
*in_buff
; /* pointer to buffer for scanned data */
58 static int in_idx
; /* index of byte being scanned */
59 static u8 in_mask
; /* mask of next bit to be scanned */
64 /* loop through the queue */
65 while (bitq_in_state
.cmd
) {
66 /* only JTAG_SCAN command may return data */
67 if (bitq_in_state
.cmd
->type
==JTAG_SCAN
) {
68 /* loop through the fields */
69 while (bitq_in_state
.field_idx
<bitq_in_state
.cmd
->cmd
.scan
->num_fields
) {
71 field
=&bitq_in_state
.cmd
->cmd
.scan
->fields
[bitq_in_state
.field_idx
];
72 if (field
->in_check_value
|| field
->in_value
|| field
->in_handler
) {
74 if (bitq_in_state
.bit_pos
==0) {
75 /* initialize field scanning */
78 if (field
->in_value
) in_buff
=field
->in_value
;
80 /* buffer reallocation needed? */
81 if (field
->num_bits
>bitq_in_bufsize
*8) {
82 /* buffer previously allocated? */
83 if (bitq_in_buffer
!=NULL
) {
88 /* double the buffer size until it fits */
89 while (field
->num_bits
>bitq_in_bufsize
*8) bitq_in_bufsize
*=2;
91 /* if necessary, allocate buffer and check for malloc error */
92 if (bitq_in_buffer
==NULL
&& (bitq_in_buffer
=malloc(bitq_in_bufsize
))==NULL
) {
93 ERROR("malloc error");
96 in_buff
=(void *)bitq_in_buffer
;
101 while (bitq_in_state
.bit_pos
<field
->num_bits
) {
102 if ((tdo
=bitq_interface
->in())<0) {
103 #ifdef _DEBUG_JTAG_IO_
104 DEBUG("bitq in EOF");
108 if (in_mask
==0x01) in_buff
[in_idx
]=0;
109 if (tdo
) in_buff
[in_idx
]|=in_mask
;
115 bitq_in_state
.bit_pos
++;
118 if (field
->in_check_value
) {
119 /* match scanned in value */
120 for (in_idx
=0; in_idx
*8<field
->num_bits
; in_idx
++) {
121 if (field
->in_check_mask
) in_mask
=field
->in_check_mask
[in_idx
];
123 if (field
->num_bits
-in_idx
*8<8) in_mask
>>=8-(field
->num_bits
-in_idx
*8);
124 if (field
->in_check_value
[in_idx
]&in_mask
!=in_buff
[in_idx
]&in_mask
) {
125 char *captured_char
= buf_to_str(in_buff
, (field
->num_bits
> 64) ? 64 : field
->num_bits
, 16);
126 char *in_check_value_char
= buf_to_str(field
->in_check_value
, (field
->num_bits
> 64) ? 64 : field
->num_bits
, 16);
127 char *in_check_mask_char
= buf_to_str(field
->in_check_mask
, (field
->num_bits
> 64) ? 64 : field
->num_bits
, 16);
128 /* TODO: error reporting */
129 WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s check_mask: 0x%s", captured_char
, in_check_value_char
, in_check_mask_char
);
130 bitq_in_state
.status
=ERROR_JTAG_QUEUE_FAILED
;
132 free(in_check_value_char
);
133 free(in_check_mask_char
);
134 break; /* leave the comparison loop upon first mismatch */
139 if (field
->in_handler
&& bitq_in_state
.status
==ERROR_OK
) {
140 bitq_in_state
.status
=(*field
->in_handler
)(in_buff
, field
->in_handler_priv
);
145 bitq_in_state
.field_idx
++; /* advance to next field */
146 bitq_in_state
.bit_pos
=0; /* start next field from the first bit */
150 bitq_in_state
.cmd
=bitq_in_state
.cmd
->next
; /* advance to next command */
151 bitq_in_state
.field_idx
=0; /* preselect first field */
157 void bitq_io(int tms
, int tdi
, int tdo_req
)
159 bitq_interface
->out(tms
, tdi
, tdo_req
);
160 /* check and process the input queue */
161 if (bitq_interface
->in_rdy()) bitq_in_proc();
165 void bitq_end_state(enum tap_state state
)
167 if (state
==-1) return;
168 if (tap_move_map
[state
]==-1) {
169 ERROR("BUG: %i is not a valid end state", state
);
176 void bitq_state_move(enum tap_state new_state
)
181 if (tap_move_map
[cur_state
]==-1 || tap_move_map
[new_state
]==-1) {
182 ERROR("TAP move from or to unstable state");
186 tms_scan
=TAP_MOVE(cur_state
, new_state
);
188 for (i
=0; i
<7; i
++) {
189 bitq_io(tms_scan
&1, 0, 0);
193 cur_state
= new_state
;
197 void bitq_path_move(pathmove_command_t
*cmd
)
201 for (i
=0; i
<=cmd
->num_states
; i
++) {
202 if (tap_transitions
[cur_state
].low
== cmd
->path
[i
]) bitq_io(0, 0, 0);
203 else if (tap_transitions
[cur_state
].high
== cmd
->path
[i
]) bitq_io(1, 0, 0);
205 ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings
[cur_state
], tap_state_strings
[cmd
->path
[i
]]);
209 cur_state
= cmd
->path
[i
];
212 end_state
= cur_state
;
216 void bitq_runtest(int num_cycles
)
220 /* only do a state_move when we're not already in RTI */
221 if (cur_state
!= TAP_RTI
) bitq_state_move(TAP_RTI
);
223 /* execute num_cycles */
224 for (i
= 0; i
< num_cycles
; i
++)
227 /* finish in end_state */
228 if (cur_state
!= end_state
) bitq_state_move(end_state
);
232 void bitq_scan_field(scan_field_t
*field
, int pause
)
240 if (field
->in_check_value
|| field
->in_value
|| field
->in_handler
) tdo_req
=1;
243 if (field
->out_value
==NULL
) {
244 /* just send zeros and request data from TDO */
245 for (bit_cnt
=field
->num_bits
; bit_cnt
>1; bit_cnt
--)
246 bitq_io(0, 0, tdo_req
);
247 bitq_io(pause
, 0, tdo_req
);
250 /* send data, and optionally request TDO */
252 out_ptr
=field
->out_value
;
253 for (bit_cnt
=field
->num_bits
; bit_cnt
>1; bit_cnt
--) {
254 bitq_io(0, ((*out_ptr
)&out_mask
)!=0, tdo_req
);
255 if (out_mask
==0x80) {
261 bitq_io(pause
, ((*out_ptr
)&out_mask
)!=0, tdo_req
);
266 if (cur_state
==TAP_SI
) cur_state
=TAP_PI
;
267 else if (cur_state
==TAP_SD
) cur_state
=TAP_PD
;
272 void bitq_scan(scan_command_t
*cmd
)
276 if (cmd
->ir_scan
) bitq_state_move(TAP_SI
);
277 else bitq_state_move(TAP_SD
);
279 for (i
=0; i
< cmd
->num_fields
-1; i
++)
280 bitq_scan_field(&cmd
->fields
[i
], 0);
281 bitq_scan_field(&cmd
->fields
[i
], 1);
285 int bitq_execute_queue(void)
287 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
289 bitq_in_state
.cmd
= jtag_command_queue
;
290 bitq_in_state
.field_idx
= 0;
291 bitq_in_state
.bit_pos
= 0;
292 bitq_in_state
.status
= ERROR_OK
;
299 #ifdef _DEBUG_JTAG_IO_
300 DEBUG("end_state: %i", cmd
->cmd
.end_state
->end_state
);
302 bitq_end_state(cmd
->cmd
.end_state
->end_state
);
306 #ifdef _DEBUG_JTAG_IO_
307 DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
309 bitq_interface
->reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
310 if (bitq_interface
->in_rdy()) bitq_in_proc();
314 #ifdef _DEBUG_JTAG_IO_
315 DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
317 bitq_end_state(cmd
->cmd
.runtest
->end_state
);
318 bitq_runtest(cmd
->cmd
.runtest
->num_cycles
);
322 #ifdef _DEBUG_JTAG_IO_
323 DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
325 bitq_end_state(cmd
->cmd
.statemove
->end_state
);
326 bitq_state_move(end_state
); /* uncoditional TAP move */
330 #ifdef _DEBUG_JTAG_IO_
331 DEBUG("pathmove: %i states, end in %i", cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
333 bitq_path_move(cmd
->cmd
.pathmove
);
337 #ifdef _DEBUG_JTAG_IO_
338 DEBUG("scan end in %i", cmd
->cmd
.scan
->end_state
);
339 if (cmd
->cmd
.scan
->ir_scan
) DEBUG("scan ir");
340 else DEBUG("scan dr");
342 bitq_end_state(cmd
->cmd
.scan
->end_state
);
343 bitq_scan(cmd
->cmd
.scan
);
344 if (cur_state
!= end_state
) bitq_state_move(end_state
);
348 #ifdef _DEBUG_JTAG_IO_
349 DEBUG("sleep %i", cmd
->cmd
.sleep
->us
);
351 bitq_interface
->sleep(cmd
->cmd
.sleep
->us
);
352 if (bitq_interface
->in_rdy()) bitq_in_proc();
356 ERROR("BUG: unknown JTAG command type encountered");
363 bitq_interface
->flush();
366 if (bitq_in_state
.cmd
) {
367 ERROR("missing data from bitq interface");
368 return ERROR_JTAG_QUEUE_FAILED
;
370 if (bitq_interface
->in()>=0) {
371 ERROR("extra data from bitq interface");
372 return ERROR_JTAG_QUEUE_FAILED
;
375 return bitq_in_state
.status
;
379 void bitq_cleanup(void)
381 if (bitq_in_buffer
!=NULL
)
383 free(bitq_in_buffer
);
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)