* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
***************************************************************************/
/**
case DP_RDBUFF:
reg_name = "RDBUFF";
break;
- case DP_WCR:
- reg_name = "WCR";
+ case DP_DLCR:
+ reg_name = "DLCR";
break;
default:
reg_name = "UNK";
int retval;
struct dap_cmd *el, *tmp, *prev = NULL;
int found_wait = 0;
- uint64_t time_now;
+ int64_t time_now;
LIST_HEAD(replay_list);
/* make sure all queued transactions are complete */
/* timeout happened */
if (tmp->ack != JTAG_ACK_OK_FAULT) {
LOG_ERROR("Timeout during WAIT recovery");
+ dap->select = DP_SELECT_INVALID;
jtag_ap_q_abort(dap, NULL);
+ /* clear the sticky overrun condition */
+ adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
+ DP_CTRL_STAT, DPAP_WRITE,
+ dap->dp_ctrl_stat | SSTICKYORUN, NULL, 0);
retval = ERROR_JTAG_DEVICE_ERROR;
}
}
if (retval == ERROR_OK) {
if (el->ack != JTAG_ACK_OK_FAULT) {
LOG_ERROR("Timeout during WAIT recovery");
+ dap->select = DP_SELECT_INVALID;
jtag_ap_q_abort(dap, NULL);
+ /* clear the sticky overrun condition */
+ adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
+ DP_CTRL_STAT, DPAP_WRITE,
+ dap->dp_ctrl_stat | SSTICKYORUN, NULL, 0);
retval = ERROR_JTAG_DEVICE_ERROR;
+ break;
}
} else
break;
static int jtagdp_transaction_endcheck(struct adiv5_dap *dap)
{
int retval;
- uint32_t ctrlstat;
+ uint32_t ctrlstat, pwrmask;
/* too expensive to call keep_alive() here */
if (ctrlstat & SSTICKYERR) {
LOG_DEBUG("jtag-dp: CTRL/STAT 0x%" PRIx32, ctrlstat);
/* Check power to debug regions */
- if ((ctrlstat & (CDBGPWRUPREQ | CDBGPWRUPACK | CSYSPWRUPREQ | CSYSPWRUPACK)) !=
- (CDBGPWRUPREQ | CDBGPWRUPACK | CSYSPWRUPREQ | CSYSPWRUPACK)) {
+ pwrmask = CDBGPWRUPREQ | CDBGPWRUPACK | CSYSPWRUPREQ;
+ if (!dap->ignore_syspwrupack)
+ pwrmask |= CSYSPWRUPACK;
+ if ((ctrlstat & pwrmask) != pwrmask) {
LOG_ERROR("Debug regions are unpowered, an unexpected reset might have happened");
- retval = ERROR_JTAG_DEVICE_ERROR;
- goto done;
+ dap->do_reconnect = true;
}
if (ctrlstat & SSTICKYERR)
if (retval != ERROR_OK)
goto done;
- if (ctrlstat & SSTICKYERR) {
- retval = ERROR_JTAG_DEVICE_ERROR;
- goto done;
- }
+ retval = ERROR_JTAG_DEVICE_ERROR;
}
done:
/*--------------------------------------------------------------------------*/
+static int jtag_connect(struct adiv5_dap *dap)
+{
+ dap->do_reconnect = false;
+ return dap_dp_init(dap);
+}
+
+static int jtag_check_reconnect(struct adiv5_dap *dap)
+{
+ if (dap->do_reconnect)
+ return jtag_connect(dap);
+
+ return ERROR_OK;
+}
+
static int jtag_dp_q_read(struct adiv5_dap *dap, unsigned reg,
uint32_t *data)
{
static int jtag_ap_q_read(struct adiv5_ap *ap, unsigned reg,
uint32_t *data)
{
- int retval = jtag_ap_q_bankselect(ap, reg);
+ int retval = jtag_check_reconnect(ap->dap);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = jtag_ap_q_bankselect(ap, reg);
if (retval != ERROR_OK)
return retval;
static int jtag_ap_q_write(struct adiv5_ap *ap, unsigned reg,
uint32_t data)
{
- int retval = jtag_ap_q_bankselect(ap, reg);
+ int retval = jtag_check_reconnect(ap->dap);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = jtag_ap_q_bankselect(ap, reg);
if (retval != ERROR_OK)
return retval;
return (retval2 != ERROR_OK) ? retval2 : retval;
}
+static int jtag_dp_sync(struct adiv5_dap *dap)
+{
+ return jtagdp_overrun_check(dap);
+}
+
/* FIXME don't export ... just initialize as
* part of DAP setup
*/
const struct dap_ops jtag_dp_ops = {
+ .connect = jtag_connect,
.queue_dp_read = jtag_dp_q_read,
.queue_dp_write = jtag_dp_q_write,
.queue_ap_read = jtag_ap_q_read,
.queue_ap_write = jtag_ap_q_write,
.queue_ap_abort = jtag_ap_q_abort,
.run = jtag_dp_run,
+ .sync = jtag_dp_sync,
};
-
-
-static const uint8_t swd2jtag_bitseq[] = {
- /* More than 50 TCK/SWCLK cycles with TMS/SWDIO high,
- * putting both JTAG and SWD logic into reset state.
- */
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- /* Switching equence disables SWD and enables JTAG
- * NOTE: bits in the DP's IDCODE can expose the need for
- * the old/deprecated sequence (0xae 0xde).
- */
- 0x3c, 0xe7,
- /* At least 50 TCK/SWCLK cycles with TMS/SWDIO high,
- * putting both JTAG and SWD logic into reset state.
- * NOTE: some docs say "at least 5".
- */
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-};
-
-/** Put the debug link into JTAG mode, if the target supports it.
- * The link's initial mode may be either SWD or JTAG.
- *
- * @param target Enters JTAG mode (if possible).
- *
- * Note that targets implemented with SW-DP do not support JTAG, and
- * that some targets which could otherwise support it may have been
- * configured to disable JTAG signaling
- *
- * @return ERROR_OK or else a fault code.
- */
-int dap_to_jtag(struct target *target)
-{
- int retval;
-
- LOG_DEBUG("Enter JTAG mode");
-
- /* REVISIT it's nasty to need to make calls to a "jtag"
- * subsystem if the link isn't in JTAG mode...
- */
-
- retval = jtag_add_tms_seq(8 * sizeof(swd2jtag_bitseq),
- swd2jtag_bitseq, TAP_RESET);
- if (retval == ERROR_OK)
- retval = jtag_execute_queue();
-
- /* REVISIT set up the DAP's ops vector for JTAG mode. */
-
- return retval;
-}