X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fjtag%2Fjtag.c;h=d34cec5a257b3187221eadb7b9870408ff3f2d87;hb=f370d70670bd5e30befe6fbfbc8d472e760f032b;hp=2b1a56fb8df92505e5e512dada98fa05d6ab7e5f;hpb=b06f254b248db04c71f685c811e4371ea8ae8ff3;p=fw%2Fopenocd diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index 2b1a56fb8..d34cec5a2 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -2,6 +2,9 @@ * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * + * Copyright (C) 2007,2008 Øyvind Harboe * + * oyvind.harboe@zylin.com * + * * * 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 * @@ -32,9 +35,6 @@ #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 */ @@ -143,7 +143,7 @@ int jtag_ntrst_delay = 0; /* default to no nTRST delay */ jtag_event_callback_t *jtag_event_callbacks; /* speed in kHz*/ -static int speed1 = 0, speed2 = 0; +static int speed_khz = 0; /* flag if the kHz speed was defined */ static int hasKHz = 0; @@ -243,7 +243,7 @@ jtag_interface_t *jtag = NULL; /* configuration */ jtag_interface_t *jtag_interface = NULL; int jtag_speed = 0; -int jtag_speed_post_reset = 0; + /* forward declarations */ @@ -401,7 +401,7 @@ void* cmd_queue_alloc(size_t size) return t + offset; } -void cmd_queue_free() +void cmd_queue_free(void) { cmd_queue_page_t *page = cmd_queue_pages; @@ -416,7 +416,7 @@ void cmd_queue_free() cmd_queue_pages = NULL; } -static void jtag_prelude1() +static void jtag_prelude1(void) { if (jtag_trst == 1) { @@ -764,9 +764,6 @@ void MINIDRIVER(interface_jtag_add_dr_out)(int device_num, } } - - - void jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state) { int retval; @@ -857,6 +854,11 @@ void jtag_add_pathmove(int num_states, enum tap_state *path) for (i=0; icmd.reset->trst = req_trst; (*last_cmd)->cmd.reset->srst = req_srst; - return ERROR_OK; } void jtag_add_end_state(enum tap_state state) { cmd_queue_end_state = state; - if ((cmd_queue_end_state == TAP_SD)||(cmd_queue_end_state == TAP_SD)) + if ((cmd_queue_end_state == TAP_SD)||(cmd_queue_end_state == TAP_SI)) { LOG_ERROR("BUG: TAP_SD/SI can't be end state. Calling code should use a larger scan field"); } @@ -1074,6 +1074,7 @@ int MINIDRIVER(interface_jtag_add_sleep)(u32 us) void jtag_add_sleep(u32 us) { + keep_alive(); /* we might be running on a very slow JTAG clk */ int retval=interface_jtag_add_sleep(us); if (retval!=ERROR_OK) jtag_error=retval; @@ -1122,7 +1123,6 @@ int jtag_build_buffer(scan_command_t *cmd, u8 **buffer) } return bit_count; - } int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) @@ -1366,6 +1366,8 @@ int jtag_examine_chain() /* LSB must not be 0, this indicates a device in bypass */ device_count++; + LOG_WARNING("Device was in bypass after TRST/TMS reset"); + bit_count += 1; } else @@ -1376,7 +1378,28 @@ int jtag_examine_chain() if (idcode == 0x000000FF) { - /* End of chain (invalid manufacturer ID) */ + int unexpected=0; + /* End of chain (invalid manufacturer ID) + * + * The JTAG examine is the very first thing that happens + * + * A single JTAG device requires only 64 bits to be read back correctly. + * + * The code below adds a check that the rest of the data scanned (640 bits) + * are all as expected. This helps diagnose/catch problems with the JTAG chain + * + * earlier and gives more helpful/explicit error messages. + */ + for (bit_count += 32; bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31;bit_count += 32) + { + idcode = buf_get_u32(idcode_buffer, bit_count, 32); + if (unexpected||(idcode != 0x000000FF)) + { + LOG_WARNING("Unexpected idcode after end of chain! %d 0x%08x", bit_count, idcode); + unexpected = 1; + } + } + break; } @@ -1410,7 +1433,7 @@ int jtag_examine_chain() return ERROR_OK; } -int jtag_validate_chain() +int jtag_validate_chain(void) { jtag_device_t *device = jtag_devices; int total_ir_length = 0; @@ -1475,7 +1498,7 @@ int jtag_register_commands(struct command_context_s *cmd_ctx) register_command(cmd_ctx, NULL, "interface", handle_interface_command, COMMAND_CONFIG, NULL); register_command(cmd_ctx, NULL, "jtag_speed", handle_jtag_speed_command, - COMMAND_ANY, "set jtag speed (if supported) []"); + COMMAND_ANY, "set jtag speed (if supported)"); register_command(cmd_ctx, NULL, "jtag_khz", handle_jtag_khz_command, COMMAND_ANY, "same as jtag_speed, except it takes maximum khz as arguments. 0 KHz = RTCK."); register_command(cmd_ctx, NULL, "jtag_device", handle_jtag_device_command, @@ -1498,7 +1521,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] ..."); - add_jim("drscan", Jim_Command_drscan, "execute DR scan ..."); + register_jim(cmd_ctx, "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 "); @@ -1518,9 +1541,7 @@ int jtag_interface_init(struct command_context_s *cmd_ctx) } if(hasKHz) { - /*stay on "reset speed"*/ - jtag_interface->khz(speed1, &jtag_speed); - jtag_interface->khz(speed2, &jtag_speed_post_reset); + jtag_interface->khz(speed_khz, &jtag_speed); hasKHz = 0; } @@ -1633,7 +1654,6 @@ int jtag_init(struct command_context_s *cmd_ctx) return jtag_init_reset(cmd_ctx); } - static int default_khz(int khz, int *jtag_speed) { LOG_ERROR("Translation from khz to jtag_speed not implemented"); @@ -1858,81 +1878,68 @@ int handle_jtag_ntrst_delay_command(struct command_context_s *cmd_ctx, char *cmd int handle_jtag_speed_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { - int cur_speed = 0; + int retval=ERROR_OK; - if (argc != 0) + if (argc == 1) { - if ((argc<1) || (argc>2)) - return ERROR_COMMAND_SYNTAX_ERROR; - LOG_DEBUG("handle jtag speed"); - - if (argc >= 1) - cur_speed = jtag_speed = jtag_speed_post_reset = strtoul(args[0], NULL, 0); - if (argc == 2) - cur_speed = jtag_speed_post_reset = strtoul(args[1], NULL, 0); + + int cur_speed = 0; + cur_speed = jtag_speed = strtoul(args[0], NULL, 0); /* 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); + retval=jtag->speed(cur_speed); } - } - command_print(cmd_ctx, "jtag_speed: %d, %d", jtag_speed, jtag_speed_post_reset); + } else if (argc == 0) + { + } else + { + retval=ERROR_COMMAND_SYNTAX_ERROR; + } + command_print(cmd_ctx, "jtag_speed: %d", jtag_speed); - return ERROR_OK; + return retval; } int handle_jtag_khz_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { + int retval=ERROR_OK; LOG_DEBUG("handle jtag khz"); - if (argc>2) - return ERROR_COMMAND_SYNTAX_ERROR; - - if(argc != 0) + if(argc == 1) { - - if (argc >= 1) - speed1 = speed2 = strtoul(args[0], NULL, 0); - if (argc == 2) - speed2 = strtoul(args[1], NULL, 0); - + speed_khz = strtoul(args[0], 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) + int speed_div1; + if ((retval=jtag->khz(speed_khz, &speed_div1))!=ERROR_OK) { - speed1 = speed2 = 0; - return ERROR_OK; + speed_khz = 0; + return retval; } - if (argc >= 1) - cur_speed = jtag_speed = jtag_speed_post_reset = speed_div1; - if (argc == 2) - cur_speed = jtag_speed_post_reset = speed_div2; + cur_speed = jtag_speed = speed_div1; - jtag->speed(cur_speed); + retval=jtag->speed(cur_speed); } else { hasKHz = 1; } + } else if (argc==0) + { + } else + { + retval=ERROR_COMMAND_SYNTAX_ERROR; } - command_print(cmd_ctx, "jtag_khz: %d, %d", speed1, speed2); - - return ERROR_OK; -} + command_print(cmd_ctx, "jtag_khz: %d", speed_khz); + return retval; +} int handle_endstate_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { @@ -2009,7 +2016,6 @@ int handle_runtest_command(struct command_context_s *cmd_ctx, char *cmd, char ** } - int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { int i; @@ -2053,7 +2059,7 @@ int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args) scan_field_t *fields; int num_fields; int field_count = 0; - int i, j, e; + int i, e; long device; /* args[1] = device