diff options
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | doc/openocd.texi | 6 | ||||
-rw-r--r-- | src/jtag/Makefile.am | 1 | ||||
-rw-r--r-- | src/jtag/adapter.c | 459 | ||||
-rw-r--r-- | src/jtag/startup.tcl | 2 | ||||
-rw-r--r-- | src/jtag/tcl.c | 434 |
6 files changed, 471 insertions, 434 deletions
@@ -6,9 +6,10 @@ and other issues not mentioned here. JTAG Layer: New driver for "Bus Pirate" Rename various commands so they're not JTAG-specific - There are migration procedures for these, but you should + There are migration procedures for most of these, but you should convert your scripts to the new names, since those procedures will not be around forever. + jtag jinterface ... is now adapter_name jtag_khz ... is now adapter_khz jtag_nsrst_delay ... is now adapter_nsrst_delay jtag_nsrst_assert_width ... is now adapter_nsrst_assert_width diff --git a/doc/openocd.texi b/doc/openocd.texi index 83a6369c..bb8f3abb 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2093,12 +2093,12 @@ target. @end deffn @deffn Command {interface_list} -List the interface drivers that have been built into +List the debug adapter drivers that have been built into the running copy of OpenOCD. @end deffn -@deffn Command {jtag interface} -Returns the name of the interface driver being used. +@deffn Command {adapter_name} +Returns the name of the debug adapter driver being used. @end deffn @section Interface Drivers diff --git a/src/jtag/Makefile.am b/src/jtag/Makefile.am index 3f132d47..875fbcb6 100644 --- a/src/jtag/Makefile.am +++ b/src/jtag/Makefile.am @@ -53,6 +53,7 @@ minidriver_imp.h: $(MINIDRIVER_IMP_DIR)/minidriver_imp.h libjtag_la_SOURCES = \ + adapter.c \ core.c \ interface.c \ interfaces.c \ diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c new file mode 100644 index 00000000..b262a9a7 --- /dev/null +++ b/src/jtag/adapter.c @@ -0,0 +1,459 @@ +/*************************************************************************** + * Copyright (C) 2005 by Dominic Rath * + * Dominic.Rath@gmx.de * + * * + * Copyright (C) 2007-2010 Øyvind Harboe * + * oyvind.harboe@zylin.com * + * * + * Copyright (C) 2009 SoftPLC Corporation * + * http://softplc.com * + * dick@softplc.com * + * * + * Copyright (C) 2009 Zachary T Welch * + * zw@superlucidity.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 * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "jtag.h" +#include "minidriver.h" +#include "interface.h" +#include "interfaces.h" + +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif + +/** + * @file + * Holds support for configuring debug adapters from TCl scripts. + */ + +extern struct jtag_interface *jtag_interface; + + + +static int +jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + Jim_GetOptInfo goi; + Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); + + /* 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; + } + const char *name = jtag_interface ? jtag_interface->name : NULL; + Jim_SetResultString(goi.interp, name ? : "undefined", -1); + return JIM_OK; +} + + +static int default_khz(int khz, int *jtag_speed) +{ + LOG_ERROR("Translation from khz to jtag_speed not implemented"); + return ERROR_FAIL; +} + +static int default_speed_div(int speed, int *khz) +{ + LOG_ERROR("Translation from jtag_speed to khz not implemented"); + return ERROR_FAIL; +} + +static int default_power_dropout(int *dropout) +{ + *dropout = 0; /* by default we can't detect power dropout */ + return ERROR_OK; +} + +static int default_srst_asserted(int *srst_asserted) +{ + *srst_asserted = 0; /* by default we can't detect srst asserted */ + return ERROR_OK; +} + +COMMAND_HANDLER(handle_interface_list_command) +{ + if (strcmp(CMD_NAME, "interface_list") == 0 && CMD_ARGC > 0) + return ERROR_COMMAND_SYNTAX_ERROR; + + command_print(CMD_CTX, "The following debug interfaces are available:"); + for (unsigned i = 0; NULL != jtag_interfaces[i]; i++) + { + const char *name = jtag_interfaces[i]->name; + command_print(CMD_CTX, "%u: %s", i + 1, name); + } + + return ERROR_OK; +} + +COMMAND_HANDLER(handle_interface_command) +{ + /* check whether the interface is already configured */ + if (jtag_interface) + { + LOG_WARNING("Interface already configured, ignoring"); + return ERROR_OK; + } + + /* interface name is a mandatory argument */ + if (CMD_ARGC != 1 || CMD_ARGV[0][0] == '\0') + return ERROR_COMMAND_SYNTAX_ERROR; + + for (unsigned i = 0; NULL != jtag_interfaces[i]; i++) + { + if (strcmp(CMD_ARGV[0], jtag_interfaces[i]->name) != 0) + continue; + + if (NULL != jtag_interfaces[i]->commands) + { + int retval = register_commands(CMD_CTX, NULL, + jtag_interfaces[i]->commands); + if (ERROR_OK != retval) + return retval; + } + + jtag_interface = jtag_interfaces[i]; + + if (jtag_interface->khz == NULL) + jtag_interface->khz = default_khz; + if (jtag_interface->speed_div == NULL) + jtag_interface->speed_div = default_speed_div; + if (jtag_interface->power_dropout == NULL) + jtag_interface->power_dropout = default_power_dropout; + if (jtag_interface->srst_asserted == NULL) + jtag_interface->srst_asserted = default_srst_asserted; + + return ERROR_OK; + } + + /* no valid interface was found (i.e. the configuration option, + * didn't match one of the compiled-in interfaces + */ + LOG_ERROR("The specified debug interface was not found (%s)", CMD_ARGV[0]); + CALL_COMMAND_HANDLER(handle_interface_list_command); + return ERROR_JTAG_INVALID_INTERFACE; +} + +COMMAND_HANDLER(handle_reset_config_command) +{ + int new_cfg = 0; + int mask = 0; + + /* Original versions cared about the order of these tokens: + * reset_config signals [combination [trst_type [srst_type]]] + * They also clobbered the previous configuration even on error. + * + * Here we don't care about the order, and only change values + * which have been explicitly specified. + */ + for (; CMD_ARGC; CMD_ARGC--, CMD_ARGV++) { + int tmp = 0; + int m; + + /* gating */ + m = RESET_SRST_NO_GATING; + if (strcmp(*CMD_ARGV, "srst_gates_jtag") == 0) + /* default: don't use JTAG while SRST asserted */; + else if (strcmp(*CMD_ARGV, "srst_nogate") == 0) + tmp = RESET_SRST_NO_GATING; + else + m = 0; + if (mask & m) { + LOG_ERROR("extra reset_config %s spec (%s)", + "gating", *CMD_ARGV); + return ERROR_INVALID_ARGUMENTS; + } + if (m) + goto next; + + /* signals */ + m = RESET_HAS_TRST | RESET_HAS_SRST; + if (strcmp(*CMD_ARGV, "none") == 0) + tmp = RESET_NONE; + else if (strcmp(*CMD_ARGV, "trst_only") == 0) + tmp = RESET_HAS_TRST; + else if (strcmp(*CMD_ARGV, "srst_only") == 0) + tmp = RESET_HAS_SRST; + else if (strcmp(*CMD_ARGV, "trst_and_srst") == 0) + tmp = RESET_HAS_TRST | RESET_HAS_SRST; + else + m = 0; + if (mask & m) { + LOG_ERROR("extra reset_config %s spec (%s)", + "signal", *CMD_ARGV); + return ERROR_INVALID_ARGUMENTS; + } + if (m) + goto next; + + /* combination (options for broken wiring) */ + m = RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST; + if (strcmp(*CMD_ARGV, "separate") == 0) + /* separate reset lines - default */; + else if (strcmp(*CMD_ARGV, "srst_pulls_trst") == 0) + tmp |= RESET_SRST_PULLS_TRST; + else if (strcmp(*CMD_ARGV, "trst_pulls_srst") == 0) + tmp |= RESET_TRST_PULLS_SRST; + else if (strcmp(*CMD_ARGV, "combined") == 0) + tmp |= RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST; + else + m = 0; + if (mask & m) { + LOG_ERROR("extra reset_config %s spec (%s)", + "combination", *CMD_ARGV); + return ERROR_INVALID_ARGUMENTS; + } + if (m) + goto next; + + /* trst_type (NOP without HAS_TRST) */ + m = RESET_TRST_OPEN_DRAIN; + if (strcmp(*CMD_ARGV, "trst_open_drain") == 0) + tmp |= RESET_TRST_OPEN_DRAIN; + else if (strcmp(*CMD_ARGV, "trst_push_pull") == 0) + /* push/pull from adapter - default */; + else + m = 0; + if (mask & m) { + LOG_ERROR("extra reset_config %s spec (%s)", + "trst_type", *CMD_ARGV); + return ERROR_INVALID_ARGUMENTS; + } + if (m) + goto next; + + /* srst_type (NOP without HAS_SRST) */ + m |= RESET_SRST_PUSH_PULL; + if (strcmp(*CMD_ARGV, "srst_push_pull") == 0) + tmp |= RESET_SRST_PUSH_PULL; + else if (strcmp(*CMD_ARGV, "srst_open_drain") == 0) + /* open drain from adapter - default */; + else + m = 0; + if (mask & m) { + LOG_ERROR("extra reset_config %s spec (%s)", + "srst_type", *CMD_ARGV); + return ERROR_INVALID_ARGUMENTS; + } + if (m) + goto next; + + /* caller provided nonsense; fail */ + LOG_ERROR("unknown reset_config flag (%s)", *CMD_ARGV); + return ERROR_INVALID_ARGUMENTS; + +next: + /* Remember the bits which were specified (mask) + * and their new values (new_cfg). + */ + mask |= m; + new_cfg |= tmp; + } + + /* clear previous values of those bits, save new values */ + if (mask) { + int old_cfg = jtag_get_reset_config(); + + old_cfg &= ~mask; + new_cfg |= old_cfg; + jtag_set_reset_config(new_cfg); + } else + new_cfg = jtag_get_reset_config(); + + + /* + * Display the (now-)current reset mode + */ + char *modes[5]; + + /* minimal JTAG has neither SRST nor TRST (so that's the default) */ + switch (new_cfg & (RESET_HAS_TRST | RESET_HAS_SRST)) { + case RESET_HAS_SRST: + modes[0] = "srst_only"; + break; + case RESET_HAS_TRST: + modes[0] = "trst_only"; + break; + case RESET_TRST_AND_SRST: + modes[0] = "trst_and_srst"; + break; + default: + modes[0] = "none"; + break; + } + + /* normally SRST and TRST are decoupled; but bugs happen ... */ + switch (new_cfg & (RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST)) { + case RESET_SRST_PULLS_TRST: + modes[1] = "srst_pulls_trst"; + break; + case RESET_TRST_PULLS_SRST: + modes[1] = "trst_pulls_srst"; + break; + case RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST: + modes[1] = "combined"; + break; + default: + modes[1] = "separate"; + break; + } + + /* TRST-less connectors include Altera, Xilinx, and minimal JTAG */ + if (new_cfg & RESET_HAS_TRST) { + if (new_cfg & RESET_TRST_OPEN_DRAIN) + modes[3] = " trst_open_drain"; + else + modes[3] = " trst_push_pull"; + } else + modes[3] = ""; + + /* SRST-less connectors include TI-14, Xilinx, and minimal JTAG */ + if (new_cfg & RESET_HAS_SRST) { + if (new_cfg & RESET_SRST_NO_GATING) + modes[2] = " srst_nogate"; + else + modes[2] = " srst_gates_jtag"; + + if (new_cfg & RESET_SRST_PUSH_PULL) + modes[4] = " srst_push_pull"; + else + modes[4] = " srst_open_drain"; + } else { + modes[2] = ""; + modes[4] = ""; + } + + command_print(CMD_CTX, "%s %s%s%s%s", + modes[0], modes[1], + modes[2], modes[3], modes[4]); + + return ERROR_OK; +} + +COMMAND_HANDLER(handle_adapter_nsrst_delay_command) +{ + if (CMD_ARGC > 1) + return ERROR_COMMAND_SYNTAX_ERROR; + if (CMD_ARGC == 1) + { + unsigned delay; + COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay); + + jtag_set_nsrst_delay(delay); + } + command_print(CMD_CTX, "adapter_nsrst_delay: %u", jtag_get_nsrst_delay()); + return ERROR_OK; +} + +COMMAND_HANDLER(handle_adapter_khz_command) +{ + if (CMD_ARGC > 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + int retval = ERROR_OK; + if (CMD_ARGC == 1) + { + unsigned khz = 0; + COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], khz); + + retval = jtag_config_khz(khz); + if (ERROR_OK != retval) + return retval; + } + + int cur_speed = jtag_get_speed_khz(); + retval = jtag_get_speed_readable(&cur_speed); + if (ERROR_OK != retval) + return retval; + + if (cur_speed) + command_print(CMD_CTX, "%d kHz", cur_speed); + else + command_print(CMD_CTX, "RCLK - adaptive"); + + return retval; +} + +static const struct command_registration interface_command_handlers[] = { + { + .name = "adapter_khz", + .handler = handle_adapter_khz_command, + .mode = COMMAND_ANY, + .help = "With an argument, change to the specified maximum " + "jtag speed. For JTAG, 0 KHz signifies adaptive " + " clocking. " + "With or without argument, display current setting.", + .usage = "[khz]", + }, + { + .name = "adapter_name", + .mode = COMMAND_ANY, + .jim_handler = jim_adapter_name, + .help = "Returns the name of the currently " + "selected adapter (driver)", + }, + { + .name = "adapter_nsrst_delay", + .handler = handle_adapter_nsrst_delay_command, + .mode = COMMAND_ANY, + .help = "delay after deasserting SRST in ms", + .usage = "[milliseconds]", + }, + { + .name = "interface", + .handler = handle_interface_command, + .mode = COMMAND_CONFIG, + .help = "Select a debug adapter interface (driver)", + .usage = "driver_name", + }, + { + .name = "interface_list", + .handler = handle_interface_list_command, + .mode = COMMAND_ANY, + .help = "List all built-in debug adapter interfaces (drivers)", + }, + { + .name = "reset_config", + .handler = handle_reset_config_command, + .mode = COMMAND_ANY, + .help = "configure adapter reset behavior", + .usage = "[none|trst_only|srst_only|trst_and_srst] " + "[srst_pulls_trst|trst_pulls_srst|combined|separate] " + "[srst_gates_jtag|srst_nogate] " + "[trst_push_pull|trst_open_drain] " + "[srst_push_pull|srst_open_drain]", + }, + COMMAND_REGISTRATION_DONE +}; + +/** + * Register the commands which deal with arbitrary debug adapter drivers. + * + * @todo Remove internal assumptions that all debug adapters use JTAG for + * transport. Various types and data structures are not named generically. + */ +int interface_register_commands(struct command_context *ctx) +{ + return register_commands(ctx, NULL, interface_command_handlers); +} diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index 3a36886d..496fdc82 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -78,7 +78,7 @@ proc srst_asserted {} { # BEGIN MIGRATION AIDS ... these adapter operations originally had # JTAG-specific names despite the fact that the operations were not -# specific to JTAG. +# specific to JTAG, or otherewise had troublesome/misleading names. # # FIXME phase these aids out after about April 2011 # diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index 25516cf9..7dc7fb7c 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -40,6 +40,11 @@ #include <strings.h> #endif +/** + * @file + * Holds support for accessing JTAG-specific mechanisms from TCl scripts. + */ + static const Jim_Nvp nvp_jtag_tap_event[] = { { .value = JTAG_TRST_ASSERTED, .name = "post-reset" }, { .value = JTAG_TAP_EVENT_SETUP, .name = "setup" }, @@ -671,24 +676,6 @@ static void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e) } } -static int -jim_jtag_interface(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); - - /* 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; - } - const char *name = jtag_interface ? jtag_interface->name : NULL; - Jim_SetResultString(goi.interp, name ? : "undefined", -1); - return JIM_OK; -} - static int jim_jtag_arp_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { Jim_GetOptInfo goi; @@ -863,12 +850,6 @@ static const struct command_registration jtag_subcommand_handlers[] = { .help = "initialize jtag scan chain", }, { - .name = "interface", - .mode = COMMAND_ANY, - .jim_handler = jim_jtag_interface, - .help = "Returns the name of the currently selected interface.", - }, - { .name = "arp_init", .mode = COMMAND_ANY, .jim_handler = jim_jtag_arp_init, @@ -957,93 +938,6 @@ void jtag_notify_event(enum jtag_event event) } -static int default_khz(int khz, int *jtag_speed) -{ - LOG_ERROR("Translation from khz to jtag_speed not implemented"); - return ERROR_FAIL; -} - -static int default_speed_div(int speed, int *khz) -{ - LOG_ERROR("Translation from jtag_speed to khz not implemented"); - return ERROR_FAIL; -} - -static int default_power_dropout(int *dropout) -{ - *dropout = 0; /* by default we can't detect power dropout */ - return ERROR_OK; -} - -static int default_srst_asserted(int *srst_asserted) -{ - *srst_asserted = 0; /* by default we can't detect srst asserted */ - return ERROR_OK; -} - -COMMAND_HANDLER(handle_interface_list_command) -{ - if (strcmp(CMD_NAME, "interface_list") == 0 && CMD_ARGC > 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - command_print(CMD_CTX, "The following debug interfaces are available:"); - for (unsigned i = 0; NULL != jtag_interfaces[i]; i++) - { - const char *name = jtag_interfaces[i]->name; - command_print(CMD_CTX, "%u: %s", i + 1, name); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_interface_command) -{ - /* check whether the interface is already configured */ - if (jtag_interface) - { - LOG_WARNING("Interface already configured, ignoring"); - return ERROR_OK; - } - - /* interface name is a mandatory argument */ - if (CMD_ARGC != 1 || CMD_ARGV[0][0] == '\0') - return ERROR_COMMAND_SYNTAX_ERROR; - - for (unsigned i = 0; NULL != jtag_interfaces[i]; i++) - { - if (strcmp(CMD_ARGV[0], jtag_interfaces[i]->name) != 0) - continue; - - if (NULL != jtag_interfaces[i]->commands) - { - int retval = register_commands(CMD_CTX, NULL, - jtag_interfaces[i]->commands); - if (ERROR_OK != retval) - return retval; - } - - jtag_interface = jtag_interfaces[i]; - - if (jtag_interface->khz == NULL) - jtag_interface->khz = default_khz; - if (jtag_interface->speed_div == NULL) - jtag_interface->speed_div = default_speed_div; - if (jtag_interface->power_dropout == NULL) - jtag_interface->power_dropout = default_power_dropout; - if (jtag_interface->srst_asserted == NULL) - jtag_interface->srst_asserted = default_srst_asserted; - - return ERROR_OK; - } - - /* no valid interface was found (i.e. the configuration option, - * didn't match one of the compiled-in interfaces - */ - LOG_ERROR("The specified debug interface was not found (%s)", CMD_ARGV[0]); - CALL_COMMAND_HANDLER(handle_interface_list_command); - return ERROR_JTAG_INVALID_INTERFACE; -} - COMMAND_HANDLER(handle_scan_chain_command) { struct jtag_tap *tap; @@ -1096,217 +990,6 @@ COMMAND_HANDLER(handle_scan_chain_command) return ERROR_OK; } -COMMAND_HANDLER(handle_reset_config_command) -{ - int new_cfg = 0; - int mask = 0; - - /* Original versions cared about the order of these tokens: - * reset_config signals [combination [trst_type [srst_type]]] - * They also clobbered the previous configuration even on error. - * - * Here we don't care about the order, and only change values - * which have been explicitly specified. - */ - for (; CMD_ARGC; CMD_ARGC--, CMD_ARGV++) { - int tmp = 0; - int m; - - /* gating */ - m = RESET_SRST_NO_GATING; - if (strcmp(*CMD_ARGV, "srst_gates_jtag") == 0) - /* default: don't use JTAG while SRST asserted */; - else if (strcmp(*CMD_ARGV, "srst_nogate") == 0) - tmp = RESET_SRST_NO_GATING; - else - m = 0; - if (mask & m) { - LOG_ERROR("extra reset_config %s spec (%s)", - "gating", *CMD_ARGV); - return ERROR_INVALID_ARGUMENTS; - } - if (m) - goto next; - - /* signals */ - m = RESET_HAS_TRST | RESET_HAS_SRST; - if (strcmp(*CMD_ARGV, "none") == 0) - tmp = RESET_NONE; - else if (strcmp(*CMD_ARGV, "trst_only") == 0) - tmp = RESET_HAS_TRST; - else if (strcmp(*CMD_ARGV, "srst_only") == 0) - tmp = RESET_HAS_SRST; - else if (strcmp(*CMD_ARGV, "trst_and_srst") == 0) - tmp = RESET_HAS_TRST | RESET_HAS_SRST; - else - m = 0; - if (mask & m) { - LOG_ERROR("extra reset_config %s spec (%s)", - "signal", *CMD_ARGV); - return ERROR_INVALID_ARGUMENTS; - } - if (m) - goto next; - - /* combination (options for broken wiring) */ - m = RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST; - if (strcmp(*CMD_ARGV, "separate") == 0) - /* separate reset lines - default */; - else if (strcmp(*CMD_ARGV, "srst_pulls_trst") == 0) - tmp |= RESET_SRST_PULLS_TRST; - else if (strcmp(*CMD_ARGV, "trst_pulls_srst") == 0) - tmp |= RESET_TRST_PULLS_SRST; - else if (strcmp(*CMD_ARGV, "combined") == 0) - tmp |= RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST; - else - m = 0; - if (mask & m) { - LOG_ERROR("extra reset_config %s spec (%s)", - "combination", *CMD_ARGV); - return ERROR_INVALID_ARGUMENTS; - } - if (m) - goto next; - - /* trst_type (NOP without HAS_TRST) */ - m = RESET_TRST_OPEN_DRAIN; - if (strcmp(*CMD_ARGV, "trst_open_drain") == 0) - tmp |= RESET_TRST_OPEN_DRAIN; - else if (strcmp(*CMD_ARGV, "trst_push_pull") == 0) - /* push/pull from adapter - default */; - else - m = 0; - if (mask & m) { - LOG_ERROR("extra reset_config %s spec (%s)", - "trst_type", *CMD_ARGV); - return ERROR_INVALID_ARGUMENTS; - } - if (m) - goto next; - - /* srst_type (NOP without HAS_SRST) */ - m |= RESET_SRST_PUSH_PULL; - if (strcmp(*CMD_ARGV, "srst_push_pull") == 0) - tmp |= RESET_SRST_PUSH_PULL; - else if (strcmp(*CMD_ARGV, "srst_open_drain") == 0) - /* open drain from adapter - default */; - else - m = 0; - if (mask & m) { - LOG_ERROR("extra reset_config %s spec (%s)", - "srst_type", *CMD_ARGV); - return ERROR_INVALID_ARGUMENTS; - } - if (m) - goto next; - - /* caller provided nonsense; fail */ - LOG_ERROR("unknown reset_config flag (%s)", *CMD_ARGV); - return ERROR_INVALID_ARGUMENTS; - -next: - /* Remember the bits which were specified (mask) - * and their new values (new_cfg). - */ - mask |= m; - new_cfg |= tmp; - } - - /* clear previous values of those bits, save new values */ - if (mask) { - int old_cfg = jtag_get_reset_config(); - - old_cfg &= ~mask; - new_cfg |= old_cfg; - jtag_set_reset_config(new_cfg); - } else - new_cfg = jtag_get_reset_config(); - - - /* - * Display the (now-)current reset mode - */ - char *modes[5]; - - /* minimal JTAG has neither SRST nor TRST (so that's the default) */ - switch (new_cfg & (RESET_HAS_TRST | RESET_HAS_SRST)) { - case RESET_HAS_SRST: - modes[0] = "srst_only"; - break; - case RESET_HAS_TRST: - modes[0] = "trst_only"; - break; - case RESET_TRST_AND_SRST: - modes[0] = "trst_and_srst"; - break; - default: - modes[0] = "none"; - break; - } - - /* normally SRST and TRST are decoupled; but bugs happen ... */ - switch (new_cfg & (RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST)) { - case RESET_SRST_PULLS_TRST: - modes[1] = "srst_pulls_trst"; - break; - case RESET_TRST_PULLS_SRST: - modes[1] = "trst_pulls_srst"; - break; - case RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST: - modes[1] = "combined"; - break; - default: - modes[1] = "separate"; - break; - } - - /* TRST-less connectors include Altera, Xilinx, and minimal JTAG */ - if (new_cfg & RESET_HAS_TRST) { - if (new_cfg & RESET_TRST_OPEN_DRAIN) - modes[3] = " trst_open_drain"; - else - modes[3] = " trst_push_pull"; - } else - modes[3] = ""; - - /* SRST-less connectors include TI-14, Xilinx, and minimal JTAG */ - if (new_cfg & RESET_HAS_SRST) { - if (new_cfg & RESET_SRST_NO_GATING) - modes[2] = " srst_nogate"; - else - modes[2] = " srst_gates_jtag"; - - if (new_cfg & RESET_SRST_PUSH_PULL) - modes[4] = " srst_push_pull"; - else - modes[4] = " srst_open_drain"; - } else { - modes[2] = ""; - modes[4] = ""; - } - - command_print(CMD_CTX, "%s %s%s%s%s", - modes[0], modes[1], - modes[2], modes[3], modes[4]); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_adapter_nsrst_delay_command) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - if (CMD_ARGC == 1) - { - unsigned delay; - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay); - - jtag_set_nsrst_delay(delay); - } - command_print(CMD_CTX, "adapter_nsrst_delay: %u", jtag_get_nsrst_delay()); - return ERROR_OK; -} - COMMAND_HANDLER(handle_jtag_ntrst_delay_command) { if (CMD_ARGC > 1) @@ -1322,21 +1005,6 @@ COMMAND_HANDLER(handle_jtag_ntrst_delay_command) return ERROR_OK; } -COMMAND_HANDLER(handle_adapter_nsrst_assert_width_command) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - if (CMD_ARGC == 1) - { - unsigned delay; - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay); - - jtag_set_nsrst_assert_width(delay); - } - command_print(CMD_CTX, "adapter_nsrst_assert_width: %u", jtag_get_nsrst_assert_width()); - return ERROR_OK; -} - COMMAND_HANDLER(handle_jtag_ntrst_assert_width_command) { if (CMD_ARGC > 1) @@ -1352,35 +1020,6 @@ COMMAND_HANDLER(handle_jtag_ntrst_assert_width_command) return ERROR_OK; } -COMMAND_HANDLER(handle_adapter_khz_command) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - int retval = ERROR_OK; - if (CMD_ARGC == 1) - { - unsigned khz = 0; - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], khz); - - retval = jtag_config_khz(khz); - if (ERROR_OK != retval) - return retval; - } - - int cur_speed = jtag_get_speed_khz(); - retval = jtag_get_speed_readable(&cur_speed); - if (ERROR_OK != retval) - return retval; - - if (cur_speed) - command_print(CMD_CTX, "%d kHz", cur_speed); - else - command_print(CMD_CTX, "RCLK - adaptive"); - - return retval; -} - COMMAND_HANDLER(handle_jtag_rclk_command) { if (CMD_ARGC > 1) @@ -1608,69 +1247,6 @@ COMMAND_HANDLER(handle_tms_sequence_command) return ERROR_OK; } -static const struct command_registration interface_command_handlers[] = { - { - .name = "adapter_khz", - .handler = handle_adapter_khz_command, - .mode = COMMAND_ANY, - .help = "With an argument, change to the specified maximum " - "jtag speed. For JTAG, 0 KHz signifies adaptive " - " clocking. " - "With or without argument, display current setting.", - .usage = "[khz]", - }, - { - .name = "adapter_nsrst_assert_width", - .handler = handle_adapter_nsrst_assert_width_command, - .mode = COMMAND_ANY, - .help = "delay after asserting SRST in ms", - .usage = "[milliseconds]", - }, - { - .name = "adapter_nsrst_delay", - .handler = handle_adapter_nsrst_delay_command, - .mode = COMMAND_ANY, - .help = "delay after deasserting SRST in ms", - .usage = "[milliseconds]", - }, - { - .name = "interface", - .handler = handle_interface_command, - .mode = COMMAND_CONFIG, - .help = "Select a debug adapter interface (driver)", - .usage = "driver_name", - }, - { - .name = "interface_list", - .handler = handle_interface_list_command, - .mode = COMMAND_ANY, - .help = "List all built-in debug adapter interfaces (drivers)", - }, - { - .name = "reset_config", - .handler = handle_reset_config_command, - .mode = COMMAND_ANY, - .help = "configure adapter reset behavior", - .usage = "[none|trst_only|srst_only|trst_and_srst] " - "[srst_pulls_trst|trst_pulls_srst|combined|separate] " - "[srst_gates_jtag|srst_nogate] " - "[trst_push_pull|trst_open_drain] " - "[srst_push_pull|srst_open_drain]", - }, - COMMAND_REGISTRATION_DONE -}; - -/** - * Register the commands which deal with arbitrary debug adapter drivers. - * - * @todo Remove internal assumptions that all debug adapters use JTAG for - * transport. Various types and data structures are not named generically. - */ -int interface_register_commands(struct command_context *ctx) -{ - return register_commands(ctx, NULL, interface_command_handlers); -} - static const struct command_registration jtag_command_handlers[] = { { .name = "jtag_rclk", |