> > thanks for your reply. Any chance you still
> have that patch around somewhere?
> 
> Yes, but not accessible for the next couple
> months (wrong coast)...

Or maybe not.  Here it is -- don't know if it
still applies or works though.

- Dave
From: David Brownell <[email protected]>
Subject: xscale:  reset assert/deassert behaves on pxa255

Switch to the slightly simpler debug reset sequence shown in the
"Hot-Debug" white paper (and various docs that are newer than the
arch spec).  All the interesting work is now done in deassert_reset().

This [ALSO??] fixes the bug where the first reset fails on PXA255.

(Also:  add a few more TCK cycles after our last write to
the minicache, as suggested by the Hot-Debug paper; and
remove several seemingly-needless delays.)

# Hrmm, hakt and semi-broken??  Delays restored for a bit.
# There seem to be timing-sensitive bug triggers...

# FIXME cleanup and merge after 0.3.0 ships
---
 src/target/xscale.c |  111 ++++++++++++++++++++++++--------------------------
 1 file changed, 54 insertions(+), 57 deletions(-)

--- a/src/target/xscale.c
+++ b/src/target/xscale.c
@@ -669,7 +669,10 @@ static int xscale_write_dcsr(struct targ
 
 	if ((retval = jtag_execute_queue()) != ERROR_OK)
 	{
-		LOG_ERROR("JTAG error while writing DCSR");
+		unsigned dcsr = buf_get_u32(xscale->reg_cache->
+				reg_list[XSCALE_DCSR].value, 0, 32);
+
+		LOG_ERROR("JTAG error while writing DCSR %08x", dcsr);
 		return retval;
 	}
 
@@ -1488,44 +1491,12 @@ static int xscale_step(struct target *ta
 
 static int xscale_assert_reset(struct target *target)
 {
-	struct xscale_common *xscale = target_to_xscale(target);
-
-	LOG_DEBUG("target->state: %s",
-		  target_state_name(target));
-
-	/* select DCSR instruction (set endstate to R-T-I to ensure we don't
-	 * end up in T-L-R, which would reset JTAG
+	/* just assert reset ... on deassert, we'll set up
+	 * DCSR, the debug handler, and maybe arrange to halt.
 	 */
-	jtag_set_end_state(TAP_IDLE);
-	xscale_jtag_set_instr(target->tap,
-		XSCALE_SELDCSR << xscale->xscale_variant);
-
-	/* set Hold reset, Halt mode and Trap Reset */
-	buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
-	buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
-	xscale_write_dcsr(target, 1, 0);
-
-	/* select BYPASS, because having DCSR selected caused problems on the PXA27x */
-	xscale_jtag_set_instr(target->tap, ~0);
-	jtag_execute_queue();
-
-	/* assert reset */
+// XXX previous: set_instr(... BYPASS)
 	jtag_add_reset(0, 1);
-
-	/* sleep 1ms, to be sure we fulfill any requirements */
-	jtag_add_sleep(1000);
-	jtag_execute_queue();
-
-	target->state = TARGET_RESET;
-
-    if (target->reset_halt)
-    {
-	int retval;
-		if ((retval = target_halt(target)) != ERROR_OK)
-			return retval;
-    }
-
-	return ERROR_OK;
+	return jtag_execute_queue();
 }
 
 static int xscale_deassert_reset(struct target *target)
@@ -1533,7 +1504,7 @@ static int xscale_deassert_reset(struct 
 	struct xscale_common *xscale = target_to_xscale(target);
 	struct breakpoint *breakpoint = target->breakpoints;
 
-	LOG_DEBUG("-");
+	LOG_DEBUG("target->state: %s", target_state_name(target));
 
 	xscale->ibcr_available = 2;
 	xscale->ibcr0_used = 0;
@@ -1568,21 +1539,32 @@ static int xscale_deassert_reset(struct 
 		uint32_t address;
 		unsigned buf_cnt;
 		const uint8_t *buffer = xscale_debug_handler;
+		struct reg *dcsr;
 		int retval;
 
-		/* release SRST */
-		jtag_add_reset(0, 0);
+// XXX previous: set_instr(... XSCALE_SELDCSR << xscale->xscale_variant)
+// ... before asserting reset ...
 
-		/* wait 300ms; 150 and 100ms were not enough */
-		jtag_add_sleep(300*1000);
+		/* Set hold_reset, Halt mode and Trap Reset; but note
+		 * that only hold_reset is guaranteed to work until
+		 * after we release SRST.  (So we could speed this up
+		 * a bit by using SELDCSR plus pathmove, without any
+		 * DR scan...)
+		 */
+		dcsr = xscale->reg_cache->reg_list + XSCALE_DCSR;
+		buf_set_u32(dcsr->value, 30, 1, 0x1);
+		buf_set_u32(dcsr->value, 16, 1, 0x1);
+		retval = xscale_write_dcsr(target, 1, 0);
 
+		/* Release SRST then wait for core stability; hold_reset
+		 * ensures the internal reset signal stays active.  Note
+		 * that parameterized delays from jtag_nsrst_assert_width
+		 * and jtag_nsrst_delay will kick in here.
+		 */
+		jtag_add_reset(0, 0);
+		jtag_add_sleep(300*1000);
 		jtag_add_runtest(2030, jtag_set_end_state(TAP_IDLE));
-		jtag_execute_queue();
-
-		/* set Hold reset, Halt mode and Trap Reset */
-		buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
-		buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
-		xscale_write_dcsr(target, 1, 0);
+		retval = jtag_execute_queue();
 
 		/* Load the debug handler into the mini-icache.  Since
 		 * it's using halt mode (not monitor mode), it runs in
@@ -1633,19 +1615,35 @@ static int xscale_deassert_reset(struct 
 		if (retval != ERROR_OK)
 			return retval;
 
-		jtag_add_runtest(30, jtag_set_end_state(TAP_IDLE));
+		/* make sure the core finishes writing everything */
+		jtag_add_runtest(50, jtag_set_end_state(TAP_IDLE));
 
 		jtag_add_sleep(100000);
 
-		/* set Hold reset, Halt mode and Trap Reset */
-		buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
-		buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
-		xscale_write_dcsr(target, 1, 0);
+		/* Reprogram DCSR ... set Halt mode and Trap Reset.
+		 * Both settings should stick this time.
+		 */
+		buf_set_u32(dcsr->value, 30, 1, 0x1);
+		buf_set_u32(dcsr->value, 16, 1, 0x1);
 
-		/* clear Hold reset to let the target run (should enter debug handler) */
-		xscale_write_dcsr(target, 0, 1);
-		target->state = TARGET_RUNNING;
+		/* Clear hold_reset to let the target run.  It should enter
+		 * the debug handler in special debug state ...  it's in
+		 * Halt mode, coming out of reset, and we've set *BOTH* the
+		 * Trap Reset flag (which has priority) and ext_dbg_brk.
+		 *
+		 * The debug handler will set DCSR.GE (cleared by TRST)
+		 * so all other debug capabilities become available.
+		 * (That includes the ability to write trap bits other
+		 * than TR.)  It will then wait for commands from us.
+		 */
+		retval = xscale_write_dcsr(target, 0, 1);
 
+		/* REVISIT surely "halt" could just mean "skip resume"?
+		 * The debug handler *could* just notice that it's not in
+		 * debug mode, then hand off to the real reset code; that
+		 * would also work better in "poll off" configurations...
+		 */
+		target->state = TARGET_RUNNING;
 		if (!target->reset_halt)
 		{
 			jtag_add_sleep(10000);
@@ -1658,7 +1656,6 @@ static int xscale_deassert_reset(struct 
 			xscale_resume(target, 1, 0x0, 1, 0);
 		}
 	}
-
 	return ERROR_OK;
 }
 
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to