4c2f343f5f1e6fb83b2991785d9c22827f8fa3fb
[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, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
19 ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 /* project specific includes */
26 #include <jtag/interface.h>
27 #include <jtag/tcl.h>
28 #include <transport/transport.h>
29 #include <target/target.h>
30 #include <jtag/aice/aice_interface.h>
31 #include <jtag/aice/aice_transport.h>
32
33 /* */
34 static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
35 struct jtag_tap *pTap)
36 {
37 jim_wide w;
38 int e = Jim_GetOpt_Wide(goi, &w);
39 if (e != JIM_OK) {
40 Jim_SetResultFormatted(goi->interp, "option: %s bad parameter",
41 n->name);
42 return e;
43 }
44
45 unsigned expected_len = sizeof(uint32_t) * pTap->expected_ids_cnt;
46 uint32_t *new_expected_ids = malloc(expected_len + sizeof(uint32_t));
47 if (new_expected_ids == NULL) {
48 Jim_SetResultFormatted(goi->interp, "no memory");
49 return JIM_ERR;
50 }
51
52 memcpy(new_expected_ids, pTap->expected_ids, expected_len);
53
54 new_expected_ids[pTap->expected_ids_cnt] = w;
55
56 free(pTap->expected_ids);
57 pTap->expected_ids = new_expected_ids;
58 pTap->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(Jim_GetOptInfo *goi)
67 {
68 struct jtag_tap *pTap;
69 int x;
70 int e;
71 Jim_Nvp *n;
72 char *cp;
73 const Jim_Nvp opts[] = {
74 {.name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID},
75 {.name = NULL, .value = -1},
76 };
77
78 pTap = calloc(1, sizeof(struct jtag_tap));
79 if (!pTap) {
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(pTap);
91 return JIM_ERR;
92 }
93
94 const char *tmp;
95 Jim_GetOpt_String(goi, &tmp, NULL);
96 pTap->chip = strdup(tmp);
97
98 Jim_GetOpt_String(goi, &tmp, NULL);
99 pTap->tapname = strdup(tmp);
100
101 /* name + dot + name + null */
102 x = strlen(pTap->chip) + 1 + strlen(pTap->tapname) + 1;
103 cp = malloc(x);
104 sprintf(cp, "%s.%s", pTap->chip, pTap->tapname);
105 pTap->dotted_name = cp;
106
107 LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
108 pTap->chip, pTap->tapname, pTap->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_NvpUnknown(goi, opts, 0);
114 free(cp);
115 free(pTap);
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, pTap);
122 if (JIM_OK != e) {
123 free(cp);
124 free(pTap);
125 return e;
126 }
127 break;
128 } /* switch (n->value) */
129 } /* while (goi->argc) */
130
131 /* default is enabled-after-reset */
132 pTap->enabled = !pTap->disabled_after_reset;
133
134 jtag_tap_init(pTap);
135 return JIM_OK;
136 }
137
138 /* */
139 static int jim_aice_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
140 {
141 Jim_GetOptInfo 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 static int jim_aice_arp_init(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
164 {
165 LOG_DEBUG("No implement: jim_aice_arp_init");
166
167 return JIM_OK;
168 }
169
170 /* */
171 static int aice_init_reset(struct command_context *cmd_ctx)
172 {
173 LOG_DEBUG("Initializing with hard TRST+SRST reset");
174
175 int retval;
176 enum reset_types jtag_reset_config = jtag_get_reset_config();
177
178 jtag_add_reset(1, 0); /* TAP_RESET */
179 if (jtag_reset_config & RESET_HAS_SRST) {
180 jtag_add_reset(1, 1);
181 if ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0)
182 jtag_add_reset(0, 1);
183 }
184 jtag_add_reset(0, 0);
185 retval = jtag_execute_queue();
186 if (retval != ERROR_OK)
187 return retval;
188
189 return ERROR_OK;
190 }
191
192 /* */
193 static int jim_aice_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
194 {
195 int e = ERROR_OK;
196 Jim_GetOptInfo goi;
197 Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
198 if (goi.argc != 0) {
199 Jim_WrongNumArgs(goi.interp, 1, goi.argv - 1, "(no params)");
200 return JIM_ERR;
201 }
202 struct command_context *context = current_command_context(interp);
203 e = aice_init_reset(context);
204
205 if (e != ERROR_OK) {
206 Jim_Obj *eObj = Jim_NewIntObj(goi.interp, e);
207 Jim_SetResultFormatted(goi.interp, "error: %#s", eObj);
208 Jim_FreeNewObj(goi.interp, eObj);
209 return JIM_ERR;
210 }
211 return JIM_OK;
212 }
213
214 static int jim_aice_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
215 {
216 Jim_GetOptInfo goi;
217 Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
218 if (goi.argc != 0) {
219 Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters");
220 return JIM_ERR;
221 }
222 Jim_SetResult(goi.interp, Jim_NewListObj(goi.interp, NULL, 0));
223 struct jtag_tap *tap;
224
225 for (tap = jtag_all_taps(); tap; tap = tap->next_tap)
226 Jim_ListAppendElement(goi.interp,
227 Jim_GetResult(goi.interp),
228 Jim_NewStringObj(goi.interp,
229 tap->dotted_name, -1));
230
231 return JIM_OK;
232 }
233
234 /* */
235 static const struct command_registration
236 aice_transport_jtag_subcommand_handlers[] = {
237 {
238 .name = "init",
239 .mode = COMMAND_ANY,
240 .handler = handle_aice_init_command,
241 .help = "initialize jtag scan chain",
242 .usage = ""
243 },
244 {
245 .name = "arp_init",
246 .mode = COMMAND_ANY,
247 .jim_handler = jim_aice_arp_init,
248 .help = "Validates JTAG scan chain against the list of "
249 "declared TAPs.",
250 },
251 {
252 .name = "arp_init-reset",
253 .mode = COMMAND_ANY,
254 .jim_handler = jim_aice_arp_init_reset,
255 .help = "Uses TRST and SRST to try resetting everything on "
256 "the JTAG scan chain, then performs 'jtag arp_init'."
257 },
258 {
259 .name = "newtap",
260 .mode = COMMAND_CONFIG,
261 .jim_handler = jim_aice_newtap,
262 .help = "Create a new TAP instance named basename.tap_type, "
263 "and appends it to the scan chain.",
264 .usage = "basename tap_type ['-expected_id' number]"
265 },
266 {
267 .name = "tapisenabled",
268 .mode = COMMAND_EXEC,
269 .jim_handler = jim_jtag_tap_enabler,
270 .help = "Returns a Tcl boolean (0/1) indicating whether "
271 "the TAP is enabled (1) or not (0).",
272 .usage = "tap_name",
273 },
274 {
275 .name = "tapenable",
276 .mode = COMMAND_EXEC,
277 .jim_handler = jim_jtag_tap_enabler,
278 .help = "Try to enable the specified TAP using the "
279 "'tap-enable' TAP event.",
280 .usage = "tap_name",
281 },
282 {
283 .name = "tapdisable",
284 .mode = COMMAND_EXEC,
285 .jim_handler = jim_jtag_tap_enabler,
286 .help = "Try to disable the specified TAP using the "
287 "'tap-disable' TAP event.",
288 .usage = "tap_name",
289 },
290 {
291 .name = "configure",
292 .mode = COMMAND_EXEC,
293 .jim_handler = jim_jtag_configure,
294 .help = "Provide a Tcl handler for the specified "
295 "TAP event.",
296 .usage = "tap_name '-event' event_name handler",
297 },
298 {
299 .name = "cget",
300 .mode = COMMAND_EXEC,
301 .jim_handler = jim_jtag_configure,
302 .help = "Return any Tcl handler for the specified "
303 "TAP event.",
304 .usage = "tap_name '-event' event_name",
305 },
306 {
307 .name = "names",
308 .mode = COMMAND_ANY,
309 .jim_handler = jim_aice_names,
310 .help = "Returns list of all JTAG tap names.",
311 },
312
313 COMMAND_REGISTRATION_DONE
314 };
315
316 /* */
317 static const struct command_registration aice_transport_command_handlers[] = {
318 {
319 .name = "jtag",
320 .mode = COMMAND_ANY,
321 .usage = "",
322 .chain = aice_transport_jtag_subcommand_handlers,
323 },
324 COMMAND_REGISTRATION_DONE
325
326 };
327
328 /* */
329 static int aice_transport_register_commands(struct command_context *cmd_ctx)
330 {
331 return register_commands(cmd_ctx, NULL,
332 aice_transport_command_handlers);
333 }
334
335 /* */
336 static int aice_transport_init(struct command_context *cmd_ctx)
337 {
338 LOG_DEBUG("aice_transport_init");
339 struct target *t = get_current_target(cmd_ctx);
340 struct transport *transport;
341
342 if (!t) {
343 LOG_ERROR("no current target");
344 return ERROR_FAIL;
345 }
346
347 transport = get_current_transport();
348
349 if (!transport) {
350 LOG_ERROR("no transport selected");
351 return ERROR_FAIL;
352 }
353
354 LOG_DEBUG("current transport %s", transport->name);
355
356 return aice_init_targets();
357 }
358
359 /* */
360 static int aice_transport_select(struct command_context *ctx)
361 {
362 LOG_DEBUG("aice_transport_select");
363
364 int retval;
365
366 retval = aice_transport_register_commands(ctx);
367
368 if (retval != ERROR_OK)
369 return retval;
370
371 return ERROR_OK;
372 }
373
374 static struct transport aice_jtag_transport = {
375 .name = "aice_jtag",
376 .select = aice_transport_select,
377 .init = aice_transport_init,
378 };
379
380 const char *aice_transports[] = { "aice_jtag", NULL };
381
382 static void aice_constructor(void) __attribute__((constructor));
383 static void aice_constructor(void)
384 {
385 transport_register(&aice_jtag_transport);
386 }
387

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)