X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Ftarget.c;h=560ee78c218d07533e5b0b9618730e80b967f7f0;hp=d0936d996585040898fd9a8dab87d8e94dd96273;hb=a28eaa85f73759bb189a46308642502c9fa5aa4b;hpb=199ebae564fb0701e5bf9ad1e9bb07c668cd998f diff --git a/src/target/target.c b/src/target/target.c index d0936d9965..560ee78c21 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -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 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 - * - * and - * - * target - * - * 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 */ - chain_position_offset = 2; - } else { - chain_position_offset = 3; - /* target */ - } - - /* 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 ){