1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
5 * Copyright (C) 2010 by David Brownell
6 ***************************************************************************/
10 * Utilities to support ARM "Serial Wire Debug" (SWD), a low pin-count debug
11 * link protocol used in cases where JTAG is not wanted. This is coupled to
12 * recent versions of ARM's "CoreSight" debug framework. This specific code
13 * is a transport level interface, with "target/arm_adi_v5.[hc]" code
14 * understanding operation semantics, shared with the JTAG transport.
16 * Single-DAP support only.
18 * for details, see "ARM IHI 0031A"
19 * ARM Debug Interface v5 Architecture Specification
20 * especially section 5.3 for SWD protocol
21 * and "ARM IHI 0074C" ARM Debug Interface Architecture Specification ADIv6.0
23 * On many chips (most current Cortex-M3 parts) SWD is a run-time alternative
24 * to JTAG. Boards may support one or both. There are also SWD-only chips,
25 * (using SW-DP not SWJ-DP).
27 * Even boards that also support JTAG can benefit from SWD support, because
28 * usually there's no way to access the SWO trace view mechanism in JTAG mode.
29 * That is, trace access may require SWD support.
38 #include "arm_adi_v5.h"
39 #include <helper/time_support.h>
41 #include <transport/transport.h>
42 #include <jtag/interface.h>
46 /* for debug, set do_sync to true to force synchronous transfers */
49 static struct adiv5_dap
*swd_multidrop_selected_dap
;
52 static int swd_queue_dp_write_inner(struct adiv5_dap
*dap
, unsigned int reg
,
56 static int swd_send_sequence(struct adiv5_dap
*dap
, enum swd_special_seq seq
)
58 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
61 return swd
->switch_seq(seq
);
64 static void swd_finish_read(struct adiv5_dap
*dap
)
66 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
68 swd
->read_reg(swd_cmd(true, false, DP_RDBUFF
), dap
->last_read
, 0);
69 dap
->last_read
= NULL
;
73 static void swd_clear_sticky_errors(struct adiv5_dap
*dap
)
75 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
78 swd
->write_reg(swd_cmd(false, false, DP_ABORT
),
79 STKCMPCLR
| STKERRCLR
| WDERRCLR
| ORUNERRCLR
, 0);
82 static int swd_run_inner(struct adiv5_dap
*dap
)
84 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
89 if (retval
!= ERROR_OK
) {
91 dap
->do_reconnect
= true;
97 static inline int check_sync(struct adiv5_dap
*dap
)
99 return do_sync
? swd_run_inner(dap
) : ERROR_OK
;
102 /** Select the DP register bank matching bits 7:4 of reg. */
103 static int swd_queue_dp_bankselect(struct adiv5_dap
*dap
, unsigned int reg
)
105 /* Only register address 0 and 4 are banked. */
109 uint64_t sel
= (reg
& 0x000000F0) >> 4;
110 if (dap
->select
!= DP_SELECT_INVALID
)
111 sel
|= dap
->select
& ~0xfULL
;
113 if (sel
== dap
->select
)
118 int retval
= swd_queue_dp_write_inner(dap
, DP_SELECT
, (uint32_t)sel
);
119 if (retval
!= ERROR_OK
)
120 dap
->select
= DP_SELECT_INVALID
;
125 static int swd_queue_dp_read_inner(struct adiv5_dap
*dap
, unsigned int reg
,
128 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
131 int retval
= swd_queue_dp_bankselect(dap
, reg
);
132 if (retval
!= ERROR_OK
)
135 swd
->read_reg(swd_cmd(true, false, reg
), data
, 0);
137 return check_sync(dap
);
140 static int swd_queue_dp_write_inner(struct adiv5_dap
*dap
, unsigned int reg
,
144 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
147 swd_finish_read(dap
);
149 if (reg
== DP_SELECT
) {
150 dap
->select
= data
& (DP_SELECT_APSEL
| DP_SELECT_APBANK
| DP_SELECT_DPBANK
);
152 swd
->write_reg(swd_cmd(false, false, reg
), data
, 0);
154 retval
= check_sync(dap
);
155 if (retval
!= ERROR_OK
)
156 dap
->select
= DP_SELECT_INVALID
;
161 retval
= swd_queue_dp_bankselect(dap
, reg
);
162 if (retval
!= ERROR_OK
)
165 swd
->write_reg(swd_cmd(false, false, reg
), data
, 0);
167 return check_sync(dap
);
171 static int swd_multidrop_select_inner(struct adiv5_dap
*dap
, uint32_t *dpidr_ptr
,
172 uint32_t *dlpidr_ptr
, bool clear_sticky
)
175 uint32_t dpidr
, dlpidr
;
177 assert(dap_is_multidrop(dap
));
179 swd_send_sequence(dap
, LINE_RESET
);
180 /* From ARM IHI 0074C ADIv6.0, chapter B4.3.3 "Connection and line reset
182 * - line reset sets DP_SELECT_DPBANK to zero;
183 * - read of DP_DPIDR takes the connection out of reset;
184 * - write of DP_TARGETSEL keeps the connection in reset;
185 * - other accesses return protocol error (SWDIO not driven by target).
187 * Read DP_DPIDR to get out of reset. Initialize dap->select to zero to
188 * skip the write to DP_SELECT, avoiding the protocol error. Set again
189 * dap->select to DP_SELECT_INVALID because the rest of the register is
190 * unknown after line reset.
194 retval
= swd_queue_dp_write_inner(dap
, DP_TARGETSEL
, dap
->multidrop_targetsel
);
195 if (retval
!= ERROR_OK
)
198 retval
= swd_queue_dp_read_inner(dap
, DP_DPIDR
, &dpidr
);
199 if (retval
!= ERROR_OK
)
203 /* Clear all sticky errors (including ORUN) */
204 swd_clear_sticky_errors(dap
);
206 /* Ideally just clear ORUN flag which is set by reset */
207 retval
= swd_queue_dp_write_inner(dap
, DP_ABORT
, ORUNERRCLR
);
208 if (retval
!= ERROR_OK
)
212 dap
->select
= DP_SELECT_INVALID
;
214 retval
= swd_queue_dp_read_inner(dap
, DP_DLPIDR
, &dlpidr
);
215 if (retval
!= ERROR_OK
)
218 retval
= swd_run_inner(dap
);
219 if (retval
!= ERROR_OK
)
222 if ((dpidr
& DP_DPIDR_VERSION_MASK
) < (2UL << DP_DPIDR_VERSION_SHIFT
)) {
223 LOG_INFO("Read DPIDR 0x%08" PRIx32
224 " has version < 2. A non multidrop capable device connected?",
229 /* TODO: check TARGETID if DLIPDR is same for more than one DP */
230 uint32_t expected_dlpidr
= DP_DLPIDR_PROTVSN
|
231 (dap
->multidrop_targetsel
& DP_TARGETSEL_INSTANCEID_MASK
);
232 if (dlpidr
!= expected_dlpidr
) {
233 LOG_INFO("Read incorrect DLPIDR 0x%08" PRIx32
234 " (possibly CTRL/STAT value)",
239 LOG_DEBUG_IO("Selected DP_TARGETSEL 0x%08" PRIx32
, dap
->multidrop_targetsel
);
240 swd_multidrop_selected_dap
= dap
;
246 *dlpidr_ptr
= dlpidr
;
251 static int swd_multidrop_select(struct adiv5_dap
*dap
)
253 if (!dap_is_multidrop(dap
))
256 if (swd_multidrop_selected_dap
== dap
)
259 int retval
= ERROR_OK
;
260 for (unsigned int retry
= 0; ; retry
++) {
261 bool clear_sticky
= retry
> 0;
263 retval
= swd_multidrop_select_inner(dap
, NULL
, NULL
, clear_sticky
);
264 if (retval
== ERROR_OK
)
267 swd_multidrop_selected_dap
= NULL
;
269 LOG_ERROR("Failed to select multidrop %s", adiv5_dap_name(dap
));
273 LOG_DEBUG("Failed to select multidrop %s, retrying...",
274 adiv5_dap_name(dap
));
275 /* we going to retry localy, do not ask for full reconnect */
276 dap
->do_reconnect
= false;
282 static int swd_connect_multidrop(struct adiv5_dap
*dap
)
285 uint32_t dpidr
= 0xdeadbeef;
286 uint32_t dlpidr
= 0xdeadbeef;
287 int64_t timeout
= timeval_ms() + 500;
290 swd_send_sequence(dap
, JTAG_TO_DORMANT
);
291 swd_send_sequence(dap
, DORMANT_TO_SWD
);
293 /* Clear link state, including the SELECT cache. */
294 dap
->do_reconnect
= false;
295 dap_invalidate_cache(dap
);
296 swd_multidrop_selected_dap
= NULL
;
298 retval
= swd_multidrop_select_inner(dap
, &dpidr
, &dlpidr
, true);
299 if (retval
== ERROR_OK
)
304 } while (timeval_ms() < timeout
);
306 if (retval
!= ERROR_OK
) {
307 swd_multidrop_selected_dap
= NULL
;
308 LOG_ERROR("Failed to connect multidrop %s", adiv5_dap_name(dap
));
312 LOG_INFO("SWD DPIDR 0x%08" PRIx32
", DLPIDR 0x%08" PRIx32
,
318 static int swd_connect_single(struct adiv5_dap
*dap
)
321 uint32_t dpidr
= 0xdeadbeef;
322 int64_t timeout
= timeval_ms() + 500;
325 if (dap
->switch_through_dormant
) {
326 swd_send_sequence(dap
, JTAG_TO_DORMANT
);
327 swd_send_sequence(dap
, DORMANT_TO_SWD
);
329 swd_send_sequence(dap
, JTAG_TO_SWD
);
332 /* Clear link state, including the SELECT cache. */
333 dap
->do_reconnect
= false;
334 dap_invalidate_cache(dap
);
336 /* The sequences to enter in SWD (JTAG_TO_SWD and DORMANT_TO_SWD) end
337 * with a SWD line reset sequence (50 clk with SWDIO high).
338 * From ARM IHI 0074C ADIv6.0, chapter B4.3.3 "Connection and line reset
340 * - line reset sets DP_SELECT_DPBANK to zero;
341 * - read of DP_DPIDR takes the connection out of reset;
342 * - write of DP_TARGETSEL keeps the connection in reset;
343 * - other accesses return protocol error (SWDIO not driven by target).
345 * Read DP_DPIDR to get out of reset. Initialize dap->select to zero to
346 * skip the write to DP_SELECT, avoiding the protocol error. Set again
347 * dap->select to DP_SELECT_INVALID because the rest of the register is
348 * unknown after line reset.
351 retval
= swd_queue_dp_read_inner(dap
, DP_DPIDR
, &dpidr
);
352 if (retval
== ERROR_OK
) {
353 retval
= swd_run_inner(dap
);
354 if (retval
== ERROR_OK
)
360 dap
->switch_through_dormant
= !dap
->switch_through_dormant
;
361 } while (timeval_ms() < timeout
);
363 dap
->select
= DP_SELECT_INVALID
;
365 if (retval
!= ERROR_OK
) {
366 LOG_ERROR("Error connecting DP: cannot read IDR");
370 LOG_INFO("SWD DPIDR 0x%08" PRIx32
, dpidr
);
373 dap
->do_reconnect
= false;
375 /* force clear all sticky faults */
376 swd_clear_sticky_errors(dap
);
378 retval
= swd_run_inner(dap
);
379 if (retval
!= ERROR_WAIT
)
384 } while (timeval_ms() < timeout
);
389 static int swd_connect(struct adiv5_dap
*dap
)
393 /* FIXME validate transport config ... is the
394 * configured DAP present (check IDCODE)?
397 /* Check if we should reset srst already when connecting, but not if reconnecting. */
398 if (!dap
->do_reconnect
) {
399 enum reset_types jtag_reset_config
= jtag_get_reset_config();
401 if (jtag_reset_config
& RESET_CNCT_UNDER_SRST
) {
402 if (jtag_reset_config
& RESET_SRST_NO_GATING
)
403 adapter_assert_reset();
405 LOG_WARNING("\'srst_nogate\' reset_config option is required");
409 if (dap_is_multidrop(dap
))
410 status
= swd_connect_multidrop(dap
);
412 status
= swd_connect_single(dap
);
415 * "A WAIT response must not be issued to the ...
416 * ... writes to the ABORT register"
417 * swd_clear_sticky_errors() writes to the ABORT register only.
419 * Unfortunately at least Microchip SAMD51/E53/E54 returns WAIT
420 * in a corner case. Just try if ABORT resolves the problem.
422 if (status
== ERROR_WAIT
) {
423 LOG_WARNING("Connecting DP: stalled AP operation, issuing ABORT");
425 dap
->do_reconnect
= false;
427 status
= swd_queue_dp_write_inner(dap
, DP_ABORT
,
428 DAPABORT
| STKCMPCLR
| STKERRCLR
| WDERRCLR
| ORUNERRCLR
);
430 if (status
== ERROR_OK
)
431 status
= swd_run_inner(dap
);
434 if (status
== ERROR_OK
)
435 status
= dap_dp_init(dap
);
440 static int swd_check_reconnect(struct adiv5_dap
*dap
)
442 if (dap
->do_reconnect
)
443 return swd_connect(dap
);
448 static int swd_queue_ap_abort(struct adiv5_dap
*dap
, uint8_t *ack
)
450 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
453 /* TODO: Send DAPABORT in swd_multidrop_select_inner()
454 * in the case the multidrop dap is not selected?
455 * swd_queue_ap_abort() is not currently used anyway...
457 int retval
= swd_multidrop_select(dap
);
458 if (retval
!= ERROR_OK
)
461 swd
->write_reg(swd_cmd(false, false, DP_ABORT
),
462 DAPABORT
| STKCMPCLR
| STKERRCLR
| WDERRCLR
| ORUNERRCLR
, 0);
463 return check_sync(dap
);
466 static int swd_queue_dp_read(struct adiv5_dap
*dap
, unsigned reg
,
469 int retval
= swd_check_reconnect(dap
);
470 if (retval
!= ERROR_OK
)
473 retval
= swd_multidrop_select(dap
);
474 if (retval
!= ERROR_OK
)
477 return swd_queue_dp_read_inner(dap
, reg
, data
);
480 static int swd_queue_dp_write(struct adiv5_dap
*dap
, unsigned reg
,
483 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
486 int retval
= swd_check_reconnect(dap
);
487 if (retval
!= ERROR_OK
)
490 retval
= swd_multidrop_select(dap
);
491 if (retval
!= ERROR_OK
)
494 return swd_queue_dp_write_inner(dap
, reg
, data
);
497 /** Select the AP register bank matching bits 7:4 of reg. */
498 static int swd_queue_ap_bankselect(struct adiv5_ap
*ap
, unsigned reg
)
501 struct adiv5_dap
*dap
= ap
->dap
;
505 sel
= ap
->ap_num
| (reg
& 0x00000FF0);
506 if (sel
== (dap
->select
& ~0xfULL
))
509 if (dap
->select
!= DP_SELECT_INVALID
)
510 sel
|= dap
->select
& 0xf;
512 LOG_DEBUG("AP BANKSEL: %" PRIx64
, sel
);
514 retval
= swd_queue_dp_write(dap
, DP_SELECT
, (uint32_t)sel
);
516 if (retval
== ERROR_OK
&& dap
->asize
> 32)
517 retval
= swd_queue_dp_write(dap
, DP_SELECT1
, (uint32_t)(sel
>> 32));
519 if (retval
!= ERROR_OK
)
520 dap
->select
= DP_SELECT_INVALID
;
526 sel
= (ap
->ap_num
<< 24) | (reg
& 0x000000F0);
527 if (dap
->select
!= DP_SELECT_INVALID
)
528 sel
|= dap
->select
& DP_SELECT_DPBANK
;
530 if (sel
== dap
->select
)
535 retval
= swd_queue_dp_write_inner(dap
, DP_SELECT
, sel
);
536 if (retval
!= ERROR_OK
)
537 dap
->select
= DP_SELECT_INVALID
;
542 static int swd_queue_ap_read(struct adiv5_ap
*ap
, unsigned reg
,
545 struct adiv5_dap
*dap
= ap
->dap
;
546 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
549 int retval
= swd_check_reconnect(dap
);
550 if (retval
!= ERROR_OK
)
553 retval
= swd_multidrop_select(dap
);
554 if (retval
!= ERROR_OK
)
557 retval
= swd_queue_ap_bankselect(ap
, reg
);
558 if (retval
!= ERROR_OK
)
561 swd
->read_reg(swd_cmd(true, true, reg
), dap
->last_read
, ap
->memaccess_tck
);
562 dap
->last_read
= data
;
564 return check_sync(dap
);
567 static int swd_queue_ap_write(struct adiv5_ap
*ap
, unsigned reg
,
570 struct adiv5_dap
*dap
= ap
->dap
;
571 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
574 int retval
= swd_check_reconnect(dap
);
575 if (retval
!= ERROR_OK
)
578 retval
= swd_multidrop_select(dap
);
579 if (retval
!= ERROR_OK
)
582 swd_finish_read(dap
);
584 retval
= swd_queue_ap_bankselect(ap
, reg
);
585 if (retval
!= ERROR_OK
)
588 swd
->write_reg(swd_cmd(false, true, reg
), data
, ap
->memaccess_tck
);
590 return check_sync(dap
);
593 /** Executes all queued DAP operations. */
594 static int swd_run(struct adiv5_dap
*dap
)
596 int retval
= swd_multidrop_select(dap
);
597 if (retval
!= ERROR_OK
)
600 swd_finish_read(dap
);
602 return swd_run_inner(dap
);
605 /** Put the SWJ-DP back to JTAG mode */
606 static void swd_quit(struct adiv5_dap
*dap
)
608 const struct swd_driver
*swd
= adiv5_dap_swd_driver(dap
);
611 /* There is no difference if the sequence is sent at the last
612 * or the first swd_quit() call, send it just once */
617 if (dap_is_multidrop(dap
)) {
618 swd
->switch_seq(SWD_TO_DORMANT
);
620 * Leaving DPs in dormant state was tested and offers some safety
621 * against DPs mismatch in case of unintentional use of non-multidrop SWD.
622 * To put SWJ-DPs to power-on state issue
623 * swd->switch_seq(DORMANT_TO_JTAG);
626 if (dap
->switch_through_dormant
) {
627 swd
->switch_seq(SWD_TO_DORMANT
);
628 swd
->switch_seq(DORMANT_TO_JTAG
);
630 swd
->switch_seq(SWD_TO_JTAG
);
634 /* flush the queue to shift out the sequence before exit */
638 const struct dap_ops swd_dap_ops
= {
639 .connect
= swd_connect
,
640 .send_sequence
= swd_send_sequence
,
641 .queue_dp_read
= swd_queue_dp_read
,
642 .queue_dp_write
= swd_queue_dp_write
,
643 .queue_ap_read
= swd_queue_ap_read
,
644 .queue_ap_write
= swd_queue_ap_write
,
645 .queue_ap_abort
= swd_queue_ap_abort
,
650 static const struct command_registration swd_commands
[] = {
653 * Set up SWD and JTAG targets identically, unless/until
654 * infrastructure improves ... meanwhile, ignore all
655 * JTAG-specific stuff like IR length for SWD.
657 * REVISIT can we verify "just one SWD DAP" here/early?
660 .jim_handler
= jim_jtag_newtap
,
661 .mode
= COMMAND_CONFIG
,
662 .help
= "declare a new SWD DAP"
664 COMMAND_REGISTRATION_DONE
667 static const struct command_registration swd_handlers
[] = {
671 .help
= "SWD command group",
672 .chain
= swd_commands
,
675 COMMAND_REGISTRATION_DONE
678 static int swd_select(struct command_context
*ctx
)
680 /* FIXME: only place where global 'adapter_driver' is still needed */
681 extern struct adapter_driver
*adapter_driver
;
682 const struct swd_driver
*swd
= adapter_driver
->swd_ops
;
685 retval
= register_commands(ctx
, NULL
, swd_handlers
);
686 if (retval
!= ERROR_OK
)
689 /* be sure driver is in SWD mode; start
690 * with hardware default TRN (1), it can be changed later
692 if (!swd
|| !swd
->read_reg
|| !swd
->write_reg
|| !swd
->init
) {
693 LOG_DEBUG("no SWD driver?");
697 retval
= swd
->init();
698 if (retval
!= ERROR_OK
) {
699 LOG_DEBUG("can't init SWD driver");
706 static int swd_init(struct command_context
*ctx
)
708 /* nothing done here, SWD is initialized
709 * together with the DAP */
713 static struct transport swd_transport
= {
715 .select
= swd_select
,
719 static void swd_constructor(void) __attribute__((constructor
));
720 static void swd_constructor(void)
722 transport_register(&swd_transport
);
725 /** Returns true if the current debug session
726 * is using SWD as its transport.
728 bool transport_is_swd(void)
730 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)