target/adi_v5_swd: suppress reconnect in swd_multidrop_select()
[fw/openocd] / src / target / adi_v5_swd.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4  *
5  *   Copyright (C) 2010 by David Brownell
6  ***************************************************************************/
7
8 /**
9  * @file
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.
15  *
16  * Single-DAP support only.
17  *
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
22  *
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).
26  *
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.
30  *
31  */
32
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36
37 #include "arm.h"
38 #include "arm_adi_v5.h"
39 #include <helper/time_support.h>
40
41 #include <transport/transport.h>
42 #include <jtag/interface.h>
43
44 #include <jtag/swd.h>
45
46 /* for debug, set do_sync to true to force synchronous transfers */
47 static bool do_sync;
48
49 static struct adiv5_dap *swd_multidrop_selected_dap;
50
51
52 static int swd_queue_dp_write_inner(struct adiv5_dap *dap, unsigned int reg,
53                 uint32_t data);
54
55
56 static int swd_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)
57 {
58         const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
59         assert(swd);
60
61         return swd->switch_seq(seq);
62 }
63
64 static void swd_finish_read(struct adiv5_dap *dap)
65 {
66         const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
67         if (dap->last_read) {
68                 swd->read_reg(swd_cmd(true, false, DP_RDBUFF), dap->last_read, 0);
69                 dap->last_read = NULL;
70         }
71 }
72
73 static void swd_clear_sticky_errors(struct adiv5_dap *dap)
74 {
75         const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
76         assert(swd);
77
78         swd->write_reg(swd_cmd(false, false, DP_ABORT),
79                 STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);
80 }
81
82 static int swd_run_inner(struct adiv5_dap *dap)
83 {
84         const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
85         int retval;
86
87         retval = swd->run();
88
89         if (retval != ERROR_OK) {
90                 /* fault response */
91                 dap->do_reconnect = true;
92         }
93
94         return retval;
95 }
96
97 static inline int check_sync(struct adiv5_dap *dap)
98 {
99         return do_sync ? swd_run_inner(dap) : ERROR_OK;
100 }
101
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)
104 {
105         /* Only register address 0 and 4 are banked. */
106         if ((reg & 0xf) > 4)
107                 return ERROR_OK;
108
109         uint64_t sel = (reg & 0x000000F0) >> 4;
110         if (dap->select != DP_SELECT_INVALID)
111                 sel |= dap->select & ~0xfULL;
112
113         if (sel == dap->select)
114                 return ERROR_OK;
115
116         dap->select = sel;
117
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;
121
122         return retval;
123 }
124
125 static int swd_queue_dp_read_inner(struct adiv5_dap *dap, unsigned int reg,
126                 uint32_t *data)
127 {
128         const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
129         assert(swd);
130
131         int retval = swd_queue_dp_bankselect(dap, reg);
132         if (retval != ERROR_OK)
133                 return retval;
134
135         swd->read_reg(swd_cmd(true, false, reg), data, 0);
136
137         return check_sync(dap);
138 }
139
140 static int swd_queue_dp_write_inner(struct adiv5_dap *dap, unsigned int reg,
141                 uint32_t data)
142 {
143         int retval;
144         const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
145         assert(swd);
146
147         swd_finish_read(dap);
148
149         if (reg == DP_SELECT) {
150                 dap->select = data & (DP_SELECT_APSEL | DP_SELECT_APBANK | DP_SELECT_DPBANK);
151
152                 swd->write_reg(swd_cmd(false, false, reg), data, 0);
153
154                 retval = check_sync(dap);
155                 if (retval != ERROR_OK)
156                         dap->select = DP_SELECT_INVALID;
157
158                 return retval;
159         }
160
161         retval = swd_queue_dp_bankselect(dap, reg);
162         if (retval != ERROR_OK)
163                 return retval;
164
165         swd->write_reg(swd_cmd(false, false, reg), data, 0);
166
167         return check_sync(dap);
168 }
169
170
171 static int swd_multidrop_select_inner(struct adiv5_dap *dap, uint32_t *dpidr_ptr,
172                 uint32_t *dlpidr_ptr, bool clear_sticky)
173 {
174         int retval;
175         uint32_t dpidr, dlpidr;
176
177         assert(dap_is_multidrop(dap));
178
179         swd_send_sequence(dap, LINE_RESET);
180         /* From ARM IHI 0074C ADIv6.0, chapter B4.3.3 "Connection and line reset
181          * sequence":
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).
186          *
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.
191          */
192         dap->select = 0;
193
194         retval = swd_queue_dp_write_inner(dap, DP_TARGETSEL, dap->multidrop_targetsel);
195         if (retval != ERROR_OK)
196                 return retval;
197
198         retval = swd_queue_dp_read_inner(dap, DP_DPIDR, &dpidr);
199         if (retval != ERROR_OK)
200                 return retval;
201
202         if (clear_sticky) {
203                 /* Clear all sticky errors (including ORUN) */
204                 swd_clear_sticky_errors(dap);
205         } else {
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)
209                         return retval;
210         }
211
212         dap->select = DP_SELECT_INVALID;
213
214         retval = swd_queue_dp_read_inner(dap, DP_DLPIDR, &dlpidr);
215         if (retval != ERROR_OK)
216                 return retval;
217
218         retval = swd_run_inner(dap);
219         if (retval != ERROR_OK)
220                 return retval;
221
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?",
225                                  dpidr);
226                 return ERROR_FAIL;
227         }
228
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)",
235                                  dlpidr);
236                 return ERROR_FAIL;
237         }
238
239         LOG_DEBUG_IO("Selected DP_TARGETSEL 0x%08" PRIx32, dap->multidrop_targetsel);
240         swd_multidrop_selected_dap = dap;
241
242         if (dpidr_ptr)
243                 *dpidr_ptr = dpidr;
244
245         if (dlpidr_ptr)
246                 *dlpidr_ptr = dlpidr;
247
248         return retval;
249 }
250
251 static int swd_multidrop_select(struct adiv5_dap *dap)
252 {
253         if (!dap_is_multidrop(dap))
254                 return ERROR_OK;
255
256         if (swd_multidrop_selected_dap == dap)
257                 return ERROR_OK;
258
259         int retval = ERROR_OK;
260         for (unsigned int retry = 0; ; retry++) {
261                 bool clear_sticky = retry > 0;
262
263                 retval = swd_multidrop_select_inner(dap, NULL, NULL, clear_sticky);
264                 if (retval == ERROR_OK)
265                         break;
266
267                 swd_multidrop_selected_dap = NULL;
268                 if (retry > 3) {
269                         LOG_ERROR("Failed to select multidrop %s", adiv5_dap_name(dap));
270                         return retval;
271                 }
272
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;
277         }
278
279         return retval;
280 }
281
282 static int swd_connect_multidrop(struct adiv5_dap *dap)
283 {
284         int retval;
285         uint32_t dpidr = 0xdeadbeef;
286         uint32_t dlpidr = 0xdeadbeef;
287         int64_t timeout = timeval_ms() + 500;
288
289         do {
290                 swd_send_sequence(dap, JTAG_TO_DORMANT);
291                 swd_send_sequence(dap, DORMANT_TO_SWD);
292
293                 /* Clear link state, including the SELECT cache. */
294                 dap->do_reconnect = false;
295                 dap_invalidate_cache(dap);
296                 swd_multidrop_selected_dap = NULL;
297
298                 retval = swd_multidrop_select_inner(dap, &dpidr, &dlpidr, true);
299                 if (retval == ERROR_OK)
300                         break;
301
302                 alive_sleep(1);
303
304         } while (timeval_ms() < timeout);
305
306         if (retval != ERROR_OK) {
307                 swd_multidrop_selected_dap = NULL;
308                 LOG_ERROR("Failed to connect multidrop %s", adiv5_dap_name(dap));
309                 return retval;
310         }
311
312         LOG_INFO("SWD DPIDR 0x%08" PRIx32 ", DLPIDR 0x%08" PRIx32,
313                           dpidr, dlpidr);
314
315         return retval;
316 }
317
318 static int swd_connect_single(struct adiv5_dap *dap)
319 {
320         int retval;
321         uint32_t dpidr = 0xdeadbeef;
322         int64_t timeout = timeval_ms() + 500;
323
324         do {
325                 if (dap->switch_through_dormant) {
326                         swd_send_sequence(dap, JTAG_TO_DORMANT);
327                         swd_send_sequence(dap, DORMANT_TO_SWD);
328                 } else {
329                         swd_send_sequence(dap, JTAG_TO_SWD);
330                 }
331
332                 /* Clear link state, including the SELECT cache. */
333                 dap->do_reconnect = false;
334                 dap_invalidate_cache(dap);
335
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
339                  * sequence":
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).
344                  *
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.
349                  */
350                 dap->select = 0;
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)
355                                 break;
356                 }
357
358                 alive_sleep(1);
359
360                 dap->switch_through_dormant = !dap->switch_through_dormant;
361         } while (timeval_ms() < timeout);
362
363         dap->select = DP_SELECT_INVALID;
364
365         if (retval != ERROR_OK) {
366                 LOG_ERROR("Error connecting DP: cannot read IDR");
367                 return retval;
368         }
369
370         LOG_INFO("SWD DPIDR 0x%08" PRIx32, dpidr);
371
372         do {
373                 dap->do_reconnect = false;
374
375                 /* force clear all sticky faults */
376                 swd_clear_sticky_errors(dap);
377
378                 retval = swd_run_inner(dap);
379                 if (retval != ERROR_WAIT)
380                         break;
381
382                 alive_sleep(10);
383
384         } while (timeval_ms() < timeout);
385
386         return retval;
387 }
388
389 static int swd_connect(struct adiv5_dap *dap)
390 {
391         int status;
392
393         /* FIXME validate transport config ... is the
394          * configured DAP present (check IDCODE)?
395          */
396
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();
400
401                 if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
402                         if (jtag_reset_config & RESET_SRST_NO_GATING)
403                                 adapter_assert_reset();
404                         else
405                                 LOG_WARNING("\'srst_nogate\' reset_config option is required");
406                 }
407         }
408
409         if (dap_is_multidrop(dap))
410                 status = swd_connect_multidrop(dap);
411         else
412                 status = swd_connect_single(dap);
413
414         /* IHI 0031E B4.3.2:
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.
418          *
419          * Unfortunately at least Microchip SAMD51/E53/E54 returns WAIT
420          * in a corner case. Just try if ABORT resolves the problem.
421          */
422         if (status == ERROR_WAIT) {
423                 LOG_WARNING("Connecting DP: stalled AP operation, issuing ABORT");
424
425                 dap->do_reconnect = false;
426
427                 status = swd_queue_dp_write_inner(dap, DP_ABORT,
428                         DAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR);
429
430                 if (status == ERROR_OK)
431                         status = swd_run_inner(dap);
432         }
433
434         if (status == ERROR_OK)
435                 status = dap_dp_init(dap);
436
437         return status;
438 }
439
440 static int swd_check_reconnect(struct adiv5_dap *dap)
441 {
442         if (dap->do_reconnect)
443                 return swd_connect(dap);
444
445         return ERROR_OK;
446 }
447
448 static int swd_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)
449 {
450         const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
451         assert(swd);
452
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...
456          */
457         int retval = swd_multidrop_select(dap);
458         if (retval != ERROR_OK)
459                 return retval;
460
461         swd->write_reg(swd_cmd(false, false, DP_ABORT),
462                 DAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);
463         return check_sync(dap);
464 }
465
466 static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned reg,
467                 uint32_t *data)
468 {
469         int retval = swd_check_reconnect(dap);
470         if (retval != ERROR_OK)
471                 return retval;
472
473         retval = swd_multidrop_select(dap);
474         if (retval != ERROR_OK)
475                 return retval;
476
477         return swd_queue_dp_read_inner(dap, reg, data);
478 }
479
480 static int swd_queue_dp_write(struct adiv5_dap *dap, unsigned reg,
481                 uint32_t data)
482 {
483         const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
484         assert(swd);
485
486         int retval = swd_check_reconnect(dap);
487         if (retval != ERROR_OK)
488                 return retval;
489
490         retval = swd_multidrop_select(dap);
491         if (retval != ERROR_OK)
492                 return retval;
493
494         return swd_queue_dp_write_inner(dap, reg, data);
495 }
496
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)
499 {
500         int retval;
501         struct adiv5_dap *dap = ap->dap;
502         uint64_t sel;
503
504         if (is_adiv6(dap)) {
505                 sel = ap->ap_num | (reg & 0x00000FF0);
506                 if (sel == (dap->select & ~0xfULL))
507                         return ERROR_OK;
508
509                 if (dap->select != DP_SELECT_INVALID)
510                         sel |= dap->select & 0xf;
511                 dap->select = sel;
512                 LOG_DEBUG("AP BANKSEL: %" PRIx64, sel);
513
514                 retval = swd_queue_dp_write(dap, DP_SELECT, (uint32_t)sel);
515
516                 if (retval == ERROR_OK && dap->asize > 32)
517                         retval = swd_queue_dp_write(dap, DP_SELECT1, (uint32_t)(sel >> 32));
518
519                 if (retval != ERROR_OK)
520                         dap->select = DP_SELECT_INVALID;
521
522                 return retval;
523         }
524
525         /* ADIv5 */
526         sel = (ap->ap_num << 24) | (reg & 0x000000F0);
527         if (dap->select != DP_SELECT_INVALID)
528                 sel |= dap->select & DP_SELECT_DPBANK;
529
530         if (sel == dap->select)
531                 return ERROR_OK;
532
533         dap->select = sel;
534
535         retval = swd_queue_dp_write_inner(dap, DP_SELECT, sel);
536         if (retval != ERROR_OK)
537                 dap->select = DP_SELECT_INVALID;
538
539         return retval;
540 }
541
542 static int swd_queue_ap_read(struct adiv5_ap *ap, unsigned reg,
543                 uint32_t *data)
544 {
545         struct adiv5_dap *dap = ap->dap;
546         const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
547         assert(swd);
548
549         int retval = swd_check_reconnect(dap);
550         if (retval != ERROR_OK)
551                 return retval;
552
553         retval = swd_multidrop_select(dap);
554         if (retval != ERROR_OK)
555                 return retval;
556
557         retval = swd_queue_ap_bankselect(ap, reg);
558         if (retval != ERROR_OK)
559                 return retval;
560
561         swd->read_reg(swd_cmd(true, true, reg), dap->last_read, ap->memaccess_tck);
562         dap->last_read = data;
563
564         return check_sync(dap);
565 }
566
567 static int swd_queue_ap_write(struct adiv5_ap *ap, unsigned reg,
568                 uint32_t data)
569 {
570         struct adiv5_dap *dap = ap->dap;
571         const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
572         assert(swd);
573
574         int retval = swd_check_reconnect(dap);
575         if (retval != ERROR_OK)
576                 return retval;
577
578         retval = swd_multidrop_select(dap);
579         if (retval != ERROR_OK)
580                 return retval;
581
582         swd_finish_read(dap);
583
584         retval = swd_queue_ap_bankselect(ap, reg);
585         if (retval != ERROR_OK)
586                 return retval;
587
588         swd->write_reg(swd_cmd(false, true, reg), data, ap->memaccess_tck);
589
590         return check_sync(dap);
591 }
592
593 /** Executes all queued DAP operations. */
594 static int swd_run(struct adiv5_dap *dap)
595 {
596         int retval = swd_multidrop_select(dap);
597         if (retval != ERROR_OK)
598                 return retval;
599
600         swd_finish_read(dap);
601
602         return swd_run_inner(dap);
603 }
604
605 /** Put the SWJ-DP back to JTAG mode */
606 static void swd_quit(struct adiv5_dap *dap)
607 {
608         const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
609         static bool done;
610
611         /* There is no difference if the sequence is sent at the last
612          * or the first swd_quit() call, send it just once */
613         if (done)
614                 return;
615
616         done = true;
617         if (dap_is_multidrop(dap)) {
618                 swd->switch_seq(SWD_TO_DORMANT);
619                 /* Revisit!
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);
624                  */
625         } else {
626                 if (dap->switch_through_dormant) {
627                         swd->switch_seq(SWD_TO_DORMANT);
628                         swd->switch_seq(DORMANT_TO_JTAG);
629                 } else {
630                         swd->switch_seq(SWD_TO_JTAG);
631                 }
632         }
633
634         /* flush the queue to shift out the sequence before exit */
635         swd->run();
636 }
637
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,
646         .run = swd_run,
647         .quit = swd_quit,
648 };
649
650 static const struct command_registration swd_commands[] = {
651         {
652                 /*
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.
656                  *
657                  * REVISIT can we verify "just one SWD DAP" here/early?
658                  */
659                 .name = "newdap",
660                 .jim_handler = jim_jtag_newtap,
661                 .mode = COMMAND_CONFIG,
662                 .help = "declare a new SWD DAP"
663         },
664         COMMAND_REGISTRATION_DONE
665 };
666
667 static const struct command_registration swd_handlers[] = {
668         {
669                 .name = "swd",
670                 .mode = COMMAND_ANY,
671                 .help = "SWD command group",
672                 .chain = swd_commands,
673                 .usage = "",
674         },
675         COMMAND_REGISTRATION_DONE
676 };
677
678 static int swd_select(struct command_context *ctx)
679 {
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;
683         int retval;
684
685         retval = register_commands(ctx, NULL, swd_handlers);
686         if (retval != ERROR_OK)
687                 return retval;
688
689          /* be sure driver is in SWD mode; start
690           * with hardware default TRN (1), it can be changed later
691           */
692         if (!swd || !swd->read_reg || !swd->write_reg || !swd->init) {
693                 LOG_DEBUG("no SWD driver?");
694                 return ERROR_FAIL;
695         }
696
697         retval = swd->init();
698         if (retval != ERROR_OK) {
699                 LOG_DEBUG("can't init SWD driver");
700                 return retval;
701         }
702
703         return retval;
704 }
705
706 static int swd_init(struct command_context *ctx)
707 {
708         /* nothing done here, SWD is initialized
709          * together with the DAP */
710         return ERROR_OK;
711 }
712
713 static struct transport swd_transport = {
714         .name = "swd",
715         .select = swd_select,
716         .init = swd_init,
717 };
718
719 static void swd_constructor(void) __attribute__((constructor));
720 static void swd_constructor(void)
721 {
722         transport_register(&swd_transport);
723 }
724
725 /** Returns true if the current debug session
726  * is using SWD as its transport.
727  */
728 bool transport_is_swd(void)
729 {
730         return get_current_transport() == &swd_transport;
731 }