]> git.sur5r.net Git - openocd/commitdiff
cortex m3: add cortex_m3 reset_config cmd
authorSpencer Oliver <ntfreak@users.sourceforge.net>
Wed, 25 Aug 2010 19:29:22 +0000 (20:29 +0100)
committerSpencer Oliver <ntfreak@users.sourceforge.net>
Tue, 31 Aug 2010 19:09:26 +0000 (20:09 +0100)
This new cmd adds the ability to choose the Cortex-M3
reset method used.
It defaults to using SRST for reset if available otherwise
it falls back to using NVIC VECTRESET. This is known to work
on all cores.

Move any luminary specific reset handling to the stellaris cfg file.

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
doc/openocd.texi
src/target/cortex_m3.c
src/target/cortex_m3.h
tcl/target/stellaris.cfg

index cbb9c141b1967f7bc061361ddada6d9114cfe9ae..bc026b90c7bf4aaa380951131dab9d7173c26c03 100644 (file)
@@ -6592,6 +6592,21 @@ must also be explicitly enabled.
 This finishes by listing the current vector catch configuration.
 @end deffn
 
+@deffn Command {cortex_m3 reset_config} (@option{srst}|@option{sysresetreq}|@option{vectreset})
+Control reset handling. The default @option{srst} is to use srst if fitted,
+otherwise fallback to @option{vectreset}.
+@itemize @minus
+@item @option{srst} use hardware srst if fitted otherwise fallback to @option{vectreset}.
+@item @option{sysresetreq} use NVIC SYSRESETREQ to reset system.
+@item @option{vectreset} use NVIC VECTRESET to reset system.
+@end itemize
+Using @option{vectreset} is a safe option for all current Cortex-M3 cores.
+This however has the disadvantage of only resetting the core, all peripherals
+are uneffected. A solution would be to use a @code{reset-init} event handler to manually reset
+the peripherals.
+@xref{Target Events}.
+@end deffn
+
 @anchor{Software Debug Messages and Tracing}
 @section Software Debug Messages and Tracing
 @cindex Linux-ARM DCC support
index 2a58f5bf0d6201f801737acbb584d7665bb7b52e..f87c3e0b80634d4b8ab6e8008abfc14869ba4377 100644 (file)
@@ -913,7 +913,7 @@ static int cortex_m3_assert_reset(struct target *target)
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
        struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
-       int assert_srst = 1;
+       enum cortex_m3_soft_reset_config reset_config = cortex_m3->soft_reset_config;
 
        LOG_DEBUG("target->state: %s",
                target_state_name(target));
@@ -925,8 +925,10 @@ static int cortex_m3_assert_reset(struct target *target)
         * requiring SRST, getting a SoC reset (or a core-only reset)
         * instead of a system reset.
         */
-       if (!(jtag_reset_config & RESET_HAS_SRST))
-               assert_srst = 0;
+       if (!(jtag_reset_config & RESET_HAS_SRST) &&
+                       (cortex_m3->soft_reset_config == CORTEX_M3_RESET_SRST)) {
+               reset_config = CORTEX_M3_RESET_VECTRESET;
+       }
 
        /* Enable debug requests */
        int retval;
@@ -975,49 +977,7 @@ static int cortex_m3_assert_reset(struct target *target)
                        return retval;
        }
 
