From: Antonio Borneo Date: Sun, 22 Dec 2024 16:06:12 +0000 (+0100) Subject: transport: use a bitmask for the transport X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=236208a5ff2d;p=users%2Fborneoa%2Fopenocd-next.git transport: use a bitmask for the transport Move the transport's names in a local array in the transport framework. Replace the string struct transport::name, that identifies the transport, with a bitmask where each bit corresponds to one of the available transports. Change-Id: I6bdf7264d5979c355299f63fcf80bf54dcd95cee Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8674 Tested-by: jenkins Reviewed-by: zapb --- diff --git a/src/jtag/core.c b/src/jtag/core.c index 030c173be..6dd2144c6 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -1823,7 +1823,7 @@ static int jtag_select(struct command_context *ctx) } static struct transport jtag_transport = { - .name = "jtag", + .id = TRANSPORT_JTAG, .select = jtag_select, .init = jtag_init, }; @@ -1868,7 +1868,7 @@ int adapter_resets(int trst, int srst) transport_is_swim()) { if (trst == TRST_ASSERT) { LOG_ERROR("transport %s has no trst signal", - get_current_transport()->name); + get_current_transport_name()); return ERROR_FAIL; } @@ -1884,7 +1884,7 @@ int adapter_resets(int trst, int srst) return ERROR_OK; LOG_ERROR("reset is not supported on transport %s", - get_current_transport()->name); + get_current_transport_name()); return ERROR_FAIL; } @@ -1903,7 +1903,7 @@ int adapter_assert_reset(void) return adapter_system_reset(1); else if (get_current_transport()) LOG_ERROR("reset is not supported on %s", - get_current_transport()->name); + get_current_transport_name()); else LOG_ERROR("transport is not selected"); return ERROR_FAIL; @@ -1920,7 +1920,7 @@ int adapter_deassert_reset(void) return adapter_system_reset(0); else if (get_current_transport()) LOG_ERROR("reset is not supported on %s", - get_current_transport()->name); + get_current_transport_name()); else LOG_ERROR("transport is not selected"); return ERROR_FAIL; diff --git a/src/jtag/hla/hla_transport.c b/src/jtag/hla/hla_transport.c index b826eb0fe..333825eff 100644 --- a/src/jtag/hla/hla_transport.c +++ b/src/jtag/hla/hla_transport.c @@ -177,15 +177,20 @@ static int hl_transport_init(struct command_context *cmd_ctx) return ERROR_FAIL; } - LOG_DEBUG("current transport %s", transport->name); + LOG_DEBUG("current transport %s", get_current_transport_name()); /* get selected transport as enum */ - tr = HL_TRANSPORT_UNKNOWN; - - if (strcmp(transport->name, "hla_swd") == 0) + switch (transport->id) { + case TRANSPORT_HLA_SWD: tr = HL_TRANSPORT_SWD; - else if (strcmp(transport->name, "hla_jtag") == 0) + break; + case TRANSPORT_HLA_JTAG: tr = HL_TRANSPORT_JTAG; + break; + default: + tr = HL_TRANSPORT_UNKNOWN; + break; + } int retval = hl_interface_open(tr); @@ -213,14 +218,14 @@ static int hl_swd_transport_select(struct command_context *cmd_ctx) } static struct transport hl_swd_transport = { - .name = "hla_swd", + .id = TRANSPORT_HLA_SWD, .select = hl_swd_transport_select, .init = hl_transport_init, .override_target = hl_interface_override_target, }; static struct transport hl_jtag_transport = { - .name = "hla_jtag", + .id = TRANSPORT_HLA_JTAG, .select = hl_jtag_transport_select, .init = hl_transport_init, .override_target = hl_interface_override_target, diff --git a/src/jtag/swim.c b/src/jtag/swim.c index de3e106a1..004a9fd4f 100644 --- a/src/jtag/swim.c +++ b/src/jtag/swim.c @@ -136,7 +136,7 @@ static int swim_transport_init(struct command_context *cmd_ctx) } static struct transport swim_transport = { - .name = "swim", + .id = TRANSPORT_SWIM, .select = swim_transport_select, .init = swim_transport_init, }; diff --git a/src/target/adi_v5_dapdirect.c b/src/target/adi_v5_dapdirect.c index d198dacf3..07ea313d1 100644 --- a/src/target/adi_v5_dapdirect.c +++ b/src/target/adi_v5_dapdirect.c @@ -207,13 +207,13 @@ static int dapdirect_init(struct command_context *ctx) } static struct transport dapdirect_jtag_transport = { - .name = "dapdirect_jtag", + .id = TRANSPORT_DAPDIRECT_JTAG, .select = dapdirect_jtag_select, .init = dapdirect_init, }; static struct transport dapdirect_swd_transport = { - .name = "dapdirect_swd", + .id = TRANSPORT_DAPDIRECT_SWD, .select = dapdirect_swd_select, .init = dapdirect_init, }; diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c index e50f8f137..2d286136a 100644 --- a/src/target/adi_v5_swd.c +++ b/src/target/adi_v5_swd.c @@ -756,7 +756,7 @@ static int swd_init(struct command_context *ctx) } static struct transport swd_transport = { - .name = "swd", + .id = TRANSPORT_SWD, .select = swd_select, .init = swd_init, }; diff --git a/src/transport/transport.c b/src/transport/transport.c index 4a1f71d40..411b0a5e0 100644 --- a/src/transport/transport.c +++ b/src/transport/transport.c @@ -30,6 +30,8 @@ * messaging and error handling. */ +#include +#include #include #include #include @@ -43,6 +45,20 @@ extern struct command_context *global_cmd_ctx; */ /** List of transports known to OpenOCD. */ +static const struct { + unsigned int id; + const char *name; +} transport_names[] = { + { TRANSPORT_JTAG, "jtag", }, + { TRANSPORT_SWD, "swd", }, + { TRANSPORT_HLA_JTAG, "hla_jtag", }, + { TRANSPORT_HLA_SWD, "hla_swd", }, + { TRANSPORT_DAPDIRECT_JTAG, "dapdirect_jtag", }, + { TRANSPORT_DAPDIRECT_SWD, "dapdirect_swd", }, + { TRANSPORT_SWIM, "swim", }, +}; + +/** List of transports registered in OpenOCD. */ static struct transport *transport_list; /** @@ -60,12 +76,26 @@ static bool transport_single_is_autoselected; /** * The transport being used for the current OpenOCD session. */ static struct transport *session; +static const char *transport_name(unsigned int id) +{ + for (unsigned int i = 0; i < ARRAY_SIZE(transport_names); i++) + if (id == transport_names[i].id) + return transport_names[i].name; + + return NULL; +} + +static bool is_transport_id_valid(unsigned int id) +{ + return (id != 0) && ((id & ~TRANSPORT_VALID_MASK) == 0) && IS_PWR_OF_2(id); +} + static int transport_select(struct command_context *ctx, const char *name) { /* name may only identify a known transport; * caller guarantees session's transport isn't yet set.*/ for (struct transport *t = transport_list; t; t = t->next) { - if (strcmp(t->name, name) == 0) { + if (!strcmp(transport_name(t->id), name)) { int retval = t->select(ctx); /* select() registers commands specific to this * transport, and may also reset the link, e.g. @@ -74,7 +104,7 @@ static int transport_select(struct command_context *ctx, const char *name) if (retval == ERROR_OK) session = t; else - LOG_ERROR("Error selecting '%s' as transport", t->name); + LOG_ERROR("Error selecting '%s' as transport", name); return retval; } } @@ -136,20 +166,28 @@ int transport_register(struct transport *new_transport) { struct transport *t; + if (!is_transport_id_valid(new_transport->id)) { + LOG_ERROR("invalid transport ID 0x%x", new_transport->id); + return ERROR_FAIL; + } + for (t = transport_list; t; t = t->next) { - if (strcmp(t->name, new_transport->name) == 0) { - LOG_ERROR("transport name already used"); + if (t->id == new_transport->id) { + LOG_ERROR("transport '%s' already registered", + transport_name(t->id)); return ERROR_FAIL; } } if (!new_transport->select || !new_transport->init) - LOG_ERROR("invalid transport %s", new_transport->name); + LOG_ERROR("invalid transport %s", + transport_name(new_transport->id)); /* splice this into the list */ new_transport->next = transport_list; transport_list = new_transport; - LOG_DEBUG("register '%s'", new_transport->name); + LOG_DEBUG("register '%s' (ID %d)", + transport_name(new_transport->id), new_transport->id); return ERROR_OK; } @@ -166,6 +204,14 @@ struct transport *get_current_transport(void) return session; } +const char *get_current_transport_name(void) +{ + if (!session || !is_transport_id_valid(session->id)) + NULL; + + return transport_name(session->id); +} + /*-----------------------------------------------------------------------*/ /* @@ -191,7 +237,7 @@ COMMAND_HANDLER(handle_transport_init) if (transport_single_is_autoselected) LOG_WARNING("DEPRECATED: auto-selecting transport \"%s\". " "Use 'transport select %s' to suppress this message.", - session->name, session->name); + transport_name(session->id), transport_name(session->id)); return session->init(CMD_CTX); } @@ -204,7 +250,7 @@ COMMAND_HANDLER(handle_transport_list) command_print(CMD, "The following transports are available:"); for (struct transport *t = transport_list; t; t = t->next) - command_print(CMD, "\t%s", t->name); + command_print(CMD, "\t%s", transport_name(t->id)); return ERROR_OK; } @@ -234,19 +280,19 @@ COMMAND_HANDLER(handle_transport_select) if (retval != ERROR_OK) return retval; } - command_print(CMD, "%s", session->name); + command_print(CMD, "%s", transport_name(session->id)); return ERROR_OK; } /* assign transport */ if (session) { - if (!strcmp(session->name, CMD_ARGV[0])) { + if (!strcmp(transport_name(session->id), CMD_ARGV[0])) { if (transport_single_is_autoselected) { /* Nothing to do, but also nothing to complain */ transport_single_is_autoselected = false; return ERROR_OK; } - LOG_WARNING("Transport \"%s\" was already selected", session->name); + LOG_WARNING("Transport \"%s\" was already selected", CMD_ARGV[0]); return ERROR_OK; } command_print(CMD, "Can't change session's transport after the initial selection was made"); diff --git a/src/transport/transport.h b/src/transport/transport.h index 2e3dcc61a..dde7c6ba7 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h @@ -12,8 +12,27 @@ #include "config.h" #endif +#include "helper/bits.h" #include "helper/command.h" +#define TRANSPORT_JTAG BIT(0) +#define TRANSPORT_SWD BIT(1) +#define TRANSPORT_HLA_JTAG BIT(2) +#define TRANSPORT_HLA_SWD BIT(3) +#define TRANSPORT_DAPDIRECT_JTAG BIT(4) +#define TRANSPORT_DAPDIRECT_SWD BIT(5) +#define TRANSPORT_SWIM BIT(6) + +/* mask for valid ID */ +#define TRANSPORT_VALID_MASK \ + (TRANSPORT_JTAG | \ + TRANSPORT_SWD | \ + TRANSPORT_HLA_JTAG | \ + TRANSPORT_HLA_SWD | \ + TRANSPORT_DAPDIRECT_JTAG | \ + TRANSPORT_DAPDIRECT_SWD | \ + TRANSPORT_SWIM) + /** * Wrapper for transport lifecycle operations. * @@ -34,11 +53,10 @@ */ struct transport { /** - * Each transport has a unique name, used to select it - * from among the alternatives. Examples might include - * "jtag", * "swd", "AVR_ISP" and more. + * Each transport has a unique ID, used to select it + * from among the alternatives. */ - const char *name; + unsigned int id; /** * When a transport is selected, this method registers @@ -75,6 +93,8 @@ int transport_register(struct transport *new_transport); struct transport *get_current_transport(void); +const char *get_current_transport_name(void); + int transport_register_commands(struct command_context *ctx); int allow_transports(struct command_context *ctx, const char * const *vector);