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

Reply via email to