jtag: simplify management of non-implemented handlers
[fw/openocd] / src / jtag / adapter.c
1 /***************************************************************************
2  *   Copyright (C) 2005 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   Copyright (C) 2007-2010 Ã˜yvind Harboe                                 *
6  *   oyvind.harboe@zylin.com                                               *
7  *                                                                         *
8  *   Copyright (C) 2009 SoftPLC Corporation                                *
9  *       http://softplc.com                                                *
10  *   dick@softplc.com                                                      *
11  *                                                                         *
12  *   Copyright (C) 2009 Zachary T Welch                                    *
13  *   zw@superlucidity.net                                                  *
14  *                                                                         *
15  *   This program is free software; you can redistribute it and/or modify  *
16  *   it under the terms of the GNU General Public License as published by  *
17  *   the Free Software Foundation; either version 2 of the License, or     *
18  *   (at your option) any later version.                                   *
19  *                                                                         *
20  *   This program is distributed in the hope that it will be useful,       *
21  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
22  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
23  *   GNU General Public License for more details.                          *
24  *                                                                         *
25  *   You should have received a copy of the GNU General Public License     *
26  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
27  ***************************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "jtag.h"
34 #include "minidriver.h"
35 #include "interface.h"
36 #include "interfaces.h"
37 #include <transport/transport.h>
38 #include <jtag/drivers/jtag_usb_common.h>
39
40 #ifdef HAVE_STRINGS_H
41 #include <strings.h>
42 #endif
43
44 /**
45  * @file
46  * Holds support for configuring debug adapters from TCl scripts.
47  */
48
49 extern struct jtag_interface *jtag_interface;
50 const char * const jtag_only[] = { "jtag", NULL };
51
52 static int jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
53 {
54         Jim_GetOptInfo goi;
55         Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
56
57         /* return the name of the interface */
58         /* TCL code might need to know the exact type... */
59         /* FUTURE: we allow this as a means to "set" the interface. */
60         if (goi.argc != 0) {
61                 Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
62                 return JIM_ERR;
63         }
64         const char *name = jtag_interface ? jtag_interface->name : NULL;
65         Jim_SetResultString(goi.interp, name ? : "undefined", -1);
66         return JIM_OK;
67 }
68
69 COMMAND_HANDLER(interface_transport_command)
70 {
71         char **transports;
72         int retval;
73
74         retval = CALL_COMMAND_HANDLER(transport_list_parse, &transports);
75         if (retval != ERROR_OK)
76                 return retval;
77
78         retval = allow_transports(CMD_CTX, (const char **)transports);
79
80         if (retval != ERROR_OK) {
81                 for (unsigned i = 0; transports[i]; i++)
82                         free(transports[i]);
83                 free(transports);
84         }
85         return retval;
86 }
87
88 COMMAND_HANDLER(handle_interface_list_command)
89 {
90         if (strcmp(CMD_NAME, "interface_list") == 0 && CMD_ARGC > 0)
91                 return ERROR_COMMAND_SYNTAX_ERROR;
92
93         command_print(CMD, "The following debug interfaces are available:");
94         for (unsigned i = 0; NULL != jtag_interfaces[i]; i++) {
95                 const char *name = jtag_interfaces[i]->name;
96                 command_print(CMD, "%u: %s", i + 1, name);
97         }
98
99         return ERROR_OK;
100 }
101
102 COMMAND_HANDLER(handle_interface_command)
103 {
104         int retval;
105
106         /* check whether the interface is already configured */
107         if (jtag_interface) {
108                 LOG_WARNING("Interface already configured, ignoring");
109                 return ERROR_OK;
110         }
111
112         /* interface name is a mandatory argument */
113         if (CMD_ARGC != 1 || CMD_ARGV[0][0] == '\0')
114                 return ERROR_COMMAND_SYNTAX_ERROR;
115
116         for (unsigned i = 0; NULL != jtag_interfaces[i]; i++) {
117                 if (strcmp(CMD_ARGV[0], jtag_interfaces[i]->name) != 0)
118                         continue;
119
120                 if (NULL != jtag_interfaces[i]->commands) {
121                         retval = register_commands(CMD_CTX, NULL,
122                                         jtag_interfaces[i]->commands);
123                         if (ERROR_OK != retval)
124                                 return retval;
125                 }
126
127                 jtag_interface = jtag_interfaces[i];
128
129                 /* LEGACY SUPPORT ... adapter drivers  must declare what
130                  * transports they allow.  Until they all do so, assume
131                  * the legacy drivers are JTAG-only
132                  */
133                 if (!jtag_interface->transports)
134                         LOG_WARNING("Adapter driver '%s' did not declare "
135                                 "which transports it allows; assuming "
136                                 "legacy JTAG-only", jtag_interface->name);
137                 return allow_transports(CMD_CTX, jtag_interface->transports
138                                                 ? jtag_interface->transports : jtag_only);
139         }
140
141         /* no valid interface was found (i.e. the configuration option,
142          * didn't match one of the compiled-in interfaces
143          */
144         LOG_ERROR("The specified debug interface was not found (%s)",
145                                 CMD_ARGV[0]);
146         CALL_COMMAND_HANDLER(handle_interface_list_command);
147         return ERROR_JTAG_INVALID_INTERFACE;
148 }
149
150 COMMAND_HANDLER(handle_reset_config_command)
151 {
152         int new_cfg = 0;
153         int mask = 0;
154
155         /* Original versions cared about the order of these tokens:
156          *   reset_config signals [combination [trst_type [srst_type]]]
157          * They also clobbered the previous configuration even on error.
158          *
159          * Here we don't care about the order, and only change values
160          * which have been explicitly specified.
161          */
162         for (; CMD_ARGC; CMD_ARGC--, CMD_ARGV++) {
163                 int tmp = 0;
164                 int m;
165
166                 /* gating */
167                 m = RESET_SRST_NO_GATING;
168                 if (strcmp(*CMD_ARGV, "srst_gates_jtag") == 0)
169                         /* default: don't use JTAG while SRST asserted */;
170                 else if (strcmp(*CMD_ARGV, "srst_nogate") == 0)
171                         tmp = RESET_SRST_NO_GATING;
172                 else
173                         m = 0;
174                 if (mask & m) {
175                         LOG_ERROR("extra reset_config %s spec (%s)",
176                                         "gating", *CMD_ARGV);
177                         return ERROR_COMMAND_SYNTAX_ERROR;
178                 }
179                 if (m)
180                         goto next;
181
182                 /* signals */
183                 m = RESET_HAS_TRST | RESET_HAS_SRST;
184                 if (strcmp(*CMD_ARGV, "none") == 0)
185                         tmp = RESET_NONE;
186                 else if (strcmp(*CMD_ARGV, "trst_only") == 0)
187                         tmp = RESET_HAS_TRST;
188                 else if (strcmp(*CMD_ARGV, "srst_only") == 0)
189                         tmp = RESET_HAS_SRST;
190                 else if (strcmp(*CMD_ARGV, "trst_and_srst") == 0)
191                         tmp = RESET_HAS_TRST | RESET_HAS_SRST;
192                 else
193                         m = 0;
194                 if (mask & m) {
195                         LOG_ERROR("extra reset_config %s spec (%s)",
196                                         "signal", *CMD_ARGV);
197                         return ERROR_COMMAND_SYNTAX_ERROR;
198                 }
199                 if (m)
200                         goto next;
201
202                 /* combination (options for broken wiring) */
203                 m = RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST;
204                 if (strcmp(*CMD_ARGV, "separate") == 0)
205                         /* separate reset lines - default */;
206                 else if (strcmp(*CMD_ARGV, "srst_pulls_trst") == 0)
207                         tmp |= RESET_SRST_PULLS_TRST;
208                 else if (strcmp(*CMD_ARGV, "trst_pulls_srst") == 0)
209                         tmp |= RESET_TRST_PULLS_SRST;
210                 else if (strcmp(*CMD_ARGV, "combined") == 0)
211                         tmp |= RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST;
212                 else
213                         m = 0;
214                 if (mask & m) {
215                         LOG_ERROR("extra reset_config %s spec (%s)",
216                                         "combination", *CMD_ARGV);
217                         return ERROR_COMMAND_SYNTAX_ERROR;
218                 }
219                 if (m)
220                         goto next;
221
222                 /* trst_type (NOP without HAS_TRST) */
223                 m = RESET_TRST_OPEN_DRAIN;
224                 if (strcmp(*CMD_ARGV, "trst_open_drain") == 0)
225                         tmp |= RESET_TRST_OPEN_DRAIN;
226                 else if (strcmp(*CMD_ARGV, "trst_push_pull") == 0)
227                         /* push/pull from adapter - default */;
228                 else
229                         m = 0;
230                 if (mask & m) {
231                         LOG_ERROR("extra reset_config %s spec (%s)",
232                                         "trst_type", *CMD_ARGV);
233                         return ERROR_COMMAND_SYNTAX_ERROR;
234                 }
235                 if (m)
236                         goto next;
237
238                 /* srst_type (NOP without HAS_SRST) */
239                 m = RESET_SRST_PUSH_PULL;
240                 if (strcmp(*CMD_ARGV, "srst_push_pull") == 0)
241                         tmp |= RESET_SRST_PUSH_PULL;
242                 else if (strcmp(*CMD_ARGV, "srst_open_drain") == 0)
243                         /* open drain from adapter - default */;
244                 else
245                         m = 0;
246                 if (mask & m) {
247                         LOG_ERROR("extra reset_config %s spec (%s)",
248                                         "srst_type", *CMD_ARGV);
249                         return ERROR_COMMAND_SYNTAX_ERROR;
250                 }
251                 if (m)
252                         goto next;
253
254                 /* connect_type - only valid when srst_nogate */
255                 m = RESET_CNCT_UNDER_SRST;
256                 if (strcmp(*CMD_ARGV, "connect_assert_srst") == 0)
257                         tmp |= RESET_CNCT_UNDER_SRST;
258                 else if (strcmp(*CMD_ARGV, "connect_deassert_srst") == 0)
259                         /* connect normally - default */;
260                 else
261                         m = 0;
262                 if (mask & m) {
263                         LOG_ERROR("extra reset_config %s spec (%s)",
264                                         "connect_type", *CMD_ARGV);
265                         return ERROR_COMMAND_SYNTAX_ERROR;
266                 }
267                 if (m)
268                         goto next;
269
270                 /* caller provided nonsense; fail */
271                 LOG_ERROR("unknown reset_config flag (%s)", *CMD_ARGV);
272                 return ERROR_COMMAND_SYNTAX_ERROR;
273
274 next:
275                 /* Remember the bits which were specified (mask)
276                  * and their new values (new_cfg).
277                  */
278                 mask |= m;
279                 new_cfg |= tmp;
280         }
281
282         /* clear previous values of those bits, save new values */
283         if (mask) {
284                 int old_cfg = jtag_get_reset_config();
285
286                 old_cfg &= ~mask;
287                 new_cfg |= old_cfg;
288                 jtag_set_reset_config(new_cfg);
289         } else
290                 new_cfg = jtag_get_reset_config();
291
292         /*
293          * Display the (now-)current reset mode
294          */
295         char *modes[6];
296
297         /* minimal JTAG has neither SRST nor TRST (so that's the default) */
298         switch (new_cfg & (RESET_HAS_TRST | RESET_HAS_SRST)) {
299                 case RESET_HAS_SRST:
300                         modes[0] = "srst_only";
301                         break;
302                 case RESET_HAS_TRST:
303                         modes[0] = "trst_only";
304                         break;
305                 case RESET_TRST_AND_SRST:
306                         modes[0] = "trst_and_srst";
307                         break;
308                 default:
309                         modes[0] = "none";
310                         break;
311         }
312
313         /* normally SRST and TRST are decoupled; but bugs happen ... */
314         switch (new_cfg & (RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST)) {
315                 case RESET_SRST_PULLS_TRST:
316                         modes[1] = "srst_pulls_trst";
317                         break;
318                 case RESET_TRST_PULLS_SRST:
319                         modes[1] = "trst_pulls_srst";
320                         break;
321                 case RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST:
322                         modes[1] = "combined";
323                         break;
324                 default:
325                         modes[1] = "separate";
326                         break;
327         }
328
329         /* TRST-less connectors include Altera, Xilinx, and minimal JTAG */
330         if (new_cfg & RESET_HAS_TRST) {
331                 if (new_cfg & RESET_TRST_OPEN_DRAIN)
332                         modes[3] = " trst_open_drain";
333                 else
334                         modes[3] = " trst_push_pull";
335         } else
336                 modes[3] = "";
337
338         /* SRST-less connectors include TI-14, Xilinx, and minimal JTAG */
339         if (new_cfg & RESET_HAS_SRST) {
340                 if (new_cfg & RESET_SRST_NO_GATING)
341                         modes[2] = " srst_nogate";
342                 else
343                         modes[2] = " srst_gates_jtag";
344
345                 if (new_cfg & RESET_SRST_PUSH_PULL)
346                         modes[4] = " srst_push_pull";
347                 else
348                         modes[4] = " srst_open_drain";
349
350                 if (new_cfg & RESET_CNCT_UNDER_SRST)
351                         modes[5] = " connect_assert_srst";
352                 else
353                         modes[5] = " connect_deassert_srst";
354         } else {
355                 modes[2] = "";
356                 modes[4] = "";
357                 modes[5] = "";
358         }
359
360         command_print(CMD, "%s %s%s%s%s%s",
361                         modes[0], modes[1],
362                         modes[2], modes[3], modes[4], modes[5]);
363
364         return ERROR_OK;
365 }
366
367 COMMAND_HANDLER(handle_adapter_nsrst_delay_command)
368 {
369         if (CMD_ARGC > 1)
370                 return ERROR_COMMAND_SYNTAX_ERROR;
371         if (CMD_ARGC == 1) {
372                 unsigned delay;
373                 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay);
374
375                 jtag_set_nsrst_delay(delay);
376         }
377         command_print(CMD, "adapter_nsrst_delay: %u", jtag_get_nsrst_delay());
378         return ERROR_OK;
379 }
380
381 COMMAND_HANDLER(handle_adapter_nsrst_assert_width_command)
382 {
383         if (CMD_ARGC > 1)
384                 return ERROR_COMMAND_SYNTAX_ERROR;
385         if (CMD_ARGC == 1) {
386                 unsigned width;
387                 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], width);
388
389                 jtag_set_nsrst_assert_width(width);
390         }
391         command_print(CMD, "adapter_nsrst_assert_width: %u", jtag_get_nsrst_assert_width());
392         return ERROR_OK;
393 }
394
395 COMMAND_HANDLER(handle_adapter_khz_command)
396 {
397         if (CMD_ARGC > 1)
398                 return ERROR_COMMAND_SYNTAX_ERROR;
399
400         int retval = ERROR_OK;
401         if (CMD_ARGC == 1) {
402                 unsigned khz = 0;
403                 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], khz);
404
405                 retval = jtag_config_khz(khz);
406                 if (ERROR_OK != retval)
407                         return retval;
408         }
409
410         int cur_speed = jtag_get_speed_khz();
411         retval = jtag_get_speed_readable(&cur_speed);
412         if (ERROR_OK != retval)
413                 return retval;
414
415         if (cur_speed)
416                 command_print(CMD, "adapter speed: %d kHz", cur_speed);
417         else
418                 command_print(CMD, "adapter speed: RCLK - adaptive");
419
420         return retval;
421 }
422
423 #ifndef HAVE_JTAG_MINIDRIVER_H
424 #ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
425 COMMAND_HANDLER(handle_usb_location_command)
426 {
427         if (CMD_ARGC == 1)
428                 jtag_usb_set_location(CMD_ARGV[0]);
429
430         command_print(CMD, "adapter usb location: %s", jtag_usb_get_location());
431
432         return ERROR_OK;
433 }
434 #endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */
435
436 static const struct command_registration adapter_usb_command_handlers[] = {
437 #ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
438         {
439                 .name = "location",
440                 .handler = &handle_usb_location_command,
441                 .mode = COMMAND_CONFIG,
442                 .help = "display or set the USB bus location of the USB device",
443                 .usage = "[<bus>-port[.port]...]",
444         },
445 #endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */
446         COMMAND_REGISTRATION_DONE
447 };
448 #endif /* MINIDRIVER */
449
450 static const struct command_registration adapter_command_handlers[] = {
451 #ifndef HAVE_JTAG_MINIDRIVER_H
452         {
453                 .name = "usb",
454                 .mode = COMMAND_ANY,
455                 .help = "usb adapter command group",
456                 .usage = "",
457                 .chain = adapter_usb_command_handlers,
458         },
459 #endif /* MINIDRIVER */
460         COMMAND_REGISTRATION_DONE
461 };
462
463 static const struct command_registration interface_command_handlers[] = {
464         {
465                 .name = "adapter",
466                 .mode = COMMAND_ANY,
467                 .help = "adapter command group",
468                 .usage = "",
469                 .chain = adapter_command_handlers,
470         },
471         {
472                 .name = "adapter_khz",
473                 .handler = handle_adapter_khz_command,
474                 .mode = COMMAND_ANY,
475                 .help = "With an argument, change to the specified maximum "
476                         "jtag speed.  For JTAG, 0 KHz signifies adaptive "
477                         " clocking. "
478                         "With or without argument, display current setting.",
479                 .usage = "[khz]",
480         },
481         {
482                 .name = "adapter_name",
483                 .mode = COMMAND_ANY,
484                 .jim_handler = jim_adapter_name,
485                 .help = "Returns the name of the currently "
486                         "selected adapter (driver)",
487         },
488         {
489                 .name = "adapter_nsrst_delay",
490                 .handler = handle_adapter_nsrst_delay_command,
491                 .mode = COMMAND_ANY,
492                 .help = "delay after deasserting SRST in ms",
493                 .usage = "[milliseconds]",
494         },
495         {
496                 .name = "adapter_nsrst_assert_width",
497                 .handler = handle_adapter_nsrst_assert_width_command,
498                 .mode = COMMAND_ANY,
499                 .help = "delay after asserting SRST in ms",
500                 .usage = "[milliseconds]",
501         },
502         {
503                 .name = "interface",
504                 .handler = handle_interface_command,
505                 .mode = COMMAND_CONFIG,
506                 .help = "Select a debug adapter interface (driver)",
507                 .usage = "driver_name",
508         },
509         {
510                 .name = "interface_transports",
511                 .handler = interface_transport_command,
512                 .mode = COMMAND_CONFIG,
513                 .help = "Declare transports the interface supports.",
514                 .usage = "transport ... ",
515         },
516         {
517                 .name = "interface_list",
518                 .handler = handle_interface_list_command,
519                 .mode = COMMAND_ANY,
520                 .help = "List all built-in debug adapter interfaces (drivers)",
521                 .usage = "",
522         },
523         {
524                 .name = "reset_config",
525                 .handler = handle_reset_config_command,
526                 .mode = COMMAND_ANY,
527                 .help = "configure adapter reset behavior",
528                 .usage = "[none|trst_only|srst_only|trst_and_srst] "
529                         "[srst_pulls_trst|trst_pulls_srst|combined|separate] "
530                         "[srst_gates_jtag|srst_nogate] "
531                         "[trst_push_pull|trst_open_drain] "
532                         "[srst_push_pull|srst_open_drain] "
533                         "[connect_deassert_srst|connect_assert_srst]",
534         },
535         COMMAND_REGISTRATION_DONE
536 };
537
538 /**
539  * Register the commands which deal with arbitrary debug adapter drivers.
540  *
541  * @todo Remove internal assumptions that all debug adapters use JTAG for
542  * transport.  Various types and data structures are not named generically.
543  */
544 int interface_register_commands(struct command_context *ctx)
545 {
546         return register_commands(ctx, NULL, interface_command_handlers);
547 }