1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2007-2010 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
8 * Copyright (C) 2009 SoftPLC Corporation *
12 * Copyright (C) 2009 Zachary T Welch *
13 * zw@superlucidity.net *
15 * This program is free software; you can redistribute it and/or modify *
16 * it under the terms of the GNU General Public License as published by *
17 * the Free Software Foundation; either version 2 of the License, or *
18 * (at your option) any later version. *
20 * This program is distributed in the hope that it will be useful, *
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
23 * GNU General Public License for more details. *
25 * You should have received a copy of the GNU General Public License *
26 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
27 ***************************************************************************/
33 #include <jtag/jtag.h>
34 #include <jtag/interface.h>
35 #include <jtag/commands.h>
36 #include <jtag/minidriver.h>
37 #include <helper/command.h>
39 struct jtag_callback_entry
{
40 struct jtag_callback_entry
*next
;
42 jtag_callback_t callback
;
43 jtag_callback_data_t data0
;
44 jtag_callback_data_t data1
;
45 jtag_callback_data_t data2
;
46 jtag_callback_data_t data3
;
49 static struct jtag_callback_entry
*jtag_callback_queue_head
;
50 static struct jtag_callback_entry
*jtag_callback_queue_tail
;
52 static void jtag_callback_queue_reset(void)
54 jtag_callback_queue_head
= NULL
;
55 jtag_callback_queue_tail
= NULL
;
59 * Copy a struct scan_field for insertion into the queue.
61 * This allocates a new copy of out_value using cmd_queue_alloc.
63 static void cmd_queue_scan_field_clone(struct scan_field
*dst
, const struct scan_field
*src
)
65 dst
->num_bits
= src
->num_bits
;
66 dst
->out_value
= buf_cpy(src
->out_value
, cmd_queue_alloc(DIV_ROUND_UP(src
->num_bits
, 8)), src
->num_bits
);
67 dst
->in_value
= src
->in_value
;
71 * see jtag_add_ir_scan()
74 int interface_jtag_add_ir_scan(struct jtag_tap
*active
,
75 const struct scan_field
*in_fields
, tap_state_t state
)
77 size_t num_taps
= jtag_tap_count_enabled();
79 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
80 struct scan_command
*scan
= cmd_queue_alloc(sizeof(struct scan_command
));
81 struct scan_field
*out_fields
= cmd_queue_alloc(num_taps
* sizeof(struct scan_field
));
83 jtag_queue_command(cmd
);
85 cmd
->type
= JTAG_SCAN
;
89 scan
->num_fields
= num_taps
; /* one field per device */
90 scan
->fields
= out_fields
;
91 scan
->end_state
= state
;
93 struct scan_field
*field
= out_fields
; /* keep track where we insert data */
95 /* loop over all enabled TAPs */
97 for (struct jtag_tap
*tap
= jtag_tap_next_enabled(NULL
); tap
!= NULL
; tap
= jtag_tap_next_enabled(tap
)) {
98 /* search the input field list for fields for the current TAP */
101 /* if TAP is listed in input fields, copy the value */
104 cmd_queue_scan_field_clone(field
, in_fields
);
106 /* if a TAP isn't listed in input fields, set it to BYPASS */
110 field
->num_bits
= tap
->ir_length
;
111 field
->out_value
= buf_set_ones(cmd_queue_alloc(DIV_ROUND_UP(tap
->ir_length
, 8)), tap
->ir_length
);
112 field
->in_value
= NULL
; /* do not collect input for tap's in bypass */
115 /* update device information */
116 buf_cpy(field
->out_value
, tap
->cur_instr
, tap
->ir_length
);
120 /* paranoia: jtag_tap_count_enabled() and jtag_tap_next_enabled() not in sync */
121 assert(field
== out_fields
+ num_taps
);
127 * see jtag_add_dr_scan()
130 int interface_jtag_add_dr_scan(struct jtag_tap
*active
, int in_num_fields
,
131 const struct scan_field
*in_fields
, tap_state_t state
)
133 /* count devices in bypass */
135 size_t bypass_devices
= 0;
137 for (struct jtag_tap
*tap
= jtag_tap_next_enabled(NULL
); tap
!= NULL
; tap
= jtag_tap_next_enabled(tap
)) {
142 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
143 struct scan_command
*scan
= cmd_queue_alloc(sizeof(struct scan_command
));
144 struct scan_field
*out_fields
= cmd_queue_alloc((in_num_fields
+ bypass_devices
) * sizeof(struct scan_field
));
146 jtag_queue_command(cmd
);
148 cmd
->type
= JTAG_SCAN
;
149 cmd
->cmd
.scan
= scan
;
151 scan
->ir_scan
= false;
152 scan
->num_fields
= in_num_fields
+ bypass_devices
;
153 scan
->fields
= out_fields
;
154 scan
->end_state
= state
;
156 struct scan_field
*field
= out_fields
; /* keep track where we insert data */
158 /* loop over all enabled TAPs */
160 for (struct jtag_tap
*tap
= jtag_tap_next_enabled(NULL
); tap
!= NULL
; tap
= jtag_tap_next_enabled(tap
)) {
161 /* if TAP is not bypassed insert matching input fields */
164 assert(active
== tap
);
166 /* remember initial position for assert() */
167 struct scan_field
*start_field
= field
;
170 for (int j
= 0; j
< in_num_fields
; j
++) {
171 cmd_queue_scan_field_clone(field
, in_fields
+ j
);
176 assert(field
> start_field
); /* must have at least one input field per not bypassed TAP */
179 /* if a TAP is bypassed, generated a dummy bit*/
182 field
->out_value
= NULL
;
183 field
->in_value
= NULL
;
189 assert(field
== out_fields
+ scan
->num_fields
); /* no superfluous input fields permitted */
194 static int jtag_add_plain_scan(int num_bits
, const uint8_t *out_bits
,
195 uint8_t *in_bits
, tap_state_t state
, bool ir_scan
)
197 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
198 struct scan_command
*scan
= cmd_queue_alloc(sizeof(struct scan_command
));
199 struct scan_field
*out_fields
= cmd_queue_alloc(sizeof(struct scan_field
));
201 jtag_queue_command(cmd
);
203 cmd
->type
= JTAG_SCAN
;
204 cmd
->cmd
.scan
= scan
;
206 scan
->ir_scan
= ir_scan
;
207 scan
->num_fields
= 1;
208 scan
->fields
= out_fields
;
209 scan
->end_state
= state
;
211 out_fields
->num_bits
= num_bits
;
212 out_fields
->out_value
= buf_cpy(out_bits
, cmd_queue_alloc(DIV_ROUND_UP(num_bits
, 8)), num_bits
);
213 out_fields
->in_value
= in_bits
;
218 int interface_jtag_add_plain_dr_scan(int num_bits
, const uint8_t *out_bits
, uint8_t *in_bits
, tap_state_t state
)
220 return jtag_add_plain_scan(num_bits
, out_bits
, in_bits
, state
, false);
223 int interface_jtag_add_plain_ir_scan(int num_bits
, const uint8_t *out_bits
, uint8_t *in_bits
, tap_state_t state
)
225 return jtag_add_plain_scan(num_bits
, out_bits
, in_bits
, state
, true);
228 int interface_jtag_add_tlr(void)
230 tap_state_t state
= TAP_RESET
;
232 /* allocate memory for a new list member */
233 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
235 jtag_queue_command(cmd
);
237 cmd
->type
= JTAG_TLR_RESET
;
239 cmd
->cmd
.statemove
= cmd_queue_alloc(sizeof(struct statemove_command
));
240 cmd
->cmd
.statemove
->end_state
= state
;
245 int interface_add_tms_seq(unsigned num_bits
, const uint8_t *seq
, enum tap_state state
)
247 struct jtag_command
*cmd
;
249 cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
253 cmd
->type
= JTAG_TMS
;
254 cmd
->cmd
.tms
= cmd_queue_alloc(sizeof(*cmd
->cmd
.tms
));
258 /* copy the bits; our caller doesn't guarantee they'll persist */
259 cmd
->cmd
.tms
->num_bits
= num_bits
;
260 cmd
->cmd
.tms
->bits
= buf_cpy(seq
,
261 cmd_queue_alloc(DIV_ROUND_UP(num_bits
, 8)), num_bits
);
262 if (!cmd
->cmd
.tms
->bits
)
265 jtag_queue_command(cmd
);
270 int interface_jtag_add_pathmove(int num_states
, const tap_state_t
*path
)
272 /* allocate memory for a new list member */
273 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
275 jtag_queue_command(cmd
);
277 cmd
->type
= JTAG_PATHMOVE
;
279 cmd
->cmd
.pathmove
= cmd_queue_alloc(sizeof(struct pathmove_command
));
280 cmd
->cmd
.pathmove
->num_states
= num_states
;
281 cmd
->cmd
.pathmove
->path
= cmd_queue_alloc(sizeof(tap_state_t
) * num_states
);
283 for (int i
= 0; i
< num_states
; i
++)
284 cmd
->cmd
.pathmove
->path
[i
] = path
[i
];
289 int interface_jtag_add_runtest(int num_cycles
, tap_state_t state
)
291 /* allocate memory for a new list member */
292 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
294 jtag_queue_command(cmd
);
296 cmd
->type
= JTAG_RUNTEST
;
298 cmd
->cmd
.runtest
= cmd_queue_alloc(sizeof(struct runtest_command
));
299 cmd
->cmd
.runtest
->num_cycles
= num_cycles
;
300 cmd
->cmd
.runtest
->end_state
= state
;
305 int interface_jtag_add_clocks(int num_cycles
)
307 /* allocate memory for a new list member */
308 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
310 jtag_queue_command(cmd
);
312 cmd
->type
= JTAG_STABLECLOCKS
;
314 cmd
->cmd
.stableclocks
= cmd_queue_alloc(sizeof(struct stableclocks_command
));
315 cmd
->cmd
.stableclocks
->num_cycles
= num_cycles
;
320 int interface_jtag_add_reset(int req_trst
, int req_srst
)
322 /* allocate memory for a new list member */
323 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
325 jtag_queue_command(cmd
);
327 cmd
->type
= JTAG_RESET
;
329 cmd
->cmd
.reset
= cmd_queue_alloc(sizeof(struct reset_command
));
330 cmd
->cmd
.reset
->trst
= req_trst
;
331 cmd
->cmd
.reset
->srst
= req_srst
;
336 int interface_jtag_add_sleep(uint32_t us
)
338 /* allocate memory for a new list member */
339 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
341 jtag_queue_command(cmd
);
343 cmd
->type
= JTAG_SLEEP
;
345 cmd
->cmd
.sleep
= cmd_queue_alloc(sizeof(struct sleep_command
));
346 cmd
->cmd
.sleep
->us
= us
;
351 /* add callback to end of queue */
352 void interface_jtag_add_callback4(jtag_callback_t callback
,
353 jtag_callback_data_t data0
, jtag_callback_data_t data1
,
354 jtag_callback_data_t data2
, jtag_callback_data_t data3
)
356 struct jtag_callback_entry
*entry
= cmd_queue_alloc(sizeof(struct jtag_callback_entry
));
359 entry
->callback
= callback
;
360 entry
->data0
= data0
;
361 entry
->data1
= data1
;
362 entry
->data2
= data2
;
363 entry
->data3
= data3
;
365 if (jtag_callback_queue_head
== NULL
) {
366 jtag_callback_queue_head
= entry
;
367 jtag_callback_queue_tail
= entry
;
369 jtag_callback_queue_tail
->next
= entry
;
370 jtag_callback_queue_tail
= entry
;
374 int interface_jtag_execute_queue(void)
378 assert(reentry
== 0);
381 int retval
= default_interface_jtag_execute_queue();
382 if (retval
== ERROR_OK
) {
383 struct jtag_callback_entry
*entry
;
384 for (entry
= jtag_callback_queue_head
; entry
!= NULL
; entry
= entry
->next
) {
385 retval
= entry
->callback(entry
->data0
, entry
->data1
, entry
->data2
, entry
->data3
);
386 if (retval
!= ERROR_OK
)
391 jtag_command_queue_reset();
392 jtag_callback_queue_reset();
399 static int jtag_convert_to_callback4(jtag_callback_data_t data0
,
400 jtag_callback_data_t data1
, jtag_callback_data_t data2
, jtag_callback_data_t data3
)
402 ((jtag_callback1_t
)data1
)(data0
);
406 void interface_jtag_add_callback(jtag_callback1_t callback
, jtag_callback_data_t data0
)
408 jtag_add_callback4(jtag_convert_to_callback4
, data0
, (jtag_callback_data_t
)callback
, 0, 0);
411 void jtag_add_callback(jtag_callback1_t f
, jtag_callback_data_t data0
)
413 interface_jtag_add_callback(f
, data0
);
416 void jtag_add_callback4(jtag_callback_t f
, jtag_callback_data_t data0
,
417 jtag_callback_data_t data1
, jtag_callback_data_t data2
,
418 jtag_callback_data_t data3
)
420 interface_jtag_add_callback4(f
, data0
, data1
, data2
, data3
);
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)