1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2007,2008 Ø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, write to the *
27 * Free Software Foundation, Inc., *
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
29 ***************************************************************************/
34 #include "interface.h"
35 #include "minidriver.h"
38 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
= NULL
;
50 static struct jtag_callback_entry
*jtag_callback_queue_tail
= NULL
;
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
)
66 dst
->num_bits
= src
->num_bits
;
67 dst
->out_value
= buf_cpy(src
->out_value
, cmd_queue_alloc(CEIL(src
->num_bits
, 8)), src
->num_bits
);
68 dst
->in_value
= src
->in_value
;
73 * see jtag_add_ir_scan()
76 int interface_jtag_add_ir_scan(int in_num_fields
, const struct scan_field
*in_fields
, tap_state_t state
)
78 size_t num_taps
= jtag_tap_count_enabled();
80 struct jtag_command
* cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
81 struct scan_command
* scan
= cmd_queue_alloc(sizeof(struct scan_command
));
82 struct scan_field
* out_fields
= cmd_queue_alloc(num_taps
* sizeof(struct scan_field
));
84 jtag_queue_command(cmd
);
86 cmd
->type
= JTAG_SCAN
;
90 scan
->num_fields
= num_taps
; /* one field per device */
91 scan
->fields
= out_fields
;
92 scan
->end_state
= state
;
95 struct scan_field
* field
= out_fields
; /* keep track where we insert data */
97 /* loop over all enabled TAPs */
99 for (struct jtag_tap
* tap
= jtag_tap_next_enabled(NULL
); tap
!= NULL
; tap
= jtag_tap_next_enabled(tap
))
101 /* search the input field list for fields for the current TAP */
105 for (int j
= 0; j
< in_num_fields
; j
++)
107 if (tap
!= in_fields
[j
].tap
)
110 /* if TAP is listed in input fields, copy the value */
116 assert(in_fields
[j
].num_bits
== tap
->ir_length
); /* input fields must have the same length as the TAP's IR */
118 cmd_queue_scan_field_clone(field
, in_fields
+ j
);
125 /* if a TAP isn't listed in input fields, set it to BYPASS */
130 field
->num_bits
= tap
->ir_length
;
131 field
->out_value
= buf_set_ones(cmd_queue_alloc(CEIL(tap
->ir_length
, 8)), tap
->ir_length
);
132 field
->in_value
= NULL
; /* do not collect input for tap's in bypass */
135 /* update device information */
136 buf_cpy(field
->out_value
, tap
->cur_instr
, tap
->ir_length
);
141 assert(field
== out_fields
+ num_taps
); /* paranoia: jtag_tap_count_enabled() and jtag_tap_next_enabled() not in sync */
147 * see jtag_add_plain_ir_scan()
150 int interface_jtag_add_plain_ir_scan(int in_num_fields
, const struct scan_field
*in_fields
, tap_state_t state
)
153 struct jtag_command
* cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
154 struct scan_command
* scan
= cmd_queue_alloc(sizeof(struct scan_command
));
155 struct scan_field
* out_fields
= cmd_queue_alloc(in_num_fields
* sizeof(struct scan_field
));
157 jtag_queue_command(cmd
);
159 cmd
->type
= JTAG_SCAN
;
160 cmd
->cmd
.scan
= scan
;
162 scan
->ir_scan
= true;
163 scan
->num_fields
= in_num_fields
;
164 scan
->fields
= out_fields
;
165 scan
->end_state
= state
;
167 for (int i
= 0; i
< in_num_fields
; i
++)
168 cmd_queue_scan_field_clone(out_fields
+ i
, in_fields
+ i
);
176 * see jtag_add_dr_scan()
179 int interface_jtag_add_dr_scan(int in_num_fields
, const struct scan_field
*in_fields
, tap_state_t state
)
181 /* count devices in bypass */
183 size_t bypass_devices
= 0;
185 for (struct jtag_tap
* tap
= jtag_tap_next_enabled(NULL
); tap
!= NULL
; tap
= jtag_tap_next_enabled(tap
))
191 struct jtag_command
* cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
192 struct scan_command
* scan
= cmd_queue_alloc(sizeof(struct scan_command
));
193 struct scan_field
* out_fields
= cmd_queue_alloc((in_num_fields
+ bypass_devices
) * sizeof(struct scan_field
));
195 jtag_queue_command(cmd
);
197 cmd
->type
= JTAG_SCAN
;
198 cmd
->cmd
.scan
= scan
;
200 scan
->ir_scan
= false;
201 scan
->num_fields
= in_num_fields
+ bypass_devices
;
202 scan
->fields
= out_fields
;
203 scan
->end_state
= state
;
206 struct scan_field
* field
= out_fields
; /* keep track where we insert data */
208 /* loop over all enabled TAPs */
210 for (struct jtag_tap
* tap
= jtag_tap_next_enabled(NULL
); tap
!= NULL
; tap
= jtag_tap_next_enabled(tap
))
212 /* if TAP is not bypassed insert matching input fields */
216 struct scan_field
* start_field
= field
; /* keep initial position for assert() */
218 for (int j
= 0; j
< in_num_fields
; j
++)
220 if (tap
!= in_fields
[j
].tap
)
223 cmd_queue_scan_field_clone(field
, in_fields
+ j
);
228 assert(field
> start_field
); /* must have at least one input field per not bypassed TAP */
231 /* if a TAP is bypassed, generated a dummy bit*/
236 field
->out_value
= NULL
;
237 field
->in_value
= NULL
;
243 assert(field
== out_fields
+ scan
->num_fields
); /* no superfluous input fields permitted */
251 * Generate a DR SCAN using the array of output values passed to the function
253 * This function assumes that the parameter target_tap specifies the one TAP
254 * that is not bypassed. All other TAPs must be bypassed and the function will
255 * generate a dummy 1bit field for them.
257 * For the target_tap a sequence of output-only fields will be generated where
258 * each field has the size num_bits and the field's values are taken from
261 * The bypass status of TAPs is set by jtag_add_ir_scan().
264 void interface_jtag_add_dr_out(struct jtag_tap
*target_tap
,
267 const uint32_t *value
,
268 tap_state_t end_state
)
270 /* count devices in bypass */
272 size_t bypass_devices
= 0;
274 for (struct jtag_tap
* tap
= jtag_tap_next_enabled(NULL
); tap
!= NULL
; tap
= jtag_tap_next_enabled(tap
))
281 struct jtag_command
* cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
282 struct scan_command
* scan
= cmd_queue_alloc(sizeof(struct scan_command
));
283 struct scan_field
* out_fields
= cmd_queue_alloc((in_num_fields
+ bypass_devices
) * sizeof(struct scan_field
));
285 jtag_queue_command(cmd
);
287 cmd
->type
= JTAG_SCAN
;
288 cmd
->cmd
.scan
= scan
;
290 scan
->ir_scan
= false;
291 scan
->num_fields
= in_num_fields
+ bypass_devices
;
292 scan
->fields
= out_fields
;
293 scan
->end_state
= end_state
;
296 bool target_tap_match
= false;
298 struct scan_field
* field
= out_fields
; /* keep track where we insert data */
300 /* loop over all enabled TAPs */
302 for (struct jtag_tap
* tap
= jtag_tap_next_enabled(NULL
); tap
!= NULL
; tap
= jtag_tap_next_enabled(tap
))
304 /* if TAP is not bypassed insert matching input fields */
308 assert(tap
== target_tap
); /* target_tap must match the one not bypassed TAP */
310 target_tap_match
= true;
312 for (int j
= 0; j
< in_num_fields
; j
++)
314 uint8_t out_value
[4];
315 size_t scan_size
= num_bits
[j
];
316 buf_set_u32(out_value
, 0, scan_size
, value
[j
]);
319 field
->num_bits
= scan_size
;
320 field
->out_value
= buf_cpy(out_value
, cmd_queue_alloc(CEIL(scan_size
, 8)), scan_size
);
321 field
->in_value
= NULL
;
327 /* if a TAP is bypassed, generated a dummy bit*/
333 field
->out_value
= NULL
;
334 field
->in_value
= NULL
;
340 assert(target_tap_match
); /* target_tap should be enabled and not bypassed */
344 * see jtag_add_plain_dr_scan()
347 int interface_jtag_add_plain_dr_scan(int in_num_fields
, const struct scan_field
*in_fields
, tap_state_t state
)
349 struct jtag_command
* cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
350 struct scan_command
* scan
= cmd_queue_alloc(sizeof(struct scan_command
));
351 struct scan_field
* out_fields
= cmd_queue_alloc(in_num_fields
* sizeof(struct scan_field
));
353 jtag_queue_command(cmd
);
355 cmd
->type
= JTAG_SCAN
;
356 cmd
->cmd
.scan
= scan
;
358 scan
->ir_scan
= false;
359 scan
->num_fields
= in_num_fields
;
360 scan
->fields
= out_fields
;
361 scan
->end_state
= state
;
363 for (int i
= 0; i
< in_num_fields
; i
++)
364 cmd_queue_scan_field_clone(out_fields
+ i
, in_fields
+ i
);
369 int interface_jtag_add_tlr(void)
371 tap_state_t state
= TAP_RESET
;
373 /* allocate memory for a new list member */
374 struct jtag_command
* cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
376 jtag_queue_command(cmd
);
378 cmd
->type
= JTAG_STATEMOVE
;
380 cmd
->cmd
.statemove
= cmd_queue_alloc(sizeof(struct statemove_command
));
381 cmd
->cmd
.statemove
->end_state
= state
;
386 int interface_jtag_add_pathmove(int num_states
, const tap_state_t
*path
)
388 /* allocate memory for a new list member */
389 struct jtag_command
* cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
391 jtag_queue_command(cmd
);
393 cmd
->type
= JTAG_PATHMOVE
;
395 cmd
->cmd
.pathmove
= cmd_queue_alloc(sizeof(struct pathmove_command
));
396 cmd
->cmd
.pathmove
->num_states
= num_states
;
397 cmd
->cmd
.pathmove
->path
= cmd_queue_alloc(sizeof(tap_state_t
) * num_states
);
399 for (int i
= 0; i
< num_states
; i
++)
400 cmd
->cmd
.pathmove
->path
[i
] = path
[i
];
405 int interface_jtag_add_runtest(int num_cycles
, tap_state_t state
)
407 /* allocate memory for a new list member */
408 struct jtag_command
* cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
410 jtag_queue_command(cmd
);
412 cmd
->type
= JTAG_RUNTEST
;
414 cmd
->cmd
.runtest
= cmd_queue_alloc(sizeof(struct runtest_command
));
415 cmd
->cmd
.runtest
->num_cycles
= num_cycles
;
416 cmd
->cmd
.runtest
->end_state
= state
;
421 int interface_jtag_add_clocks(int num_cycles
)
423 /* allocate memory for a new list member */
424 struct jtag_command
* cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
426 jtag_queue_command(cmd
);
428 cmd
->type
= JTAG_STABLECLOCKS
;
430 cmd
->cmd
.stableclocks
= cmd_queue_alloc(sizeof(struct stableclocks_command
));
431 cmd
->cmd
.stableclocks
->num_cycles
= num_cycles
;
436 int interface_jtag_add_reset(int req_trst
, int req_srst
)
438 /* allocate memory for a new list member */
439 struct jtag_command
* cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
441 jtag_queue_command(cmd
);
443 cmd
->type
= JTAG_RESET
;
445 cmd
->cmd
.reset
= cmd_queue_alloc(sizeof(struct reset_command
));
446 cmd
->cmd
.reset
->trst
= req_trst
;
447 cmd
->cmd
.reset
->srst
= req_srst
;
452 int interface_jtag_add_sleep(uint32_t us
)
454 /* allocate memory for a new list member */
455 struct jtag_command
* cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
457 jtag_queue_command(cmd
);
459 cmd
->type
= JTAG_SLEEP
;
461 cmd
->cmd
.sleep
= cmd_queue_alloc(sizeof(struct sleep_command
));
462 cmd
->cmd
.sleep
->us
= us
;
467 /* add callback to end of queue */
468 void interface_jtag_add_callback4(jtag_callback_t callback
, jtag_callback_data_t data0
, jtag_callback_data_t data1
, jtag_callback_data_t data2
, jtag_callback_data_t data3
)
470 struct jtag_callback_entry
*entry
= cmd_queue_alloc(sizeof(struct jtag_callback_entry
));
473 entry
->callback
= callback
;
474 entry
->data0
= data0
;
475 entry
->data1
= data1
;
476 entry
->data2
= data2
;
477 entry
->data3
= data3
;
479 if (jtag_callback_queue_head
== NULL
)
481 jtag_callback_queue_head
= entry
;
482 jtag_callback_queue_tail
= entry
;
485 jtag_callback_queue_tail
->next
= entry
;
486 jtag_callback_queue_tail
= entry
;
490 int interface_jtag_execute_queue(void)
492 static int reentry
= 0;
497 int retval
= default_interface_jtag_execute_queue();
498 if (retval
== ERROR_OK
)
500 struct jtag_callback_entry
*entry
;
501 for (entry
= jtag_callback_queue_head
; entry
!= NULL
; entry
= entry
->next
)
503 retval
= entry
->callback(entry
->data0
, entry
->data1
, entry
->data2
, entry
->data3
);
504 if (retval
!= ERROR_OK
)
509 jtag_command_queue_reset();
510 jtag_callback_queue_reset();
517 static int jtag_convert_to_callback4(jtag_callback_data_t data0
, jtag_callback_data_t data1
, jtag_callback_data_t data2
, jtag_callback_data_t data3
)
519 ((jtag_callback1_t
)data1
)(data0
);
523 void interface_jtag_add_callback(jtag_callback1_t callback
, jtag_callback_data_t data0
)
525 jtag_add_callback4(jtag_convert_to_callback4
, data0
, (jtag_callback_data_t
)callback
, 0, 0);
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)