X-Git-Url: https://git.gag.com/?a=blobdiff_plain;ds=sidebyside;f=src%2Fjtag%2Fjtag.c;h=2b1a56fb8df92505e5e512dada98fa05d6ab7e5f;hb=b06f254b248db04c71f685c811e4371ea8ae8ff3;hp=fa439ec5a026854b04232dd13ddeeae0be4b1056;hpb=c4a2fdbc39dd31170e61e7fe0be332826825acbd;p=fw%2Fopenocd diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index fa439ec5a..2b1a56fb8 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -27,12 +27,13 @@ #include "command.h" #include "log.h" -#include "interpreter.h" #include "stdlib.h" #include "string.h" #include +#include "openocd_tcl.h" + /* note that this is not marked as static as it must be available from outside jtag.c for those that implement the jtag_xxx() minidriver layer @@ -106,7 +107,7 @@ tap_transition_t tap_transitions[16] = char* jtag_event_strings[] = { - "JTAG controller reset(tms or TRST)" + "JTAG controller reset (TLR or TRST)" }; /* kludge!!!! these are just global variables that the @@ -156,7 +157,11 @@ static int hasKHz = 0; #if BUILD_PARPORT == 1 extern jtag_interface_t parport_interface; #endif - + +#if BUILD_DUMMY == 1 + extern jtag_interface_t dummy_interface; +#endif + #if BUILD_FT2232_FTD2XX == 1 extern jtag_interface_t ft2232_interface; #endif @@ -189,6 +194,10 @@ static int hasKHz = 0; extern jtag_interface_t usbprog_interface; #endif +#if BUILD_JLINK == 1 + extern jtag_interface_t jlink_interface; +#endif + jtag_interface_t *jtag_interfaces[] = { #if BUILD_ECOSBOARD == 1 &eCosBoard_interface, @@ -196,6 +205,9 @@ jtag_interface_t *jtag_interfaces[] = { #if BUILD_PARPORT == 1 &parport_interface, #endif +#if BUILD_DUMMY == 1 + &dummy_interface, +#endif #if BUILD_FT2232_FTD2XX == 1 &ft2232_interface, #endif @@ -219,6 +231,9 @@ jtag_interface_t *jtag_interfaces[] = { #endif #if BUILD_USBPROG == 1 &usbprog_interface, +#endif +#if BUILD_JLINK == 1 + &jlink_interface, #endif NULL, }; @@ -254,7 +269,7 @@ int handle_endstate_command(struct command_context_s *cmd_ctx, char *cmd, char * int handle_jtag_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int handle_runtest_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -int handle_drscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); +int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *argv); int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); @@ -588,6 +603,11 @@ int MINIDRIVER(interface_jtag_add_dr_scan)(int num_fields, scan_field_t *fields, bypass_devices++; device = device->next; } + if (bypass_devices >= jtag_num_devices) + { + LOG_ERROR("all devices in bypass"); + return ERROR_JTAG_DEVICE_ERROR; + } /* allocate memory for a new list member */ *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t)); @@ -660,8 +680,8 @@ int MINIDRIVER(interface_jtag_add_dr_scan)(int num_fields, scan_field_t *fields, void MINIDRIVER(interface_jtag_add_dr_out)(int device_num, int num_fields, - int *num_bits, - u32 *value, + const int *num_bits, + const u32 *value, enum tap_state end_state) { int i; @@ -913,18 +933,18 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst) /* FIX!!! there are *many* different cases here. A better * approach is needed for legal combinations of transitions... - */ + */ if ((jtag_reset_config & RESET_HAS_SRST)&& (jtag_reset_config & RESET_HAS_TRST)&& - ((jtag_reset_config & RESET_SRST_PULLS_TRST)==0)&& - ((jtag_reset_config & RESET_TRST_PULLS_SRST)==0)) + ((jtag_reset_config & RESET_SRST_PULLS_TRST)==0)) { if (((req_tlr_or_trst&&!jtag_trst)|| (!req_tlr_or_trst&&jtag_trst))&& ((req_srst&&!jtag_srst)|| (!req_srst&&jtag_srst))) { - LOG_ERROR("BUG: transition of req_tlr_or_trst and req_srst in the same jtag_add_reset() call is undefined"); + /* FIX!!! srst_pulls_trst allows 1,1 => 0,0 transition.... */ + //LOG_ERROR("BUG: transition of req_tlr_or_trst and req_srst in the same jtag_add_reset() call is undefined"); } } @@ -986,7 +1006,7 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst) if (trst_with_tlr) { - LOG_DEBUG("JTAG reset with tms instead of TRST"); + LOG_DEBUG("JTAG reset with TLR instead of TRST"); jtag_add_end_state(TAP_TLR); jtag_add_tlr(); jtag_call_event_callbacks(JTAG_TRST_ASSERTED); @@ -1222,7 +1242,7 @@ void jtag_set_check_value(scan_field_t *field, u8 *value, u8 *mask, error_handle field->in_handler = jtag_check_value; else field->in_handler = NULL; /* No check, e.g. embeddedice uses value==NULL to indicate no check */ - field->in_handler_priv = NULL; /* this will be filled in at the invocation site to point to the field duplicate */ + field->in_handler_priv = NULL; field->in_check_value = value; field->in_check_mask = mask; } @@ -1246,7 +1266,13 @@ enum scan_type jtag_scan_type(scan_command_t *cmd) int MINIDRIVER(interface_jtag_execute_queue)(void) { int retval; - + + if (jtag==NULL) + { + LOG_ERROR("No JTAG interface configured yet. Issue 'init' command in startup scripts before communicating with targets."); + return ERROR_FAIL; + } + retval = jtag->execute_queue(); cmd_queue_free(); @@ -1472,8 +1498,7 @@ int jtag_register_commands(struct command_context_s *cmd_ctx) COMMAND_EXEC, "move to Run-Test/Idle, and execute "); register_command(cmd_ctx, NULL, "irscan", handle_irscan_command, COMMAND_EXEC, "execute IR scan [dev2] [instr2] ..."); - register_command(cmd_ctx, NULL, "drscan", handle_drscan_command, - COMMAND_EXEC, "execute DR scan [dev2] [var2] ..."); + add_jim("drscan", Jim_Command_drscan, "execute DR scan ..."); register_command(cmd_ctx, NULL, "verify_ircapture", handle_verify_ircapture_command, COMMAND_ANY, "verify value captured during Capture-IR "); @@ -1494,10 +1519,8 @@ int jtag_interface_init(struct command_context_s *cmd_ctx) if(hasKHz) { /*stay on "reset speed"*/ - if (jtag_interface->khz(speed1, &speed1) == ERROR_OK) - jtag_speed = speed1; - if (jtag_interface->khz(speed2, &speed2) == ERROR_OK) - jtag_speed_post_reset = speed2; + jtag_interface->khz(speed1, &jtag_speed); + jtag_interface->khz(speed2, &jtag_speed_post_reset); hasKHz = 0; } @@ -1516,11 +1539,8 @@ static int jtag_init_inner(struct command_context_s *cmd_ctx) jtag_device_t *device; int retval; - LOG_DEBUG("-"); + LOG_DEBUG("Init JTAG chain"); - if ((retval=jtag_interface_init(cmd_ctx)) != ERROR_OK) - return retval; - device = jtag_devices; jtag_ir_scan_size = 0; jtag_num_devices = 0; @@ -1532,7 +1552,7 @@ static int jtag_init_inner(struct command_context_s *cmd_ctx) } jtag_add_tlr(); - if ((retval=jtag_execute_queue())==ERROR_OK) + if ((retval=jtag_execute_queue())!=ERROR_OK) return retval; /* examine chain first, as this could discover the real chain layout */ @@ -1559,11 +1579,15 @@ static int jtag_init_inner(struct command_context_s *cmd_ctx) int jtag_init_reset(struct command_context_s *cmd_ctx) { int retval; - LOG_DEBUG("Trying to bring the JTAG controller to life by asserting TRST / tms"); + + if ((retval=jtag_interface_init(cmd_ctx)) != ERROR_OK) + return retval; + + LOG_DEBUG("Trying to bring the JTAG controller to life by asserting TRST / TLR"); /* Reset can happen after a power cycle. * - * Ideally we would only assert TRST or run tms before the target reset. + * Ideally we would only assert TRST or run TLR before the target reset. * * However w/srst_pulls_trst, trst is asserted together with the target * reset whether we want it or not. @@ -1576,7 +1600,7 @@ int jtag_init_reset(struct command_context_s *cmd_ctx) * NB! order matters!!!! srst *can* disconnect JTAG circuitry * */ - jtag_add_reset(1, 0); /* TMS or TRST */ + jtag_add_reset(1, 0); /* TLR or TRST */ if (jtag_reset_config & RESET_HAS_SRST) { jtag_add_reset(1, 1); @@ -1599,6 +1623,9 @@ int jtag_init_reset(struct command_context_s *cmd_ctx) int jtag_init(struct command_context_s *cmd_ctx) { + int retval; + if ((retval=jtag_interface_init(cmd_ctx)) != ERROR_OK) + return retval; if (jtag_init_inner(cmd_ctx)==ERROR_OK) { return ERROR_OK; @@ -1613,6 +1640,11 @@ static int default_khz(int khz, int *jtag_speed) return ERROR_FAIL; } +static int default_speed_div(int speed, int *khz) +{ + return ERROR_FAIL; +} + int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { int i; @@ -1643,6 +1675,10 @@ int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char { jtag_interface->khz = default_khz; } + if (jtag_interface->speed_div == NULL) + { + jtag_interface->speed_div = default_speed_div; + } return ERROR_OK; } } @@ -1839,7 +1875,11 @@ int handle_jtag_speed_command(struct command_context_s *cmd_ctx, char *cmd, char /* this command can be called during CONFIG, * in which case jtag isn't initialized */ if (jtag) + { + jtag->speed_div(jtag_speed, &speed1); + jtag->speed_div(jtag_speed_post_reset, &speed2); jtag->speed(cur_speed); + } } command_print(cmd_ctx, "jtag_speed: %d, %d", jtag_speed, jtag_speed_post_reset); @@ -1850,34 +1890,45 @@ int handle_jtag_khz_command(struct command_context_s *cmd_ctx, char *cmd, char * { LOG_DEBUG("handle jtag khz"); - if ((argc<1) || (argc>2)) + if (argc>2) return ERROR_COMMAND_SYNTAX_ERROR; - if (argc >= 1) - speed1 = speed2 = strtoul(args[0], NULL, 0); - if (argc == 2) - speed2 = strtoul(args[1], NULL, 0); - - if (jtag != NULL) + if(argc != 0) { - int cur_speed = 0; - LOG_DEBUG("have interface set up"); - int speed_div1, speed_div2; - if (jtag->khz(speed1, &speed_div1)!=ERROR_OK) - return ERROR_OK; - if (jtag->khz(speed2, &speed_div2)!=ERROR_OK) - return ERROR_OK; - + if (argc >= 1) - cur_speed = jtag_speed = jtag_speed_post_reset = speed_div1; + speed1 = speed2 = strtoul(args[0], NULL, 0); if (argc == 2) - cur_speed = jtag_speed_post_reset = speed_div2; - - jtag->speed(cur_speed); - } else - { - hasKHz = 1; + speed2 = strtoul(args[1], NULL, 0); + + if (jtag != NULL) + { + int cur_speed = 0; + LOG_DEBUG("have interface set up"); + int speed_div1, speed_div2; + if (jtag->khz(speed1, &speed_div1)!=ERROR_OK) + { + speed1 = speed2 = 0; + return ERROR_OK; + } + if (jtag->khz(speed2, &speed_div2)!=ERROR_OK) + { + speed1 = speed2 = 0; + return ERROR_OK; + } + + if (argc >= 1) + cur_speed = jtag_speed = jtag_speed_post_reset = speed_div1; + if (argc == 2) + cur_speed = jtag_speed_post_reset = speed_div2; + + jtag->speed(cur_speed); + } else + { + hasKHz = 1; + } } + command_print(cmd_ctx, "jtag_khz: %d, %d", speed1, speed2); return ERROR_OK; } @@ -1996,63 +2047,92 @@ int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **a return ERROR_OK; } -int handle_drscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args) { + int retval; scan_field_t *fields; - int num_fields = 0; + int num_fields; int field_count = 0; - var_t *var; - int i, j; - - if ((argc < 2) || (argc % 2)) + int i, j, e; + long device; + + /* args[1] = device + * args[2] = num_bits + * args[3] = hex string + * ... repeat num bits and hex string ... + */ + if ((argc < 4) || ((argc % 2)!=0)) { - return ERROR_COMMAND_SYNTAX_ERROR; + Jim_WrongNumArgs(interp, 1, args, "wrong arguments"); + return JIM_ERR; } - for (i = 0; i < argc; i+=2) + for (i = 2; i < argc; i+=2) { - var = get_var_by_namenum(args[i+1]); - if (var) - { - num_fields += var->num_fields; - } - else - { - command_print(cmd_ctx, "variable %s doesn't exist", args[i+1]); - return ERROR_OK; - } + long bits; + + e = Jim_GetLong(interp, args[i], &bits); + if (e != JIM_OK) + return e; } - fields = malloc(sizeof(scan_field_t) * num_fields); + e = Jim_GetLong(interp, args[1], &device); + if (e != JIM_OK) + return e; - for (i = 0; i < argc; i+=2) + num_fields=(argc-2)/2; + fields = malloc(sizeof(scan_field_t) * num_fields); + for (i = 2; i < argc; i+=2) { - var = get_var_by_namenum(args[i+1]); - - for (j = 0; j < var->num_fields; j++) - { - fields[field_count].device = strtol(args[i], NULL, 0); - fields[field_count].num_bits = var->fields[j].num_bits; - fields[field_count].out_value = malloc(CEIL(var->fields[j].num_bits, 8)); - buf_set_u32(fields[field_count].out_value, 0, var->fields[j].num_bits, var->fields[j].value); - fields[field_count].out_mask = NULL; - fields[field_count].in_value = fields[field_count].out_value; - fields[field_count].in_check_mask = NULL; - fields[field_count].in_check_value = NULL; - fields[field_count].in_handler = field_le_to_host; - fields[field_count++].in_handler_priv = &(var->fields[j]); - } + long bits; + int len; + const char *str; + + Jim_GetLong(interp, args[i], &bits); + str = Jim_GetString(args[i+1], &len); + + fields[field_count].device = device; + fields[field_count].num_bits = bits; + fields[field_count].out_value = malloc(CEIL(bits, 8)); + str_to_buf(str, len, fields[field_count].out_value, bits, 0); + fields[field_count].out_mask = NULL; + fields[field_count].in_value = fields[field_count].out_value; + fields[field_count].in_check_mask = NULL; + fields[field_count].in_check_value = NULL; + fields[field_count].in_handler = NULL; + fields[field_count++].in_handler_priv = NULL; } jtag_add_dr_scan(num_fields, fields, -1); - jtag_execute_queue(); - - for (i = 0; i < argc / 2; i++) - free(fields[i].out_value); + retval = jtag_execute_queue(); + if (retval != ERROR_OK) + { + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings(interp, Jim_GetResult(interp), "drscan: jtag execute failed", NULL); + return JIM_ERR; + } + + field_count=0; + Jim_Obj *list = Jim_NewListObj(interp, NULL, 0); + for (i = 2; i < argc; i+=2) + { + long bits; + char *str; + Jim_GetLong(interp, args[i], &bits); + str = buf_to_str(fields[field_count].in_value, bits, 16); + free(fields[field_count].out_value); + + Jim_ListAppendElement(interp, list, Jim_NewStringObj(interp, str, strlen(str))); + free(str); + field_count++; + } + + Jim_SetResult(interp, list); + free(fields); - return ERROR_OK; + return JIM_OK; } int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)