3030 * messaging and error handling.
3131 */
3232
33+ #include <helper/align.h>
34+ #include <helper/bits.h>
3335#include <helper/log.h>
3436#include <helper/replacements.h>
3537#include <transport/transport.h>
@@ -43,6 +45,20 @@ extern struct command_context *global_cmd_ctx;
4345 */
4446
4547/** List of transports known to OpenOCD. */
48+ static const struct {
49+ unsigned int id ;
50+ const char * name ;
51+ } transport_names [] = {
52+ { TRANSPORT_JTAG , "jtag" , },
53+ { TRANSPORT_SWD , "swd" , },
54+ { TRANSPORT_HLA_JTAG , "hla_jtag" , },
55+ { TRANSPORT_HLA_SWD , "hla_swd" , },
56+ { TRANSPORT_DAPDIRECT_JTAG , "dapdirect_jtag" , },
57+ { TRANSPORT_DAPDIRECT_SWD , "dapdirect_swd" , },
58+ { TRANSPORT_SWIM , "swim" , },
59+ };
60+
61+ /** List of transports registered in OpenOCD. */
4662static struct transport * transport_list ;
4763
4864/**
@@ -60,12 +76,26 @@ static bool transport_single_is_autoselected;
6076/** * The transport being used for the current OpenOCD session. */
6177static struct transport * session ;
6278
79+ static const char * transport_name (unsigned int id )
80+ {
81+ for (unsigned int i = 0 ; i < ARRAY_SIZE (transport_names ); i ++ )
82+ if (id == transport_names [i ].id )
83+ return transport_names [i ].name ;
84+
85+ return NULL ;
86+ }
87+
88+ static bool is_transport_id_valid (unsigned int id )
89+ {
90+ return (id != 0 ) && ((id & ~TRANSPORT_VALID_MASK ) == 0 ) && IS_PWR_OF_2 (id );
91+ }
92+
6393static int transport_select (struct command_context * ctx , const char * name )
6494{
6595 /* name may only identify a known transport;
6696 * caller guarantees session's transport isn't yet set.*/
6797 for (struct transport * t = transport_list ; t ; t = t -> next ) {
68- if (strcmp (t -> name , name ) == 0 ) {
98+ if (! strcmp (transport_name ( t -> id ) , name )) {
6999 int retval = t -> select (ctx );
70100 /* select() registers commands specific to this
71101 * transport, and may also reset the link, e.g.
@@ -74,7 +104,7 @@ static int transport_select(struct command_context *ctx, const char *name)
74104 if (retval == ERROR_OK )
75105 session = t ;
76106 else
77- LOG_ERROR ("Error selecting '%s' as transport" , t -> name );
107+ LOG_ERROR ("Error selecting '%s' as transport" , name );
78108 return retval ;
79109 }
80110 }
@@ -136,20 +166,28 @@ int transport_register(struct transport *new_transport)
136166{
137167 struct transport * t ;
138168
169+ if (!is_transport_id_valid (new_transport -> id )) {
170+ LOG_ERROR ("invalid transport ID 0x%x" , new_transport -> id );
171+ return ERROR_FAIL ;
172+ }
173+
139174 for (t = transport_list ; t ; t = t -> next ) {
140- if (strcmp (t -> name , new_transport -> name ) == 0 ) {
141- LOG_ERROR ("transport name already used" );
175+ if (t -> id == new_transport -> id ) {
176+ LOG_ERROR ("transport '%s' already registered" ,
177+ transport_name (t -> id ));
142178 return ERROR_FAIL ;
143179 }
144180 }
145181
146182 if (!new_transport -> select || !new_transport -> init )
147- LOG_ERROR ("invalid transport %s" , new_transport -> name );
183+ LOG_ERROR ("invalid transport %s" ,
184+ transport_name (new_transport -> id ));
148185
149186 /* splice this into the list */
150187 new_transport -> next = transport_list ;
151188 transport_list = new_transport ;
152- LOG_DEBUG ("register '%s'" , new_transport -> name );
189+ LOG_DEBUG ("register '%s' (ID %d)" ,
190+ transport_name (new_transport -> id ), new_transport -> id );
153191
154192 return ERROR_OK ;
155193}
@@ -166,6 +204,14 @@ struct transport *get_current_transport(void)
166204 return session ;
167205}
168206
207+ const char * get_current_transport_name (void )
208+ {
209+ if (!session || !is_transport_id_valid (session -> id ))
210+ NULL ;
211+
212+ return transport_name (session -> id );
213+ }
214+
169215/*-----------------------------------------------------------------------*/
170216
171217/*
@@ -191,7 +237,7 @@ COMMAND_HANDLER(handle_transport_init)
191237 if (transport_single_is_autoselected )
192238 LOG_WARNING ("DEPRECATED: auto-selecting transport \"%s\". "
193239 "Use 'transport select %s' to suppress this message." ,
194- session -> name , session -> name );
240+ transport_name ( session -> id ), transport_name ( session -> id ) );
195241
196242 return session -> init (CMD_CTX );
197243}
@@ -204,7 +250,7 @@ COMMAND_HANDLER(handle_transport_list)
204250 command_print (CMD , "The following transports are available:" );
205251
206252 for (struct transport * t = transport_list ; t ; t = t -> next )
207- command_print (CMD , "\t%s" , t -> name );
253+ command_print (CMD , "\t%s" , transport_name ( t -> id ) );
208254
209255 return ERROR_OK ;
210256}
@@ -234,19 +280,19 @@ COMMAND_HANDLER(handle_transport_select)
234280 if (retval != ERROR_OK )
235281 return retval ;
236282 }
237- command_print (CMD , "%s" , session -> name );
283+ command_print (CMD , "%s" , transport_name ( session -> id ) );
238284 return ERROR_OK ;
239285 }
240286
241287 /* assign transport */
242288 if (session ) {
243- if (!strcmp (session -> name , CMD_ARGV [0 ])) {
289+ if (!strcmp (transport_name ( session -> id ) , CMD_ARGV [0 ])) {
244290 if (transport_single_is_autoselected ) {
245291 /* Nothing to do, but also nothing to complain */
246292 transport_single_is_autoselected = false;
247293 return ERROR_OK ;
248294 }
249- LOG_WARNING ("Transport \"%s\" was already selected" , session -> name );
295+ LOG_WARNING ("Transport \"%s\" was already selected" , CMD_ARGV [ 0 ] );
250296 return ERROR_OK ;
251297 }
252298 command_print (CMD , "Can't change session's transport after the initial selection was made" );
0 commit comments