> > 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