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

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)