979c643e903d0a028b221bf254ccfc81e4fa868c
[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
181         retval = swd_queue_dp_write_inner(dap, DP_TARGETSEL, dap->multidrop_targetsel);
182         if (retval != ERROR_OK)
183                 return retval;
184
185         retval = swd_queue_dp_read_inner(dap, DP_DPIDR, &dpidr);
186         if (retval != ERROR_OK)
187                 return retval;
188
189         if (clear_sticky) {
190                 /* Clear all sticky errors (including ORUN) */
191                 swd_clear_sticky_errors(dap);
192         } else {
193                 /* Ideally just clear ORUN flag which is set by reset */
194                 retval = swd_queue_dp_write_inner(dap, DP_ABORT, ORUNERRCLR);
195                 if (retval != ERROR_OK)
196                         return retval;
197         }
198
199         retval = swd_queue_dp_read_inner(dap, DP_DLPIDR, &dlpidr);
200         if (retval != ERROR_OK)
201                 return retval;
202
203         retval = swd_run_inner(dap);
204         if (retval != ERROR_OK)
205                 return retval;
206
207         if ((dpidr & DP_DPIDR_VERSION_MASK) < (2UL << DP_DPIDR_VERSION_SHIFT)) {
208                 LOG_INFO("Read DPIDR 0x%08" PRIx32
209                                  " has version < 2. A non multidrop capable device connected?",
210                                  dpidr);
211                 return ERROR_FAIL;
212         }
213
214         /* TODO: check TARGETID if DLIPDR is same for more than one DP */
215         uint32_t expected_dlpidr = DP_DLPIDR_PROTVSN |
216                         (dap->multidrop_targetsel & DP_TARGETSEL_INSTANCEID_MASK);
217         if (dlpidr != expected_dlpidr) {
218                 LOG_INFO("Read incorrect DLPIDR 0x%08" PRIx32
219                                  " (possibly CTRL/STAT value)",
220                                  dlpidr);
221                 return ERROR_FAIL;
222         }
223
224         LOG_DEBUG_IO("Selected DP_TARGETSEL 0x%08" PRIx32, dap->multidrop_targetsel);
225         swd_multidrop_selected_dap = dap;
226
227         if (dpidr_ptr)
228                 *dpidr_ptr = dpidr;
229
230         if (dlpidr_ptr)
231                 *dlpidr_ptr = dlpidr;
232
233         return retval;
234 }
235
236 static int swd_multidrop_select(struct adiv5_dap *dap)
237 {
238         if (!dap_is_multidrop(dap))
239                 return ERROR_OK;
240
241         if (swd_multidrop_selected_dap == dap)
242                 return ERROR_OK;
243
244         int retval = ERROR_OK;
245         for (unsigned int retry = 0; ; retry++) {
246                 bool clear_sticky = retry > 0;
247
248                 retval = swd_multidrop_select_inner(dap, NULL, NULL, clear_sticky);
249                 if (retval == ERROR_OK)
250                         break;
251
252                 swd_multidrop_selected_dap = NULL;
253                 if (retry > 3) {
254                         LOG_ERROR("Failed to select multidrop %s", adiv5_dap_name(dap));
255                         return retval;
256                 }
257
258                 LOG_DEBUG("Failed to select multidrop %s, retrying...",
259                                   adiv5_dap_name(dap));
260         }
261
262         return retval;
263 }
264
265 static int swd_connect_multidrop(struct adiv5_dap *dap)
266 {
267         int retval;
268         uint32_t dpidr = 0xdeadbeef;
269         uint32_t dlpidr = 0xdeadbeef;
270         int64_t timeout = timeval_ms() + 500;
271
272         do {
273                 swd_send_sequence(dap, JTAG_TO_DORMANT);
274                 swd_send_sequence(dap, DORMANT_TO_SWD);
275
276                 /* Clear link state, including the SELECT cache. */
277                 dap->do_reconnect = false;
278                 dap_invalidate_cache(dap);
279                 swd_multidrop_selected_dap = NULL;
280
281                 retval = swd_multidrop_select_inner(dap, &dpidr, &dlpidr, true);
282                 if (retval == ERROR_OK)
283                         break;
284
285                 alive_sleep(1);
286
287         } while (timeval_ms() < timeout);
288
289         if (retval != ERROR_OK) {
290                 swd_multidrop_selected_dap = NULL;
291                 LOG_ERROR("Failed to connect multidrop %s", adiv5_dap_name(dap));
292                 return retval;
293         }
294
295         LOG_INFO("SWD DPIDR 0x%08" PRIx32 ", DLPIDR 0x%08" PRIx32,
296                           dpidr, dlpidr);
297
298         return retval;
299 }
300
301 static int swd_connect_single(struct adiv5_dap *dap)
302 {
303         int retval;
304         uint32_t dpidr = 0xdeadbeef;
305         int64_t timeout = timeval_ms() + 500;
306
307         do {
308                 if (dap->switch_through_dormant) {
309                         swd_send_sequence(dap, JTAG_TO_DORMANT);
310                         swd_send_sequence(dap, DORMANT_TO_SWD);
311                 } else {
312                         swd_send_sequence(dap, JTAG_TO_SWD);
313                 }
314
315                 /* Clear link state, including the SELECT cache. */
316                 dap->do_reconnect = false;
317                 dap_invalidate_cache(dap);
318
319                 /* The sequences to enter in SWD (JTAG_TO_SWD and DORMANT_TO_SWD) end
320                  * with a SWD line reset sequence (50 clk with SWDIO high).
321                  * From ARM IHI 0074C ADIv6.0, chapter B4.3.3 "Connection and line reset
322                  * sequence":
323                  * - line reset sets DP_SELECT_DPBANK to zero;
324                  * - read of DP_DPIDR takes the connection out of reset;
325                  * - write of DP_TARGETSEL keeps the connection in reset;
326                  * - other accesses return protocol error (SWDIO not driven by target).
327                  *
328                  * Read DP_DPIDR to get out of reset. Initialize dap->select to zero to
329                  * skip the write to DP_SELECT, avoiding the protocol error. Set again
330                  * dap->select to DP_SELECT_INVALID because the rest of the register is
331                  * unknown after line reset.
332                  */
333                 dap->select = 0;
334                 retval = swd_queue_dp_read_inner(dap, DP_DPIDR, &dpidr);
335                 if (retval == ERROR_OK) {
336                         retval = swd_run_inner(dap);
337                         if (retval == ERROR_OK)
338                                 break;
339                 }
340
341                 alive_sleep(1);
342
343                 dap->switch_through_dormant = !dap->switch_through_dormant;
344         } while (timeval_ms() < timeout);
345         dap->select = DP_SELECT_INVALID;
346
347         if (retval != ERROR_OK) {
348                 LOG_ERROR("Error connecting DP: cannot read IDR");
349                 return retval;
350         }
351
352         LOG_INFO("SWD DPIDR 0x%08" PRIx32, dpidr);
353
354         do {
355                 dap->do_reconnect = false;
356
357                 /* force clear all sticky faults */
358                 swd_clear_sticky_errors(dap);
359
360                 retval = swd_run_inner(dap);
361                 if (retval != ERROR_WAIT)
362                         break;
363
364                 alive_sleep(10);
365
366         } while (timeval_ms() < timeout);
367
368         return retval;
369 }
370
371 static int swd_connect(struct adiv5_dap *dap)
372 {
373         int status;
374
375         /* FIXME validate transport config ... is the
376          * configured DAP present (check IDCODE)?
377          */
378
379         /* Check if we should reset srst already when connecting, but not if reconnecting. */
380         if (!dap->do_reconnect) {
381                 enum reset_types jtag_reset_config = jtag_get_reset_config();
382
383                 if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
384                         if (jtag_reset_config & RESET_SRST_NO_GATING)
385                                 adapter_assert_reset();
386                         else
387                                 LOG_WARNING("\'srst_nogate\' reset_config option is required");
388                 }
389         }
390
391         if (dap_is_multidrop(dap))
392                 status = swd_connect_multidrop(dap);
393         else
394                 status = swd_connect_single(dap);
395
396         /* IHI 0031E B4.3.2:
397          * "A WAIT response must not be issued to the ...
398          * ... writes to the ABORT register"
399          * swd_clear_sticky_errors() writes to the ABORT register only.
400          *
401          * Unfortunately at least Microchip SAMD51/E53/E54 returns WAIT
402          * in a corner case. Just try if ABORT resolves the problem.
403          */
404         if (status == ERROR_WAIT) {
405                 LOG_WARNING("Connecting DP: stalled AP operation, issuing ABORT");
406
407                 dap->do_reconnect = false;
408
409                 status = swd_queue_dp_write_inner(dap, DP_ABORT,
410                         DAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR);
411
412                 if (status == ERROR_OK)
413                         status = swd_run_inner(dap);
414         }
415
416         if (status == ERROR_OK)
417                 status = dap_dp_init(dap);
418
419         return status;
420 }
421
422 static int swd_check_reconnect(struct adiv5_dap *dap)
423 {
424         if (dap->do_reconnect)
425                 return swd_connect(dap);
426
427         return ERROR_OK;
428 }
429
430 static int swd_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)
431 {
432         const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
433         assert(swd);
434
435         /* TODO: Send DAPABORT in swd_multidrop_select_inner()
436          * in the case the multidrop dap is not selected?
437          * swd_queue_ap_abort() is not currently used anyway...
438          */
439         int retval = swd_multidrop_select(dap);
440         if (retval != ERROR_OK)
441                 return retval;
442
443         swd->write_reg(swd_cmd(false, false, DP_ABORT),
444                 DAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);
445         return check_sync(dap);
446 }
447
448 static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned reg,
449                 uint32_t *data)
450 {
451         int retval = swd_check_reconnect(dap);
452         if (retval != ERROR_OK)
453                 return retval;
454
455         retval = swd_multidrop_select(dap);
456         if (retval != ERROR_OK)
457                 return retval;
458
459         return swd_queue_dp_read_inner(dap, reg, data);
460 }
461
462 static int swd_queue_dp_write(struct adiv5_dap *dap, unsigned reg,
463                 uint32_t data)
464 {
465         const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
466         assert(swd);
467
468         int retval = swd_check_reconnect(dap);
469         if (retval != ERROR_OK)
470                 return retval;
471
472         retval = swd_multidrop_select(dap);
473         if (retval != ERROR_OK)
474                 return retval;
475
476         return swd_queue_dp_write_inner(dap, reg, data);
477 }
478
479 /** Select the AP register bank matching bits 7:4 of reg. */
480 static int swd_queue_ap_bankselect(struct adiv5_ap *ap, unsigned reg)
481 {
482         int retval;
483         struct adiv5_dap *dap = ap->dap;
484         uint64_t sel;
485
486         if (is_adiv6(dap)) {
487                 sel = ap->ap_num | (reg & 0x00000FF0);
488                 if (sel == (dap->select & ~0xfULL))
489                         return ERROR_OK;
490
491                 if (dap->select != DP_SELECT_INVALID)
492                         sel |= dap->select & 0xf;
493                 dap->select = sel;
494                 LOG_DEBUG("AP BANKSEL: %" PRIx64, sel);
495
496                 retval = swd_queue_dp_write(dap, DP_SELECT, (uint32_t)sel);
497
498                 if (retval == ERROR_OK && dap->asize > 32)
499                         retval = swd_queue_dp_write(dap, DP_SELECT1, (uint32_t)(sel >> 32));
500
501                 if (retval != ERROR_OK)
502                         dap->select = DP_SELECT_INVALID;
503
504                 return retval;
505         }
506
507         /* ADIv5 */
508         sel = (ap->ap_num << 24) | (reg & 0x000000F0);
509         if (dap->select != DP_SELECT_INVALID)
510                 sel |= dap->select & DP_SELECT_DPBANK;
511
512         if (sel == dap->select)
513                 return ERROR_OK;
514
515         dap->select = sel;
516
517         retval = swd_queue_dp_write_inner(dap, DP_SELECT, sel);
518         if (retval != ERROR_OK)
519                 dap->select = DP_SELECT_INVALID;
520
521         return retval;
522 }
523
524 static int swd_queue_ap_read(struct adiv5_ap *ap, unsigned reg,
525                 uint32_t *data)
526 {
527         struct adiv5_dap *dap = ap->dap;
528         const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
529         assert(swd);
530
531         int retval = swd_check_reconnect(dap);
532         if (retval != ERROR_OK)
533                 return retval;
534
535         retval = swd_multidrop_select(dap);
536         if (retval != ERROR_OK)
537                 return retval;
538
539         retval = swd_queue_ap_bankselect(ap, reg);
540         if (retval != ERROR_OK)
541                 return retval;
542
543         swd->read_reg(swd_cmd(true, true, reg), dap->last_read, ap->memaccess_tck);
544         dap->last_read = data;
545
546         return check_sync(dap);
547 }
548
549 static int swd_queue_ap_write(struct adiv5_ap *ap, unsigned reg,
550                 uint32_t data)
551 {
552         struct adiv5_dap *dap = ap->dap;
553         const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
554         assert(swd);
555
556         int retval = swd_check_reconnect(dap);
557         if (retval != ERROR_OK)
558                 return retval;
559
560         retval = swd_multidrop_select(dap);
561         if (retval != ERROR_OK)
562                 return retval;
563
564         swd_finish_read(dap);
565
566         retval = swd_queue_ap_bankselect(ap, reg);
567         if (retval != ERROR_OK)
568                 return retval;
569
570         swd->write_reg(swd_cmd(false, true, reg), data, ap->memaccess_tck);
571
572         return check_sync(dap);
573 }
574
575 /** Executes all queued DAP operations. */
576 static int swd_run(struct adiv5_dap *dap)
577 {
578         int retval = swd_multidrop_select(dap);
579         if (retval != ERROR_OK)
580                 return retval;
581
582         swd_finish_read(dap);
583
584         return swd_run_inner(dap);
585 }
586
587 /** Put the SWJ-DP back to JTAG mode */
588 static void swd_quit(struct adiv5_dap *dap)
589 {
590         const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
591         static bool done;
592
593         /* There is no difference if the sequence is sent at the last
594          * or the first swd_quit() call, send it just once */
595         if (done)
596                 return;
597
598         done = true;
599         if (dap_is_multidrop(dap)) {
600                 swd->switch_seq(SWD_TO_DORMANT);
601                 /* Revisit!
602                  * Leaving DPs in dormant state was tested and offers some safety
603                  * against DPs mismatch in case of unintentional use of non-multidrop SWD.
604                  * To put SWJ-DPs to power-on state issue
605                  * swd->switch_seq(DORMANT_TO_JTAG);
606                  */
607         } else {
608                 if (dap->switch_through_dormant) {
609                         swd->switch_seq(SWD_TO_DORMANT);
610                         swd->switch_seq(DORMANT_TO_JTAG);
611                 } else {
612                         swd->switch_seq(SWD_TO_JTAG);
613                 }
614         }
615
616         /* flush the queue to shift out the sequence before exit */
617         swd->run();
618 }
619
620 const struct dap_ops swd_dap_ops = {
621         .connect = swd_connect,
622         .send_sequence = swd_send_sequence,
623         .queue_dp_read = swd_queue_dp_read,
624         .queue_dp_write = swd_queue_dp_write,
625         .queue_ap_read = swd_queue_ap_read,
626         .queue_ap_write = swd_queue_ap_write,
627         .queue_ap_abort = swd_queue_ap_abort,
628         .run = swd_run,
629         .quit = swd_quit,
630 };
631
632 static const struct command_registration swd_commands[] = {
633         {
634                 /*
635                  * Set up SWD and JTAG targets identically, unless/until
636                  * infrastructure improves ...  meanwhile, ignore all
637                  * JTAG-specific stuff like IR length for SWD.
638                  *
639                  * REVISIT can we verify "just one SWD DAP" here/early?
640                  */
641                 .name = "newdap",
642                 .jim_handler = jim_jtag_newtap,
643                 .mode = COMMAND_CONFIG,
644                 .help = "declare a new SWD DAP"
645         },
646         COMMAND_REGISTRATION_DONE
647 };
648
649 static const struct command_registration swd_handlers[] = {
650         {
651                 .name = "swd",
652                 .mode = COMMAND_ANY,
653                 .help = "SWD command group",
654                 .chain = swd_commands,
655                 .usage = "",
656         },
657         COMMAND_REGISTRATION_DONE
658 };
659
660 static int swd_select(struct command_context *ctx)
661 {
662         /* FIXME: only place where global 'adapter_driver' is still needed */
663         extern struct adapter_driver *adapter_driver;
664         const struct swd_driver *swd = adapter_driver->swd_ops;
665         int retval;
666
667         retval = register_commands(ctx, NULL, swd_handlers);
668         if (retval != ERROR_OK)
669                 return retval;
670
671          /* be sure driver is in SWD mode; start
672           * with hardware default TRN (1), it can be changed later
673           */
674         if (!swd || !swd->read_reg || !swd->write_reg || !swd->init) {
675                 LOG_DEBUG("no SWD driver?");
676                 return ERROR_FAIL;
677         }
678
679         retval = swd->init();
680         if (retval != ERROR_OK) {
681                 LOG_DEBUG("can't init SWD driver");
682                 return retval;
683         }
684
685         return retval;
686 }
687
688 static int swd_init(struct command_context *ctx)
689 {
690         /* nothing done here, SWD is initialized
691          * together with the DAP */
692         return ERROR_OK;
693 }
694
695 static struct transport swd_transport = {
696         .name = "swd",
697         .select = swd_select,
698         .init = swd_init,
699 };
700
701 static void swd_constructor(void) __attribute__((constructor));
702 static void swd_constructor(void)
703 {
704         transport_register(&swd_transport);
705 }
706
707 /** Returns true if the current debug session
708  * is using SWD as its transport.
709  */
710 bool transport_is_swd(void)
711 {
712         return get_current_transport() == &swd_transport;
713 }