+
+/**
+ * This represents an ARM Debug Interface (v5) Debug Access Port (DAP).
+ * A DAP has two types of component: one Debug Port (DP), which is a
+ * transport agent; and at least one Access Port (AP), controlling
+ * resource access.
+ *
+ * There are two basic DP transports: JTAG, and ARM's low pin-count SWD.
+ * Accordingly, this interface is responsible for hiding the transport
+ * differences so upper layer code can largely ignore them.
+ *
+ * When the chip is implemented with JTAG-DP or SW-DP, the transport is
+ * fixed as JTAG or SWD, respectively. Chips incorporating SWJ-DP permit
+ * a choice made at board design time (by only using the SWD pins), or
+ * as part of setting up a debug session (if all the dual-role JTAG/SWD
+ * signals are available).
+ */
+struct adiv5_dap {
+ const struct dap_ops *ops;
+
+ /* dap transaction list for WAIT support */
+ struct list_head cmd_journal;
+
+ struct jtag_tap *tap;
+ /* Control config */
+ uint32_t dp_ctrl_stat;
+
+ struct adiv5_ap ap[256];
+
+ /* The current manually selected AP by the "dap apsel" command */
+ uint32_t apsel;
+
+ /**
+ * Cache for DP_SELECT register. A value of DP_SELECT_INVALID
+ * indicates no cached value and forces rewrite of the register.
+ */
+ uint32_t select;
+
+ /* information about current pending SWjDP-AHBAP transaction */
+ uint8_t ack;
+
+ /**
+ * Holds the pointer to the destination word for the last queued read,
+ * for use with posted AP read sequence optimization.
+ */
+ uint32_t *last_read;
+
+ /* The TI TMS470 and TMS570 series processors use a BE-32 memory ordering
+ * despite lack of support in the ARMv7 architecture. Memory access through
+ * the AHB-AP has strange byte ordering these processors, and we need to
+ * swizzle appropriately. */
+ bool ti_be_32_quirks;
+
+ /**
+ * Signals that an attempt to reestablish communication afresh
+ * should be performed before the next access.
+ */
+ bool do_reconnect;
+};
+
+/**
+ * Transport-neutral representation of queued DAP transactions, supporting
+ * both JTAG and SWD transports. All submitted transactions are logically
+ * queued, until the queue is executed by run(). Some implementations might
+ * execute transactions as soon as they're submitted, but no status is made
+ * available until run().
+ */
+struct dap_ops {
+ /** DP register read. */
+ int (*queue_dp_read)(struct adiv5_dap *dap, unsigned reg,
+ uint32_t *data);
+ /** DP register write. */
+ int (*queue_dp_write)(struct adiv5_dap *dap, unsigned reg,
+ uint32_t data);
+
+ /** AP register read. */
+ int (*queue_ap_read)(struct adiv5_ap *ap, unsigned reg,
+ uint32_t *data);
+ /** AP register write. */
+ int (*queue_ap_write)(struct adiv5_ap *ap, unsigned reg,
+ uint32_t data);
+
+ /** AP operation abort. */
+ int (*queue_ap_abort)(struct adiv5_dap *dap, uint8_t *ack);
+
+ /** Executes all queued DAP operations. */
+ int (*run)(struct adiv5_dap *dap);
+
+ /** Executes all queued DAP operations but doesn't check
+ * sticky error conditions */
+ int (*sync)(struct adiv5_dap *dap);
+};
+
+/*
+ * Access Port classes
+ */
+enum ap_class {
+ AP_CLASS_NONE = 0x00000, /* No class defined */
+ AP_CLASS_MEM_AP = 0x10000, /* MEM-AP */
+};
+
+/*
+ * Access Port types
+ */
+enum ap_type {
+ AP_TYPE_JTAG_AP = 0x0, /* JTAG-AP - JTAG master for controlling other JTAG devices */
+ AP_TYPE_AHB_AP = 0x1, /* AHB Memory-AP */
+ AP_TYPE_APB_AP = 0x2, /* APB Memory-AP */
+ AP_TYPE_AXI_AP = 0x4, /* AXI Memory-AP */
+};
+
+/**
+ * Queue a DP register read.
+ * Note that not all DP registers are readable; also, that JTAG and SWD
+ * have slight differences in DP register support.
+ *
+ * @param dap The DAP used for reading.
+ * @param reg The two-bit number of the DP register being read.
+ * @param data Pointer saying where to store the register's value
+ * (in host endianness).
+ *
+ * @return ERROR_OK for success, else a fault code.
+ */
+static inline int dap_queue_dp_read(struct adiv5_dap *dap,
+ unsigned reg, uint32_t *data)
+{
+ assert(dap->ops != NULL);
+ return dap->ops->queue_dp_read(dap, reg, data);
+}
+
+/**
+ * Queue a DP register write.
+ * Note that not all DP registers are writable; also, that JTAG and SWD
+ * have slight differences in DP register support.
+ *
+ * @param dap The DAP used for writing.
+ * @param reg The two-bit number of the DP register being written.
+ * @param data Value being written (host endianness)
+ *
+ * @return ERROR_OK for success, else a fault code.
+ */
+static inline int dap_queue_dp_write(struct adiv5_dap *dap,
+ unsigned reg, uint32_t data)
+{
+ assert(dap->ops != NULL);
+ return dap->ops->queue_dp_write(dap, reg, data);
+}
+
+/**
+ * Queue an AP register read.
+ *
+ * @param ap The AP used for reading.
+ * @param reg The number of the AP register being read.
+ * @param data Pointer saying where to store the register's value
+ * (in host endianness).
+ *
+ * @return ERROR_OK for success, else a fault code.
+ */
+static inline int dap_queue_ap_read(struct adiv5_ap *ap,
+ unsigned reg, uint32_t *data)
+{
+ assert(ap->dap->ops != NULL);
+ return ap->dap->ops->queue_ap_read(ap, reg, data);
+}
+
+/**
+ * Queue an AP register write.
+ *
+ * @param ap The AP used for writing.
+ * @param reg The number of the AP register being written.
+ * @param data Value being written (host endianness)
+ *
+ * @return ERROR_OK for success, else a fault code.
+ */
+static inline int dap_queue_ap_write(struct adiv5_ap *ap,
+ unsigned reg, uint32_t data)
+{
+ assert(ap->dap->ops != NULL);
+ return ap->dap->ops->queue_ap_write(ap, reg, data);
+}
+
+/**
+ * Queue an AP abort operation. The current AP transaction is aborted,
+ * including any update of the transaction counter. The AP is left in
+ * an unknown state (so it must be re-initialized). For use only after
+ * the AP has reported WAIT status for an extended period.
+ *
+ * @param dap The DAP used for writing.
+ * @param ack Pointer to where transaction status will be stored.
+ *
+ * @return ERROR_OK for success, else a fault code.
+ */
+static inline int dap_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)