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

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)