-       /*
-        * When nRST is asserted on most Stellaris devices, it clears some of
-        * the debug state.  The ARMv7M and Cortex-M3 TRMs say that's wrong;
-        * and OpenOCD depends on those TRMs.  So we won't use SRST on those
-        * chips.  (Only power-on reset should affect debug state, beyond a
-        * few specified bits; not the chip's nRST input, wired to SRST.)
-        *
-        * REVISIT current errata specs don't seem to cover this issue.
-        * Do we have more details than this email?
-        *   https://lists.berlios.de/pipermail
-        *      /openocd-development/2008-August/003065.html
-        */
-       if (strcmp(target->variant, "lm3s") == 0)
-       {
-               /* Check for silicon revisions with the issue. */
-               uint32_t did0;
-
-               if (target_read_u32(target, 0x400fe000, &did0) == ERROR_OK)
-               {
-                       switch ((did0 >> 16) & 0xff)
-                       {
-                               case 0:
-                                       /* all Sandstorm suffer issue */
-                                       assert_srst = 0;
-                                       break;
-
-                               case 1:
-                               case 3:
-                                       /* Fury and DustDevil rev A have
-                                        * this nRST problem.  It should
-                                        * be fixed in rev B silicon.
-                                        */
-                                       if (((did0 >> 8) & 0xff) == 0)
-                                               assert_srst = 0;
-                                       break;
-                               case 4:
-                                       /* Tempest should be fine. */
-                                       break;
-                       }
-               }
-       }
-
-       if (assert_srst)
+       if (reset_config == CORTEX_M3_RESET_SRST)
        {
                /* default to asserting srst */
                if (jtag_reset_config & RESET_SRST_PULLS_TRST)
@@ -1032,15 +992,23 @@ static int cortex_m3_assert_reset(struct target *target)
        else
        {
                /* Use a standard Cortex-M3 software reset mechanism.
-                * SYSRESETREQ will reset SoC peripherals outside the
-                * core, like watchdog timers, if the SoC wires it up
-                * correctly.  Else VECRESET can reset just the core.
+                * We default to using VECRESET as it is supported on all current cores.
+                * This has the disadvantage of not resetting the peripherals, so a
+                * reset-init event handler is needed to perform any peripheral resets.
                 */
                retval = mem_ap_write_atomic_u32(swjdp, NVIC_AIRCR,
-                               AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
+                               AIRCR_VECTKEY | ((reset_config == CORTEX_M3_RESET_SYSRESETREQ)
+                               ? AIRCR_SYSRESETREQ : AIRCR_VECTRESET));
                if (retval != ERROR_OK)
                        return retval;
-               LOG_DEBUG("Using Cortex-M3 SYSRESETREQ");
+
+               LOG_DEBUG("Using Cortex-M3 %s", (reset_config == CORTEX_M3_RESET_SYSRESETREQ)
+                               ? "SYSRESETREQ" : "VECTRESET");
+
+               if (reset_config == CORTEX_M3_RESET_VECTRESET) {
+                       LOG_WARNING("Only resetting the Cortex-M3 core, use a reset-init event "
+                                       "handler to reset any peripherals");
+               }
 
                {
                        /* I do not know why this is necessary, but it
@@ -1969,6 +1937,10 @@ static int cortex_m3_init_arch_info(struct target *target,
        cortex_m3->jtag_info.tap = tap;
        cortex_m3->jtag_info.scann_size = 4;
 
+       /* default reset mode is to use srst if fitted
+        * if not it will use CORTEX_M3_RESET_VECTRESET */
+       cortex_m3->soft_reset_config = CORTEX_M3_RESET_SRST;
+
        armv7m->arm.dap = &armv7m->dap;
 
        /* Leave (only) generic DAP stuff for debugport_init(); */
@@ -2143,6 +2115,51 @@ COMMAND_HANDLER(handle_cortex_m3_mask_interrupts_command)
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(handle_cortex_m3_reset_config_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
+       int retval;
+       char *reset_config;
+
+       retval = cortex_m3_verify_pointer(CMD_CTX, cortex_m3);
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (CMD_ARGC > 0)
+       {
+               if (strcmp(*CMD_ARGV, "systesetreq") == 0)
+                       cortex_m3->soft_reset_config = CORTEX_M3_RESET_SYSRESETREQ;
+               else if (strcmp(*CMD_ARGV, "vectreset") == 0)
+                       cortex_m3->soft_reset_config = CORTEX_M3_RESET_VECTRESET;
+               else
+                       cortex_m3->soft_reset_config = CORTEX_M3_RESET_SRST;
+       }
+
+       switch (cortex_m3->soft_reset_config)
+       {
+               case CORTEX_M3_RESET_SRST:
+                       reset_config = "srst";
+                       break;
+
+               case CORTEX_M3_RESET_SYSRESETREQ:
+                       reset_config = "sysresetreq";
+                       break;
+
+               case CORTEX_M3_RESET_VECTRESET:
+                       reset_config = "vectreset";
+                       break;
+
+               default:
+                       reset_config = "unknown";
+                       break;
+       }
+
+       command_print(CMD_CTX, "cortex_m3 reset_config %s", reset_config);
+
+       return ERROR_OK;
+}
+
 static const struct command_registration cortex_m3_exec_command_handlers[] = {
        {
                .name = "maskisr",
@@ -2158,6 +2175,13 @@ static const struct command_registration cortex_m3_exec_command_handlers[] = {
                .help = "configure hardware vectors to trigger debug entry",
                .usage = "['all'|'none'|('bus_err'|'chk_err'|...)*]",
        },
+       {
+               .name = "reset_config",
+               .handler = handle_cortex_m3_reset_config_command,
+               .mode = COMMAND_ANY,
+               .help = "configure software reset handling",
+               .usage = "['srst'|'sysresetreq'|'vectreset']",
+       },
        COMMAND_REGISTRATION_DONE
 };
 static const struct command_registration cortex_m3_command_handlers[] = {
index 7ce89014bbbc8eec7ca5705ed769892203f543a5..db8071110edbc9b25dc73a48cc5059774eb54f40 100644 (file)
@@ -134,6 +134,13 @@ struct cortex_m3_dwt_comparator
        uint32_t dwt_comparator_address;
 };
 
+enum cortex_m3_soft_reset_config
+{
+       CORTEX_M3_RESET_SRST,
+       CORTEX_M3_RESET_SYSRESETREQ,
+       CORTEX_M3_RESET_VECTRESET,
+};
+
 struct cortex_m3_common
 {
        int common_magic;
@@ -158,6 +165,8 @@ struct cortex_m3_common
        struct cortex_m3_dwt_comparator *dwt_comparator_list;
        struct reg_cache *dwt_cache;
 
+       enum cortex_m3_soft_reset_config soft_reset_config;
+
        struct armv7m_common armv7m;
 };
 
index 4235f9106c58eb5ae8615f3718ff752779456ff0..6ba5f14a208425a8a74dc4fd2fed467378b27bbe 100644 (file)
@@ -21,18 +21,15 @@ if { [info exists CPUTAPID ] } {
 if { [info exists WORKAREASIZE ] } {
    set _WORKAREASIZE $WORKAREASIZE
 } else {
+   # default to 8K working area
    set _WORKAREASIZE 0x2000
 }
 
 jtag newtap $_CHIPNAME cpu -irlen 4 -irmask 0xf \
        -expected-id $_CPUTAPID -ignore-version
 
-# The "lm3s" variant uses a software reset rather than SRST.
-# This stops the debug registers from being cleared; it works
-# around an erratum which should be fixed in later silicon.
 set _TARGETNAME $_CHIPNAME.cpu
-target create $_TARGETNAME cortex_m3 -chain-position $_CHIPNAME.cpu \
-       -variant lm3s
+target create $_TARGETNAME cortex_m3 -chain-position $_CHIPNAME.cpu
 
 # 8K working area at base of ram, not backed up
 #
@@ -48,7 +45,41 @@ $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE
 # configures and enables the PLL.  Or you might need to decrease
 # this, if you're using a slower clock.
 adapter_khz 500
-$_TARGETNAME configure -event reset-start {adapter_khz 500}
+
+# mrw: "memory read word", returns value of $reg
+proc mrw {reg} {
+       set value ""
+       mem2array value 32 $reg 1
+       return $value(0)
+}
+
+$_TARGETNAME configure -event reset-start {
+       adapter_khz 500
+
+       #       
+       # When nRST is asserted on most Stellaris devices, it clears some of
+       # the debug state.  The ARMv7M and Cortex-M3 TRMs say that's wrong;
+       # and OpenOCD depends on those TRMs.  So we won't use SRST on those
+       # chips.  (Only power-on reset should affect debug state, beyond a
+       # few specified bits; not the chip's nRST input, wired to SRST.)
+       #
+       # REVISIT current errata specs don't seem to cover this issue.
+       # Do we have more details than this email?
+       #   https://lists.berlios.de/pipermail
+       #       /openocd-development/2008-August/003065.html
+       #
+
+       set device_class [expr (([mrw 0x400fe000] >> 16) & 0xff)]
+       if {$device_class == 0 || $device_class == 1 || $device_class == 3} {
+               # Sandstorm, Fury and DustDevil are able to use NVIC SYSRESETREQ
+               cortex_m3 reset_config systesetreq
+       } else {
+               # Tempest and newer default to using NVIC VECTRESET
+               # this does mean a reset-init event handler is required to reset
+               # any peripherals
+               cortex_m3 reset_config vectreset
+       }
+}
 
 # flash configuration ... autodetects sizes, autoprobed
 flash bank $_CHIPNAME.flash stellaris 0 0 0 0 $_TARGETNAME