Add -defer-examine option to target create command 76/3076/15
authorMatthias Welwarsky <matthias.welwarsky@sysgo.com>
Fri, 11 Nov 2016 13:39:09 +0000 (14:39 +0100)
committerPaul Fertser <fercerpav@gmail.com>
Thu, 8 Dec 2016 12:24:11 +0000 (12:24 +0000)
The '-defer-examine' option to target create allows declaring targets
that are present on the chain, but not fully functional.  They will
be skipped by the initial arp_examine as well as arp_examine after
reset.

Manual examine using 'arp_examine' is needed to examine them, with the
idea that some kind of actions is neeed to bring them to a state where
examine will succeed (if at all possible).

In order to allow value less options to target command, I had to relax
the goi.argc check in jim_target_configure().

Change-Id: I9bf4e8d27eb6476dd9353d15f48965a8cfd5c122
Signed-off-by: Esben Haabendal <esben@haabendal.dk>
Signed-off-by: Matthias Welwarsky <matthias.welwarsky@sysgo.com>
Reviewed-on: http://openocd.zylin.com/3076
Tested-by: jenkins
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
doc/openocd.texi
src/rtos/rtos.c
src/target/startup.tcl
src/target/target.c
src/target/target.h

index 0fef9fb..4ce6187 100644 (file)
@@ -4126,6 +4126,10 @@ The value should normally correspond to a static mapping for the
 @option{FreeRTOS}|@option{linux}|@option{ChibiOS}|@option{embKernel}|@option{mqx}
 @xref{gdbrtossupport,,RTOS Support}.
 
+@item @code{-defer-examine} -- skip target examination at initial JTAG chain
+scan and after a reset. A manual call to arp_examine is required to
+access the target for debugging.
+
 @end itemize
 @end deffn
 
@@ -4162,7 +4166,7 @@ omap3530.cpu  mww 0x5555 123
 
 The commands supported by OpenOCD target objects are:
 
-@deffn Command {$target_name arp_examine}
+@deffn Command {$target_name arp_examine} @option{allow-defer}
 @deffnx Command {$target_name arp_halt}
 @deffnx Command {$target_name arp_poll}
 @deffnx Command {$target_name arp_reset}
index 448c49c..aa8efbe 100644 (file)
@@ -104,6 +104,7 @@ int rtos_create(Jim_GetOptInfo *goi, struct target *target)
        int x;
        const char *cp;
        struct Jim_Obj *res;
+       int e;
 
        if (!goi->isconfigure && goi->argc != 0) {
                Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "NO PARAMS");
@@ -112,7 +113,9 @@ int rtos_create(Jim_GetOptInfo *goi, struct target *target)
 
        os_free(target);
 
-       Jim_GetOpt_String(goi, &cp, NULL);
+       e = Jim_GetOpt_String(goi, &cp, NULL);
+       if (e != JIM_OK)
+               return e;
 
        if (0 == strcmp(cp, "auto")) {
                /* Auto detect tries to look up all symbols for each RTOS,
index cf2813b..9bbc6e3 100644 (file)
@@ -65,7 +65,7 @@ proc ocd_process_reset_inner { MODE } {
        foreach t $targets {
                if {![using_jtag] || [jtag tapisenabled [$t cget -chain-position]]} {
                        $t invoke-event examine-start
-                       set err [catch "$t arp_examine"]
+                       set err [catch "$t arp_examine allow-defer"]
                        if { $err == 0 } {
                                $t invoke-event examine-end
                        }
@@ -111,6 +111,12 @@ proc ocd_process_reset_inner { MODE } {
                                continue
                        }
 
+                       # don't wait for targets where examination is deferred
+                       # they can not be halted anyway at this point
+                       if { ![$t was_examined] && [$t examine_deferred] } {
+                               continue
+                       }
+
                        # Wait upto 1 second for target to halt.  Why 1sec? Cause
                        # the JTAG tap reset signal might be hooked to a slow
                        # resistor/capacitor circuit - and it might take a while
@@ -135,6 +141,12 @@ proc ocd_process_reset_inner { MODE } {
                                continue
                        }
 
+                       # don't wait for targets where examination is deferred
+                       # they can not be halted anyway at this point
+                       if { ![$t was_examined] && [$t examine_deferred] } {
+                               continue
+                       }
+
                        set err [catch "$t arp_waitstate halted 5000"]
                        # Did it halt?
                        if { $err == 0 } {
index c23590e..4c5ddd3 100644 (file)
@@ -283,6 +283,10 @@ const char *target_state_name(struct target *t)
                LOG_ERROR("Invalid target state: %d", (int)(t->state));
                cp = "(*BUG*unknown*BUG*)";
        }
+
+       if (!target_was_examined(t) && t->defer_examine)
+               cp = "examine deferred";
+
        return cp;
 }
 
@@ -731,6 +735,9 @@ int target_examine(void)
                        continue;
                }
 
+               if (target->defer_examine)
+                       continue;
+
                retval = target_examine_one(target);
                if (retval != ERROR_OK)
                        return retval;
@@ -4325,6 +4332,7 @@ enum target_cfg_param {
        TCFG_CHAIN_POSITION,
        TCFG_DBGBASE,
        TCFG_RTOS,
+       TCFG_DEFER_EXAMINE,
 };
 
 static Jim_Nvp nvp_config_opts[] = {
@@ -4339,6 +4347,7 @@ static Jim_Nvp nvp_config_opts[] = {
        { .name = "-chain-position",   .value = TCFG_CHAIN_POSITION },
        { .name = "-dbgbase",          .value = TCFG_DBGBASE },
        { .name = "-rtos",             .value = TCFG_RTOS },
+       { .name = "-defer-examine",    .value = TCFG_DEFER_EXAMINE },
        { .name = NULL, .value = -1 }
 };
 
@@ -4613,6 +4622,13 @@ no_params:
                        }
                        /* loop for more */
                        break;
+
+               case TCFG_DEFER_EXAMINE:
+                       /* DEFER_EXAMINE */
+                       target->defer_examine = true;
+                       /* loop for more */
+                       break;
+
                }
        } /* while (goi->argc) */
 
