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 
54 
55 static int swd_queue_dp_write_inner(struct adiv5_dap *dap, unsigned int reg,
56  uint32_t data);
57 
58 
59 static int swd_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)
60 {
61  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
62  assert(swd);
63 
64  return swd->switch_seq(seq);
65 }
66 
67 static void swd_finish_read(struct adiv5_dap *dap)
68 {
69  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
70  if (dap->last_read) {
71  swd->read_reg(swd_cmd(true, false, DP_RDBUFF), dap->last_read, 0);
72  dap->last_read = NULL;
73  }
74 }
75 
76 static void swd_clear_sticky_errors(struct adiv5_dap *dap)
77 {
78  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
79  assert(swd);
80 
81  swd->write_reg(swd_cmd(false, false, DP_ABORT),
83 }
84 
85 static int swd_run_inner(struct adiv5_dap *dap)
86 {
87  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
88 
89  return swd->run();
90 }
91 
92 static inline int check_sync(struct adiv5_dap *dap)
93 {
94  return do_sync ? swd_run_inner(dap) : ERROR_OK;
95 }
96 
98 static int swd_queue_dp_bankselect(struct adiv5_dap *dap, unsigned int reg)
99 {
100  /* Only register address 0 (ADIv6 only) and 4 are banked. */
101  if (is_adiv6(dap) ? (reg & 0xf) > 4 : (reg & 0xf) != 4)
102  return ERROR_OK;
103 
104  uint32_t sel = (reg >> 4) & DP_SELECT_DPBANK;
105 
106  /* ADIv6 ensures DPBANKSEL = 0 after line reset */
107  if ((dap->select_valid || (is_adiv6(dap) && dap->select_dpbanksel_valid))
108  && (sel == (dap->select & DP_SELECT_DPBANK)))
109  return ERROR_OK;
110 
111  /* Use the AP part of dap->select regardless of dap->select_valid:
112  * if !dap->select_valid
113  * dap->select contains a speculative value likely going to be used
114  * in the following swd_queue_ap_bankselect() */
115  sel |= (uint32_t)(dap->select & SELECT_AP_MASK);
116 
117  LOG_DEBUG_IO("DP BANK SELECT: %" PRIx32, sel);
118 
119  /* dap->select cache gets updated in the following call */
120  return swd_queue_dp_write_inner(dap, DP_SELECT, sel);
121 }
122 
123 static int swd_queue_dp_read_inner(struct adiv5_dap *dap, unsigned int reg,
124  uint32_t *data)
125 {
126  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
127  assert(swd);
128 
129  int retval = swd_queue_dp_bankselect(dap, reg);
130  if (retval != ERROR_OK)
131  return retval;
132 
133  swd->read_reg(swd_cmd(true, false, reg), data, 0);
134 
135  return check_sync(dap);
136 }
137 
138 static int swd_queue_dp_write_inner(struct adiv5_dap *dap, unsigned int reg,
139  uint32_t data)
140 {
141  int retval = ERROR_OK;
142  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
143  assert(swd);
144 
145  swd_finish_read(dap);
146 
147  if (reg == DP_SELECT) {
148  dap->select = data | (dap->select & (0xffffffffull << 32));
149 
150  swd->write_reg(swd_cmd(false, false, reg), data, 0);
151 
152  retval = check_sync(dap);
153  dap->select_valid = (retval == ERROR_OK);
155 
156  return retval;
157  }
158 
159  if (reg == DP_SELECT1)
160  dap->select = ((uint64_t)data << 32) | (dap->select & 0xffffffffull);
161 
162  /* DP_ABORT write is not banked.
163  * Prevent writing DP_SELECT before as it would fail on locked up DP */
164  if (reg != DP_ABORT)
165  retval = swd_queue_dp_bankselect(dap, reg);
166 
167  if (retval == ERROR_OK) {
168  swd->write_reg(swd_cmd(false, false, reg), data, 0);
169 
170  retval = check_sync(dap);
171  }
172 
173  if (reg == DP_SELECT1)
174  dap->select1_valid = (retval == ERROR_OK);
175 
176  return retval;
177 }
178 
179 
180 static int swd_multidrop_select_inner(struct adiv5_dap *dap, uint32_t *dpidr_ptr,
181  uint32_t *dlpidr_ptr, bool clear_sticky)
182 {
183  int retval;
184  uint32_t dpidr, dlpidr;
185 
186  assert(dap_is_multidrop(dap));
187 
188  /* Send JTAG_TO_DORMANT and DORMANT_TO_SWD just once
189  * and then use shorter LINE_RESET until communication fails */
193  } else {
195  }
196 
197  /*
198  * Zero dap->select and set dap->select_dpbanksel_valid
199  * to skip the write to DP_SELECT before DPIDR read, avoiding
200  * the protocol error.
201  * Clear the other validity flags because the rest of the DP
202  * SELECT and SELECT1 registers is unknown after line reset.
203  */
204  dap->select = 0;
205  dap->select_dpbanksel_valid = true;
206  dap->select_valid = false;
207  dap->select1_valid = false;
208 
210  if (retval != ERROR_OK)
211  return retval;
212 
213  retval = swd_queue_dp_read_inner(dap, DP_DPIDR, &dpidr);
214  if (retval != ERROR_OK)
215  return retval;
216 
217  if (clear_sticky) {
218  /* Clear all sticky errors (including ORUN) */
220  } else {
221  /* Ideally just clear ORUN flag which is set by reset */
223  if (retval != ERROR_OK)
224  return retval;
225  }
226 
227  retval = swd_queue_dp_read_inner(dap, DP_DLPIDR, &dlpidr);
228  if (retval != ERROR_OK)
229  return retval;
230 
231  retval = swd_run_inner(dap);
232  if (retval != ERROR_OK)
233  return retval;
234 
235  if ((dpidr & DP_DPIDR_VERSION_MASK) < (2UL << DP_DPIDR_VERSION_SHIFT)) {
236  LOG_INFO("Read DPIDR 0x%08" PRIx32
237  " has version < 2. A non multidrop capable device connected?",
238  dpidr);
239  return ERROR_FAIL;
240  }
241 
242  /* TODO: check TARGETID if DLIPDR is same for more than one DP */
243  uint32_t expected_dlpidr = DP_DLPIDR_PROTVSN |
245  if (dlpidr != expected_dlpidr) {
246  LOG_INFO("Read incorrect DLPIDR 0x%08" PRIx32
247  " (possibly CTRL/STAT value)",
248  dlpidr);
249  return ERROR_FAIL;
250  }
251 
252  LOG_DEBUG_IO("Selected DP_TARGETSEL 0x%08" PRIx32, dap->multidrop_targetsel);
255 
256  if (dpidr_ptr)
257  *dpidr_ptr = dpidr;
258 
259  if (dlpidr_ptr)
260  *dlpidr_ptr = dlpidr;
261 
262  return retval;
263 }
264 
265 static int swd_multidrop_select(struct adiv5_dap *dap)
266 {
267  if (!dap_is_multidrop(dap))
268  return ERROR_OK;
269 
270  if (swd_multidrop_selected_dap == dap)
271  return ERROR_OK;
272 
273  int retval = ERROR_OK;
274  for (unsigned int retry = 0; ; retry++) {
275  bool clear_sticky = retry > 0;
276 
277  retval = swd_multidrop_select_inner(dap, NULL, NULL, clear_sticky);
278  if (retval == ERROR_OK)
279  break;
280 
282  if (retry > 3) {
283  LOG_ERROR("Failed to select multidrop %s", adiv5_dap_name(dap));
284  dap->do_reconnect = true;
285  return retval;
286  }
287 
288  LOG_DEBUG("Failed to select multidrop %s, retrying...",
289  adiv5_dap_name(dap));
290  }
291 
292  dap->do_reconnect = false;
293  return retval;
294 }
295 
296 static int swd_connect_multidrop(struct adiv5_dap *dap)
297 {
298  int retval;
299  uint32_t dpidr = 0xdeadbeef;
300  uint32_t dlpidr = 0xdeadbeef;
301  int64_t timeout = timeval_ms() + 500;
302 
303  do {
304  /* Do not make any assumptions about SWD state in case of reconnect */
305  if (dap->do_reconnect)
307 
308  /* Clear link state, including the SELECT cache. */
309  dap->do_reconnect = false;
312 
313  retval = swd_multidrop_select_inner(dap, &dpidr, &dlpidr, true);
314  if (retval == ERROR_OK)
315  break;
316 
318  alive_sleep(1);
319 
320  } while (timeval_ms() < timeout);
321 
322  if (retval != ERROR_OK) {
324  LOG_ERROR("Failed to connect multidrop %s", adiv5_dap_name(dap));
325  return retval;
326  }
327 
329  LOG_INFO("SWD DPIDR 0x%08" PRIx32 ", DLPIDR 0x%08" PRIx32,
330  dpidr, dlpidr);
331 
332  return retval;
333 }
334 
335 static int swd_connect_single(struct adiv5_dap *dap)
336 {
337  int retval;
338  uint32_t dpidr = 0xdeadbeef;
339  int64_t timeout = timeval_ms() + 500;
340 
341  do {
342  if (dap->switch_through_dormant) {
345  } else {
347  }
348 
349  /* Clear link state, including the SELECT cache. */
350  dap->do_reconnect = false;
352 
353  /* The sequences to enter in SWD (JTAG_TO_SWD and DORMANT_TO_SWD) end
354  * with a SWD line reset sequence (50 clk with SWDIO high).
355  * From ARM IHI 0031F ADIv5.2 and ARM IHI 0074C ADIv6.0,
356  * chapter B4.3.3 "Connection and line reset sequence":
357  * - DPv3 (ADIv6) only: line reset sets DP_SELECT_DPBANK to zero;
358  * - read of DP_DPIDR takes the connection out of reset;
359  * - write of DP_TARGETSEL keeps the connection in reset;
360  * - other accesses return protocol error (SWDIO not driven by target).
361  *
362  * dap_invalidate_cache() sets dap->select to zero and all validity
363  * flags to invalid. Set dap->select_dpbanksel_valid only
364  * to skip the write to DP_SELECT, avoiding the protocol error.
365  * Read DP_DPIDR to get out of reset.
366  */
367  dap->select_dpbanksel_valid = true;
368 
369  retval = swd_queue_dp_read_inner(dap, DP_DPIDR, &dpidr);
370  if (retval == ERROR_OK) {
371  retval = swd_run_inner(dap);
372  if (retval == ERROR_OK)
373  break;
374  }
375 
376  alive_sleep(1);
377 
379  } while (timeval_ms() < timeout);
380 
381  if (retval != ERROR_OK) {
382  LOG_ERROR("Error connecting DP: cannot read IDR");
383  return retval;
384  }
385 
386  LOG_INFO("SWD DPIDR 0x%08" PRIx32, dpidr);
387 
388  do {
389  dap->do_reconnect = false;
390 
391  /* force clear all sticky faults */
393 
394  retval = swd_run_inner(dap);
395  if (retval != ERROR_WAIT)
396  break;
397 
398  alive_sleep(10);
399 
400  } while (timeval_ms() < timeout);
401 
402  return retval;
403 }
404 
405 static int swd_pre_connect(struct adiv5_dap *dap)
406 {
408 
409  return ERROR_OK;
410 }
411 
412 static int swd_connect(struct adiv5_dap *dap)
413 {
414  int status;
415 
416  /* FIXME validate transport config ... is the
417  * configured DAP present (check IDCODE)?
418  */
419 
420  /* Check if we should reset srst already when connecting, but not if reconnecting. */
421  if (!dap->do_reconnect) {
423 
427  else
428  LOG_WARNING("\'srst_nogate\' reset_config option is required");
429  }
430  }
431 
432  if (dap_is_multidrop(dap))
434  else
435  status = swd_connect_single(dap);
436 
437  /* IHI 0031E B4.3.2:
438  * "A WAIT response must not be issued to the ...
439  * ... writes to the ABORT register"
440  * swd_clear_sticky_errors() writes to the ABORT register only.
441  *
442  * Unfortunately at least Microchip SAMD51/E53/E54 returns WAIT
443  * in a corner case. Just try if ABORT resolves the problem.
444  */
445  if (status == ERROR_WAIT) {
446  LOG_WARNING("Connecting DP: stalled AP operation, issuing ABORT");
447 
448  dap->do_reconnect = false;
449 
452 
453  if (status == ERROR_OK)
454  status = swd_run_inner(dap);
455  }
456 
457  if (status == ERROR_OK)
458  status = dap_dp_init(dap);
459 
460  return status;
461 }
462 
463 static int swd_check_reconnect(struct adiv5_dap *dap)
464 {
465  if (dap->do_reconnect)
466  return swd_connect(dap);
467 
468  return ERROR_OK;
469 }
470 
471 static int swd_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)
472 {
473  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
474  assert(swd);
475 
476  /* TODO: Send DAPABORT in swd_multidrop_select_inner()
477  * in the case the multidrop dap is not selected?
478  * swd_queue_ap_abort() is not currently used anyway...
479  */
480  int retval = swd_multidrop_select(dap);
481  if (retval != ERROR_OK)
482  return retval;
483 
484  swd->write_reg(swd_cmd(false, false, DP_ABORT),
486  return check_sync(dap);
487 }
488 
489 static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned int reg,
490  uint32_t *data)
491 {
492  int retval = swd_check_reconnect(dap);
493  if (retval != ERROR_OK)
494  return retval;
495 
496  retval = swd_multidrop_select(dap);
497  if (retval != ERROR_OK)
498  return retval;
499 
500  return swd_queue_dp_read_inner(dap, reg, data);
501 }
502 
503 static int swd_queue_dp_write(struct adiv5_dap *dap, unsigned int reg,
504  uint32_t data)
505 {
506  int retval = swd_check_reconnect(dap);
507  if (retval != ERROR_OK)
508  return retval;
509 
510  retval = swd_multidrop_select(dap);
511  if (retval != ERROR_OK)
512  return retval;
513 
514  return swd_queue_dp_write_inner(dap, reg, data);
515 }
516 
518 static int swd_queue_ap_bankselect(struct adiv5_ap *ap, unsigned int reg)
519 {
520  int retval;
521  struct adiv5_dap *dap = ap->dap;
522  uint64_t sel;
523 
524  if (is_adiv6(dap))
525  sel = ap->ap_num | (reg & 0x00000FF0);
526  else
527  sel = (ap->ap_num << 24) | (reg & ADIV5_DP_SELECT_APBANK);
528 
529  uint64_t sel_diff = (sel ^ dap->select) & SELECT_AP_MASK;
530 
531  bool set_select = !dap->select_valid || (sel_diff & 0xffffffffull);
532  bool set_select1 = is_adiv6(dap) && dap->asize > 32
533  && (!dap->select1_valid
534  || sel_diff & (0xffffffffull << 32));
535 
536  if (set_select && set_select1) {
537  /* Prepare DP bank for DP_SELECT1 now to save one write */
538  sel |= (DP_SELECT1 & 0x000000f0) >> 4;
539  } else {
540  /* Use the DP part of dap->select regardless of dap->select_valid:
541  * if !dap->select_valid
542  * dap->select contains a speculative value likely going to be used
543  * in the following swd_queue_dp_bankselect().
544  * Moreover dap->select_valid should never be false here as a DP bank
545  * is always selected before selecting an AP bank */
546  sel |= dap->select & DP_SELECT_DPBANK;
547  }
548 
549  if (set_select) {
550  LOG_DEBUG_IO("AP BANK SELECT: %" PRIx32, (uint32_t)sel);
551 
552  retval = swd_queue_dp_write(dap, DP_SELECT, (uint32_t)sel);
553  if (retval != ERROR_OK)
554  return retval;
555  }
556 
557  if (set_select1) {
558  LOG_DEBUG_IO("AP BANK SELECT1: %" PRIx32, (uint32_t)(sel >> 32));
559 
560  retval = swd_queue_dp_write(dap, DP_SELECT1, (uint32_t)(sel >> 32));
561  if (retval != ERROR_OK)
562  return retval;
563  }
564 
565  return ERROR_OK;
566 }
567 
568 static int swd_queue_ap_read(struct adiv5_ap *ap, unsigned int reg,
569  uint32_t *data)
570 {
571  struct adiv5_dap *dap = ap->dap;
572  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
573  assert(swd);
574 
575  int retval = swd_check_reconnect(dap);
576  if (retval != ERROR_OK)
577  return retval;
578 
579  retval = swd_multidrop_select(dap);
580  if (retval != ERROR_OK)
581  return retval;
582 
583  retval = swd_queue_ap_bankselect(ap, reg);
584  if (retval != ERROR_OK)
585  return retval;
586 
587  swd->read_reg(swd_cmd(true, true, reg), dap->last_read, ap->memaccess_tck);
588  dap->last_read = data;
589 
590  return check_sync(dap);
591 }
592 
593 static int swd_queue_ap_write(struct adiv5_ap *ap, unsigned int reg,
594  uint32_t data)
595 {
596  struct adiv5_dap *dap = ap->dap;
597  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
598  assert(swd);
599 
600  int retval = swd_check_reconnect(dap);
601  if (retval != ERROR_OK)
602  return retval;
603 
604  retval = swd_multidrop_select(dap);
605  if (retval != ERROR_OK)
606  return retval;
607 
608  swd_finish_read(dap);
609 
610  retval = swd_queue_ap_bankselect(ap, reg);
611  if (retval != ERROR_OK)
612  return retval;
613 
614  swd->write_reg(swd_cmd(false, true, reg), data, ap->memaccess_tck);
615 
616  return check_sync(dap);
617 }
618 
620 static int swd_run(struct adiv5_dap *dap)
621 {
622  int retval = swd_multidrop_select(dap);
623  if (retval != ERROR_OK)
624  return retval;
625 
626  swd_finish_read(dap);
627 
628  retval = swd_run_inner(dap);
629  if (retval != ERROR_OK) {
630  /* fault response */
631  dap->do_reconnect = true;
632  }
633 
634  return retval;
635 }
636 
638 static void swd_quit(struct adiv5_dap *dap)
639 {
640  const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
641  static bool done;
642 
643  /* There is no difference if the sequence is sent at the last
644  * or the first swd_quit() call, send it just once */
645  if (done)
646  return;
647 
648  done = true;
649  if (dap_is_multidrop(dap)) {
650  /* Emit the switch seq to dormant state regardless the state mirrored
651  * in swd_multidrop_in_swd_state. Doing so ensures robust operation
652  * in the case the variable is out of sync.
653  * Sending SWD_TO_DORMANT makes no change if the DP is already dormant. */
656  /* Revisit!
657  * Leaving DPs in dormant state was tested and offers some safety
658  * against DPs mismatch in case of unintentional use of non-multidrop SWD.
659  * To put SWJ-DPs to power-on state issue
660  * swd->switch_seq(DORMANT_TO_JTAG);
661  */
662  } else {
663  if (dap->switch_through_dormant) {
666  } else {
667  swd->switch_seq(SWD_TO_JTAG);
668  }
669  }
670 
671  /* flush the queue to shift out the sequence before exit */
672  swd->run();
673 }
674 
675 const struct dap_ops swd_dap_ops = {
677  .connect = swd_connect,
678  .send_sequence = swd_send_sequence,
679  .queue_dp_read = swd_queue_dp_read,
680  .queue_dp_write = swd_queue_dp_write,
681  .queue_ap_read = swd_queue_ap_read,
682  .queue_ap_write = swd_queue_ap_write,
683  .queue_ap_abort = swd_queue_ap_abort,
684  .run = swd_run,
685  .quit = swd_quit,
686 };
687 
688 static const struct command_registration swd_commands[] = {
689  {
690  /*
691  * Set up SWD and JTAG targets identically, unless/until
692  * infrastructure improves ... meanwhile, ignore all
693  * JTAG-specific stuff like IR length for SWD.
694  *
695  * REVISIT can we verify "just one SWD DAP" here/early?
696  */
697  .name = "newdap",
698  .handler = handle_jtag_newtap,
699  .mode = COMMAND_CONFIG,
700  .help = "declare a new SWD DAP",
701  .usage = "basename dap_type ['-irlen' count] "
702  "['-enable'|'-disable'] "
703  "['-expected_id' number] "
704  "['-ignore-version'] "
705  "['-ignore-bypass'] "
706  "['-ircapture' number] "
707  "['-ir-bypass' number] "
708  "['-mask' number]",
709  },
711 };
712 
713 static const struct command_registration swd_handlers[] = {
714  {
715  .name = "swd",
716  .mode = COMMAND_ANY,
717  .help = "SWD command group",
718  .chain = swd_commands,
719  .usage = "",
720  },
722 };
723 
724 static int swd_select(struct command_context *ctx)
725 {
726  const struct swd_driver *swd = adapter_driver->swd_ops;
727  int retval;
728 
729  retval = register_commands(ctx, NULL, swd_handlers);
730  if (retval != ERROR_OK)
731  return retval;
732 
733  /* be sure driver is in SWD mode; start
734  * with hardware default TRN (1), it can be changed later
735  */
736  if (!swd || !swd->read_reg || !swd->write_reg || !swd->init) {
737  LOG_DEBUG("no SWD driver?");
738  return ERROR_FAIL;
739  }
740 
741  retval = swd->init();
742  if (retval != ERROR_OK) {
743  LOG_DEBUG("can't init SWD driver");
744  return retval;
745  }
746 
747  return retval;
748 }
749 
750 static int swd_init(struct command_context *ctx)
751 {
752  /* nothing done here, SWD is initialized
753  * together with the DAP */
754  return ERROR_OK;
755 }
756 
757 static struct transport swd_transport = {
758  .id = TRANSPORT_SWD,
759  .select = swd_select,
760  .init = swd_init,
761 };
762 
763 static void swd_constructor(void) __attribute__((constructor));
764 static void swd_constructor(void)
765 {
767 }
768 
773 {
775 }
static int swd_multidrop_select(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:265
const struct dap_ops swd_dap_ops
Definition: adi_v5_swd.c:675
static int swd_connect_single(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:335
static int swd_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)
Definition: adi_v5_swd.c:471
static const struct command_registration swd_commands[]
Definition: adi_v5_swd.c:688
static void swd_clear_sticky_errors(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:76
static int swd_queue_dp_write_inner(struct adiv5_dap *dap, unsigned int reg, uint32_t data)
Definition: adi_v5_swd.c:138
static int check_sync(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:92
static int swd_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, uint32_t *data)
Definition: adi_v5_swd.c:568
static int swd_queue_dp_write(struct adiv5_dap *dap, unsigned int reg, uint32_t data)
Definition: adi_v5_swd.c:503
static int swd_run_inner(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:85
static int swd_connect(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:412
static int swd_pre_connect(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:405
static int swd_connect_multidrop(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:296
static int swd_init(struct command_context *ctx)
Definition: adi_v5_swd.c:750
static int swd_run(struct adiv5_dap *dap)
Executes all queued DAP operations.
Definition: adi_v5_swd.c:620
static int swd_select(struct command_context *ctx)
Definition: adi_v5_swd.c:724
static void swd_finish_read(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:67
static int swd_queue_ap_bankselect(struct adiv5_ap *ap, unsigned int reg)
Select the AP register bank.
Definition: adi_v5_swd.c:518
static int swd_queue_dp_bankselect(struct adiv5_dap *dap, unsigned int reg)
Select the DP register bank.
Definition: adi_v5_swd.c:98
static int swd_queue_dp_read_inner(struct adiv5_dap *dap, unsigned int reg, uint32_t *data)
Definition: adi_v5_swd.c:123
static struct transport swd_transport
Definition: adi_v5_swd.c:757
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:772
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:593
static int swd_check_reconnect(struct adiv5_dap *dap)
Definition: adi_v5_swd.c:463
static int swd_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)
Definition: adi_v5_swd.c:59
static void swd_quit(struct adiv5_dap *dap)
Put the SWJ-DP back to JTAG mode.
Definition: adi_v5_swd.c:638
static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned int reg, uint32_t *data)
Definition: adi_v5_swd.c:489
static const struct command_registration swd_handlers[]
Definition: adi_v5_swd.c:713
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:180
static void swd_constructor(void)
Definition: adi_v5_swd.c:763
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
#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:1745
int adapter_assert_reset(void)
Definition: jtag/core.c:1890
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:1060
Represents a driver for a debugging interface.
Definition: interface.h:208
const struct swd_driver * swd_ops
Low-level SWD APIs.
Definition: interface.h:354
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
void(* read_reg)(uint8_t cmd, uint32_t *value, uint32_t ap_delay_hint)
Queued read of an AP or DP register.
Definition: swd.h:275
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:294
void(* write_reg)(uint8_t cmd, uint32_t value, uint32_t ap_delay_hint)
Queued write of an AP or DP register.
Definition: swd.h:286
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