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 <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8674
Tested-by: jenkins
Reviewed-by: zapb <dev@zapb.de>
This commit is contained in:
Antonio Borneo
2024-12-22 17:06:12 +01:00
parent 9a5de74423
commit 236208a5ff
7 changed files with 102 additions and 31 deletions

View File

@@ -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;

View File

@@ -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,

View File

@@ -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,
};

View File

@@ -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,
};

View File

@@ -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,
};

View File

@@ -30,6 +30,8 @@
* messaging and error handling.
*/
#include <helper/align.h>
#include <helper/bits.h>
#include <helper/log.h>
#include <helper/replacements.h>
#include <transport/transport.h>
@@ -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");

View File

@@ -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);