- u8 trans_mode;
- u8 trans_rw;
- u8 ack;
-} swjdp_common_t;
-
-/* Internal functions used in the module, partial transactions, use with caution */
-extern int dap_dp_write_reg(swjdp_common_t *swjdp, u32 value, u8 reg_addr);
-/* extern int swjdp_write_apacc(swjdp_common_t *swjdp, u32 value, u8 reg_addr); */
-extern int dap_dp_read_reg(swjdp_common_t *swjdp, u32 *value, u8 reg_addr);
-/* extern int swjdp_read_apacc(swjdp_common_t *swjdp, u32 *value, u8 reg_addr); */
-extern int dap_setup_accessport(swjdp_common_t *swjdp, u32 csw, u32 tar);
-extern int dap_ap_select(swjdp_common_t *swjdp,u8 apsel);
-
-extern int dap_ap_write_reg(swjdp_common_t *swjdp, u32 reg_addr, u8* out_value_buf);
-extern int dap_ap_write_reg_u32(swjdp_common_t *swjdp, u32 reg_addr, u32 value);
-extern int dap_ap_read_reg(swjdp_common_t *swjdp, u32 reg_addr, u8 *in_value_buf);
-extern int dap_ap_read_reg_u32(swjdp_common_t *swjdp, u32 reg_addr, u32 *value);
-
-/* External interface, partial operations must be completed with swjdp_transaction_endcheck() */
-extern int swjdp_transaction_endcheck(swjdp_common_t *swjdp);
-
-/* MEM-AP memory mapped bus single u32 register transfers, without endcheck */
-extern int mem_ap_read_u32(swjdp_common_t *swjdp, u32 address, u32 *value);
-extern int mem_ap_write_u32(swjdp_common_t *swjdp, u32 address, u32 value);
-
-/* MEM-AP memory mapped bus transfers, single registers, complete transactions */
-extern int mem_ap_read_atomic_u32(swjdp_common_t *swjdp, u32 address, u32 *value);
-extern int mem_ap_write_atomic_u32(swjdp_common_t *swjdp, u32 address, u32 value);
-
-/* MEM-AP memory mapped bus block transfers */
-extern int mem_ap_read_buf_u8(swjdp_common_t *swjdp, u8 *buffer, int count, u32 address);
-extern int mem_ap_read_buf_u16(swjdp_common_t *swjdp, u8 *buffer, int count, u32 address);
-extern int mem_ap_read_buf_u32(swjdp_common_t *swjdp, u8 *buffer, int count, u32 address);
-extern int mem_ap_write_buf_u8(swjdp_common_t *swjdp, u8 *buffer, int count, u32 address);
-extern int mem_ap_write_buf_u16(swjdp_common_t *swjdp, u8 *buffer, int count, u32 address);
-extern int mem_ap_write_buf_u32(swjdp_common_t *swjdp, u8 *buffer, int count, u32 address);
+ 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;
+
+ /**
+ * Configures how many extra tck clocks are added after starting a
+ * MEM-AP access before we try to read its status (and/or result).
+ */
+ uint32_t memaccess_tck;
+
+ /* Size of TAR autoincrement block, ARM ADI Specification requires at least 10 bits */
+ uint32_t tar_autoincr_block;
+
+ /* true if packed transfers are supported by the MEM-AP */
+ bool packed_transfers;
+
+ /* true if unaligned memory access is not supported by the MEM-AP */
+ bool unaligned_access_bad;
+
+ /* 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;
+};
+
+/**
+ * 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 {
+ /** If the DAP transport isn't SWD, it must be JTAG. Upper level
+ * code may need to care about the difference in some cases.
+ */
+ bool is_swd;
+
+ /** 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_dap *dap, unsigned reg,
+ uint32_t *data);
+ /** AP register write. */
+ int (*queue_ap_write)(struct adiv5_dap *dap, 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);
+};
+
+/*
+ * Access Port types
+ */
+enum ap_type {
+ AP_TYPE_AHB_AP = 0x01, /* AHB Memory-AP */
+ AP_TYPE_APB_AP = 0x02, /* APB Memory-AP */
+ AP_TYPE_JTAG_AP = 0x10 /* JTAG-AP - JTAG master for controlling other JTAG devices */
+};
+
+/**
+ * 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 dap The DAP 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_dap *dap,
+ unsigned reg, uint32_t *data)
+{
+ assert(dap->ops != NULL);
+ return dap->ops->queue_ap_read(dap, reg, data);
+}
+
+/**
+ * Queue an AP register write.
+ *
+ * @param dap The DAP 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_dap *dap,
+ unsigned reg, uint32_t data)
+{
+ assert(dap->ops != NULL);
+ return dap->ops->queue_ap_write(dap, 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)
+{
+ assert(dap->ops != NULL);
+ return dap->ops->queue_ap_abort(dap, ack);
+}
+
+/**
+ * Perform all queued DAP operations, and clear any errors posted in the
+ * CTRL_STAT register when they are done. Note that if more than one AP
+ * operation will be queued, one of the first operations in the queue
+ * should probably enable CORUNDETECT in the CTRL/STAT register.
+ *
+ * @param dap The DAP used.
+ *
+ * @return ERROR_OK for success, else a fault code.
+ */
+static inline int dap_run(struct adiv5_dap *dap)
+{
+ assert(dap->ops != NULL);
+ return dap->ops->run(dap);
+}
+
+static inline int dap_dp_read_atomic(struct adiv5_dap *dap, unsigned reg,
+ uint32_t *value)
+{
+ int retval;
+
+ retval = dap_queue_dp_read(dap, reg, value);
+ if (retval != ERROR_OK)
+ return retval;
+
+ return dap_run(dap);
+}
+
+static inline int dap_dp_poll_register(struct adiv5_dap *dap, unsigned reg,
+ uint32_t mask, uint32_t value, int timeout)
+{
+ assert(timeout > 0);
+ assert((value & mask) == value);
+
+ int ret;
+ uint32_t regval;
+ LOG_DEBUG("DAP: poll %x, mask 0x08%" PRIx32 ", value 0x%08" PRIx32,
+ reg, mask, value);
+ do {
+ ret = dap_dp_read_atomic(dap, reg, ®val);
+ if (ret != ERROR_OK)
+ return ret;
+
+ if ((regval & mask) == value)
+ break;
+
+ alive_sleep(10);
+ } while (--timeout);
+
+ if (!timeout) {
+ LOG_DEBUG("DAP: poll %x timeout", reg);
+ return ERROR_FAIL;
+ } else {
+ return ERROR_OK;
+ }
+}
+
+/** Accessor for currently selected DAP-AP number (0..255) */
+static inline uint8_t dap_ap_get_select(struct adiv5_dap *swjdp)
+{
+ return (uint8_t)(swjdp->ap_current >> 24);
+}
+
+/* AP selection applies to future AP transactions */
+void dap_ap_select(struct adiv5_dap *dap, uint8_t ap);
+
+/* Queued AP transactions */
+int dap_setup_accessport(struct adiv5_dap *swjdp,
+ uint32_t csw, uint32_t tar);
+
+/* Queued MEM-AP memory mapped single word transfers */
+int mem_ap_read_u32(struct adiv5_dap *swjdp, uint32_t address, uint32_t *value);
+int mem_ap_write_u32(struct adiv5_dap *swjdp, uint32_t address, uint32_t value);
+
+/* Synchronous MEM-AP memory mapped single word transfers */
+int mem_ap_read_atomic_u32(struct adiv5_dap *swjdp,
+ uint32_t address, uint32_t *value);
+int mem_ap_write_atomic_u32(struct adiv5_dap *swjdp,
+ uint32_t address, uint32_t value);
+
+/* Queued MEM-AP memory mapped single word transfers with selection of ap */
+int mem_ap_sel_read_u32(struct adiv5_dap *swjdp, uint8_t ap,
+ uint32_t address, uint32_t *value);
+int mem_ap_sel_write_u32(struct adiv5_dap *swjdp, uint8_t ap,
+ uint32_t address, uint32_t value);
+
+/* Synchronous MEM-AP memory mapped single word transfers with selection of ap */
+int mem_ap_sel_read_atomic_u32(struct adiv5_dap *swjdp, uint8_t ap,
+ uint32_t address, uint32_t *value);
+int mem_ap_sel_write_atomic_u32(struct adiv5_dap *swjdp, uint8_t ap,
+ uint32_t address, uint32_t value);
+
+/* Synchronous MEM-AP memory mapped bus block transfers */
+int mem_ap_read(struct adiv5_dap *dap, uint8_t *buffer, uint32_t size,
+ uint32_t count, uint32_t address, bool addrinc);
+int mem_ap_write(struct adiv5_dap *dap, const uint8_t *buffer, uint32_t size,
+ uint32_t count, uint32_t address, bool addrinc);
+
+/* Synchronous MEM-AP memory mapped bus block transfers with selection of ap */
+int mem_ap_sel_read_buf(struct adiv5_dap *swjdp, uint8_t ap,
+ uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address);
+int mem_ap_sel_write_buf(struct adiv5_dap *swjdp, uint8_t ap,
+ const uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address);
+
+/* Synchronous, non-incrementing buffer functions for accessing fifos, with
+ * selection of ap */
+int mem_ap_sel_read_buf_noincr(struct adiv5_dap *swjdp, uint8_t ap,
+ uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address);
+int mem_ap_sel_write_buf_noincr(struct adiv5_dap *swjdp, uint8_t ap,
+ const uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address);