jtag newtap change & huge manual update
[openocd.git] / src / target / target.c
index d0936d996585040898fd9a8dab87d8e94dd96273..560ee78c218d07533e5b0b9618730e80b967f7f0 100644 (file)
@@ -11,6 +11,9 @@
  *   Copyright (C) 2008 by Spencer Oliver                                  *
  *   spen@spen-soft.co.uk                                                  *
  *                                                                         *
+ *   Copyright (C) 2008 by Rick Altherr                                    *
+ *   kc8apf@kc8apf.net>                                                    *
+ *                                                                         *
  *   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     *
@@ -61,8 +64,6 @@ int cli_target_callback_event_handler(struct target_s *target, enum target_event
 
 int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 
-int handle_working_area_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-
 int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
@@ -172,6 +173,11 @@ const Jim_Nvp nvp_target_event[] = {
        { .value = TARGET_EVENT_RESUME_START, .name = "resume-start" },
        { .value = TARGET_EVENT_RESUME_END, .name = "resume-end" },
 
+
+       { .name = "gdb-start", .value = TARGET_EVENT_GDB_START },
+       { .name = "gdb-end", .value = TARGET_EVENT_GDB_END },
+
+
        /* historical name */
 
        { .value = TARGET_EVENT_RESET_START, .name = "reset-start" },
@@ -192,7 +198,7 @@ const Jim_Nvp nvp_target_event[] = {
 
 
        { .value = TARGET_EVENT_EXAMINE_START, .name = "examine-start" },
-       { .value = TARGET_EVENT_EXAMINE_START, .name = "examine-end" },
+       { .value = TARGET_EVENT_EXAMINE_END, .name = "examine-end" },
 
 
        { .value = TARGET_EVENT_DEBUG_HALTED, .name = "debug-halted" },
@@ -939,7 +945,6 @@ int target_register_commands(struct command_context_s *cmd_ctx)
 {
 
        register_command(cmd_ctx, NULL, "targets", handle_targets_command, COMMAND_EXEC, "change the current command line target (one parameter) or lists targets (with no parameter)");
-       register_command(cmd_ctx, NULL, "working_area", handle_working_area_command, COMMAND_ANY, "set a new working space");
        register_command(cmd_ctx, NULL, "virt2phys", handle_virt2phys_command, COMMAND_ANY, "translate a virtual address into a physical address");
        register_command(cmd_ctx, NULL, "profile", handle_profile_command, COMMAND_EXEC, "profiling samples the CPU PC");
 
@@ -1354,7 +1359,7 @@ int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **
        if (argc == 1)
        {
                /* try as tcltarget name */
-               for( target = all_targets ; target ; target++ ){
+               for( target = all_targets ; target ; target = target->next ){
                  if( target->cmd_name ){
                        if( 0 == strcmp( args[0], target->cmd_name ) ){
                                /* MATCH */
@@ -1380,19 +1385,21 @@ int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **
                cmd_ctx->current_target = target->target_number;
                return ERROR_OK;
        }
- DumpTargets:
+DumpTargets:
 
-       command_print(cmd_ctx, "    CmdName    Type       Endian     ChainPos State     ");
-       command_print(cmd_ctx, "--  ---------- ---------- ---------- -------- ----------");
+  target = all_targets;
+       command_print(cmd_ctx, "    CmdName    Type       Endian     AbsChainPos Name          State     ");
+       command_print(cmd_ctx, "--  ---------- ---------- ---------- ----------- ------------- ----------");
        while (target)
        {
                /* XX: abcdefghij abcdefghij abcdefghij abcdefghij */
-               command_print(cmd_ctx, "%2d: %-10s %-10s %-10s %8d %s",
+               command_print(cmd_ctx, "%2d: %-10s %-10s %-10s %10d %14s %s",
                                          target->target_number,
                                          target->cmd_name,
                                          target->type->name,
                                          Jim_Nvp_value2name_simple( nvp_target_endian, target->endianness )->name,
-                                         target->chain_position,
+                                         target->tap->abs_chain_position,
+                                         target->tap->dotted_name,
                                          Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
                target = target->next;
        }
@@ -1400,47 +1407,73 @@ int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **
        return ERROR_OK;
 }
 
+// every 300ms we check for reset & powerdropout and issue a "reset halt" if
+// so.
 
+static int powerDropout;
+static int srstAsserted;
 
-int handle_working_area_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int runPowerRestore;
+static int runPowerDropout;
+static int runSrstAsserted;
+static int runSrstDeasserted;
+
+static int sense_handler(void)
 {
-       int retval = ERROR_OK;
-       target_t *target = NULL;
+       static int prevSrstAsserted = 0;
+       static int prevPowerdropout = 0;
 
-       if ((argc < 4) || (argc > 5))
-       {
-               return ERROR_COMMAND_SYNTAX_ERROR;
-       }
+       int retval;
+       if ((retval=jtag_power_dropout(&powerDropout))!=ERROR_OK)
+               return retval;
 
-       target = get_target_by_num(strtoul(args[0], NULL, 0));
-       if (!target)
+       int powerRestored;
+       powerRestored = prevPowerdropout && !powerDropout;
+       if (powerRestored)
        {
-               return ERROR_COMMAND_SYNTAX_ERROR;
+               runPowerRestore = 1;
        }
-       target_free_all_working_areas(target);
 
-       target->working_area_phys = target->working_area_virt = strtoul(args[1], NULL, 0);
-       if (argc == 5)
+       long long current = timeval_ms();
+       static long long lastPower = 0;
+       int waitMore = lastPower + 2000 > current;
+       if (powerDropout && !waitMore)
        {
-               target->working_area_virt = strtoul(args[4], NULL, 0);
+               runPowerDropout = 1;
+               lastPower = current;
        }
-       target->working_area_size = strtoul(args[2], NULL, 0);
 
-       if (strcmp(args[3], "backup") == 0)
+       if ((retval=jtag_srst_asserted(&srstAsserted))!=ERROR_OK)
+               return retval;
+
+       int srstDeasserted;
+       srstDeasserted = prevSrstAsserted && !srstAsserted;
+
+       static long long lastSrst = 0;
+       waitMore = lastSrst + 2000 > current;
+       if (srstDeasserted && !waitMore)
        {
-               target->backup_working_area = 1;
+               runSrstDeasserted = 1;
+               lastSrst = current;
        }
-       else if (strcmp(args[3], "nobackup") == 0)
+
+       if (!prevSrstAsserted && srstAsserted)
        {
-               target->backup_working_area = 0;
+               runSrstAsserted = 1;
        }
-       else
+
+       prevSrstAsserted = srstAsserted;
+       prevPowerdropout = powerDropout;
+
+       if (srstDeasserted || powerRestored)
        {
-               LOG_ERROR("unrecognized <backup|nobackup> argument (%s)", args[3]);
-               return ERROR_COMMAND_SYNTAX_ERROR;
+               /* Other than logging the event we can't do anything here.
+                * Issuing a reset is a particularly bad idea as we might
+                * be inside a reset already.
+                */
        }
 
-       return retval;
+       return ERROR_OK;
 }
 
 
@@ -1448,11 +1481,62 @@ int handle_working_area_command(struct command_context_s *cmd_ctx, char *cmd, ch
 int handle_target(void *priv)
 {
        int retval = ERROR_OK;
+
+       /* we do not want to recurse here... */
+       static int recursive = 0;
+       if (! recursive)
+       {
+               recursive = 1;
+               sense_handler();
+               /* danger! running these procedures can trigger srst assertions and power dropouts.
+                * We need to avoid an infinite loop/recursion here and we do that by
+                * clearing the flags after running these events.
+                */
+               int did_something = 0;
+               if (runSrstAsserted)
+               {
+                       Jim_Eval( interp, "srst_asserted");
+                       did_something = 1;
+               }
+               if (runSrstDeasserted)
+               {
+                       Jim_Eval( interp, "srst_deasserted");
+                       did_something = 1;
+               }
+               if (runPowerDropout)
+               {
+                       Jim_Eval( interp, "power_dropout");
+                       did_something = 1;
+               }
+               if (runPowerRestore)
+               {
+                       Jim_Eval( interp, "power_restore");
+                       did_something = 1;
+               }
+
+               if (did_something)
+               {
+                       /* clear detect flags */
+                       sense_handler();
+               }
+
+               /* clear action flags */
+
+               runSrstAsserted=0;
+               runSrstDeasserted=0;
+               runPowerRestore=0;
+               runPowerDropout=0;
+
+               recursive = 0;
+       }
+
        target_t *target = all_targets;
 
        while (target)
        {
-               if (target_continous_poll)
+
+               /* only poll target if we've got power and srst isn't asserted */
+               if (target_continous_poll&&!powerDropout&&!srstAsserted)
                {
                        /* polling may fail silently until the target has been examined */
                        if((retval = target_poll(target)) != ERROR_OK)
@@ -1462,6 +1546,7 @@ int handle_target(void *priv)
                target = target->next;
        }
 
+
        return retval;
 }
 
@@ -3265,19 +3350,25 @@ target_configure( Jim_GetOptInfo *goi,
                        break;
                case TCFG_CHAIN_POSITION:
                        if( goi->isconfigure ){
+                               Jim_Obj *o;
+                               jtag_tap_t *tap;
                                target_free_all_working_areas(target);
-                               e = Jim_GetOpt_Wide( goi, &w );
+                               e = Jim_GetOpt_Obj( goi, &o );
                                if( e != JIM_OK ){
                                        return e;
                                }
+                               tap = jtag_TapByJimObj( goi->interp, o );
+                               if( tap == NULL ){
+                                       return JIM_ERR;
+                               }
                                /* make this exactly 1 or 0 */
-                               target->chain_position = w;
+                               target->tap = tap;
                        } else {
                                if( goi->argc != 0 ){
                                        goto no_params;
                                }
                        }
-                       Jim_SetResult( interp, Jim_NewIntObj( goi->interp, target->chain_position ) );
+                       Jim_SetResultString( interp, target->tap->dotted_name, -1 );
                        /* loop for more e*/
                        break;
                }
@@ -3770,6 +3861,8 @@ target_create( Jim_GetOptInfo *goi )
        target->next                = NULL;
        target->arch_info           = NULL;
 
+       target->display             = 1;
+
        /* initialize trace information */
        target->trace_info = malloc(sizeof(trace_t));
        target->trace_info->num_trace_points         = 0;
@@ -3837,7 +3930,6 @@ jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
        int x,r,e;
        jim_wide w;
        struct command_context_s *cmd_ctx;
-       const char *cp;
        target_t *target;
        Jim_GetOptInfo goi;
        enum tcmd {
@@ -3867,97 +3959,6 @@ jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
                return JIM_ERR;
        }
 
-       /* is this old syntax? */
-       /* To determine: We have to peek at argv[0]*/
-       cp = Jim_GetString( goi.argv[0], NULL );
-       for( x = 0 ; target_types[x] ; x++ ){
-               if( 0 == strcmp(cp,target_types[x]->name) ){
-                       break;
-               }
-       }
-       if( target_types[x] ){
-               /* YES IT IS OLD SYNTAX */
-               int      chain_position_offset;
-               Jim_Obj *new_argv[10];
-               int      new_argc;
-
-               /* target_old_syntax
-                *
-                * It appears that there are 2 old syntaxes:
-                *
-                * target <typename> <endian> <chain position> <variant>
-                *
-                * and
-                *
-                * target <typename> <endian> <reset mode> <chain position> <variant>
-                *
-                * The following uses the number of arguments to switch between them.
-                */
-               if( argc < 5 ){
-                       Jim_WrongNumArgs( interp, 1, argv, "[OLDSYNTAX] ?TYPE? ?ENDIAN? ?CHAIN-POSITION? ?VARIANT?");
-                       return JIM_ERR;
-               }
-
-               /* Use the correct argument offset for the chain position */
-               if (argc < 6) {
-                       /* target <type> <endian> <chain position> <variant> */
-                       chain_position_offset = 2;
-               } else {
-                       chain_position_offset = 3;
-                       /* target <type> <endian> <reset mode> <chain position> <variant> */
-               }
-
-               /* the command */
-               new_argv[0] = argv[0];
-               new_argv[1] = Jim_NewStringObj( interp, "create", -1 );
-               {
-                       char buf[ 30 ];
-                       sprintf( buf, "target%d", new_target_number() );
-                       new_argv[2] = Jim_NewStringObj( interp, buf , -1 );
-               }
-               new_argv[3] = goi.argv[0]; /* typename */
-               new_argv[4] = Jim_NewStringObj( interp, "-endian", -1 );
-               new_argv[5] = goi.argv[1];
-               new_argv[6] = Jim_NewStringObj( interp, "-chain-position", -1 );
-               new_argv[7] = goi.argv[chain_position_offset];
-               new_argv[8] = Jim_NewStringObj( interp, "-variant", -1 );
-               new_argv[9] = goi.argv[chain_position_offset + 1];
-               new_argc = 10;
-
-               /*
-                * new arg syntax:
-                *   argv[0] = command
-                *   argv[1] = create
-                *   argv[2] = cmdname
-                *   argv[3] = typename
-                *   argv[4] = **FIRST** "configure" option.
-                *
-                * Here, we make them:
-                *
-                *   argv[4] = -endian
-                *   argv[5] = little
-                *   argv[6] = -position
-                *   argv[7] = NUMBER
-                *   argv[8] = -variant
-                *   argv[9] = "somestring"
-                */
-
-               /* don't let these be released */
-               for( x = 0 ; x < new_argc ; x++ ){
-                       Jim_IncrRefCount( new_argv[x]);
-               }
-               /* call our self */
-               LOG_DEBUG("Target OLD SYNTAX - converted to new syntax");
-
-               r = jim_target( goi.interp, new_argc, new_argv );
-
-               /* release? these items */
-               for( x = 0 ; x < new_argc ; x++ ){
-                       Jim_DecrRefCount( interp, new_argv[x] );
-               }
-               return r;
-       }
-
        //Jim_GetOpt_Debug( &goi );
        r = Jim_GetOpt_Enum( &goi, target_cmds, &x   );
        if( r != JIM_OK ){

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)