1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2005 by Dominic Rath *
5 * Dominic.Rath@gmx.de *
7 * Copyright (C) 2007-2010 Øyvind Harboe *
8 * oyvind.harboe@zylin.com *
10 * Copyright (C) 2009 SoftPLC Corporation *
11 * http://softplc.com *
14 * Copyright (C) 2009 Zachary T Welch *
15 * zw@superlucidity.net *
16 ***************************************************************************/
22 #include <jtag/jtag.h>
23 #include <jtag/interface.h>
24 #include <jtag/commands.h>
25 #include <jtag/minidriver.h>
26 #include <helper/command.h>
28 struct jtag_callback_entry
{
29 struct jtag_callback_entry
*next
;
31 jtag_callback_t callback
;
32 jtag_callback_data_t data0
;
33 jtag_callback_data_t data1
;
34 jtag_callback_data_t data2
;
35 jtag_callback_data_t data3
;
38 static struct jtag_callback_entry
*jtag_callback_queue_head
;
39 static struct jtag_callback_entry
*jtag_callback_queue_tail
;
41 static void jtag_callback_queue_reset(void)
43 jtag_callback_queue_head
= NULL
;
44 jtag_callback_queue_tail
= NULL
;
48 * see jtag_add_ir_scan()
51 int interface_jtag_add_ir_scan(struct jtag_tap
*active
,
52 const struct scan_field
*in_fields
, tap_state_t state
)
54 size_t num_taps
= jtag_tap_count_enabled();
56 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
57 struct scan_command
*scan
= cmd_queue_alloc(sizeof(struct scan_command
));
58 struct scan_field
*out_fields
= cmd_queue_alloc(num_taps
* sizeof(struct scan_field
));
60 jtag_queue_command(cmd
);
62 cmd
->type
= JTAG_SCAN
;
66 scan
->num_fields
= num_taps
; /* one field per device */
67 scan
->fields
= out_fields
;
68 scan
->end_state
= state
;
70 struct scan_field
*field
= out_fields
; /* keep track where we insert data */
72 /* loop over all enabled TAPs */
74 for (struct jtag_tap
*tap
= jtag_tap_next_enabled(NULL
); tap
; tap
= jtag_tap_next_enabled(tap
)) {
75 /* search the input field list for fields for the current TAP */
78 /* if TAP is listed in input fields, copy the value */
81 jtag_scan_field_clone(field
, in_fields
);
83 /* if a TAP isn't listed in input fields, set it to BYPASS */
87 field
->num_bits
= tap
->ir_length
;
88 field
->out_value
= buf_set_ones(cmd_queue_alloc(DIV_ROUND_UP(tap
->ir_length
, 8)), tap
->ir_length
);
89 field
->in_value
= NULL
; /* do not collect input for tap's in bypass */
92 /* update device information */
93 buf_cpy(field
->out_value
, tap
->cur_instr
, tap
->ir_length
);
97 /* paranoia: jtag_tap_count_enabled() and jtag_tap_next_enabled() not in sync */
98 assert(field
== out_fields
+ num_taps
);
104 * see jtag_add_dr_scan()
107 int interface_jtag_add_dr_scan(struct jtag_tap
*active
, int in_num_fields
,
108 const struct scan_field
*in_fields
, tap_state_t state
)
110 /* count devices in bypass */
112 size_t bypass_devices
= 0;
114 for (struct jtag_tap
*tap
= jtag_tap_next_enabled(NULL
); tap
; tap
= jtag_tap_next_enabled(tap
)) {
119 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
120 struct scan_command
*scan
= cmd_queue_alloc(sizeof(struct scan_command
));
121 struct scan_field
*out_fields
= cmd_queue_alloc((in_num_fields
+ bypass_devices
) * sizeof(struct scan_field
));
123 jtag_queue_command(cmd
);
125 cmd
->type
= JTAG_SCAN
;
126 cmd
->cmd
.scan
= scan
;
128 scan
->ir_scan
= false;
129 scan
->num_fields
= in_num_fields
+ bypass_devices
;
130 scan
->fields
= out_fields
;
131 scan
->end_state
= state
;
133 struct scan_field
*field
= out_fields
; /* keep track where we insert data */
135 /* loop over all enabled TAPs */
137 for (struct jtag_tap
*tap
= jtag_tap_next_enabled(NULL
); tap
; tap
= jtag_tap_next_enabled(tap
)) {
138 /* if TAP is not bypassed insert matching input fields */
141 assert(active
== tap
);
143 /* remember initial position for assert() */
144 struct scan_field
*start_field
= field
;
147 for (int j
= 0; j
< in_num_fields
; j
++) {
148 jtag_scan_field_clone(field
, in_fields
+ j
);
153 assert(field
> start_field
); /* must have at least one input field per not bypassed TAP */
156 /* if a TAP is bypassed, generated a dummy bit*/
159 field
->out_value
= NULL
;
160 field
->in_value
= NULL
;
166 assert(field
== out_fields
+ scan
->num_fields
); /* no superfluous input fields permitted */
171 static int jtag_add_plain_scan(int num_bits
, const uint8_t *out_bits
,
172 uint8_t *in_bits
, tap_state_t state
, bool ir_scan
)
174 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
175 struct scan_command
*scan
= cmd_queue_alloc(sizeof(struct scan_command
));
176 struct scan_field
*out_fields
= cmd_queue_alloc(sizeof(struct scan_field
));
178 jtag_queue_command(cmd
);
180 cmd
->type
= JTAG_SCAN
;
181 cmd
->cmd
.scan
= scan
;
183 scan
->ir_scan
= ir_scan
;
184 scan
->num_fields
= 1;
185 scan
->fields
= out_fields
;
186 scan
->end_state
= state
;
188 out_fields
->num_bits
= num_bits
;
189 out_fields
->out_value
= buf_cpy(out_bits
, cmd_queue_alloc(DIV_ROUND_UP(num_bits
, 8)), num_bits
);
190 out_fields
->in_value
= in_bits
;
195 int interface_jtag_add_plain_dr_scan(int num_bits
, const uint8_t *out_bits
, uint8_t *in_bits
, tap_state_t state
)
197 return jtag_add_plain_scan(num_bits
, out_bits
, in_bits
, state
, false);
200 int interface_jtag_add_plain_ir_scan(int num_bits
, const uint8_t *out_bits
, uint8_t *in_bits
, tap_state_t state
)
202 return jtag_add_plain_scan(num_bits
, out_bits
, in_bits
, state
, true);
205 int interface_jtag_add_tlr(void)
207 tap_state_t state
= TAP_RESET
;
209 /* allocate memory for a new list member */
210 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
212 jtag_queue_command(cmd
);
214 cmd
->type
= JTAG_TLR_RESET
;
216 cmd
->cmd
.statemove
= cmd_queue_alloc(sizeof(struct statemove_command
));
217 cmd
->cmd
.statemove
->end_state
= state
;
222 int interface_add_tms_seq(unsigned num_bits
, const uint8_t *seq
, enum tap_state state
)
224 struct jtag_command
*cmd
;
226 cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
230 cmd
->type
= JTAG_TMS
;
231 cmd
->cmd
.tms
= cmd_queue_alloc(sizeof(*cmd
->cmd
.tms
));
235 /* copy the bits; our caller doesn't guarantee they'll persist */
236 cmd
->cmd
.tms
->num_bits
= num_bits
;
237 cmd
->cmd
.tms
->bits
= buf_cpy(seq
,
238 cmd_queue_alloc(DIV_ROUND_UP(num_bits
, 8)), num_bits
);
239 if (!cmd
->cmd
.tms
->bits
)
242 jtag_queue_command(cmd
);
247 int interface_jtag_add_pathmove(int num_states
, const tap_state_t
*path
)
249 /* allocate memory for a new list member */
250 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
252 jtag_queue_command(cmd
);
254 cmd
->type
= JTAG_PATHMOVE
;
256 cmd
->cmd
.pathmove
= cmd_queue_alloc(sizeof(struct pathmove_command
));
257 cmd
->cmd
.pathmove
->num_states
= num_states
;
258 cmd
->cmd
.pathmove
->path
= cmd_queue_alloc(sizeof(tap_state_t
) * num_states
);
260 for (int i
= 0; i
< num_states
; i
++)
261 cmd
->cmd
.pathmove
->path
[i
] = path
[i
];
266 int interface_jtag_add_runtest(int num_cycles
, tap_state_t state
)
268 /* allocate memory for a new list member */
269 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
271 jtag_queue_command(cmd
);
273 cmd
->type
= JTAG_RUNTEST
;
275 cmd
->cmd
.runtest
= cmd_queue_alloc(sizeof(struct runtest_command
));
276 cmd
->cmd
.runtest
->num_cycles
= num_cycles
;
277 cmd
->cmd
.runtest
->end_state
= state
;
282 int interface_jtag_add_clocks(int num_cycles
)
284 /* allocate memory for a new list member */
285 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
287 jtag_queue_command(cmd
);
289 cmd
->type
= JTAG_STABLECLOCKS
;
291 cmd
->cmd
.stableclocks
= cmd_queue_alloc(sizeof(struct stableclocks_command
));
292 cmd
->cmd
.stableclocks
->num_cycles
= num_cycles
;
297 int interface_jtag_add_reset(int req_trst
, int req_srst
)
299 /* allocate memory for a new list member */
300 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
302 jtag_queue_command(cmd
);
304 cmd
->type
= JTAG_RESET
;
306 cmd
->cmd
.reset
= cmd_queue_alloc(sizeof(struct reset_command
));
307 cmd
->cmd
.reset
->trst
= req_trst
;
308 cmd
->cmd
.reset
->srst
= req_srst
;
313 int interface_jtag_add_sleep(uint32_t us
)
315 /* allocate memory for a new list member */
316 struct jtag_command
*cmd
= cmd_queue_alloc(sizeof(struct jtag_command
));
318 jtag_queue_command(cmd
);
320 cmd
->type
= JTAG_SLEEP
;
322 cmd
->cmd
.sleep
= cmd_queue_alloc(sizeof(struct sleep_command
));
323 cmd
->cmd
.sleep
->us
= us
;
328 /* add callback to end of queue */
329 void interface_jtag_add_callback4(jtag_callback_t callback
,
330 jtag_callback_data_t data0
, jtag_callback_data_t data1
,
331 jtag_callback_data_t data2
, jtag_callback_data_t data3
)
333 struct jtag_callback_entry
*entry
= cmd_queue_alloc(sizeof(struct jtag_callback_entry
));
336 entry
->callback
= callback
;
337 entry
->data0
= data0
;
338 entry
->data1
= data1
;
339 entry
->data2
= data2
;
340 entry
->data3
= data3
;
342 if (!jtag_callback_queue_head
) {
343 jtag_callback_queue_head
= entry
;
344 jtag_callback_queue_tail
= entry
;
346 jtag_callback_queue_tail
->next
= entry
;
347 jtag_callback_queue_tail
= entry
;
351 int interface_jtag_execute_queue(void)
355 assert(reentry
== 0);
358 int retval
= default_interface_jtag_execute_queue();
359 if (retval
== ERROR_OK
) {
360 struct jtag_callback_entry
*entry
;
361 for (entry
= jtag_callback_queue_head
; entry
; entry
= entry
->next
) {
362 retval
= entry
->callback(entry
->data0
, entry
->data1
, entry
->data2
, entry
->data3
);
363 if (retval
!= ERROR_OK
)
368 jtag_command_queue_reset();
369 jtag_callback_queue_reset();
376 static int jtag_convert_to_callback4(jtag_callback_data_t data0
,
377 jtag_callback_data_t data1
, jtag_callback_data_t data2
, jtag_callback_data_t data3
)
379 ((jtag_callback1_t
)data1
)(data0
);
383 void interface_jtag_add_callback(jtag_callback1_t callback
, jtag_callback_data_t data0
)
385 jtag_add_callback4(jtag_convert_to_callback4
, data0
, (jtag_callback_data_t
)callback
, 0, 0);
388 void jtag_add_callback(jtag_callback1_t f
, jtag_callback_data_t data0
)
390 interface_jtag_add_callback(f
, data0
);
393 void jtag_add_callback4(jtag_callback_t f
, jtag_callback_data_t data0
,
394 jtag_callback_data_t data1
, jtag_callback_data_t data2
,
395 jtag_callback_data_t data3
)
397 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)