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 */
66 /* loop through the queue */
67 while (bitq_in_state
.cmd
) {
68 /* only JTAG_SCAN command may return data */
69 if (bitq_in_state
.cmd
->type
==JTAG_SCAN
) {
70 /* loop through the fields */
71 while (bitq_in_state
.field_idx
<bitq_in_state
.cmd
->cmd
.scan
->num_fields
) {
73 field
=&bitq_in_state
.cmd
->cmd
.scan
->fields
[bitq_in_state
.field_idx
];
74 if (field
->in_check_value
|| field
->in_value
|| field
->in_handler
) {
76 if (bitq_in_state
.bit_pos
==0) {
77 /* initialize field scanning */
80 if (field
->in_value
) in_buff
=field
->in_value
;
82 /* buffer reallocation needed? */
83 if (field
->num_bits
>bitq_in_bufsize
*8) {
84 /* buffer previously allocated? */
85 if (bitq_in_buffer
!=NULL
) {
90 /* double the buffer size until it fits */
91 while (field
->num_bits
>bitq_in_bufsize
*8) bitq_in_bufsize
*=2;
93 /* if necessary, allocate buffer and check for malloc error */
94 if (bitq_in_buffer
==NULL
&& (bitq_in_buffer
=malloc(bitq_in_bufsize
))==NULL
) {
95 ERROR("malloc error");
98 in_buff
=(void *)bitq_in_buffer
;
103 while (bitq_in_state
.bit_pos
<field
->num_bits
) {
104 if ((tdo
=bitq_interface
->in())<0) {
105 #ifdef _DEBUG_JTAG_IO_
106 DEBUG("bitq in EOF");
110 if (in_mask
==0x01) in_buff
[in_idx
]=0;
111 if (tdo
) in_buff
[in_idx
]|=in_mask
;
117 bitq_in_state
.bit_pos
++;
120 if (field
->in_check_value
) {
121 /* match scanned in value */
122 for (in_idx
=0; in_idx
*8<field
->num_bits
; in_idx
++) {
123 if (field
->in_check_mask
) in_mask
=field
->in_check_mask
[in_idx
];
125 if (field
->num_bits
-in_idx
*8<8) in_mask
>>=8-(field
->num_bits
-in_idx
*8);
126 if (field
->in_check_value
[in_idx
]&in_mask
!=in_buff
[in_idx
]&in_mask
) {
127 char *captured_char
= buf_to_str(in_buff
, (field
->num_bits
> 64) ? 64 : field
->num_bits
, 16);
128 char *in_check_value_char
= buf_to_str(field
->in_check_value
, (field
->num_bits
> 64) ? 64 : field
->num_bits
, 16);
129 char *in_check_mask_char
= buf_to_str(field
->in_check_mask
, (field
->num_bits
> 64) ? 64 : field
->num_bits
, 16);
130 /* TODO: error reporting */
131 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
);
132 bitq_in_state
.status
=ERROR_JTAG_QUEUE_FAILED
;
134 free(in_check_value_char
);
135 free(in_check_mask_char
);
136 break; /* leave the comparison loop upon first mismatch */
141 if (field
->in_handler
&& bitq_in_state
.status
==ERROR_OK
) {
142 bitq_in_state
.status
=(*field
->in_handler
)(in_buff
, field
->in_handler_priv
);
147 bitq_in_state
.field_idx
++; /* advance to next field */
148 bitq_in_state
.bit_pos
=0; /* start next field from the first bit */
152 bitq_in_state
.cmd
=bitq_in_state
.cmd
->next
; /* advance to next command */
153 bitq_in_state
.field_idx
=0; /* preselect first field */
159 void bitq_io(int tms
, int tdi
, int tdo_req
)
161 bitq_interface
->out(tms
, tdi
, tdo_req
);
162 /* check and process the input queue */
163 if (bitq_interface
->in_rdy()) bitq_in_proc();
167 void bitq_end_state(enum tap_state state
)
169 if (state
==-1) return;
170 if (tap_move_map
[state
]==-1) {
171 ERROR("BUG: %i is not a valid end state", state
);
178 void bitq_state_move(enum tap_state new_state
)
183 if (tap_move_map
[cur_state
]==-1 || tap_move_map
[new_state
]==-1) {
184 ERROR("TAP move from or to unstable state");
188 tms_scan
=TAP_MOVE(cur_state
, new_state
);
190 for (i
=0; i
<7; i
++) {
191 bitq_io(tms_scan
&1, 0, 0);
195 cur_state
= new_state
;
199 void bitq_path_move(pathmove_command_t
*cmd
)
203 for (i
=0; i
<=cmd
->num_states
; i
++) {
204 if (tap_transitions
[cur_state
].low
== cmd
->path
[i
]) bitq_io(0, 0, 0);
205 else if (tap_transitions
[cur_state
].high
== cmd
->path
[i
]) bitq_io(1, 0, 0);
207 ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings
[cur_state
], tap_state_strings
[cmd
->path
[i
]]);
211 cur_state
= cmd
->path
[i
];
214 end_state
= cur_state
;
218 void bitq_runtest(int num_cycles
)
222 /* only do a state_move when we're not already in RTI */
223 if (cur_state
!= TAP_RTI
) bitq_state_move(TAP_RTI
);
225 /* execute num_cycles */
226 for (i
= 0; i
< num_cycles
; i
++)
229 /* finish in end_state */
230 if (cur_state
!= end_state
) bitq_state_move(end_state
);
234 void bitq_scan_field(scan_field_t
*field
, int pause
)
242 if (field
->in_check_value
|| field
->in_value
|| field
->in_handler
) tdo_req
=1;
245 if (field
->out_value
==NULL
) {
246 /* just send zeros and request data from TDO */
247 for (bit_cnt
=field
->num_bits
; bit_cnt
>1; bit_cnt
--)
248 bitq_io(0, 0, tdo_req
);
249 bitq_io(pause
, 0, tdo_req
);
252 /* send data, and optionally request TDO */
254 out_ptr
=field
->out_value
;
255 for (bit_cnt
=field
->num_bits
; bit_cnt
>1; bit_cnt
--) {
256 bitq_io(0, ((*out_ptr
)&out_mask
)!=0, tdo_req
);
257 if (out_mask
==0x80) {
263 bitq_io(pause
, ((*out_ptr
)&out_mask
)!=0, tdo_req
);
268 if (cur_state
==TAP_SI
) cur_state
=TAP_PI
;
269 else if (cur_state
==TAP_SD
) cur_state
=TAP_PD
;
274 void bitq_scan(scan_command_t
*cmd
)
278 if (cmd
->ir_scan
) bitq_state_move(TAP_SI
);
279 else bitq_state_move(TAP_SD
);
281 for (i
=0; i
< cmd
->num_fields
-1; i
++)
282 bitq_scan_field(&cmd
->fields
[i
], 0);
283 bitq_scan_field(&cmd
->fields
[i
], 1);
287 int bitq_execute_queue(void)
289 jtag_command_t
*cmd
= jtag_command_queue
; /* currently processed command */
291 bitq_in_state
.cmd
= jtag_command_queue
;
292 bitq_in_state
.field_idx
= 0;
293 bitq_in_state
.bit_pos
= 0;
294 bitq_in_state
.status
= ERROR_OK
;
301 #ifdef _DEBUG_JTAG_IO_
302 DEBUG("end_state: %i", cmd
->cmd
.end_state
->end_state
);
304 bitq_end_state(cmd
->cmd
.end_state
->end_state
);
308 #ifdef _DEBUG_JTAG_IO_
309 DEBUG("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
311 bitq_interface
->reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
312 if (bitq_interface
->in_rdy()) bitq_in_proc();
316 #ifdef _DEBUG_JTAG_IO_
317 DEBUG("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, cmd
->cmd
.runtest
->end_state
);
319 bitq_end_state(cmd
->cmd
.runtest
->end_state
);
320 bitq_runtest(cmd
->cmd
.runtest
->num_cycles
);
324 #ifdef _DEBUG_JTAG_IO_
325 DEBUG("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
327 bitq_end_state(cmd
->cmd
.statemove
->end_state
);
328 bitq_state_move(end_state
); /* uncoditional TAP move */
332 #ifdef _DEBUG_JTAG_IO_
333 DEBUG("pathmove: %i states, end in %i", cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
335 bitq_path_move(cmd
->cmd
.pathmove
);
339 #ifdef _DEBUG_JTAG_IO_
340 DEBUG("scan end in %i", cmd
->cmd
.scan
->end_state
);
341 if (cmd
->cmd
.scan
->ir_scan
) DEBUG("scan ir");
342 else DEBUG("scan dr");
344 bitq_end_state(cmd
->cmd
.scan
->end_state
);
345 bitq_scan(cmd
->cmd
.scan
);
346 if (cur_state
!= end_state
) bitq_state_move(end_state
);
350 #ifdef _DEBUG_JTAG_IO_
351 DEBUG("sleep %i", cmd
->cmd
.sleep
->us
);
353 bitq_interface
->sleep(cmd
->cmd
.sleep
->us
);
354 if (bitq_interface
->in_rdy()) bitq_in_proc();
358 ERROR("BUG: unknown JTAG command type encountered");
365 bitq_interface
->flush();
368 if (bitq_in_state
.cmd
) {
369 ERROR("missing data from bitq interface");
370 return ERROR_JTAG_QUEUE_FAILED
;
372 if (bitq_interface
->in()>=0) {
373 ERROR("extra data from bitq interface");
374 return ERROR_JTAG_QUEUE_FAILED
;
377 return bitq_in_state
.status
;
381 void bitq_cleanup(void)
383 if (bitq_in_buffer
!=NULL
)
385 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)