/* YUK! - but this is currently a global.... */
extern struct jtag_interface *jtag_interface;
+static int swd_finish_read(struct adiv5_dap *dap)
+{
+ const struct swd_driver *swd = jtag_interface->swd;
+ int retval = ERROR_OK;
+ if (dap->last_read != NULL) {
+ retval = swd->read_reg(swd_cmd(true, false, DP_RDBUFF), dap->last_read);
+ dap->last_read = NULL;
+ }
+ return retval;
+}
+
static int (swd_queue_dp_write)(struct adiv5_dap *dap, unsigned reg,
uint32_t data);
const struct swd_driver *swd = jtag_interface->swd;
assert(swd);
+ retval = swd_finish_read(dap);
+ if (retval != ERROR_OK)
+ return retval;
+
retval = swd_queue_dp_bankselect(dap, reg);
if (retval != ERROR_OK)
return retval;
if (retval != ERROR_OK)
return retval;
- retval = swd->read_reg(swd_cmd(true, true, reg), data);
+ retval = swd->read_reg(swd_cmd(true, true, reg), dap->last_read);
+ dap->last_read = data;
if (retval != ERROR_OK) {
/* fault response */
uint8_t ack = retval & 0xff;
swd_queue_ap_abort(dap, &ack);
+ return retval;
}
return retval;
/* REVISIT status return ... */
const struct swd_driver *swd = jtag_interface->swd;
assert(swd);
+ int retval;
- int retval = swd_queue_ap_bankselect(dap, reg);
+ retval = swd_finish_read(dap);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = swd_queue_ap_bankselect(dap, reg);
if (retval != ERROR_OK)
return retval;
{
/* for now the SWD interface hard-wires a zero-size queue. */
+ int retval = swd_finish_read(dap);
+
/* FIXME but we still need to check and scrub
* any hardware errors ...
*/
- return ERROR_OK;
+ return retval;
}
const struct dap_ops swd_dap_ops = {
/* 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;
+
/**
* Configures how many extra tck clocks are added after starting a
* MEM-AP access before we try to read its status (and/or result).