static int jtag_ap_q_read(struct adiv5_dap *dap, unsigned reg,
		uint32_t *data)
{
	int retval = jtag_ap_q_bankselect(dap, reg);

	if (retval != ERROR_OK)
		return retval;

	return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_APACC, reg,
			DPAP_READ, 0, data);
}
Beispiel #2
0
static int jtagdp_transaction_endcheck(struct adiv5_dap *dap)
{
	int retval;
	uint32_t ctrlstat;

	/* too expensive to call keep_alive() here */

	/* Here be dragons!
	 *
	 * It is easy to be in a JTAG clock range where the target
	 * is not operating in a stable fashion. This happens
	 * for a few reasons:
	 *
	 * - the user may construct a simple test case to try to see
	 * if a higher JTAG clock works to eke out more performance.
	 * This simple case may pass, but more complex situations can
	 * fail.
	 *
	 * - The mostly works JTAG clock rate and the complete failure
	 * JTAG clock rate may be as much as 2-4x apart. This seems
	 * to be especially true on RC oscillator driven parts.
	 *
	 * So: even if calling adi_jtag_scan_inout_check_u32() multiple
	 * times here seems to "make things better here", it is just
	 * hiding problems with too high a JTAG clock.
	 *
	 * Note that even if some parts have RCLK/RTCK, that doesn't
	 * mean that RCLK/RTCK is the *correct* rate to run the JTAG
	 * interface at, i.e. RCLK/RTCK rates can be "too high", especially
	 * before the RC oscillator phase is not yet complete.
	 */

	/* Post CTRL/STAT read; discard any previous posted read value
	 * but collect its ACK status.
	 */
	retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
			DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat, 0);
	if (retval != ERROR_OK)
		return retval;
	retval = jtag_execute_queue();
	if (retval != ERROR_OK)
		return retval;

	dap->ack = dap->ack & 0x7;

	/* common code path avoids calling timeval_ms() */
	if (dap->ack != JTAG_ACK_OK_FAULT) {
		long long then = timeval_ms();

		while (dap->ack != JTAG_ACK_OK_FAULT) {
			if (dap->ack == JTAG_ACK_WAIT) {
				if ((timeval_ms()-then) > 1000) {
					LOG_WARNING("Timeout (1000ms) waiting "
						"for ACK=OK/FAULT "
						"in JTAG-DP transaction - aborting");

					uint8_t ack;
					int abort_ret = jtag_ap_q_abort(dap, &ack);

					if (abort_ret != 0)
						LOG_WARNING("Abort failed : return=%d ack=%d", abort_ret, ack);

					return ERROR_JTAG_DEVICE_ERROR;
				}
			} else {
				LOG_WARNING("Invalid ACK %#x "
						"in JTAG-DP transaction",
						dap->ack);
				return ERROR_JTAG_DEVICE_ERROR;
			}

			retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
					DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat, 0);
			if (retval != ERROR_OK)
				return retval;
			retval = jtag_execute_queue();
			if (retval != ERROR_OK)
				return retval;
			dap->ack = dap->ack & 0x7;
		}
	}

	/* REVISIT also STICKYCMP, for pushed comparisons (nyet used) */

	/* Check for STICKYERR and STICKYORUN */
	if (ctrlstat & (SSTICKYORUN | SSTICKYERR)) {
		LOG_DEBUG("jtag-dp: CTRL/STAT error, 0x%" PRIx32, ctrlstat);
		/* Check power to debug regions */
		if ((ctrlstat & (CDBGPWRUPREQ | CDBGPWRUPACK | CSYSPWRUPREQ | CSYSPWRUPACK)) !=
						(CDBGPWRUPREQ | CDBGPWRUPACK | CSYSPWRUPREQ | CSYSPWRUPACK)) {
			LOG_ERROR("Debug regions are unpowered, an unexpected reset might have happened");
			return ERROR_JTAG_DEVICE_ERROR;
		} else {
			if (ctrlstat & SSTICKYORUN)
				LOG_ERROR("JTAG-DP OVERRUN - check clock, "
					"memaccess, or reduce jtag speed");

			if (ctrlstat & SSTICKYERR)
				LOG_ERROR("JTAG-DP STICKY ERROR");

			/* Clear Sticky Error Bits */
			retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
					DP_CTRL_STAT, DPAP_WRITE,
					dap->dp_ctrl_stat | SSTICKYORUN
						| SSTICKYERR, NULL, 0);
			if (retval != ERROR_OK)
				return retval;
			retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
					DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat, 0);
			if (retval != ERROR_OK)
				return retval;
			retval = jtag_execute_queue();
			if (retval != ERROR_OK)
				return retval;

			LOG_DEBUG("jtag-dp: CTRL/STAT 0x%" PRIx32, ctrlstat);
		}
		retval = jtag_execute_queue();
		if (retval != ERROR_OK)
			return retval;
		return ERROR_JTAG_DEVICE_ERROR;
	}

	return ERROR_OK;
}
static int jtag_dp_q_read(struct adiv5_dap *dap, unsigned reg,
		uint32_t *data)
{
	return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
			reg, DPAP_READ, 0, data);
}
static int jtag_dp_q_write(struct adiv5_dap *dap, unsigned reg,
		uint32_t data)
{
	return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
			reg, DPAP_WRITE, data, NULL);
}
Beispiel #5
0
static int jtagdp_transaction_endcheck(struct adiv5_dap *dap)
{
	int retval;
	uint32_t ctrlstat;

	/* too expensive to call keep_alive() here */

	/* Here be dragons!
	 *
	 * It is easy to be in a JTAG clock range where the target
	 * is not operating in a stable fashion. This happens
	 * for a few reasons:
	 *
	 * - the user may construct a simple test case to try to see
	 * if a higher JTAG clock works to eke out more performance.
	 * This simple case may pass, but more complex situations can
	 * fail.
	 *
	 * - The mostly works JTAG clock rate and the complete failure
	 * JTAG clock rate may be as much as 2-4x apart. This seems
	 * to be especially true on RC oscillator driven parts.
	 *
	 * So: even if calling adi_jtag_scan_inout_check_u32() multiple
	 * times here seems to "make things better here", it is just
	 * hiding problems with too high a JTAG clock.
	 *
	 * Note that even if some parts have RCLK/RTCK, that doesn't
	 * mean that RCLK/RTCK is the *correct* rate to run the JTAG
	 * interface at, i.e. RCLK/RTCK rates can be "too high", especially
	 * before the RC oscillator phase is not yet complete.
	 */

	/* Post CTRL/STAT read; discard any previous posted read value
	 * but collect its ACK status.
	 */
	retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
			DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
	if (retval != ERROR_OK)
		return retval;
	retval = jtag_execute_queue();
	if (retval != ERROR_OK)
		return retval;

	dap->ack = dap->ack & 0x7;

	/* common code path avoids calling timeval_ms() */
	if (dap->ack != JTAG_ACK_OK_FAULT) {
		long long then = timeval_ms();

		while (dap->ack != JTAG_ACK_OK_FAULT) {
			if (dap->ack == JTAG_ACK_WAIT) {
				if ((timeval_ms()-then) > 1000) {
					/* NOTE:  this would be a good spot
					 * to use JTAG_DP_ABORT.
					 */
					LOG_WARNING("Timeout (1000ms) waiting "
						"for ACK=OK/FAULT "
						"in JTAG-DP transaction");
					return ERROR_JTAG_DEVICE_ERROR;
				}
			} else {
				LOG_WARNING("Invalid ACK %#x "
						"in JTAG-DP transaction",
						dap->ack);
				return ERROR_JTAG_DEVICE_ERROR;
			}

			retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
					DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
			if (retval != ERROR_OK)
				return retval;
			retval = jtag_execute_queue();
			if (retval != ERROR_OK)
				return retval;
			dap->ack = dap->ack & 0x7;
		}
	}

	/* REVISIT also STICKYCMP, for pushed comparisons (nyet used) */

	/* Check for STICKYERR and STICKYORUN */
	if (ctrlstat & (SSTICKYORUN | SSTICKYERR)) {
		LOG_DEBUG("jtag-dp: CTRL/STAT error, 0x%" PRIx32, ctrlstat);
		/* Check power to debug regions */
		if ((ctrlstat & 0xf0000000) != 0xf0000000) {
			retval = ahbap_debugport_init(dap);
			if (retval != ERROR_OK)
				return retval;
		} else {
			uint32_t mem_ap_csw, mem_ap_tar;

			/* Maybe print information about last intended
			 * MEM-AP access; but not if autoincrementing.
			 * *Real* CSW and TAR values are always shown.
			 */
			if (dap->ap_tar_value != (uint32_t) -1)
				LOG_DEBUG("MEM-AP Cached values: "
					"ap_bank 0x%" PRIx32
					", ap_csw 0x%" PRIx32
					", ap_tar 0x%" PRIx32,
					dap->ap_bank_value,
					dap->ap_csw_value,
					dap->ap_tar_value);

			if (ctrlstat & SSTICKYORUN)
				LOG_ERROR("JTAG-DP OVERRUN - check clock, "
					"memaccess, or reduce jtag speed");

			if (ctrlstat & SSTICKYERR)
				LOG_ERROR("JTAG-DP STICKY ERROR");

			/* Clear Sticky Error Bits */
			retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
					DP_CTRL_STAT, DPAP_WRITE,
					dap->dp_ctrl_stat | SSTICKYORUN
						| SSTICKYERR, NULL);
			if (retval != ERROR_OK)
				return retval;
			retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
					DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
			if (retval != ERROR_OK)
				return retval;
			retval = jtag_execute_queue();
			if (retval != ERROR_OK)
				return retval;

			LOG_DEBUG("jtag-dp: CTRL/STAT 0x%" PRIx32, ctrlstat);

			retval = dap_queue_ap_read(dap,
					AP_REG_CSW, &mem_ap_csw);
			if (retval != ERROR_OK)
				return retval;

			retval = dap_queue_ap_read(dap,
					AP_REG_TAR, &mem_ap_tar);
			if (retval != ERROR_OK)
				return retval;

			retval = jtag_execute_queue();
			if (retval != ERROR_OK)
				return retval;
			LOG_ERROR("MEM_AP_CSW 0x%" PRIx32 ", MEM_AP_TAR 0x%"
					PRIx32, mem_ap_csw, mem_ap_tar);

		}
		retval = jtag_execute_queue();
		if (retval != ERROR_OK)
			return retval;
		return ERROR_JTAG_DEVICE_ERROR;
	}

	return ERROR_OK;
}