Teach most remaining ARM cores how to use the "reset-assert" event.
Same model as elsewhere: iff a handler is provided for that event, use that instead of trying to assert SRST (which may be unavailable); else this code is a NOP. Shrink some overlong lines. Add my 2009 copyright. --- This is a bit borderline, but I'm inclined to commit for 0.4 anyway. Comments? It could be argued to be a new feature for ARM7/ARM9 ... or a bugfix, since all the other ARM cores currently can be reset without SRST (given an appropriate reset-assert event handler). Either way it's a NOP unless you try to use this feature. Sorry I didn't merge this a long time back (patch hasn't changed in months, except for some comment tweaks) but the initial tests on a platform with severe reset problems didn't go well, and I've not touched a sanely-behaved ARM9 since then. src/target/arm7_9_common.c | 88 +++++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 31 deletions(-) --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -11,6 +11,8 @@ * Copyright (C) 2008 by Hongtao Zheng * * hon...@126.com * * * + * Copyright (C) 2009 by David Brownell * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -941,19 +943,21 @@ int arm7_9_poll(struct target *target) int arm7_9_assert_reset(struct target *target) { struct arm7_9_common *arm7_9 = target_to_arm7_9(target); + enum reset_types jtag_reset_config = jtag_get_reset_config(); + bool use_event = false; LOG_DEBUG("target->state: %s", target_state_name(target)); - enum reset_types jtag_reset_config = jtag_get_reset_config(); - if (!(jtag_reset_config & RESET_HAS_SRST)) - { - LOG_ERROR("Can't assert SRST"); + if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) + use_event = true; + else if (!(jtag_reset_config & RESET_HAS_SRST)) { + LOG_ERROR("%s: how to reset?", target_name(target)); return ERROR_FAIL; } - /* At this point trst has been asserted/deasserted once. We would - * like to program EmbeddedICE while SRST is asserted, instead of + /* At this point trst has been asserted/deasserted once. We might + * be able program EmbeddedICE while SRST is asserted, instead of * depending on SRST to leave that module alone. However, many CPUs * gate the JTAG clock while SRST is asserted; or JTAG may need * clock stability guarantees (adaptive clocking might help). @@ -963,7 +967,8 @@ int arm7_9_assert_reset(struct target *t */ bool srst_asserted = false; - if (((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0) + if (!use_event + && !(jtag_reset_config & RESET_SRST_PULLS_TRST) && (jtag_reset_config & RESET_SRST_NO_GATING)) { jtag_add_reset(0, 1); @@ -973,48 +978,69 @@ int arm7_9_assert_reset(struct target *t if (target->reset_halt) { /* - * Some targets do not support communication while SRST is asserted. We need to - * set up the reset vector catch here. + * For targets that don't support communication while SRST is + * asserted, we need to set up the reset vector catch first. * - * If TRST is asserted, then these settings will be reset anyway, so setting them - * here is harmless. + * When we use TRST+SRST and that's equivalent to a power-up + * reset, these settings may well be reset anyway; so setting + * them here won't matter. */ if (arm7_9->has_vector_catch) { - /* program vector catch register to catch reset vector */ - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH], 0x1); + /* program vector catch register to catch reset */ + embeddedice_write_reg(&arm7_9->eice_cache + ->reg_list[EICE_VEC_CATCH], 0x1); - /* extra runtest added as issues were found with certain ARM9 cores (maybe more) - AT91SAM9260 and STR9 */ + /* extra runtest added as issues were found with + * certain ARM9 cores (maybe more) - AT91SAM9260 + * and STR9 + */ jtag_add_runtest(1, jtag_get_end_state()); } else { - /* program watchpoint unit to match on reset vector address */ - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE], 0x0); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0x3); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff); + /* program watchpoint unit to match on reset vector + * address + */ + embeddedice_write_reg(&arm7_9->eice_cache + ->reg_list[EICE_W0_ADDR_VALUE], 0x0); + embeddedice_write_reg(&arm7_9->eice_cache + ->reg_list[EICE_W0_ADDR_MASK], 0x3); + embeddedice_write_reg(&arm7_9->eice_cache + ->reg_list[EICE_W0_DATA_MASK], + 0xffffffff); + embeddedice_write_reg(&arm7_9->eice_cache + ->reg_list[EICE_W0_CONTROL_VALUE], + EICE_W_CTRL_ENABLE); + embeddedice_write_reg(&arm7_9->eice_cache + ->reg_list[EICE_W0_CONTROL_MASK], + ~EICE_W_CTRL_nOPC & 0xff); } } - /* here we should issue an SRST only, but we may have to assert TRST as well */ - if (jtag_reset_config & RESET_SRST_PULLS_TRST) - { - jtag_add_reset(1, 1); - } else if (!srst_asserted) - { - jtag_add_reset(0, 1); + if (use_event) { + target_handle_event(target, TARGET_EVENT_RESET_ASSERT); + } else { + /* If we use SRST ... we'd like to issue just SRST, but the + * board or chip may be set up so we have to assert TRST as + * well. On some chips that combination is equivalent to a + * power-up reset, and generally clobbers EICE state. + */ + if (jtag_reset_config & RESET_SRST_PULLS_TRST) + jtag_add_reset(1, 1); + else if (!srst_asserted) + jtag_add_reset(0, 1); + jtag_add_sleep(50000); } target->state = TARGET_RESET; - jtag_add_sleep(50000); - register_cache_invalidate(arm7_9->armv4_5_common.core_cache); - if ((target->reset_halt) && ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0)) + if (target->reset_halt + && (!(jtag_reset_config & RESET_SRST_PULLS_TRST) + || use_event)) { - /* debug entry was already prepared in arm7_9_assert_reset() */ + /* debug entry was prepared above */ target->debug_reason = DBG_REASON_DBGRQ; } _______________________________________________ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development