openocd: use single line for register_commands*()
[openocd.git] / src / jtag / aice / aice_transport.c
1 /***************************************************************************
2 * Copyright (C) 2013 by Andes Technology *
3 * Hsiangkai Wang <hkwang@andestech.com> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 /* project specific includes */
24 #include <jtag/interface.h>
25 #include <jtag/tcl.h>
26 #include <transport/transport.h>
27 #include <target/target.h>
28 #include <jtag/aice/aice_interface.h>
29 #include <jtag/aice/aice_transport.h>
30 #include <string.h>
31
32 /* */
33 static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi,
34 struct jtag_tap *tap)
35 {
36 jim_wide w;
37 int e = jim_getopt_wide(goi, &w);
38 if (e != JIM_OK) {
39 Jim_SetResultFormatted(goi->interp, "option: %s bad parameter",
40 n->name);
41 return e;
42 }
43
44 unsigned expected_len = sizeof(uint32_t) * tap->expected_ids_cnt;
45 uint32_t *new_expected_ids = malloc(expected_len + sizeof(uint32_t));
46 if (!new_expected_ids) {
47 Jim_SetResultFormatted(goi->interp, "no memory");
48 return JIM_ERR;
49 }
50
51 assert(tap->expected_ids);
52 memcpy(new_expected_ids, tap->expected_ids, expected_len);
53
54 new_expected_ids[tap->expected_ids_cnt] = w;
55
56 free(tap->expected_ids);
57 tap->expected_ids = new_expected_ids;
58 tap->expected_ids_cnt++;
59
60 return JIM_OK;
61 }
62
63 #define NTAP_OPT_EXPECTED_ID 0
64
65 /* */
66 static int jim_aice_newtap_cmd(struct jim_getopt_info *goi)
67 {
68 struct jtag_tap *tap;
69 int x;
70 int e;
71 struct jim_nvp *n;
72 char *cp;
73 const struct jim_nvp opts[] = {
74 {.name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID},
75 {.name = NULL, .value = -1},
76 };
77
78 tap = calloc(1, sizeof(struct jtag_tap));
79 if (!tap) {
80 Jim_SetResultFormatted(goi->interp, "no memory");
81 return JIM_ERR;
82 }
83
84 /*
85 * we expect CHIP + TAP + OPTIONS
86 * */
87 if (goi->argc < 3) {
88 Jim_SetResultFormatted(goi->interp,
89 "Missing CHIP TAP OPTIONS ....");
90 free(tap);
91 return JIM_ERR;
92 }
93
94 const char *tmp;
95 jim_getopt_string(goi, &tmp, NULL);
96 tap->chip = strdup(tmp);
97
98 jim_getopt_string(goi, &tmp, NULL);
99 tap->tapname = strdup(tmp);
100
101 /* name + dot + name + null */
102 x = strlen(tap->chip) + 1 + strlen(tap->tapname) + 1;
103 cp = malloc(x);
104 sprintf(cp, "%s.%s", tap->chip, tap->tapname);
105 tap->dotted_name = cp;
106
107 LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
108 tap->chip, tap->tapname, tap->dotted_name, goi->argc);
109
110 while (goi->argc) {
111 e = jim_getopt_nvp(goi, opts, &n);
112 if (e != JIM_OK) {
113 jim_getopt_nvp_unknown(goi, opts, 0);
114 free(cp);
115 free(tap);
116 return e;
117 }
118 LOG_DEBUG("Processing option: %s", n->name);
119 switch (n->value) {
120 case NTAP_OPT_EXPECTED_ID:
121 e = jim_newtap_expected_id(n, goi, tap);
122 if (e != JIM_OK) {
123 free(cp);
124 free(tap);
125 return e;
126 }
127 break;
128 } /* switch (n->value) */
129 } /* while (goi->argc) */
130
131 /* default is enabled-after-reset */
132 tap->enabled = !tap->disabled_after_reset;
133
134 jtag_tap_init(tap);
135 return JIM_OK;
136 }
137
138 /* */
139 static int jim_aice_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
140 {
141 struct jim_getopt_info goi;
142 jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
143 return jim_aice_newtap_cmd(&goi);
144 }
145
146 /* */
147 COMMAND_HANDLER(handle_aice_init_command)
148 {
149 if (CMD_ARGC != 0)
150 return ERROR_COMMAND_SYNTAX_ERROR;
151
152 static bool jtag_initialized;
153 if (jtag_initialized) {
154 LOG_INFO("'jtag init' has already been called");
155 return ERROR_OK;
156 }
157 jtag_initialized = true;
158
159 LOG_DEBUG("Initializing jtag devices...");
160 return jtag_init(CMD_CTX);
161 }
162
163 COMMAND_HANDLER(handle_scan_chain_command)
164 {
165 struct jtag_tap *tap;
166 char expected_id[12];
167
168 aice_scan_jtag_chain();
169 tap = jtag_all_taps();
170 command_print(CMD,
171 " TapName Enabled IdCode Expected IrLen IrCap IrMask");
172 command_print(CMD,
173 "-- ------------------- -------- ---------- ---------- ----- ----- ------");
174
175 while (tap) {
176 uint32_t expected, expected_mask, ii;
177
178 snprintf(expected_id, sizeof(expected_id), "0x%08x",
179 (unsigned)((tap->expected_ids_cnt > 0)
180 ? tap->expected_ids[0]
181 : 0));
182 if (tap->ignore_version)
183 expected_id[2] = '*';
184
185 expected = buf_get_u32(tap->expected, 0, tap->ir_length);
186 expected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length);
187
188 command_print(CMD,
189 "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x",
190 tap->abs_chain_position,
191 tap->dotted_name,
192 tap->enabled ? 'Y' : 'n',
193 (unsigned int)(tap->idcode),
194 expected_id,
195 (unsigned int)(tap->ir_length),
196 (unsigned int)(expected),
197 (unsigned int)(expected_mask));
198
199 for (ii = 1; ii < tap->expected_ids_cnt; ii++) {
200 snprintf(expected_id, sizeof(expected_id), "0x%08x",
201 (unsigned) tap->expected_ids[ii]);
202 if (tap->ignore_version)
203 expected_id[2] = '*';
204
205 command_print(CMD,
206 " %s",
207 expected_id);
208 }
209
210 tap = tap->next_tap;
211 }
212
213 return ERROR_OK;
214 }
215
216 static int jim_aice_arp_init(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
217 {
218 LOG_DEBUG("No implement: jim_aice_arp_init");
219
220 return JIM_OK;
221 }
222
223 /* */
224 static int aice_init_reset(struct command_context *cmd_ctx)
225 {
226 LOG_DEBUG("Initializing with hard TRST+SRST reset");
227
228 int retval;
229 enum reset_types jtag_reset_config = jtag_get_reset_config();
230
231 jtag_add_reset(1, 0); /* TAP_RESET */
232 if (jtag_reset_config & RESET_HAS_SRST) {
233 jtag_add_reset(1, 1);
234 if ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0)
235 jtag_add_reset(0, 1);
236 }
237 jtag_add_reset(0, 0);
238 retval = jtag_execute_queue();
239 if (retval != ERROR_OK)
240 return retval;
241
242 return ERROR_OK;
243 }
244
245 /* */
246 static int jim_aice_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
247 {
248 int e = ERROR_OK;
249 struct jim_getopt_info goi;
250 jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
251 if (goi.argc != 0) {
252 Jim_WrongNumArgs(goi.interp, 1, goi.argv - 1, "(no params)");
253 return JIM_ERR;
254 }
255 struct command_context *context = current_command_context(interp);
256 e = aice_init_reset(context);
257
258 if (e != ERROR_OK) {
259 Jim_Obj *obj = Jim_NewIntObj(goi.interp, e);
260 Jim_SetResultFormatted(goi.interp, "error: %#s", obj);
261 return JIM_ERR;
262 }
263 return JIM_OK;
264 }
265
266 static int jim_aice_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
267 {
268 struct jim_getopt_info goi;
269 jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
270 if (goi.argc != 0) {
271 Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters");
272 return JIM_ERR;
273 }
274 Jim_SetResult(goi.interp, Jim_NewListObj(goi.interp, NULL, 0));
275 struct jtag_tap *tap;
276
277 for (tap = jtag_all_taps(); tap; tap = tap->next_tap)
278 Jim_ListAppendElement(goi.interp,
279 Jim_GetResult(goi.interp),
280 Jim_NewStringObj(goi.interp,
281 tap->dotted_name, -1));
282
283 return JIM_OK;
284 }
285
286 /* */
287 static const struct command_registration
288 aice_transport_jtag_subcommand_handlers[] = {
289 {
290 .name = "init",
291 .mode = COMMAND_ANY,
292 .handler = handle_aice_init_command,
293 .help = "initialize jtag scan chain",
294 .usage = ""
295 },
296 {
297 .name = "arp_init",
298 .mode = COMMAND_ANY,
299 .jim_handler = jim_aice_arp_init,
300 .help = "Validates JTAG scan chain against the list of "
301 "declared TAPs.",
302 },
303 {
304 .name = "arp_init-reset",
305 .mode = COMMAND_ANY,
306 .jim_handler = jim_aice_arp_init_reset,
307 .help = "Uses TRST and SRST to try resetting everything on "
308 "the JTAG scan chain, then performs 'jtag arp_init'."
309 },
310 {
311 .name = "newtap",
312 .mode = COMMAND_CONFIG,
313 .jim_handler = jim_aice_newtap,
314 .help = "Create a new TAP instance named basename.tap_type, "
315 "and appends it to the scan chain.",
316 .usage = "basename tap_type ['-expected_id' number]"
317 },
318 {
319 .name = "tapisenabled",
320 .mode = COMMAND_EXEC,
321 .jim_handler = jim_jtag_tap_enabler,
322 .help = "Returns a Tcl boolean (0/1) indicating whether "
323 "the TAP is enabled (1) or not (0).",
324 .usage = "tap_name",
325 },
326 {
327 .name = "tapenable",
328 .mode = COMMAND_EXEC,
329 .jim_handler = jim_jtag_tap_enabler,
330 .help = "Try to enable the specified TAP using the "
331 "'tap-enable' TAP event.",
332 .usage = "tap_name",
333 },
334 {
335 .name = "tapdisable",
336 .mode = COMMAND_EXEC,
337 .jim_handler = jim_jtag_tap_enabler,
338 .help = "Try to disable the specified TAP using the "
339 "'tap-disable' TAP event.",
340 .usage = "tap_name",
341 },
342 {
343 .name = "configure",
344 .mode = COMMAND_ANY,
345 .jim_handler = jim_jtag_configure,
346 .help = "Provide a Tcl handler for the specified "
347 "TAP event.",
348 .usage = "tap_name '-event' event_name handler",
349 },
350 {
351 .name = "cget",
352 .mode = COMMAND_EXEC,
353 .jim_handler = jim_jtag_configure,
354 .help = "Return any Tcl handler for the specified "
355 "TAP event.",
356 .usage = "tap_name '-event' event_name",
357 },
358 {
359 .name = "names",
360 .mode = COMMAND_ANY,
361 .jim_handler = jim_aice_names,
362 .help = "Returns list of all JTAG tap names.",
363 },
364 {
365 .name = "scan_chain",
366 .handler = handle_scan_chain_command,
367 .mode = COMMAND_ANY,
368 .help = "print current scan chain configuration",
369 .usage = ""
370 },
371
372 COMMAND_REGISTRATION_DONE
373 };
374
375 /* */
376 static const struct command_registration aice_transport_command_handlers[] = {
377 {
378 .name = "jtag",
379 .mode = COMMAND_ANY,
380 .usage = "",
381 .chain = aice_transport_jtag_subcommand_handlers,
382 },
383 COMMAND_REGISTRATION_DONE
384
385 };
386
387 /* */
388 static int aice_transport_register_commands(struct command_context *cmd_ctx)
389 {
390 return register_commands(cmd_ctx, NULL, aice_transport_command_handlers);
391 }
392
393 /* */
394 static int aice_transport_init(struct command_context *cmd_ctx)
395 {
396 LOG_DEBUG("aice_transport_init");
397 struct target *t = get_current_target(cmd_ctx);
398 struct transport *transport;
399
400 if (!t) {
401 LOG_ERROR("no current target");
402 return ERROR_FAIL;
403 }
404
405 transport = get_current_transport();
406
407 if (!transport) {
408 LOG_ERROR("no transport selected");
409 return ERROR_FAIL;
410 }
411
412 LOG_DEBUG("current transport %s", transport->name);
413
414 return aice_init_targets();
415 }
416
417 /* */
418 static int aice_transport_select(struct command_context *ctx)
419 {
420 LOG_DEBUG("aice_transport_select");
421
422 int retval;
423
424 retval = aice_transport_register_commands(ctx);
425
426 if (retval != ERROR_OK)
427 return retval;
428
429 return ERROR_OK;
430 }
431
432 static struct transport aice_jtag_transport = {
433 .name = "aice_jtag",
434 .select = aice_transport_select,
435 .init = aice_transport_init,
436 };
437
438 const char *aice_transports[] = { "aice_jtag", NULL };
439
440 static void aice_constructor(void) __attribute__((constructor));
441 static void aice_constructor(void)
442 {
443 transport_register(&aice_jtag_transport);
444 }

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)