1 /***************************************************************************
3 * Copyright (C) 2010 by David Brownell
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, see <http://www.gnu.org/licenses/>.
17 ***************************************************************************/
21 * Utilities to support ARM "Serial Wire Debug" (SWD), a low pin-count debug
22 * link protocol used in cases where JTAG is not wanted. This is coupled to
23 * recent versions of ARM's "CoreSight" debug framework. This specific code
24 * is a transport level interface, with "target/arm_adi_v5.[hc]" code
25 * understanding operation semantics, shared with the JTAG transport.
27 * Single-DAP support only.
29 * for details, see "ARM IHI 0031A"
30 * ARM Debug Interface v5 Architecture Specification
31 * especially section 5.3 for SWD protocol
32 * and "ARM IHI 0074C" ARM Debug Interface Architecture Specification ADIv6.0
34 * On many chips (most current Cortex-M3 parts) SWD is a run-time alternative
35 * to JTAG. Boards may support one or both. There are also SWD-only chips,
36 * (using SW-DP not SWJ-DP).
38 * Even boards that also support JTAG can benefit from SWD support, because
39 * usually there's no way to access the SWO trace view mechanism in JTAG mode.
40 * That is, trace access may require SWD support.
49 #include "arm_adi_v5.h"
50 #include <helper/time_support.h>
52 #include <transport/transport.h>
53 #include <jtag/interface.h>
57 /* for debug, set do_sync to true to force synchronous transfers */
60 static struct adiv5_dap
*swd_multidrop_selected_dap
;
63 static int swd_queue_dp_write_inner(struct adiv5_dap
*dap
, unsigned int reg
,
67 static int swd_send_sequence(struct adiv5_dap
*dap
, enum swd_special_seq seq
)
69 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
72 return swd
->switch_seq(seq
);
75 static void swd_finish_read(struct adiv5_dap
*dap
)
77 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
79 swd
->read_reg(swd_cmd(true, false, DP_RDBUFF
), dap
->last_read
, 0);
80 dap
->last_read
= NULL
;
84 static void swd_clear_sticky_errors(struct adiv5_dap
*dap
)
86 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
89 swd
->write_reg(swd_cmd(false, false, DP_ABORT
),
90 STKCMPCLR
| STKERRCLR
| WDERRCLR
| ORUNERRCLR
, 0);
93 static int swd_run_inner(struct adiv5_dap
*dap
)
95 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
100 if (retval
!= ERROR_OK
) {
102 dap
->do_reconnect
= true;
108 static inline int check_sync(struct adiv5_dap
*dap
)
110 return do_sync
? swd_run_inner(dap
) : ERROR_OK
;
113 /** Select the DP register bank matching bits 7:4 of reg. */
114 static int swd_queue_dp_bankselect(struct adiv5_dap
*dap
, unsigned int reg
)
116 /* Only register address 0 and 4 are banked. */
120 uint64_t sel
= (reg
& 0x000000F0) >> 4;
121 if (dap
->select
!= DP_SELECT_INVALID
)
122 sel
|= dap
->select
& ~0xfULL
;
124 if (sel
== dap
->select
)
129 int retval
= swd_queue_dp_write_inner(dap
, DP_SELECT
, (uint32_t)sel
);
130 if (retval
!= ERROR_OK
)
131 dap
->select
= DP_SELECT_INVALID
;
136 static int swd_queue_dp_read_inner(struct adiv5_dap
*dap
, unsigned int reg
,
139 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
142 int retval
= swd_queue_dp_bankselect(dap
, reg
);
143 if (retval
!= ERROR_OK
)
146 swd
->read_reg(swd_cmd(true, false, reg
), data
, 0);
148 return check_sync(dap
);
151 static int swd_queue_dp_write_inner(struct adiv5_dap
*dap
, unsigned int reg
,
155 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
158 swd_finish_read(dap
);
160 if (reg
== DP_SELECT
) {
161 dap
->select
= data
& (DP_SELECT_APSEL
| DP_SELECT_APBANK
| DP_SELECT_DPBANK
);
163 swd
->write_reg(swd_cmd(false, false, reg
), data
, 0);
165 retval
= check_sync(dap
);
166 if (retval
!= ERROR_OK
)
167 dap
->select
= DP_SELECT_INVALID
;
172 retval
= swd_queue_dp_bankselect(dap
, reg
);
173 if (retval
!= ERROR_OK
)
176 swd
->write_reg(swd_cmd(false, false, reg
), data
, 0);
178 return check_sync(dap
);
182 static int swd_multidrop_select_inner(struct adiv5_dap
*dap
, uint32_t *dpidr_ptr
,
183 uint32_t *dlpidr_ptr
, bool clear_sticky
)
186 uint32_t dpidr
, dlpidr
;
188 assert(dap_is_multidrop(dap
));
190 swd_send_sequence(dap
, LINE_RESET
);
192 retval
= swd_queue_dp_write_inner(dap
, DP_TARGETSEL
, dap
->multidrop_targetsel
);
193 if (retval
!= ERROR_OK
)
196 retval
= swd_queue_dp_read_inner(dap
, DP_DPIDR
, &dpidr
);
197 if (retval
!= ERROR_OK
)
201 /* Clear all sticky errors (including ORUN) */
202 swd_clear_sticky_errors(dap
);
204 /* Ideally just clear ORUN flag which is set by reset */
205 retval
= swd_queue_dp_write_inner(dap
, DP_ABORT
, ORUNERRCLR
);
206 if (retval
!= ERROR_OK
)
210 retval
= swd_queue_dp_read_inner(dap
, DP_DLPIDR
, &dlpidr
);
211 if (retval
!= ERROR_OK
)
214 retval
= swd_run_inner(dap
);
215 if (retval
!= ERROR_OK
)
218 if ((dpidr
& DP_DPIDR_VERSION_MASK
) < (2UL << DP_DPIDR_VERSION_SHIFT
)) {
219 LOG_INFO("Read DPIDR 0x%08" PRIx32
220 " has version < 2. A non multidrop capable device connected?",
225 /* TODO: check TARGETID if DLIPDR is same for more than one DP */
226 uint32_t expected_dlpidr
= DP_DLPIDR_PROTVSN
|
227 (dap
->multidrop_targetsel
& DP_TARGETSEL_INSTANCEID_MASK
);
228 if (dlpidr
!= expected_dlpidr
) {
229 LOG_INFO("Read incorrect DLPIDR 0x%08" PRIx32
230 " (possibly CTRL/STAT value)",
235 LOG_DEBUG_IO("Selected DP_TARGETSEL 0x%08" PRIx32
, dap
->multidrop_targetsel
);
236 swd_multidrop_selected_dap
= dap
;
242 *dlpidr_ptr
= dlpidr
;
247 static int swd_multidrop_select(struct adiv5_dap
*dap
)
249 if (!dap_is_multidrop(dap
))
252 if (swd_multidrop_selected_dap
== dap
)
255 int retval
= ERROR_OK
;
256 for (unsigned int retry
= 0; ; retry
++) {
257 bool clear_sticky
= retry
> 0;
259 retval
= swd_multidrop_select_inner(dap
, NULL
, NULL
, clear_sticky
);
260 if (retval
== ERROR_OK
)
263 swd_multidrop_selected_dap
= NULL
;
265 LOG_ERROR("Failed to select multidrop %s", adiv5_dap_name(dap
));
269 LOG_DEBUG("Failed to select multidrop %s, retrying...",
270 adiv5_dap_name(dap
));
276 static int swd_connect_multidrop(struct adiv5_dap
*dap
)
279 uint32_t dpidr
= 0xdeadbeef;
280 uint32_t dlpidr
= 0xdeadbeef;
281 int64_t timeout
= timeval_ms() + 500;
284 swd_send_sequence(dap
, JTAG_TO_DORMANT
);
285 swd_send_sequence(dap
, DORMANT_TO_SWD
);
287 /* Clear link state, including the SELECT cache. */
288 dap
->do_reconnect
= false;
289 dap_invalidate_cache(dap
);
290 swd_multidrop_selected_dap
= NULL
;
292 retval
= swd_multidrop_select_inner(dap
, &dpidr
, &dlpidr
, true);
293 if (retval
== ERROR_OK
)
298 } while (timeval_ms() < timeout
);
300 if (retval
!= ERROR_OK
) {
301 swd_multidrop_selected_dap
= NULL
;
302 LOG_ERROR("Failed to connect multidrop %s", adiv5_dap_name(dap
));
306 LOG_INFO("SWD DPIDR 0x%08" PRIx32
", DLPIDR 0x%08" PRIx32
,
312 static int swd_connect_single(struct adiv5_dap
*dap
)
315 uint32_t dpidr
= 0xdeadbeef;
316 int64_t timeout
= timeval_ms() + 500;
319 if (dap
->switch_through_dormant
) {
320 swd_send_sequence(dap
, JTAG_TO_DORMANT
);
321 swd_send_sequence(dap
, DORMANT_TO_SWD
);
323 swd_send_sequence(dap
, JTAG_TO_SWD
);
326 /* Clear link state, including the SELECT cache. */
327 dap
->do_reconnect
= false;
328 dap_invalidate_cache(dap
);
330 /* The sequences to enter in SWD (JTAG_TO_SWD and DORMANT_TO_SWD) end
331 * with a SWD line reset sequence (50 clk with SWDIO high).
332 * From ARM IHI 0074C ADIv6.0, chapter B4.3.3 "Connection and line reset
334 * - line reset sets DP_SELECT_DPBANK to zero;
335 * - read of DP_DPIDR takes the connection out of reset;
336 * - write of DP_TARGETSEL keeps the connection in reset;
337 * - other accesses return protocol error (SWDIO not driven by target).
339 * Read DP_DPIDR to get out of reset. Initialize dap->select to zero to
340 * skip the write to DP_SELECT, avoiding the protocol error. Set again
341 * dap->select to DP_SELECT_INVALID because the rest of the register is
342 * unknown after line reset.
345 retval
= swd_queue_dp_read_inner(dap
, DP_DPIDR
, &dpidr
);
346 if (retval
== ERROR_OK
) {
347 retval
= swd_run_inner(dap
);
348 if (retval
== ERROR_OK
)
354 dap
->switch_through_dormant
= !dap
->switch_through_dormant
;
355 } while (timeval_ms() < timeout
);
356 dap
->select
= DP_SELECT_INVALID
;
358 if (retval
!= ERROR_OK
) {
359 LOG_ERROR("Error connecting DP: cannot read IDR");
363 LOG_INFO("SWD DPIDR 0x%08" PRIx32
, dpidr
);
366 dap
->do_reconnect
= false;
368 /* force clear all sticky faults */
369 swd_clear_sticky_errors(dap
);
371 retval
= swd_run_inner(dap
);
372 if (retval
!= ERROR_WAIT
)
377 } while (timeval_ms() < timeout
);
382 static int swd_connect(struct adiv5_dap
*dap
)
386 /* FIXME validate transport config ... is the
387 * configured DAP present (check IDCODE)?
390 /* Check if we should reset srst already when connecting, but not if reconnecting. */
391 if (!dap
->do_reconnect
) {
392 enum reset_types jtag_reset_config
= jtag_get_reset_config();
394 if (jtag_reset_config
& RESET_CNCT_UNDER_SRST
) {
395 if (jtag_reset_config
& RESET_SRST_NO_GATING
)
396 adapter_assert_reset();
398 LOG_WARNING("\'srst_nogate\' reset_config option is required");
402 if (dap_is_multidrop(dap
))
403 status
= swd_connect_multidrop(dap
);
405 status
= swd_connect_single(dap
);
408 * "A WAIT response must not be issued to the ...
409 * ... writes to the ABORT register"
410 * swd_clear_sticky_errors() writes to the ABORT register only.
412 * Unfortunately at least Microchip SAMD51/E53/E54 returns WAIT
413 * in a corner case. Just try if ABORT resolves the problem.
415 if (status
== ERROR_WAIT
) {
416 LOG_WARNING("Connecting DP: stalled AP operation, issuing ABORT");
418 dap
->do_reconnect
= false;
420 status
= swd_queue_dp_write_inner(dap
, DP_ABORT
,
421 DAPABORT
| STKCMPCLR
| STKERRCLR
| WDERRCLR
| ORUNERRCLR
);
423 if (status
== ERROR_OK
)
424 status
= swd_run_inner(dap
);
427 if (status
== ERROR_OK
)
428 status
= dap_dp_init(dap
);
433 static int swd_check_reconnect(struct adiv5_dap
*dap
)
435 if (dap
->do_reconnect
)
436 return swd_connect(dap
);
441 static int swd_queue_ap_abort(struct adiv5_dap
*dap
, uint8_t *ack
)
443 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
446 /* TODO: Send DAPABORT in swd_multidrop_select_inner()
447 * in the case the multidrop dap is not selected?
448 * swd_queue_ap_abort() is not currently used anyway...
450 int retval
= swd_multidrop_select(dap
);
451 if (retval
!= ERROR_OK
)
454 swd
->write_reg(swd_cmd(false, false, DP_ABORT
),
455 DAPABORT
| STKCMPCLR
| STKERRCLR
| WDERRCLR
| ORUNERRCLR
, 0);
456 return check_sync(dap
);
459 static int swd_queue_dp_read(struct adiv5_dap
*dap
, unsigned reg
,
462 int retval
= swd_check_reconnect(dap
);
463 if (retval
!= ERROR_OK
)
466 retval
= swd_multidrop_select(dap
);
467 if (retval
!= ERROR_OK
)
470 return swd_queue_dp_read_inner(dap
, reg
, data
);
473 static int swd_queue_dp_write(struct adiv5_dap
*dap
, unsigned reg
,
476 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
479 int retval
= swd_check_reconnect(dap
);
480 if (retval
!= ERROR_OK
)
483 retval
= swd_multidrop_select(dap
);
484 if (retval
!= ERROR_OK
)
487 return swd_queue_dp_write_inner(dap
, reg
, data
);
490 /** Select the AP register bank matching bits 7:4 of reg. */
491 static int swd_queue_ap_bankselect(struct adiv5_ap
*ap
, unsigned reg
)
494 struct adiv5_dap
*dap
= ap
->dap
;
498 sel
= ap
->ap_num
| (reg
& 0x00000FF0);
499 if (sel
== (dap
->select
& ~0xfULL
))
502 if (dap
->select
!= DP_SELECT_INVALID
)
503 sel
|= dap
->select
& 0xf;
505 LOG_DEBUG("AP BANKSEL: %" PRIx64
, sel
);
507 retval
= swd_queue_dp_write(dap
, DP_SELECT
, (uint32_t)sel
);
509 if (retval
== ERROR_OK
&& dap
->asize
> 32)
510 retval
= swd_queue_dp_write(dap
, DP_SELECT1
, (uint32_t)(sel
>> 32));
512 if (retval
!= ERROR_OK
)
513 dap
->select
= DP_SELECT_INVALID
;
519 sel
= (ap
->ap_num
<< 24) | (reg
& 0x000000F0);
520 if (dap
->select
!= DP_SELECT_INVALID
)
521 sel
|= dap
->select
& DP_SELECT_DPBANK
;
523 if (sel
== dap
->select
)
528 retval
= swd_queue_dp_write_inner(dap
, DP_SELECT
, sel
);
529 if (retval
!= ERROR_OK
)
530 dap
->select
= DP_SELECT_INVALID
;
535 static int swd_queue_ap_read(struct adiv5_ap
*ap
, unsigned reg
,
538 struct adiv5_dap
*dap
= ap
->dap
;
539 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
542 int retval
= swd_check_reconnect(dap
);
543 if (retval
!= ERROR_OK
)
546 retval
= swd_multidrop_select(dap
);
547 if (retval
!= ERROR_OK
)
550 retval
= swd_queue_ap_bankselect(ap
, reg
);
551 if (retval
!= ERROR_OK
)
554 swd
->read_reg(swd_cmd(true, true, reg
), dap
->last_read
, ap
->memaccess_tck
);
555 dap
->last_read
= data
;
557 return check_sync(dap
);
560 static int swd_queue_ap_write(struct adiv5_ap
*ap
, unsigned reg
,
563 struct adiv5_dap
*dap
= ap
->dap
;
564 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
567 int retval
= swd_check_reconnect(dap
);
568 if (retval
!= ERROR_OK
)
571 retval
= swd_multidrop_select(dap
);
572 if (retval
!= ERROR_OK
)
575 swd_finish_read(dap
);
577 retval
= swd_queue_ap_bankselect(ap
, reg
);
578 if (retval
!= ERROR_OK
)
581 swd
->write_reg(swd_cmd(false, true, reg
), data
, ap
->memaccess_tck
);
583 return check_sync(dap
);
586 /** Executes all queued DAP operations. */
587 static int swd_run(struct adiv5_dap
*dap
)
589 int retval
= swd_multidrop_select(dap
);
590 if (retval
!= ERROR_OK
)
593 swd_finish_read(dap
);
595 return swd_run_inner(dap
);
598 /** Put the SWJ-DP back to JTAG mode */
599 static void swd_quit(struct adiv5_dap
*dap
)
601 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
604 /* There is no difference if the sequence is sent at the last
605 * or the first swd_quit() call, send it just once */
610 if (dap_is_multidrop(dap
)) {
611 swd
->switch_seq(SWD_TO_DORMANT
);
613 * Leaving DPs in dormant state was tested and offers some safety
614 * against DPs mismatch in case of unintentional use of non-multidrop SWD.
615 * To put SWJ-DPs to power-on state issue
616 * swd->switch_seq(DORMANT_TO_JTAG);
619 if (dap
->switch_through_dormant
) {
620 swd
->switch_seq(SWD_TO_DORMANT
);
621 swd
->switch_seq(DORMANT_TO_JTAG
);
623 swd
->switch_seq(SWD_TO_JTAG
);
627 /* flush the queue to shift out the sequence before exit */
631 const struct dap_ops swd_dap_ops
= {
632 .connect
= swd_connect
,
633 .send_sequence
= swd_send_sequence
,
634 .queue_dp_read
= swd_queue_dp_read
,
635 .queue_dp_write
= swd_queue_dp_write
,
636 .queue_ap_read
= swd_queue_ap_read
,
637 .queue_ap_write
= swd_queue_ap_write
,
638 .queue_ap_abort
= swd_queue_ap_abort
,
643 static const struct command_registration swd_commands
[] = {
646 * Set up SWD and JTAG targets identically, unless/until
647 * infrastructure improves ... meanwhile, ignore all
648 * JTAG-specific stuff like IR length for SWD.
650 * REVISIT can we verify "just one SWD DAP" here/early?
653 .jim_handler
= jim_jtag_newtap
,
654 .mode
= COMMAND_CONFIG
,
655 .help
= "declare a new SWD DAP"
657 COMMAND_REGISTRATION_DONE
660 static const struct command_registration swd_handlers
[] = {
664 .help
= "SWD command group",
665 .chain
= swd_commands
,
668 COMMAND_REGISTRATION_DONE
671 static int swd_select(struct command_context
*ctx
)
673 /* FIXME: only place where global 'adapter_driver' is still needed */
674 extern struct adapter_driver
*adapter_driver
;
675 const struct swd_driver
*swd
= adapter_driver
->swd_ops
;
678 retval
= register_commands(ctx
, NULL
, swd_handlers
);
679 if (retval
!= ERROR_OK
)
682 /* be sure driver is in SWD mode; start
683 * with hardware default TRN (1), it can be changed later
685 if (!swd
|| !swd
->read_reg
|| !swd
->write_reg
|| !swd
->init
) {
686 LOG_DEBUG("no SWD driver?");
690 retval
= swd
->init();
691 if (retval
!= ERROR_OK
) {
692 LOG_DEBUG("can't init SWD driver");
699 static int swd_init(struct command_context
*ctx
)
701 /* nothing done here, SWD is initialized
702 * together with the DAP */
706 static struct transport swd_transport
= {
708 .select
= swd_select
,
712 static void swd_constructor(void) __attribute__((constructor
));
713 static void swd_constructor(void)
715 transport_register(&swd_transport
);
718 /** Returns true if the current debug session
719 * is using SWD as its transport.
721 bool transport_is_swd(void)
723 return get_current_transport() == &swd_transport
;
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)