OpenOCD
adi_v5_swd.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  *
5  * Copyright (C) 2010 by David Brownell
6  ***************************************************************************/
7 
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/adapter.h>
43 #include <jtag/interface.h>
44 
45 #include <jtag/swd.h>
46 
47 /* for debug, set do_sync to true to force synchronous transfers */
48 static bool do_sync;
49 
51 
53 
57 };
58 
59 static int swd_queue_dp_write_inner(struct adiv5_dap *dap, unsigned int reg,
60  uint32_t data);
61 
62 
63 static int swd_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)
64 {
65  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
66  assert(swd);
67 
68  return swd->switch_seq(seq);
69 }
70 
71 static int swd_finish_read(struct adiv5_dap *dap)
72 {
73  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
74  if (!dap->last_read)
75  return ERROR_OK;
76 
77  int retval = swd->read_reg(swd_cmd(true, false, DP_RDBUFF),
78  dap->last_read, 0);
79  dap->last_read = NULL;
80  return retval;
81 }
82 
83 static int swd_clear_sticky_errors(struct adiv5_dap *dap)
84 {
85  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
86  assert(swd);
87 
88  return swd->write_reg(swd_cmd(false, false, DP_ABORT),
90 }
91 
92 static int swd_run_inner(struct adiv5_dap *dap)
93 {
94  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
95 
96  return swd->run();
97 }
98 
99 static inline int check_sync(struct adiv5_dap *dap)
100 {
101  return do_sync ? swd_run_inner(dap) : ERROR_OK;
102 }
103 
105 static int swd_queue_dp_bankselect(struct adiv5_dap *dap, unsigned int reg)
106 {
107  /* Only register address 0 (ADIv6 only) and 4 are banked. */
108  if (is_adiv6(dap) ? (reg & 0xf) > 4 : (reg & 0xf) != 4)
109  return ERROR_OK;
110 
111  uint32_t sel = (reg >> 4) & DP_SELECT_DPBANK;
112 
113  /* ADIv6 ensures DPBANKSEL = 0 after line reset */
114  if ((dap->select_valid || (is_adiv6(dap) && dap->select_dpbanksel_valid))
115  && (sel == (dap->select & DP_SELECT_DPBANK)))
116  return ERROR_OK;
117 
118  /* Use the AP part of dap->select regardless of dap->select_valid:
119  * if !dap->select_valid
120  * dap->select contains a speculative value likely going to be used
121  * in the following swd_queue_ap_bankselect() */
122  sel |= (uint32_t)(dap->select & SELECT_AP_MASK);
123 
124  LOG_DEBUG_IO("DP BANK SELECT: %" PRIx32, sel);
125 
126  /* dap->select cache gets updated in the following call */
127  return swd_queue_dp_write_inner(dap, DP_SELECT, sel);
128 }
129 
130 static int swd_queue_dp_read_inner(struct adiv5_dap *dap, unsigned int reg,
131  uint32_t *data)
132 {
133  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
134  assert(swd);
135 
136  int retval = swd_queue_dp_bankselect(dap, reg);
137  if (retval != ERROR_OK)
138  return retval;
139 
140  retval = swd->read_reg(swd_cmd(true, false, reg), data, 0);
141  if (retval != ERROR_OK)
142  return retval;
143 
144  return check_sync(dap);
145 }
146 
147 static int swd_queue_dp_write_inner(struct adiv5_dap *dap, unsigned int reg,
148  uint32_t data)
149 {
150  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
151  assert(swd);
152 
153  int retval = swd_finish_read(dap);
154  if (retval != ERROR_OK)
155  return retval;
156 
157 
158  if (reg == DP_SELECT) {
159  dap->select = data | (dap->select & (0xffffffffull << 32));
160 
161  retval = swd->write_reg(swd_cmd(false, false, reg), data, 0);
162  if (retval != ERROR_OK)
163  return retval;
164 
165  retval = check_sync(dap);
166  dap->select_valid = (retval == ERROR_OK);
168 
169  return retval;
170  }
171 
172  if (reg == DP_SELECT1)
173  dap->select = ((uint64_t)data << 32) | (dap->select & 0xffffffffull);
174 
175  /* DP_ABORT write is not banked.
176  * Prevent writing DP_SELECT before as it would fail on locked up DP */
177  if (reg != DP_ABORT)
178  retval = swd_queue_dp_bankselect(dap, reg);
179 
180  if (retval == ERROR_OK) {
181  retval = swd->write_reg(swd_cmd(false, false, reg), data, 0);
182  if (retval != ERROR_OK)
183  return retval;
184 
185  retval = check_sync(dap);
186  }
187 
188  if (reg == DP_SELECT1)
189  dap->select1_valid = (retval == ERROR_OK);
190 
191  return retval;
192 }
193 
194 
195 static int swd_multidrop_select_inner(struct adiv5_dap *dap, uint32_t *dpidr_ptr,
196  uint32_t *dlpidr_ptr, bool clear_sticky)
197 {
198  int retval;
199  uint32_t dpidr, dlpidr;
200 
201  assert(dap_is_multidrop(dap));
202 
203  /* Send JTAG_TO_DORMANT and DORMANT_TO_SWD just once
204  * and then use shorter LINE_RESET until communication fails */
208  } else {
210  }
211 
212  /*
213  * Zero dap->select and set dap->select_dpbanksel_valid
214  * to skip the write to DP_SELECT before DPIDR read, avoiding
215  * the protocol error.
216  * Clear the other validity flags because the rest of the DP
217  * SELECT and SELECT1 registers is unknown after line reset.
218  */
219  dap->select = 0;
220  dap->select_dpbanksel_valid = true;
221  dap->select_valid = false;
222  dap->select1_valid = false;
223 
225  if (retval != ERROR_OK)
226  return retval;
227 
228  retval = swd_queue_dp_read_inner(dap, DP_DPIDR, &dpidr);
229  if (retval != ERROR_OK)
230  return retval;
231 
232  if (clear_sticky) {
233  /* Clear all sticky errors (including ORUN) */
234  retval = swd_clear_sticky_errors(dap);
235  } else {
236  /* Ideally just clear ORUN flag which is set by reset */
238  }
239  if (retval != ERROR_OK)
240  return retval;
241 
242  retval = swd_queue_dp_read_inner(dap, DP_DLPIDR, &dlpidr);
243  if (retval != ERROR_OK)
244  return retval;
245 
246  retval = swd_run_inner(dap);
247  if (retval != ERROR_OK)
248  return retval;
249 
250  if ((dpidr & DP_DPIDR_VERSION_MASK) < (2UL << DP_DPIDR_VERSION_SHIFT)) {
251  LOG_INFO("Read DPIDR 0x%08" PRIx32
252  " has version < 2. A non multidrop capable device connected?",
253  dpidr);
254  return ERROR_FAIL;
255  }
256 
257  /* TODO: check TARGETID if DLIPDR is same for more than one DP */
258  uint32_t expected_dlpidr = DP_DLPIDR_PROTVSN |
260  if (dlpidr != expected_dlpidr) {
261  LOG_INFO("Read incorrect DLPIDR 0x%08" PRIx32
262  " (possibly CTRL/STAT value)",
263  dlpidr);
264  return ERROR_FAIL;
265  }
266 
267  LOG_DEBUG_IO("Selected DP_TARGETSEL 0x%08" PRIx32, dap->multidrop_targetsel);
270 
271  if (dpidr_ptr)
272  *dpidr_ptr = dpidr;
273 
274  if (dlpidr_ptr)
275  *dlpidr_ptr = dlpidr;
276 
277  return retval;
278 }
279 
280 static int swd_multidrop_select(struct adiv5_dap *dap)
281 {
282  if (!dap_is_multidrop(dap))
283  return ERROR_OK;
284 
285  if (swd_multidrop_selected_dap == dap)
286  return ERROR_OK;
287 
288  int retval = ERROR_OK;
289  for (unsigned int retry = 0; ; retry++) {
290  bool clear_sticky = retry > 0;
291 
292  retval = swd_multidrop_select_inner(dap, NULL, NULL, clear_sticky);
293  if (retval == ERROR_OK)
294  break;
295 
297  if (retry > 3) {
298  LOG_ERROR("Failed to select multidrop %s", adiv5_dap_name(dap));
299  dap->do_reconnect = true;
300  return retval;
301  }
302 
303  LOG_DEBUG("Failed to select multidrop %s, retrying...",
304  adiv5_dap_name(dap));
305  }
306 
307  dap->do_reconnect = false;
308  return retval;
309 }
310 
311 static int swd_connect_multidrop(struct adiv5_dap *dap)
312 {
313  int retval;
314  uint32_t dpidr = 0xdeadbeef;
315  uint32_t dlpidr = 0xdeadbeef;
316  int64_t timeout = timeval_ms() + 500;
317 
318  do {
319  /* Do not make any assumptions about SWD state in case of reconnect */
320  if (dap->do_reconnect)
322 
323  /* Clear link state, including the SELECT cache. */
324  dap->do_reconnect = false;
327 
328  retval = swd_multidrop_select_inner(dap, &dpidr, &dlpidr, true);
329  if (retval == ERROR_OK)
330  break;
331 
333  alive_sleep(1);
334 
335  } while (timeval_ms() < timeout);
336 
337  if (retval != ERROR_OK) {
339  LOG_ERROR("Failed to connect multidrop %s", adiv5_dap_name(dap));
340  return retval;
341  }
342 
344  LOG_INFO("SWD DPIDR 0x%08" PRIx32 ", DLPIDR 0x%08" PRIx32,
345  dpidr, dlpidr);
346 
347  return retval;
348 }
349 
350 static int swd_connect_single(struct adiv5_dap *dap)
351 {
352  int retval;
353  uint32_t dpidr = 0xdeadbeef;
354  int64_t timeout = timeval_ms() + 500;
355 
356  do {
357  if (dap->switch_through_dormant) {
360  } else {
362  }
363 
364  /* Clear link state, including the SELECT cache. */
365  dap->do_reconnect = false;
367 
368  /* The sequences to enter in SWD (JTAG_TO_SWD and DORMANT_TO_SWD) end
369  * with a SWD line reset sequence (50 clk with SWDIO high).
370  * From ARM IHI 0031F ADIv5.2 and ARM IHI 0074C ADIv6.0,
371  * chapter B4.3.3 "Connection and line reset sequence":
372  * - DPv3 (ADIv6) only: line reset sets DP_SELECT_DPBANK to zero;
373  * - read of DP_DPIDR takes the connection out of reset;
374  * - write of DP_TARGETSEL keeps the connection in reset;
375  * - other accesses return protocol error (SWDIO not driven by target).
376  *
377  * dap_invalidate_cache() sets dap->select to zero and all validity
378  * flags to invalid. Set dap->select_dpbanksel_valid only
379  * to skip the write to DP_SELECT, avoiding the protocol error.
380  * Read DP_DPIDR to get out of reset.
381  */
382  dap->select_dpbanksel_valid = true;
383 
384  retval = swd_queue_dp_read_inner(dap, DP_DPIDR, &dpidr);
385  if (retval == ERROR_OK) {
386  retval = swd_run_inner(dap);
387  if (retval == ERROR_OK)
388  break;
389  }
390 
391  alive_sleep(1);
392 
394  } while (timeval_ms() < timeout);
395 
396  if (retval != ERROR_OK) {
397  LOG_ERROR("Error connecting DP: cannot read IDR");
398  return retval;
399  }
400 
401  LOG_INFO("SWD DPIDR 0x%08" PRIx32, dpidr);
402 
403  do {
404  dap->do_reconnect = false;
405 
406  /* force clear all sticky faults */
407  retval = swd_clear_sticky_errors(dap);
408 
409  if (retval == ERROR_OK)
410  retval = swd_run_inner(dap);
411 
412  if (retval != ERROR_WAIT)
413  break;
414 
415  alive_sleep(10);
416 
417  } while (timeval_ms() < timeout);
418 
419  return retval;
420 }
421 
422 static int swd_pre_connect(struct adiv5_dap *dap)
423 {
425 
426  return ERROR_OK;
427 }
428 
429 static int swd_connect(struct adiv5_dap *dap)
430 {
431  int status;
432 
433  /* FIXME validate transport config ... is the
434  * configured DAP present (check IDCODE)?
435  */
436 
437  /* Check if we should reset srst already when connecting, but not if reconnecting. */
438  if (!dap->do_reconnect) {
440 
444  else
445  LOG_WARNING("\'srst_nogate\' reset_config option is required");
446  }
447  }
448 
449  if (dap_is_multidrop(dap))
451  else
452  status = swd_connect_single(dap);
453 
454  /* IHI 0031E B4.3.2:
455  * "A WAIT response must not be issued to the ...
456  * ... writes to the ABORT register"
457  * swd_clear_sticky_errors() writes to the ABORT register only.
458  *
459  * Unfortunately at least Microchip SAMD51/E53/E54 returns WAIT
460  * in a corner case. Just try if ABORT resolves the problem.
461  */
462  if (status == ERROR_WAIT) {
463  LOG_WARNING("Connecting DP: stalled AP operation, issuing ABORT");
464 
465  dap->do_reconnect = false;
466 
469 
470  if (status == ERROR_OK)
471  status = swd_run_inner(dap);
472  }
473 
474  if (status == ERROR_OK)
475  status = dap_dp_init(dap);
476 
477  return status;
478 }
479 
480 static int swd_error_recovery(struct adiv5_dap *dap, int err,
481  enum swd_recovery_mode mode)
482 {
483  /* TODO: do not reconnect on all errors, just clear sticky
484  * after SWD FAULT */
485  if (err != ERROR_OK) {
486  dap->do_reconnect = true;
487  LOG_DEBUG_IO("Reconnect on next SWD op");
488  }
489  return err;
490 }
491 
492 static int swd_check_reconnect(struct adiv5_dap *dap)
493 {
494  if (dap->do_reconnect)
495  return swd_connect(dap);
496 
497  return ERROR_OK;
498 }
499 
500 static int swd_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)
501 {
502  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
503  assert(swd);
504 
505  /* TODO: Send DAPABORT in swd_multidrop_select_inner()
506  * in the case the multidrop dap is not selected?
507  * swd_queue_ap_abort() is not currently used anyway...
508  */
509  int retval = swd_multidrop_select(dap);
510  if (retval != ERROR_OK)
511  return retval;
512 
513  retval = swd->write_reg(swd_cmd(false, false, DP_ABORT),
515  if (retval != ERROR_OK)
516  return retval;
517 
518  return check_sync(dap);
519 }
520 
521 static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned int reg,
522  uint32_t *data)
523 {
524  int retval = swd_check_reconnect(dap);
525  if (retval != ERROR_OK)
526  return retval;
527 
528  retval = swd_multidrop_select(dap);
529  if (retval != ERROR_OK)
530  return retval;
531 
532  retval = swd_queue_dp_read_inner(dap, reg, data);
533  return swd_error_recovery(dap, retval, SWD_RECOVERY_QUEUE);
534 }
535 
536 static int swd_queue_dp_write(struct adiv5_dap *dap, unsigned int reg,
537  uint32_t data)
538 {
539  int retval = swd_check_reconnect(dap);
540  if (retval != ERROR_OK)
541  return retval;
542 
543  retval = swd_multidrop_select(dap);
544  if (retval != ERROR_OK)
545  return retval;
546 
547  retval = swd_queue_dp_write_inner(dap, reg, data);
548  return swd_error_recovery(dap, retval, SWD_RECOVERY_QUEUE);
549 }
550 
552 static int swd_queue_ap_bankselect(struct adiv5_ap *ap, unsigned int reg)
553 {
554  int retval;
555  struct adiv5_dap *dap = ap->dap;
556  uint64_t sel;
557 
558  if (is_adiv6(dap))
559  sel = ap->ap_num | (reg & 0x00000FF0);
560  else
561  sel = (ap->ap_num << 24) | (reg & ADIV5_DP_SELECT_APBANK);
562 
563  uint64_t sel_diff = (sel ^ dap->select) & SELECT_AP_MASK;
564 
565  bool set_select = !dap->select_valid || (sel_diff & 0xffffffffull);
566  bool set_select1 = is_adiv6(dap) && dap->asize > 32
567  && (!dap->select1_valid
568  || sel_diff & (0xffffffffull << 32));
569 
570  if (set_select && set_select1) {
571  /* Prepare DP bank for DP_SELECT1 now to save one write */
572  sel |= (DP_SELECT1 & 0x000000f0) >> 4;
573  } else {
574  /* Use the DP part of dap->select regardless of dap->select_valid:
575  * if !dap->select_valid
576  * dap->select contains a speculative value likely going to be used
577  * in the following swd_queue_dp_bankselect().
578  * Moreover dap->select_valid should never be false here as a DP bank
579  * is always selected before selecting an AP bank */
580  sel |= dap->select & DP_SELECT_DPBANK;
581  }
582 
583  if (set_select) {
584  LOG_DEBUG_IO("AP BANK SELECT: %" PRIx32, (uint32_t)sel);
585 
586  retval = swd_queue_dp_write(dap, DP_SELECT, (uint32_t)sel);
587  retval = swd_error_recovery(dap, retval, SWD_RECOVERY_QUEUE);
588  if (retval != ERROR_OK)
589  return retval;
590  }
591 
592  if (set_select1) {
593  LOG_DEBUG_IO("AP BANK SELECT1: %" PRIx32, (uint32_t)(sel >> 32));
594 
595  retval = swd_queue_dp_write(dap, DP_SELECT1, (uint32_t)(sel >> 32));
596  retval = swd_error_recovery(dap, retval, SWD_RECOVERY_QUEUE);
597  if (retval != ERROR_OK)
598  return retval;
599  }
600 
601  return ERROR_OK;
602 }
603 
604 static int swd_queue_ap_read(struct adiv5_ap *ap, unsigned int reg,
605  uint32_t *data)
606 {
607  struct adiv5_dap *dap = ap->dap;
608  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
609  assert(swd);
610 
611  int retval = swd_check_reconnect(dap);
612  if (retval != ERROR_OK)
613  return retval;
614 
615  retval = swd_multidrop_select(dap);
616  if (retval != ERROR_OK)
617  return retval;
618 
619  retval = swd_queue_ap_bankselect(ap, reg);
620  if (retval != ERROR_OK)
621  return retval;
622 
623  retval = swd->read_reg(swd_cmd(true, true, reg),
624  dap->last_read, ap->memaccess_tck);
625  retval = swd_error_recovery(dap, retval, SWD_RECOVERY_QUEUE);
626  if (retval != ERROR_OK)
627  return retval;
628 
629  dap->last_read = data;
630 
631  return check_sync(dap);
632 }
633 
634 static int swd_queue_ap_write(struct adiv5_ap *ap, unsigned int reg,
635  uint32_t data)
636 {
637  struct adiv5_dap *dap = ap->dap;
638  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
639  assert(swd);
640 
641  int retval = swd_check_reconnect(dap);
642  if (retval != ERROR_OK)
643  return retval;
644 
645  retval = swd_multidrop_select(dap);
646  if (retval != ERROR_OK)
647  return retval;
648 
649  retval = swd_finish_read(dap);
650  retval = swd_error_recovery(dap, retval, SWD_RECOVERY_QUEUE);
651  if (retval != ERROR_OK)
652  return retval;
653 
654  retval = swd_queue_ap_bankselect(ap, reg);
655  if (retval != ERROR_OK)
656  return retval;
657 
658  retval = swd->write_reg(swd_cmd(false, true, reg), data, ap->memaccess_tck);
659  retval = swd_error_recovery(dap, retval, SWD_RECOVERY_QUEUE);
660  if (retval != ERROR_OK)
661  return retval;
662 
663  return check_sync(dap);
664 }
665 
667 static int swd_run(struct adiv5_dap *dap)
668 {
669  int retval = swd_multidrop_select(dap);
670  if (retval != ERROR_OK)
671  return retval;
672 
673  retval = swd_finish_read(dap);
674  retval = swd_error_recovery(dap, retval, SWD_RECOVERY_QUEUE);
675  if (retval != ERROR_OK)
676  return retval;
677 
678  retval = swd_run_inner(dap);
679  return swd_error_recovery(dap, retval, SWD_RECOVERY_RUN);
680 }
681 
683 static void swd_quit(struct adiv5_dap *dap)
684 {
685  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
686  static bool done;
687 
688  /* There is no difference if the sequence is sent at the last
689  * or the first swd_quit() call, send it just once */
690  if (done)
691  return;
692 
693  done = true;
694  if (dap_is_multidrop(dap)) {
695  /* Emit the switch seq to dormant state regardless the state mirrored
696  * in swd_multidrop_in_swd_state. Doing so ensures robust operation
697  * in the case the variable is out of sync.
698  * Sending SWD_TO_DORMANT makes no change if the DP is already dormant. */
701  /* Revisit!
702  * Leaving DPs in dormant state was tested and offers some safety
703  * against DPs mismatch in case of unintentional use of non-multidrop SWD.
704  * To put SWJ-DPs to power-on state issue
705  * swd->switch_seq(DORMANT_TO_JTAG);
706  */
707  } else {
708  if (dap->switch_through_dormant) {
711  } else {
712  swd->switch_seq(SWD_TO_JTAG);
713  }
714  }
715 
716  /* flush the queue to shift out the sequence before exit */
717  swd->run();
718 }
719 
720 const struct dap_ops swd_dap_ops = {
722  .connect = swd_connect,
723  .send_sequence = swd_send_sequence,
724  .queue_dp_read = swd_queue_dp_read,
725  .queue_dp_write = swd_queue_dp_write,
726  .queue_ap_read = swd_queue_ap_read,
727  .queue_ap_write = swd_queue_ap_write,
728  .queue_ap_abort = swd_queue_ap_abort,
729  .run = swd_run,
730  .quit = swd_quit,
731 };
732 
733 static const struct command_registration swd_commands[] = {
734  {
735  /*
736  * Set up SWD and JTAG targets identically, unless/until
737  * infrastructure improves ... meanwhile, ignore all
738  * JTAG-specific stuff like IR length for SWD.
739  *
740  * REVISIT can we verify "just one SWD DAP" here/early?
741  */
742  .name = "newdap",
743  .handler = handle_jtag_newtap,
744  .mode = COMMAND_CONFIG,
745  .help = "declare a new SWD DAP",
746  .usage = "basename dap_type ['-irlen' count] "
747  "['-enable'|'-disable'] "
748  "['-expected-id' number] "
749  "['-ignore-version'] "
750  "['-ignore-bypass'] "
751  "['-ircapture' number] "
752  "['-ir-bypass' number] "
753  "['-mask' number]",
754  },
756 };
757 
758 static const struct command_registration swd_handlers[] = {
759  {
760  .name = "swd",
761  .mode = COMMAND_ANY,
762  .help = "SWD command group",
763  .chain = swd_commands,
764  .usage = "",
765  },
767 };
768 
769 static int swd_select(struct command_context *ctx)
770 {
771  const struct swd_driver *swd = adapter_driver->swd_ops;
772  int retval;
773 
774  retval = register_commands(ctx, NULL, swd_handlers);
775  if (retval != ERROR_OK)
776  return retval;
777 
778  /* be sure driver is in SWD mode; start
779  * with hardware default TRN (1), it can be changed later
780  */
781  if (!swd || !swd->read_reg || !swd->write_reg || !swd->init) {
782  LOG_DEBUG("no SWD driver?");
783  return ERROR_FAIL;
784  }
785 
786  retval = swd->init();
787  if (retval != ERROR_OK) {
788  LOG_DEBUG("can't init SWD driver");
789  return retval;
790  }
791 
792  return retval;
793 }
794 
795 static int swd_init(struct command_context *ctx)
796 {
797  /* nothing done here, SWD is initialized
798  * together with the DAP */
799  return ERROR_OK;
800 }
801 
802 static struct transport swd_transport = {
803  .id = TRANSPORT_SWD,
804  .select = swd_select,
805  .init = swd_init,
806 };
807 
808 static void swd_constructor(void) __attribute__((constructor));
809 static void swd_constructor(void)
810 {
812 }
813 
818 {
820 }
static int swd_multidrop_select(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:280
const struct dap_ops swd_dap_ops
Definition: adi_v5_swd.c:720
static int swd_connect_single(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:350
static int swd_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)
Definition: adi_v5_swd.c:500
static const struct command_registration swd_commands[]
Definition: adi_v5_swd.c:733
static int swd_finish_read(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:71
static int swd_queue_dp_write_inner(struct adiv5_dap *dap, unsigned int reg, uint32_t data)
Definition: adi_v5_swd.c:147
static int check_sync(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:99
static int swd_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, uint32_t *data)
Definition: adi_v5_swd.c:604
static int swd_queue_dp_write(struct adiv5_dap *dap, unsigned int reg, uint32_t data)
Definition: adi_v5_swd.c:536
swd_recovery_mode
Definition: adi_v5_swd.c:54
@ SWD_RECOVERY_RUN
Definition: adi_v5_swd.c:56
@ SWD_RECOVERY_QUEUE
Definition: adi_v5_swd.c:55
static int swd_run_inner(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:92
static int swd_connect(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:429
static int swd_error_recovery(struct adiv5_dap *dap, int err, enum swd_recovery_mode mode)
Definition: adi_v5_swd.c:480
static int swd_pre_connect(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:422
static int swd_connect_multidrop(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:311
static int swd_init(struct command_context *ctx)
Definition: adi_v5_swd.c:795
static int swd_run(struct adiv5_dap *dap)
Executes all queued DAP operations.
Definition: adi_v5_swd.c:667
static int swd_select(struct command_context *ctx)
Definition: adi_v5_swd.c:769
static int swd_queue_ap_bankselect(struct adiv5_ap *ap, unsigned int reg)
Select the AP register bank.
Definition: adi_v5_swd.c:552
static int swd_queue_dp_bankselect(struct adiv5_dap *dap, unsigned int reg)
Select the DP register bank.
Definition: adi_v5_swd.c:105
static int swd_queue_dp_read_inner(struct adiv5_dap *dap, unsigned int reg, uint32_t *data)
Definition: adi_v5_swd.c:130
static int swd_clear_sticky_errors(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:83
static struct transport swd_transport
Definition: adi_v5_swd.c:802
static bool swd_multidrop_in_swd_state
Definition: adi_v5_swd.c:52
bool transport_is_swd(void)
Returns true if the current debug session is using SWD as its transport.
Definition: adi_v5_swd.c:817
static bool do_sync
Definition: adi_v5_swd.c:48
static int swd_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, uint32_t data)
Definition: adi_v5_swd.c:634
static int swd_check_reconnect(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:492
static int swd_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)
Definition: adi_v5_swd.c:63
static void swd_quit(struct adiv5_dap *dap)
Put the SWJ-DP back to JTAG mode.
Definition: adi_v5_swd.c:683
static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned int reg, uint32_t *data)
Definition: adi_v5_swd.c:521
static const struct command_registration swd_handlers[]
Definition: adi_v5_swd.c:758
static struct adiv5_dap * swd_multidrop_selected_dap
Definition: adi_v5_swd.c:50
static int swd_multidrop_select_inner(struct adiv5_dap *dap, uint32_t *dpidr_ptr, uint32_t *dlpidr_ptr, bool clear_sticky)
Definition: adi_v5_swd.c:195
static void swd_constructor(void)
Definition: adi_v5_swd.c:808
Holds the interface to ARM cores.
int dap_dp_init(struct adiv5_dap *dap)
Initialize a DAP.
Definition: arm_adi_v5.c:787
void dap_invalidate_cache(struct adiv5_dap *dap)
Invalidate cached DP select and cached TAR and CSW of all APs.
Definition: arm_adi_v5.c:764
This defines formats and data structures used to talk to ADIv5 entities.
#define DP_ABORT
Definition: arm_adi_v5.h:46
#define WDERRCLR
Definition: arm_adi_v5.h:71
#define DP_SELECT
Definition: arm_adi_v5.h:57
const struct swd_driver * adiv5_dap_swd_driver(struct adiv5_dap *self)
Definition: arm_dap.c:59
#define DP_TARGETSEL_INSTANCEID_MASK
Definition: arm_adi_v5.h:114
#define DP_SELECT1
Definition: arm_adi_v5.h:55
#define SELECT_AP_MASK
Definition: arm_adi_v5.h:107
#define STKERRCLR
Definition: arm_adi_v5.h:70
#define DP_DPIDR
Definition: arm_adi_v5.h:45
#define DP_RDBUFF
Definition: arm_adi_v5.h:58
#define DP_DLPIDR
Definition: arm_adi_v5.h:53
#define ORUNERRCLR
Definition: arm_adi_v5.h:72
#define DP_DLPIDR_PROTVSN
Definition: arm_adi_v5.h:98
#define STKCMPCLR
Definition: arm_adi_v5.h:69
#define DAPABORT
Definition: arm_adi_v5.h:68
#define DP_DPIDR_VERSION_MASK
Definition: arm_adi_v5.h:65
swd_special_seq
Definition: arm_adi_v5.h:236
@ DORMANT_TO_JTAG
Definition: arm_adi_v5.h:243
@ JTAG_TO_SWD
Definition: arm_adi_v5.h:238
@ DORMANT_TO_SWD
Definition: arm_adi_v5.h:242
@ LINE_RESET
Definition: arm_adi_v5.h:237
@ JTAG_TO_DORMANT
Definition: arm_adi_v5.h:239
@ SWD_TO_DORMANT
Definition: arm_adi_v5.h:241
@ SWD_TO_JTAG
Definition: arm_adi_v5.h:240
const char * adiv5_dap_name(struct adiv5_dap *self)
Definition: arm_dap.c:53
static bool is_adiv6(const struct adiv5_dap *dap)
Check if DAP is ADIv6.
Definition: arm_adi_v5.h:523
#define DP_TARGETSEL
Definition: arm_adi_v5.h:59
#define DP_DPIDR_VERSION_SHIFT
Definition: arm_adi_v5.h:64
static bool dap_is_multidrop(struct adiv5_dap *dap)
Check if SWD multidrop configuration is valid.
Definition: arm_adi_v5.h:767
#define ADIV5_DP_SELECT_APBANK
Definition: arm_adi_v5.h:101
#define DP_SELECT_DPBANK
Definition: arm_adi_v5.h:102
enum arm_mode mode
Definition: armv4_5.c:280
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:256
static int register_commands(struct command_context *cmd_ctx, const char *cmd_prefix, const struct command_registration *cmds)
Register one or more commands in the specified context, as children of parent (or top-level commends,...
Definition: command.h:277
@ COMMAND_CONFIG
Definition: command.h:41
@ COMMAND_ANY
Definition: command.h:42
static enum reset_types jtag_reset_config
Definition: jtag/core.c:89
enum reset_types jtag_get_reset_config(void)
Definition: jtag/core.c:1730
int adapter_assert_reset(void)
Definition: jtag/core.c:1875
reset_types
Definition: jtag.h:215
@ RESET_SRST_NO_GATING
Definition: jtag.h:224
@ RESET_CNCT_UNDER_SRST
Definition: jtag.h:225
void alive_sleep(uint64_t ms)
Definition: log.c:478
#define ERROR_WAIT
Definition: log.h:189
#define LOG_DEBUG_IO(expr ...)
Definition: log.h:116
#define LOG_WARNING(expr ...)
Definition: log.h:144
#define ERROR_FAIL
Definition: log.h:188
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define LOG_INFO(expr ...)
Definition: log.h:141
#define LOG_DEBUG(expr ...)
Definition: log.h:124
#define ERROR_OK
Definition: log.h:182
struct qn908x_flash_bank __attribute__
Definition: armv8.c:1059
Represents a driver for a debugging interface.
Definition: interface.h:214
const struct swd_driver * swd_ops
Low-level SWD APIs.
Definition: interface.h:360
This represents an ARM Debug Interface (v5) Access Port (AP).
Definition: arm_adi_v5.h:250
uint64_t ap_num
ADIv5: Number of this AP (0~255) ADIv6: Base address of this AP (4k aligned) TODO: to be more coheren...
Definition: arm_adi_v5.h:261
struct adiv5_dap * dap
DAP this AP belongs to.
Definition: arm_adi_v5.h:254
uint32_t memaccess_tck
Configures how many extra tck clocks are added after starting a MEM-AP access before we try to read i...
Definition: arm_adi_v5.h:306
This represents an ARM Debug Interface (v5) Debug Access Port (DAP).
Definition: arm_adi_v5.h:348
bool select_valid
Validity of DP SELECT cache.
Definition: arm_adi_v5.h:372
bool select1_valid
Definition: arm_adi_v5.h:373
struct adiv5_ap ap[DP_APSEL_MAX+1]
Definition: arm_adi_v5.h:364
bool select_dpbanksel_valid
Partial DPBANKSEL validity for SWD only.
Definition: arm_adi_v5.h:383
bool do_reconnect
Signals that an attempt to reestablish communication afresh should be performed before the next acces...
Definition: arm_adi_v5.h:414
uint32_t * last_read
Holds the pointer to the destination word for the last queued read, for use with posted AP read seque...
Definition: arm_adi_v5.h:392
bool switch_through_dormant
Record if enter in SWD required passing through DORMANT.
Definition: arm_adi_v5.h:430
uint32_t multidrop_targetsel
Value to select DP in SWD multidrop mode or DP_TARGETSEL_INVALID.
Definition: arm_adi_v5.h:421
uint64_t select
Cache for DP SELECT and SELECT1 (ADIv6) register.
Definition: arm_adi_v5.h:370
unsigned int asize
Definition: arm_adi_v5.h:436
const char * name
Definition: command.h:239
const char * usage
a string listing the options and arguments, required or optional
Definition: command.h:244
Transport-neutral representation of queued DAP transactions, supporting both JTAG and SWD transports.
Definition: arm_adi_v5.h:446
int(* pre_connect_init)(struct adiv5_dap *dap)
Optional; called once on the first enabled dap before connecting.
Definition: arm_adi_v5.h:448
Definition: register.h:111
int(* switch_seq)(enum swd_special_seq seq)
Queue a special SWDIO sequence.
Definition: swd.h:264
int(* read_reg)(uint8_t cmd, uint32_t *value, uint32_t ap_delay_hint)
Queued read of an AP or DP register.
Definition: swd.h:276
int(* init)(void)
Initialize the debug link so it can perform SWD operations.
Definition: swd.h:255
int(* run)(void)
Execute any queued transactions and collect the result.
Definition: swd.h:296
int(* write_reg)(uint8_t cmd, uint32_t value, uint32_t ap_delay_hint)
Queued write of an AP or DP register.
Definition: swd.h:288
Definition: psoc6.c:83
Wrapper for transport lifecycle operations.
Definition: transport.h:55
unsigned int id
Each transport has a unique ID, used to select it from among the alternatives.
Definition: transport.h:60
static uint8_t swd_cmd(bool is_read, bool is_ap, uint8_t regnum)
Construct a "cmd" byte, in lSB bit order, which swd_driver.read_reg() and swd_driver....
Definition: swd.h:35
int64_t timeval_ms(void)
struct transport * get_current_transport(void)
Returns the transport currently being used by this debug or programming session.
Definition: transport.c:252
int transport_register(struct transport *new_transport)
Registers a transport.
Definition: transport.c:211
#define TRANSPORT_SWD
Definition: transport.h:20
#define NULL
Definition: usb.h:16
uint8_t status[4]
Definition: vdebug.c:17