@@ -4627,12 +4643,9 @@ static int jim_target_configure(Jim_Interp *interp, int argc, Jim_Obj * const *a
 
        Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
        goi.isconfigure = !strcmp(Jim_GetString(argv[0], NULL), "configure");
-       int need_args = 1 + goi.isconfigure;
-       if (goi.argc < need_args) {
+       if (goi.argc < 1) {
                Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
-                       goi.isconfigure
-                               ? "missing: -option VALUE ..."
-                               : "missing: -option ...");
+                                "missing: -option ...");
                return JIM_ERR;
        }
        struct target *target = Jim_CmdPrivData(goi.interp);
@@ -4883,20 +4896,58 @@ static int jim_target_tap_disabled(Jim_Interp *interp)
 
 static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 {
-       if (argc != 1) {
-               Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
+       bool allow_defer = false;
+
+       Jim_GetOptInfo goi;
+       Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
+       if (goi.argc > 1) {
+               const char *cmd_name = Jim_GetString(argv[0], NULL);
+               Jim_SetResultFormatted(goi.interp,
+                               "usage: %s ['allow-defer']", cmd_name);
                return JIM_ERR;
        }
+       if (goi.argc > 0 &&
+           strcmp(Jim_GetString(argv[1], NULL), "allow-defer") == 0) {
+               /* consume it */
+               struct Jim_Obj *obj;
+               int e = Jim_GetOpt_Obj(&goi, &obj);
+               if (e != JIM_OK)
+                       return e;
+               allow_defer = true;
+       }
+
        struct target *target = Jim_CmdPrivData(interp);
        if (!target->tap->enabled)
                return jim_target_tap_disabled(interp);
 
+       if (allow_defer && target->defer_examine) {
+               LOG_INFO("Deferring arp_examine of %s", target_name(target));
+               LOG_INFO("Use arp_examine command to examine it manually!");
+               return JIM_OK;
+       }
+
        int e = target->type->examine(target);
        if (e != ERROR_OK)
                return JIM_ERR;
        return JIM_OK;
 }
 
+static int jim_target_was_examined(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
+{
+       struct target *target = Jim_CmdPrivData(interp);
+
+       Jim_SetResultBool(interp, target_was_examined(target));
+       return JIM_OK;
+}
+
+static int jim_target_examine_deferred(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
+{
+       struct target *target = Jim_CmdPrivData(interp);
+
+       Jim_SetResultBool(interp, target->defer_examine);
+       return JIM_OK;
+}
+
 static int jim_target_halt_gdb(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 {
        if (argc != 1) {
@@ -4964,6 +5015,10 @@ static int jim_target_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                                target_name(target));
                return JIM_ERR;
        }
+
+       if (target->defer_examine)
+               target_reset_examined(target);
+
        /* determine if we should halt or not. */
        target->reset_halt = !!a;
        /* When this happens - all workareas are invalid. */
@@ -5174,6 +5229,21 @@ static const struct command_registration target_instance_command_handlers[] = {
                .mode = COMMAND_EXEC,
                .jim_handler = jim_target_examine,
                .help = "used internally for reset processing",
+               .usage = "arp_examine ['allow-defer']",
+       },
+       {
+               .name = "was_examined",
+               .mode = COMMAND_EXEC,
+               .jim_handler = jim_target_was_examined,
+               .help = "used internally for reset processing",
+               .usage = "was_examined",
+       },
+       {
+               .name = "examine_deferred",
+               .mode = COMMAND_EXEC,
+               .jim_handler = jim_target_examine_deferred,
+               .help = "used internally for reset processing",
+               .usage = "examine_deferred",
        },
        {
                .name = "arp_halt_gdb",
index 8f6a7d9..7f6ac14 100644 (file)
@@ -130,6 +130,9 @@ struct target {
        struct jtag_tap *tap;                           /* where on the jtag chain is this */
        int32_t coreid;                                         /* which device on the TAP? */
 
+       /** Should we defer examine to later */
+       bool defer_examine;
+
        /**
         * Indicates whether this target has been examined.
         *