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

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)