}
add_help_text jtag_rclk "fallback_speed_khz - set JTAG speed to RCLK or use fallback speed"
+
+proc ocd_process_reset { MODE } {
+
+ # If this target must be halted...
+ set halt -1
+ if { 0 == [string compare $MODE halt] } {
+ set halt 1
+ }
+ if { 0 == [string compare $MODE init] } {
+ set halt 1;
+ }
+ if { 0 == [string compare $MODE run ] } {
+ set halt 0;
+ }
+ if { $halt < 0 } {
+ return -error "Invalid mode: $MODE, must be one of: halt, init, or run";
+ }
+
+ foreach t [ target names ] {
+ # For compatiblity with 'old scripts'
+ $t invoke-event old-pre_reset
+
+ # New event script.
+ $t invoke-event reset-start
+ }
+
+ # Init the tap controller.
+ jtag arp_init-reset
+
+ # Examine all targets.
+ foreach t [ target names ] {
+ $t arp_examine
+ }
+
+ # Let the C code know we are asserting reset.
+ foreach t [ target names ] {
+ $t invoke-event reset-assert-pre
+ # C code needs to know if we expect to 'halt'
+ $t arp_reset assert $halt
+ $t invoke-event reset-assert-post
+ }
+
+ # Now de-assert reset.
+ foreach t [ target names ] {
+ $t invoke-event reset-deassert-pre
+ # Again, de-assert code needs to know..
+ $t arp_reset deassert $halt
+ $t invoke-event reset-deassert-post
+ }
+
+
+ # Pass 1 - Now try to halt.
+ if { $halt } {
+ foreach t [target names] {
+
+ # 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
+ # to charge
+
+ # Catch, but ignore any errors.
+ catch { $t arp_waitstate halted 1000 }
+
+ # Did we succeed?
+ set s [$t curstate]
+
+ if { 0 != [string compare $s "halted" ] } {
+ return -error [format "TARGET: %s - Not halted" $t]
+ }
+ }
+ }
+
+ #Pass 2 - if needed "init"
+ if { 0 == [string compare init $MODE] } {
+ foreach t [target names] {
+ set err [catch "$t arp_waitstate halted 5000"]
+ # Did it halt?
+ if { $err == 0 } {
+ $t invoke-event old-post_reset
+ }
+ }
+ }
+
+ foreach t [ target names ] {
+ $t invoke-event reset-end
+ }
+}
void jtag_add_end_state(enum tap_state endstate);
void jtag_add_sleep(u32 us);
int jtag_execute_queue(void);
-int jtag_cancel_queue(void);
+
/* jtag commands */
int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
return ERROR_OK;
}
-void jtag_add_tlr()
+void jtag_add_tlr(void)
{
jtag_prelude(TAP_TLR);
return ERROR_OK;
}
+
+static int
+jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
+{
+ Jim_GetOptInfo goi;
+ int e;
+ Jim_Nvp *n;
+ struct command_context_s *context;
+
+ enum {
+ JTAG_CMD_INTERFACE,
+ JTAG_CMD_INIT_RESET,
+ };
+
+ const Jim_Nvp jtag_cmds[] = {
+ { .name = "interface" , .value = JTAG_CMD_INTERFACE },
+ { .name = "arp_init-reset", .value = JTAG_CMD_INIT_RESET },
+
+ { .name = NULL, .value = -1 },
+ };
+
+ context = Jim_GetAssocData(interp, "context");
+ // go past the command
+ Jim_GetOpt_Setup( &goi, interp, argc-1, argv+1 );
+
+ e = Jim_GetOpt_Nvp( &goi, jtag_cmds, &n );
+ if( e != JIM_OK ){
+ Jim_GetOpt_NvpUnknown( &goi, jtag_cmds, 0 );
+ return e;
+ }
+ Jim_SetEmptyResult( goi.interp );
+ switch( n->value ){
+ case JTAG_CMD_INTERFACE:
+ // return the name of the interface
+ // TCL code might need to know the exact type...
+ // FUTURE: we allow this as a means to "set" the interface.
+ if( goi.argc != 0 ){
+ Jim_WrongNumArgs( goi.interp, 1, goi.argv-1, "(no params)");
+ return JIM_ERR;
+ }
+ Jim_SetResultString( goi.interp, jtag_interface->name, -1 );
+ return JIM_OK;
+ case JTAG_CMD_INIT_RESET:
+ if( goi.argc != 0 ){
+ Jim_WrongNumArgs( goi.interp, 1, goi.argv-1, "(no params)");
+ return JIM_ERR;
+ }
+ e = jtag_init_reset(context);
+ if( e != ERROR_OK ){
+ Jim_SetResult_sprintf( goi.interp, "error: %d", e);
+ return JIM_ERR;
+ }
+ return JIM_OK;
+ }
+
+
+ return JIM_ERR;
+}
+
int jtag_register_commands(struct command_context_s *cmd_ctx)
{
+ register_jim( cmd_ctx, "jtag", jim_jtag_command, "perform jtag tap actions");
+
register_command(cmd_ctx, NULL, "interface", handle_interface_command,
COMMAND_CONFIG, NULL);
register_command(cmd_ctx, NULL, "jtag_speed", handle_jtag_speed_command,
return ERROR_OK;
}
+
+
+
+/*
+ * Local Variables: ***
+ * c-basic-offset: 4 ***
+ * tab-width: 4 ***
+ * End: ***
+ */
#include <fileio.h>
#include <image.h>
+static int USE_OLD_RESET = 0; // temp
+
int cli_target_callback_event_handler(struct target_s *target, enum target_event event, void *priv);
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);
int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int handle_NEWreset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
return retval;
}
+
+static int NEW_target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mode reset_mode)
+{
+ char buf[100];
+ Jim_Nvp *n;
+ n = Jim_Nvp_value2name_simple( nvp_reset_modes, reset_mode );
+ if( n->name == NULL ){
+ LOG_ERROR("invalid reset mode");
+ return ERROR_FAIL;
+ }
+
+ sprintf( buf, "ocd_process_reset %s", n->name );
+ Jim_Eval( interp, buf );
+ return ERROR_OK;
+}
+
// Next patch - this turns into TCL...
-int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mode reset_mode)
+static int OLD_target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mode reset_mode)
{
int retval = ERROR_OK;
target_t *target;
return retval;
}
+int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mode reset_mode)
+{
+ if( USE_OLD_RESET ){
+ return OLD_target_process_reset( cmd_ctx, reset_mode );
+ } else {
+ return NEW_target_process_reset( cmd_ctx, reset_mode );
+ }
+}
+
+
static int default_virt2phys(struct target_s *target, u32 virtual, u32 *physical)
{
*physical = virtual;
register_command(cmd_ctx, NULL, "halt", handle_halt_command, COMMAND_EXEC, "halt target");
register_command(cmd_ctx, NULL, "resume", handle_resume_command, COMMAND_EXEC, "resume target [addr]");
register_command(cmd_ctx, NULL, "step", handle_step_command, COMMAND_EXEC, "step one instruction from current PC or [addr]");
- register_command(cmd_ctx, NULL, "reset", handle_reset_command, COMMAND_EXEC, "reset target [run|halt|init] - default is run");
+ register_command(cmd_ctx, NULL, "NEWreset", handle_NEWreset_command, COMMAND_EXEC, "reset target [run|halt|init] - default is run");
+ register_command(cmd_ctx, NULL, "reset", handle_reset_command, COMMAND_EXEC, "OLDreset target [run|halt|init] - default is run");
register_command(cmd_ctx, NULL, "soft_reset_halt", handle_soft_reset_halt_command, COMMAND_EXEC, "halt the target and do a soft reset");
register_command(cmd_ctx, NULL, "mdw", handle_md_command, COMMAND_EXEC, "display memory words <addr> [count]");
return target_process_reset(cmd_ctx, reset_mode);
}
+int handle_NEWreset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ int x;
+ char *cp;
+
+ if (argc >= 1){
+ x = strtol( args[0], &cp, 0 );
+ if( *cp != 0 ){
+ command_print( cmd_ctx, "Not numeric: %s\n", args[0] );
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ USE_OLD_RESET = !!x;
+ }
+ command_print( cmd_ctx, "reset method: %d (%s)\n",
+ USE_OLD_RESET,
+ USE_OLD_RESET ? "old-method" : "new-method" );
+ return ERROR_OK;
+}
+
int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
int retval;
enum target_cfg_param {
TCFG_TYPE,
TCFG_EVENT,
- TCFG_RESET,
TCFG_WORK_AREA_VIRT,
TCFG_WORK_AREA_PHYS,
TCFG_WORK_AREA_SIZE,
static Jim_Nvp nvp_config_opts[] = {
{ .name = "-type", .value = TCFG_TYPE },
{ .name = "-event", .value = TCFG_EVENT },
- { .name = "-reset", .value = TCFG_RESET },
{ .name = "-work-area-virt", .value = TCFG_WORK_AREA_VIRT },
{ .name = "-work-area-phys", .value = TCFG_WORK_AREA_PHYS },
{ .name = "-work-area-size", .value = TCFG_WORK_AREA_SIZE },
/* parse config or cget options ... */
- while( goi->argc ){
+ while( goi->argc > 0 ){
Jim_SetEmptyResult( goi->interp );
//Jim_GetOpt_Debug( goi );
/* loop for more e*/
break;
}
- }
- /* done - we return */
+ } /* while( goi->argc ) */
+ /* done - we return */
return JIM_OK;
}
TS_CMD_WAITSTATE,
TS_CMD_EVENTLIST,
TS_CMD_CURSTATE,
+ TS_CMD_INVOKE_EVENT,
};
static const Jim_Nvp target_options[] = {
{ .name = "arp_reset", .value = TS_CMD_RESET },
{ .name = "arp_halt", .value = TS_CMD_HALT },
{ .name = "arp_waitstate", .value = TS_CMD_WAITSTATE },
+ { .name = "invoke-event", .value = TS_CMD_INVOKE_EVENT },
{ .name = NULL, .value = -1 },
};
break;
case TS_CMD_EXAMINE:
if( goi.argc ){
- Jim_WrongNumArgs( goi.interp, 0, argv, "[no parameters]");
+ Jim_WrongNumArgs( goi.interp, 2, argv, "[no parameters]");
return JIM_ERR;
}
e = target->type->examine( target );
return JIM_OK;
case TS_CMD_POLL:
if( goi.argc ){
- Jim_WrongNumArgs( goi.interp, 0, argv, "[no parameters]");
+ Jim_WrongNumArgs( goi.interp, 2, argv, "[no parameters]");
return JIM_ERR;
}
if( !(target->type->examined) ){
}
break;
case TS_CMD_RESET:
- if( goi.argc != 1 ){
- Jim_WrongNumArgs( interp, 1, argv, "reset t|f|assert|deassert");
+ if( goi.argc != 2 ){
+ Jim_WrongNumArgs( interp, 2, argv, "t|f|assert|deassert BOOL");
return JIM_ERR;
}
e = Jim_GetOpt_Nvp( &goi, nvp_assert, &n );
Jim_GetOpt_NvpUnknown( &goi, nvp_assert, 1 );
return e;
}
+ // the halt or not param
+ e = Jim_GetOpt_Wide( &goi, &a);
+ if( e != JIM_OK ){
+ return e;
+ }
+ // determine if we should halt or not.
+ target->reset_halt = !!a;
// When this happens - all workareas are invalid.
target_free_all_working_areas_restore(target, 0);
return e;
}
e = target_wait_state( target, n->value, a );
- if( e == ERROR_OK ){
+ if( e != ERROR_OK ){
Jim_SetResult_sprintf( goi.interp,
- "target: %s wait %s fails %d",
+ "target: %s wait %s fails (%d) %s",
target->cmd_name,
n->name,
- target_strerror_safe(e) );
+ e, target_strerror_safe(e) );
return JIM_ERR;
} else {
return JIM_OK;
Jim_SetResultString( goi.interp,
Jim_Nvp_value2name_simple(nvp_target_state,target->state)->name,-1);
return JIM_OK;
+ case TS_CMD_INVOKE_EVENT:
+ if( goi.argc != 1 ){
+ Jim_SetResult_sprintf( goi.interp, "%s ?EVENTNAME?",n->name);
+ return JIM_ERR;
+ }
+ e = Jim_GetOpt_Nvp( &goi, nvp_target_event, &n );
+ if( e != JIM_OK ){
+ Jim_GetOpt_NvpUnknown( &goi, nvp_target_event, 1 );
+ return e;
+ }
+ target_handle_event( target, n->value );
+ return JIM_OK;
}
return JIM_ERR;
}
Jim_NewIntObj( goi.interp, max_target_number()));
return JIM_OK;
}
+
+ return JIM_ERR;
}