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

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)