arm_adi_v5: Make the DAP API stateless
[openocd.git] / src / target / adi_v5_jtag.c
1 /***************************************************************************
2 * Copyright (C) 2006 by Magnus Lundin
3 * lundin@mlu.mine.nu
4 *
5 * Copyright (C) 2008 by Spencer Oliver
6 * spen@spen-soft.co.uk
7 *
8 * Copyright (C) 2009 by Oyvind Harboe
9 * oyvind.harboe@zylin.com
10 *
11 * Copyright (C) 2009-2010 by David Brownell
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the
25 * Free Software Foundation, Inc.,
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 ***************************************************************************/
28
29 /**
30 * @file
31 * This file implements JTAG transport support for cores implementing
32 the ARM Debug Interface version 5 (ADIv5).
33 */
34
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
38
39 #include "arm.h"
40 #include "arm_adi_v5.h"
41 #include <helper/time_support.h>
42
43 /* JTAG instructions/registers for JTAG-DP and SWJ-DP */
44 #define JTAG_DP_ABORT 0x8
45 #define JTAG_DP_DPACC 0xA
46 #define JTAG_DP_APACC 0xB
47 #define JTAG_DP_IDCODE 0xE
48
49 /* three-bit ACK values for DPACC and APACC reads */
50 #define JTAG_ACK_OK_FAULT 0x2
51 #define JTAG_ACK_WAIT 0x1
52
53 static int jtag_ap_q_abort(struct adiv5_dap *dap, uint8_t *ack);
54
55 /***************************************************************************
56 *
57 * DPACC and APACC scanchain access through JTAG-DP (or SWJ-DP)
58 *
59 ***************************************************************************/
60
61 /**
62 * Scan DPACC or APACC using target ordered uint8_t buffers. No endianness
63 * conversions are performed. See section 4.4.3 of the ADIv5 spec, which
64 * discusses operations which access these registers.
65 *
66 * Note that only one scan is performed. If RnW is set, a separate scan
67 * will be needed to collect the data which was read; the "invalue" collects
68 * the posted result of a preceding operation, not the current one.
69 *
70 * @param dap the DAP
71 * @param instr JTAG_DP_APACC (AP access) or JTAG_DP_DPACC (DP access)
72 * @param reg_addr two significant bits; A[3:2]; for APACC access, the
73 * SELECT register has more addressing bits.
74 * @param RnW false iff outvalue will be written to the DP or AP
75 * @param outvalue points to a 32-bit (little-endian) integer
76 * @param invalue NULL, or points to a 32-bit (little-endian) integer
77 * @param ack points to where the three bit JTAG_ACK_* code will be stored
78 * @param memaccess_tck number of idle cycles to add after AP access
79 */
80
81 static int adi_jtag_dp_scan(struct adiv5_dap *dap,
82 uint8_t instr, uint8_t reg_addr, uint8_t RnW,
83 uint8_t *outvalue, uint8_t *invalue, uint8_t *ack,
84 uint32_t memaccess_tck)
85 {
86 struct jtag_tap *tap = dap->tap;
87 struct scan_field fields[2];
88 uint8_t out_addr_buf;
89 int retval;
90
91 retval = arm_jtag_set_instr(tap, instr, NULL, TAP_IDLE);
92 if (retval != ERROR_OK)
93 return retval;
94
95 /* Scan out a read or write operation using some DP or AP register.
96 * For APACC access with any sticky error flag set, this is discarded.
97 */
98 fields[0].num_bits = 3;
99 buf_set_u32(&out_addr_buf, 0, 3, ((reg_addr >> 1) & 0x6) | (RnW & 0x1));
100 fields[0].out_value = &out_addr_buf;
101 fields[0].in_value = ack;
102
103 /* NOTE: if we receive JTAG_ACK_WAIT, the previous operation did not
104 * complete; data we write is discarded, data we read is unpredictable.
105 * When overrun detect is active, STICKYORUN is set.
106 */
107
108 fields[1].num_bits = 32;
109 fields[1].out_value = outvalue;
110 fields[1].in_value = invalue;
111
112 jtag_add_dr_scan(tap, 2, fields, TAP_IDLE);
113
114 /* Add specified number of tck clocks after starting memory bus
115 * access, giving the hardware time to complete the access.
116 * They provide more time for the (MEM) AP to complete the read ...
117 * See "Minimum Response Time" for JTAG-DP, in the ADIv5 spec.
118 */
119 if ((instr == JTAG_DP_APACC)
120 && ((reg_addr == MEM_AP_REG_DRW)
121 || ((reg_addr & 0xF0) == MEM_AP_REG_BD0))
122 && memaccess_tck != 0)
123 jtag_add_runtest(memaccess_tck, TAP_IDLE);
124
125 return ERROR_OK;
126 }
127
128 /**
129 * Scan DPACC or APACC out and in from host ordered uint32_t buffers.
130 * This is exactly like adi_jtag_dp_scan(), except that endianness
131 * conversions are performed (so the types of invalue and outvalue
132 * must be different).
133 */
134 static int adi_jtag_dp_scan_u32(struct adiv5_dap *dap,
135 uint8_t instr, uint8_t reg_addr, uint8_t RnW,
136 uint32_t outvalue, uint32_t *invalue, uint8_t *ack,
137 uint32_t memaccess_tck)
138 {
139 uint8_t out_value_buf[4];
140 int retval;
141
142 buf_set_u32(out_value_buf, 0, 32, outvalue);
143
144 retval = adi_jtag_dp_scan(dap, instr, reg_addr, RnW,
145 out_value_buf, (uint8_t *)invalue, ack, memaccess_tck);
146 if (retval != ERROR_OK)
147 return retval;
148
149 if (invalue)
150 jtag_add_callback(arm_le_to_h_u32,
151 (jtag_callback_data_t) invalue);
152
153 return retval;
154 }
155
156 /**
157 * Utility to write AP registers.
158 */
159 static inline int adi_jtag_ap_write_check(struct adiv5_ap *ap,
160 uint8_t reg_addr, uint8_t *outvalue)
161 {
162 return adi_jtag_dp_scan(ap->dap, JTAG_DP_APACC, reg_addr, DPAP_WRITE,
163 outvalue, NULL, NULL, ap->memaccess_tck);
164 }
165
166 static int adi_jtag_scan_inout_check_u32(struct adiv5_dap *dap,
167 uint8_t instr, uint8_t reg_addr, uint8_t RnW,
168 uint32_t outvalue, uint32_t *invalue, uint32_t memaccess_tck)
169 {
170 int retval;
171
172 /* Issue the read or write */
173 retval = adi_jtag_dp_scan_u32(dap, instr, reg_addr,
174 RnW, outvalue, NULL, NULL, memaccess_tck);
175 if (retval != ERROR_OK)
176 return retval;
177
178 /* For reads, collect posted value; RDBUFF has no other effect.
179 * Assumes read gets acked with OK/FAULT, and CTRL_STAT says "OK".
180 */
181 if ((RnW == DPAP_READ) && (invalue != NULL))
182 retval = adi_jtag_dp_scan_u32(dap, JTAG_DP_DPACC,
183 DP_RDBUFF, DPAP_READ, 0, invalue, &dap->ack, 0);
184 return retval;
185 }
186
187 static int jtagdp_transaction_endcheck(struct adiv5_dap *dap)
188 {
189 int retval;
190 uint32_t ctrlstat;
191
192 /* too expensive to call keep_alive() here */
193
194 /* Here be dragons!
195 *
196 * It is easy to be in a JTAG clock range where the target
197 * is not operating in a stable fashion. This happens
198 * for a few reasons:
199 *
200 * - the user may construct a simple test case to try to see
201 * if a higher JTAG clock works to eke out more performance.
202 * This simple case may pass, but more complex situations can
203 * fail.
204 *
205 * - The mostly works JTAG clock rate and the complete failure
206 * JTAG clock rate may be as much as 2-4x apart. This seems
207 * to be especially true on RC oscillator driven parts.
208 *
209 * So: even if calling adi_jtag_scan_inout_check_u32() multiple
210 * times here seems to "make things better here", it is just
211 * hiding problems with too high a JTAG clock.
212 *
213 * Note that even if some parts have RCLK/RTCK, that doesn't
214 * mean that RCLK/RTCK is the *correct* rate to run the JTAG
215 * interface at, i.e. RCLK/RTCK rates can be "too high", especially
216 * before the RC oscillator phase is not yet complete.
217 */
218
219 /* Post CTRL/STAT read; discard any previous posted read value
220 * but collect its ACK status.
221 */
222 retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
223 DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat, 0);
224 if (retval != ERROR_OK)
225 return retval;
226 retval = jtag_execute_queue();
227 if (retval != ERROR_OK)
228 return retval;
229
230 dap->ack = dap->ack & 0x7;
231
232 /* common code path avoids calling timeval_ms() */
233 if (dap->ack != JTAG_ACK_OK_FAULT) {
234 long long then = timeval_ms();
235
236 while (dap->ack != JTAG_ACK_OK_FAULT) {
237 if (dap->ack == JTAG_ACK_WAIT) {
238 if ((timeval_ms()-then) > 1000) {
239 LOG_WARNING("Timeout (1000ms) waiting "
240 "for ACK=OK/FAULT "
241 "in JTAG-DP transaction - aborting");
242
243 uint8_t ack;
244 int abort_ret = jtag_ap_q_abort(dap, &ack);
245
246 if (abort_ret != 0)
247 LOG_WARNING("Abort failed : return=%d ack=%d", abort_ret, ack);
248
249 return ERROR_JTAG_DEVICE_ERROR;
250 }
251 } else {
252 LOG_WARNING("Invalid ACK %#x "
253 "in JTAG-DP transaction",
254 dap->ack);
255 return ERROR_JTAG_DEVICE_ERROR;
256 }
257
258 retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
259 DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat, 0);
260 if (retval != ERROR_OK)
261 return retval;
262 retval = jtag_execute_queue();
263 if (retval != ERROR_OK)
264 return retval;
265 dap->ack = dap->ack & 0x7;
266 }
267 }
268
269 /* REVISIT also STICKYCMP, for pushed comparisons (nyet used) */
270
271 /* Check for STICKYERR and STICKYORUN */
272 if (ctrlstat & (SSTICKYORUN | SSTICKYERR)) {
273 LOG_DEBUG("jtag-dp: CTRL/STAT error, 0x%" PRIx32, ctrlstat);
274 /* Check power to debug regions */
275 if ((ctrlstat & 0xf0000000) != 0xf0000000) {
276 LOG_ERROR("Debug regions are unpowered, an unexpected reset might have happened");
277 return ERROR_JTAG_DEVICE_ERROR;
278 } else {
279 if (ctrlstat & SSTICKYORUN)
280 LOG_ERROR("JTAG-DP OVERRUN - check clock, "
281 "memaccess, or reduce jtag speed");
282
283 if (ctrlstat & SSTICKYERR)
284 LOG_ERROR("JTAG-DP STICKY ERROR");
285
286 /* Clear Sticky Error Bits */
287 retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
288 DP_CTRL_STAT, DPAP_WRITE,
289 dap->dp_ctrl_stat | SSTICKYORUN
290 | SSTICKYERR, NULL, 0);
291 if (retval != ERROR_OK)
292 return retval;
293 retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
294 DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat, 0);
295 if (retval != ERROR_OK)
296 return retval;
297 retval = jtag_execute_queue();
298 if (retval != ERROR_OK)
299 return retval;
300
301 LOG_DEBUG("jtag-dp: CTRL/STAT 0x%" PRIx32, ctrlstat);
302 }
303 retval = jtag_execute_queue();
304 if (retval != ERROR_OK)
305 return retval;
306 return ERROR_JTAG_DEVICE_ERROR;
307 }
308
309 return ERROR_OK;
310 }
311
312 /*--------------------------------------------------------------------------*/
313
314 static int jtag_dp_q_read(struct adiv5_dap *dap, unsigned reg,
315 uint32_t *data)
316 {
317 return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
318 reg, DPAP_READ, 0, data, 0);
319 }
320
321 static int jtag_dp_q_write(struct adiv5_dap *dap, unsigned reg,
322 uint32_t data)
323 {
324 return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
325 reg, DPAP_WRITE, data, NULL, 0);
326 }
327
328 /** Select the AP register bank matching bits 7:4 of reg. */
329 static int jtag_ap_q_bankselect(struct adiv5_ap *ap, unsigned reg)
330 {
331 struct adiv5_dap *dap = ap->dap;
332 uint32_t select = ((uint32_t)ap->ap_num << 24) | (reg & 0x000000F0);
333
334 if (select == dap->select)
335 return ERROR_OK;
336
337 dap->select = select;
338
339 return jtag_dp_q_write(dap, DP_SELECT, select);
340 }
341
342 static int jtag_ap_q_read(struct adiv5_ap *ap, unsigned reg,
343 uint32_t *data)
344 {
345 int retval = jtag_ap_q_bankselect(ap, reg);
346
347 if (retval != ERROR_OK)
348 return retval;
349
350 return adi_jtag_scan_inout_check_u32(ap->dap, JTAG_DP_APACC, reg,
351 DPAP_READ, 0, data, ap->memaccess_tck);
352 }
353
354 static int jtag_ap_q_write(struct adiv5_ap *ap, unsigned reg,
355 uint32_t data)
356 {
357 uint8_t out_value_buf[4];
358
359 int retval = jtag_ap_q_bankselect(ap, reg);
360 if (retval != ERROR_OK)
361 return retval;
362
363 buf_set_u32(out_value_buf, 0, 32, data);
364
365 return adi_jtag_ap_write_check(ap, reg, out_value_buf);
366 }
367
368 static int jtag_ap_q_abort(struct adiv5_dap *dap, uint8_t *ack)
369 {
370 /* for JTAG, this is the only valid ABORT register operation */
371 return adi_jtag_dp_scan_u32(dap, JTAG_DP_ABORT,
372 0, DPAP_WRITE, 1, NULL, ack, 0);
373 }
374
375 static int jtag_dp_run(struct adiv5_dap *dap)
376 {
377 return jtagdp_transaction_endcheck(dap);
378 }
379
380 /* FIXME don't export ... just initialize as
381 * part of DAP setup
382 */
383 const struct dap_ops jtag_dp_ops = {
384 .queue_dp_read = jtag_dp_q_read,
385 .queue_dp_write = jtag_dp_q_write,
386 .queue_ap_read = jtag_ap_q_read,
387 .queue_ap_write = jtag_ap_q_write,
388 .queue_ap_abort = jtag_ap_q_abort,
389 .run = jtag_dp_run,
390 };
391
392
393 static const uint8_t swd2jtag_bitseq[] = {
394 /* More than 50 TCK/SWCLK cycles with TMS/SWDIO high,
395 * putting both JTAG and SWD logic into reset state.
396 */
397 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
398 /* Switching equence disables SWD and enables JTAG
399 * NOTE: bits in the DP's IDCODE can expose the need for
400 * the old/deprecated sequence (0xae 0xde).
401 */
402 0x3c, 0xe7,
403 /* At least 50 TCK/SWCLK cycles with TMS/SWDIO high,
404 * putting both JTAG and SWD logic into reset state.
405 * NOTE: some docs say "at least 5".
406 */
407 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
408 };
409
410 /** Put the debug link into JTAG mode, if the target supports it.
411 * The link's initial mode may be either SWD or JTAG.
412 *
413 * @param target Enters JTAG mode (if possible).
414 *
415 * Note that targets implemented with SW-DP do not support JTAG, and
416 * that some targets which could otherwise support it may have been
417 * configured to disable JTAG signaling
418 *
419 * @return ERROR_OK or else a fault code.
420 */
421 int dap_to_jtag(struct target *target)
422 {
423 int retval;
424
425 LOG_DEBUG("Enter JTAG mode");
426
427 /* REVISIT it's nasty to need to make calls to a "jtag"
428 * subsystem if the link isn't in JTAG mode...
429 */
430
431 retval = jtag_add_tms_seq(8 * sizeof(swd2jtag_bitseq),
432 swd2jtag_bitseq, TAP_RESET);
433 if (retval == ERROR_OK)
434 retval = jtag_execute_queue();
435
436 /* REVISIT set up the DAP's ops vector for JTAG mode. */
437
438 return retval;
439 }

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)