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

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)