diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index 37e6ee9ae..2d95e1892 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -93,6 +93,9 @@ static int default_srst_asserted(int *srst_asserted) return ERROR_OK; } +const char *jtag_only[] = { "jtag", NULL, }; + + COMMAND_HANDLER(interface_transport_command) { char **transports; @@ -130,6 +133,8 @@ COMMAND_HANDLER(handle_interface_list_command) COMMAND_HANDLER(handle_interface_command) { + int retval; + /* check whether the interface is already configured */ if (jtag_interface) { @@ -148,7 +153,7 @@ COMMAND_HANDLER(handle_interface_command) if (NULL != jtag_interfaces[i]->commands) { - int retval = register_commands(CMD_CTX, NULL, + retval = register_commands(CMD_CTX, NULL, jtag_interfaces[i]->commands); if (ERROR_OK != retval) return retval; @@ -156,6 +161,20 @@ COMMAND_HANDLER(handle_interface_command) jtag_interface = jtag_interfaces[i]; + /* LEGACY SUPPORT ... adapter drivers must declare what + * transports they allow. Until they all do so, assume + * the legacy drivers are JTAG-only + */ + if (!jtag_interface->transports) + LOG_WARNING("Adapter driver '%s' did not declare " + "which transports it allows; assuming" + "legacy JTAG-only", jtag_interface->name); + retval = allow_transports(CMD_CTX, + jtag_interface->transports + ? : jtag_only); + if (ERROR_OK != retval) + return retval; + if (jtag_interface->khz == NULL) jtag_interface->khz = default_khz; if (jtag_interface->speed_div == NULL) @@ -171,7 +190,8 @@ COMMAND_HANDLER(handle_interface_command) /* 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]); + 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; } diff --git a/src/jtag/drivers/dummy.c b/src/jtag/drivers/dummy.c index 7cb0e33c5..8b1e5ecb4 100644 --- a/src/jtag/drivers/dummy.c +++ b/src/jtag/drivers/dummy.c @@ -166,6 +166,7 @@ struct jtag_interface dummy_interface = { .supported = DEBUG_CAP_TMS_SEQ, .commands = dummy_command_handlers, + .transports = jtag_only, .execute_queue = &bitbang_execute_queue, diff --git a/src/jtag/drivers/ft2232.c b/src/jtag/drivers/ft2232.c index f06e13b0f..bf71fa323 100644 --- a/src/jtag/drivers/ft2232.c +++ b/src/jtag/drivers/ft2232.c @@ -168,7 +168,6 @@ struct ft2232_layout { void (*reset)(int trst, int srst); void (*blink)(void); int channel; - const char **transports; }; /* init procedures for supported layouts */ @@ -213,11 +212,8 @@ static void signalyzer_h_blink(void); static void ktlink_blink(void); /* common transport support options */ -static const char *jtag_only[] = { "jtag", NULL }; - //static const char *jtag_and_swd[] = { "jtag", "swd", NULL }; -#define jtag_and_swd NULL static const struct ft2232_layout ft2232_layouts[] = { @@ -244,12 +240,10 @@ static const struct ft2232_layout ft2232_layouts[] = { .name = "evb_lm3s811", .init = lm3s811_jtag_init, .reset = ftx23_reset, - .transports = jtag_and_swd, }, { .name = "luminary_icdi", .init = icdi_jtag_init, .reset = ftx23_reset, - .transports = jtag_and_swd, }, { .name = "olimex-jtag", .init = olimex_jtag_init, @@ -3206,11 +3200,7 @@ COMMAND_HANDLER(ft2232_handle_layout_command) for (const struct ft2232_layout *l = ft2232_layouts; l->name; l++) { if (strcmp(l->name, CMD_ARGV[0]) == 0) { layout = l; - /* This may also select the transport - * if we only support one of them. - */ - return allow_transports(CMD_CTX, - l->transports ? : jtag_only); + return ERROR_OK; } } @@ -4372,6 +4362,7 @@ struct jtag_interface ft2232_interface = { .name = "ft2232", .supported = DEBUG_CAP_TMS_SEQ, .commands = ft2232_command_handlers, + .transports = jtag_only, .init = ft2232_init, .quit = ft2232_quit, diff --git a/src/jtag/interface.h b/src/jtag/interface.h index 0d474049e..3226944e3 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -206,6 +206,9 @@ struct jtag_interface { unsigned supported; #define DEBUG_CAP_TMS_SEQ (1 << 0) + /** transports supported in C code (NULL terminated vector) */ + const char **transports; + /** * Execute queued commands. * @returns ERROR_OK on success, or an error code on failure. @@ -289,4 +292,6 @@ struct jtag_interface { }; +extern const char *jtag_only[]; + #endif // OPENOCD_JTAG_INTERFACE_H diff --git a/src/jtag/transport.c b/src/jtag/transport.c index cce45fb7a..d290bd2cf 100644 --- a/src/jtag/transport.c +++ b/src/jtag/transport.c @@ -101,6 +101,10 @@ int allow_transports(struct command_context *ctx, const char **vector) * * REVISIT should we validate that? and insist there's * at least one non-NULL element in that list? + * + * ... allow removals, e.g. external strapping prevents use + * of one transport; C code should be definitive about what + * can be used when all goes well. */ if (allowed_transports != NULL || session) { LOG_ERROR("Can't modify the set of allowed transports."); @@ -116,6 +120,8 @@ int allow_transports(struct command_context *ctx, const char **vector) vector[0]); return transport_select(ctx, vector [0]); } else { + /* guard against user config errors */ + LOG_WARNING("must select a transport."); while (*vector) LOG_DEBUG("allow transport '%s'", *vector++); return ERROR_OK; @@ -304,13 +310,14 @@ COMMAND_HANDLER(handle_transport_select) /* Is this transport supported by our debug adapter? * Example, "JTAG-only" means SWD is not supported. * - * NOTE: requires adapter to have been set up, including - * declaring transport via C code or Tcl script. + * NOTE: requires adapter to have been set up, with + * transports declared via C. */ if (!allowed_transports) { LOG_ERROR("Debug adapter doesn't support any transports?"); return ERROR_FAIL; } + for (unsigned i = 0; allowed_transports[i]; i++) { if (strcmp(allowed_transports[i], CMD_ARGV[0]) == 0)