d0f7a49c085c72eb23e6f8ebc788e525c62e49a7
[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
31 /* */
32 static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
33 struct jtag_tap *pTap)
34 {
35 jim_wide w;
36 int e = Jim_GetOpt_Wide(goi, &w);
37 if (e != JIM_OK) {
38 Jim_SetResultFormatted(goi->interp, "option: %s bad parameter",
39 n->name);
40 return e;
41 }
42
43 unsigned expected_len = sizeof(uint32_t) * pTap->expected_ids_cnt;
44 uint32_t *new_expected_ids = malloc(expected_len + sizeof(uint32_t));
45 if (new_expected_ids == NULL) {
46 Jim_SetResultFormatted(goi->interp, "no memory");
47 return JIM_ERR;
48 }
49
50 assert(pTap->expected_ids);
51 memcpy(new_expected_ids, pTap->expected_ids, expected_len);
52
53 new_expected_ids[pTap->expected_ids_cnt] = w;
54
55 free(pTap->expected_ids);
56 pTap->expected_ids = new_expected_ids;
57 pTap->expected_ids_cnt++;
58
59 return JIM_OK;
60 }
61
62 #define NTAP_OPT_EXPECTED_ID 0
63
64 /* */
65 static int jim_aice_newtap_cmd(Jim_GetOptInfo *goi)
66 {
67 struct jtag_tap *pTap;
68 int x;
69 int e;
70 Jim_Nvp *n;
71 char *cp;
72 const Jim_Nvp opts[] = {
73 {.name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID},
74 {.name = NULL, .value = -1},
75 };
76
77 pTap = calloc(1, sizeof(struct jtag_tap));
78 if (!pTap) {
79 Jim_SetResultFormatted(goi->interp, "no memory");
80 return JIM_ERR;
81 }
82
83 /*
84 * we expect CHIP + TAP + OPTIONS
85 * */
86 if (goi->argc < 3) {
87 Jim_SetResultFormatted(goi->interp,
88 "Missing CHIP TAP OPTIONS ....");
89 free(pTap);
90 return JIM_ERR;
91 }
92
93 const char *tmp;
94 Jim_GetOpt_String(goi, &tmp, NULL);
95 pTap->chip = strdup(tmp);
96
97 Jim_GetOpt_String(goi, &tmp, NULL);
98 pTap->tapname = strdup(tmp);
99
100 /* name + dot + name + null */
101 x = strlen(pTap->chip) + 1 + strlen(pTap->tapname) + 1;
102 cp = malloc(x);
103 sprintf(cp, "%s.%s", pTap->chip, pTap->tapname);
104 pTap->dotted_name = cp;
105
106 LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
107 pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc);
108
109 while (goi->argc) {
110 e = Jim_GetOpt_Nvp(goi, opts, &n);
111 if (e != JIM_OK) {
112 Jim_GetOpt_NvpUnknown(goi, opts, 0);
113 free(cp);
114 free(pTap);
115 return e;
116 }
117 LOG_DEBUG("Processing option: %s", n->name);
118 switch (n->value) {
119 case NTAP_OPT_EXPECTED_ID:
120 e = jim_newtap_expected_id(n, goi, pTap);
121 if (JIM_OK != e) {
122 free(cp);
123 free(pTap);
124 return e;
125 }
126 break;
127 } /* switch (n->value) */
128 } /* while (goi->argc) */
129
130 /* default is enabled-after-reset */
131 pTap->enabled = !pTap->disabled_after_reset;
132
133 jtag_tap_init(pTap);
134 return JIM_OK;
135 }
136
137 /* */
138 static int jim_aice_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
139 {
140 Jim_GetOptInfo goi;
141 Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
142 return jim_aice_newtap_cmd(&goi);
143 }
144
145 /* */
146 COMMAND_HANDLER(handle_aice_init_command)
147 {
148 if (CMD_ARGC != 0)
149 return ERROR_COMMAND_SYNTAX_ERROR;
150
151 static bool jtag_initialized;
152 if (jtag_initialized) {
153 LOG_INFO("'jtag init' has already been called");
154 return ERROR_OK;
155 }
156 jtag_initialized = true;
157
158 LOG_DEBUG("Initializing jtag devices...");
159 return jtag_init(CMD_CTX);
160 }
161
162 COMMAND_HANDLER(handle_scan_chain_command)
163 {
164 struct jtag_tap *tap;
165 char expected_id[12];
166
167 aice_scan_jtag_chain();
168 tap = jtag_all_taps();
169 command_print(CMD,
170 " TapName Enabled IdCode Expected IrLen IrCap IrMask");
171 command_print(CMD,
172 "-- ------------------- -------- ---------- ---------- ----- ----- ------");
173
174 while (tap) {
175 uint32_t expected, expected_mask, ii;
176
177 snprintf(expected_id, sizeof expected_id, "0x%08x",
178 (unsigned)((tap->expected_ids_cnt > 0)
179 ? tap->expected_ids[0]
180 : 0));
181 if (tap->ignore_version)
182 expected_id[2] = '*';
183
184 expected = buf_get_u32(tap->expected, 0, tap->ir_length);
185 expected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length);
186
187 command_print(CMD,
188 "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x",
189 tap->abs_chain_position,
190 tap->dotted_name,
191 tap->enabled ? 'Y' : 'n',
192 (unsigned int)(tap->idcode),
193 expected_id,
194 (unsigned int)(tap->ir_length),
195 (unsigned int)(expected),
196 (unsigned int)(expected_mask));
197
198 for (ii = 1; ii < tap->expected_ids_cnt; ii++) {
199 snprintf(expected_id, sizeof expected_id, "0x%08x",
200 (unsigned) tap->expected_ids[ii]);
201 if (tap->ignore_version)
202 expected_id[2] = '*';
203
204 command_print(CMD,
205 " %s",
206 expected_id);
207 }
208
209 tap = tap->next_tap;
210 }
211
212 return ERROR_OK;
213 }
214
215 static int jim_aice_arp_init(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
216 {
217 LOG_DEBUG("No implement: jim_aice_arp_init");
218
219 return JIM_OK;
220 }
221
222 /* */
223 static int aice_init_reset(struct command_context *cmd_ctx)
224 {
225 LOG_DEBUG("Initializing with hard TRST+SRST reset");
226
227 int retval;
228 enum reset_types jtag_reset_config = jtag_get_reset_config();
229
230 jtag_add_reset(1, 0); /* TAP_RESET */
231 if (jtag_reset_config & RESET_HAS_SRST) {
232 jtag_add_reset(1, 1);
233 if ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0)
234 jtag_add_reset(0, 1);
235 }
236 jtag_add_reset(0, 0);
237 retval = jtag_execute_queue();
238 if (retval != ERROR_OK)
239 return retval;
240
241 return ERROR_OK;
242 }
243
244 /* */
245 static int jim_aice_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
246 {
247 int e = ERROR_OK;
248 Jim_GetOptInfo goi;
249 Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
250 if (goi.argc != 0) {
251 Jim_WrongNumArgs(goi.interp, 1, goi.argv - 1, "(no params)");
252 return JIM_ERR;
253 }
254 struct command_context *context = current_command_context(interp);
255 e = aice_init_reset(context);
256
257 if (e != ERROR_OK) {
258 Jim_Obj *eObj = Jim_NewIntObj(goi.interp, e);
259 Jim_SetResultFormatted(goi.interp, "error: %#s", eObj);
260 Jim_FreeNewObj(goi.interp, eObj);
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 Jim_GetOptInfo 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,
391 aice_transport_command_handlers);
392 }
393
394 /* */
395 static int aice_transport_init(struct command_context *cmd_ctx)
396 {
397 LOG_DEBUG("aice_transport_init");
398 struct target *t = get_current_target(cmd_ctx);
399 struct transport *transport;
400
401 if (!t) {
402 LOG_ERROR("no current target");
403 return ERROR_FAIL;
404 }
405
406 transport = get_current_transport();
407
408 if (!transport) {
409 LOG_ERROR("no transport selected");
410 return ERROR_FAIL;
411 }
412
413 LOG_DEBUG("current transport %s", transport->name);
414
415 return aice_init_targets();
416 }
417
418 /* */
419 static int aice_transport_select(struct command_context *ctx)
420 {
421 LOG_DEBUG("aice_transport_select");
422
423 int retval;
424
425 retval = aice_transport_register_commands(ctx);
426
427 if (retval != ERROR_OK)
428 return retval;
429
430 return ERROR_OK;
431 }
432
433 static struct transport aice_jtag_transport = {
434 .name = "aice_jtag",
435 .select = aice_transport_select,
436 .init = aice_transport_init,
437 };
438
439 const char *aice_transports[] = { "aice_jtag", NULL };
440
441 static void aice_constructor(void) __attribute__((constructor));
442 static void aice_constructor(void)
443 {
444 transport_register(&aice_jtag_transport);
445 }

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)