1 /***************************************************************************
2 * Copyright (C) 2013 by Andes Technology *
3 * Hsiangkai Wang <hkwang@andestech.com> *
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. *
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. *
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 ***************************************************************************/
23 /* project specific includes */
24 #include <jtag/interface.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>
32 static int jim_newtap_expected_id(Jim_Nvp
*n
, Jim_GetOptInfo
*goi
,
33 struct jtag_tap
*pTap
)
36 int e
= Jim_GetOpt_Wide(goi
, &w
);
38 Jim_SetResultFormatted(goi
->interp
, "option: %s bad parameter",
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");
50 memcpy(new_expected_ids
, pTap
->expected_ids
, expected_len
);
52 new_expected_ids
[pTap
->expected_ids_cnt
] = w
;
54 free(pTap
->expected_ids
);
55 pTap
->expected_ids
= new_expected_ids
;
56 pTap
->expected_ids_cnt
++;
61 #define NTAP_OPT_EXPECTED_ID 0
64 static int jim_aice_newtap_cmd(Jim_GetOptInfo
*goi
)
66 struct jtag_tap
*pTap
;
71 const Jim_Nvp opts
[] = {
72 {.name
= "-expected-id", .value
= NTAP_OPT_EXPECTED_ID
},
73 {.name
= NULL
, .value
= -1},
76 pTap
= calloc(1, sizeof(struct jtag_tap
));
78 Jim_SetResultFormatted(goi
->interp
, "no memory");
83 * we expect CHIP + TAP + OPTIONS
86 Jim_SetResultFormatted(goi
->interp
,
87 "Missing CHIP TAP OPTIONS ....");
93 Jim_GetOpt_String(goi
, &tmp
, NULL
);
94 pTap
->chip
= strdup(tmp
);
96 Jim_GetOpt_String(goi
, &tmp
, NULL
);
97 pTap
->tapname
= strdup(tmp
);
99 /* name + dot + name + null */
100 x
= strlen(pTap
->chip
) + 1 + strlen(pTap
->tapname
) + 1;
102 sprintf(cp
, "%s.%s", pTap
->chip
, pTap
->tapname
);
103 pTap
->dotted_name
= cp
;
105 LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
106 pTap
->chip
, pTap
->tapname
, pTap
->dotted_name
, goi
->argc
);
109 e
= Jim_GetOpt_Nvp(goi
, opts
, &n
);
111 Jim_GetOpt_NvpUnknown(goi
, opts
, 0);
116 LOG_DEBUG("Processing option: %s", n
->name
);
118 case NTAP_OPT_EXPECTED_ID
:
119 e
= jim_newtap_expected_id(n
, goi
, pTap
);
126 } /* switch (n->value) */
127 } /* while (goi->argc) */
129 /* default is enabled-after-reset */
130 pTap
->enabled
= !pTap
->disabled_after_reset
;
137 static int jim_aice_newtap(Jim_Interp
*interp
, int argc
, Jim_Obj
* const *argv
)
140 Jim_GetOpt_Setup(&goi
, interp
, argc
- 1, argv
+ 1);
141 return jim_aice_newtap_cmd(&goi
);
145 COMMAND_HANDLER(handle_aice_init_command
)
148 return ERROR_COMMAND_SYNTAX_ERROR
;
150 static bool jtag_initialized
;
151 if (jtag_initialized
) {
152 LOG_INFO("'jtag init' has already been called");
155 jtag_initialized
= true;
157 LOG_DEBUG("Initializing jtag devices...");
158 return jtag_init(CMD_CTX
);
161 COMMAND_HANDLER(handle_scan_chain_command
)
163 struct jtag_tap
*tap
;
164 char expected_id
[12];
166 aice_scan_jtag_chain();
167 tap
= jtag_all_taps();
168 command_print(CMD_CTX
,
169 " TapName Enabled IdCode Expected IrLen IrCap IrMask");
170 command_print(CMD_CTX
,
171 "-- ------------------- -------- ---------- ---------- ----- ----- ------");
174 uint32_t expected
, expected_mask
, ii
;
176 snprintf(expected_id
, sizeof expected_id
, "0x%08x",
177 (unsigned)((tap
->expected_ids_cnt
> 0)
178 ? tap
->expected_ids
[0]
180 if (tap
->ignore_version
)
181 expected_id
[2] = '*';
183 expected
= buf_get_u32(tap
->expected
, 0, tap
->ir_length
);
184 expected_mask
= buf_get_u32(tap
->expected_mask
, 0, tap
->ir_length
);
186 command_print(CMD_CTX
,
187 "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x",
188 tap
->abs_chain_position
,
190 tap
->enabled
? 'Y' : 'n',
191 (unsigned int)(tap
->idcode
),
193 (unsigned int)(tap
->ir_length
),
194 (unsigned int)(expected
),
195 (unsigned int)(expected_mask
));
197 for (ii
= 1; ii
< tap
->expected_ids_cnt
; ii
++) {
198 snprintf(expected_id
, sizeof expected_id
, "0x%08x",
199 (unsigned) tap
->expected_ids
[ii
]);
200 if (tap
->ignore_version
)
201 expected_id
[2] = '*';
203 command_print(CMD_CTX
,
214 static int jim_aice_arp_init(Jim_Interp
*interp
, int argc
, Jim_Obj
* const *argv
)
216 LOG_DEBUG("No implement: jim_aice_arp_init");
222 static int aice_init_reset(struct command_context
*cmd_ctx
)
224 LOG_DEBUG("Initializing with hard TRST+SRST reset");
227 enum reset_types jtag_reset_config
= jtag_get_reset_config();
229 jtag_add_reset(1, 0); /* TAP_RESET */
230 if (jtag_reset_config
& RESET_HAS_SRST
) {
231 jtag_add_reset(1, 1);
232 if ((jtag_reset_config
& RESET_SRST_PULLS_TRST
) == 0)
233 jtag_add_reset(0, 1);
235 jtag_add_reset(0, 0);
236 retval
= jtag_execute_queue();
237 if (retval
!= ERROR_OK
)
244 static int jim_aice_arp_init_reset(Jim_Interp
*interp
, int argc
, Jim_Obj
* const *argv
)
248 Jim_GetOpt_Setup(&goi
, interp
, argc
- 1, argv
+ 1);
250 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
- 1, "(no params)");
253 struct command_context
*context
= current_command_context(interp
);
254 e
= aice_init_reset(context
);
257 Jim_Obj
*eObj
= Jim_NewIntObj(goi
.interp
, e
);
258 Jim_SetResultFormatted(goi
.interp
, "error: %#s", eObj
);
259 Jim_FreeNewObj(goi
.interp
, eObj
);
265 static int jim_aice_names(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
268 Jim_GetOpt_Setup(&goi
, interp
, argc
- 1, argv
+ 1);
270 Jim_WrongNumArgs(goi
.interp
, 1, goi
.argv
, "Too many parameters");
273 Jim_SetResult(goi
.interp
, Jim_NewListObj(goi
.interp
, NULL
, 0));
274 struct jtag_tap
*tap
;
276 for (tap
= jtag_all_taps(); tap
; tap
= tap
->next_tap
)
277 Jim_ListAppendElement(goi
.interp
,
278 Jim_GetResult(goi
.interp
),
279 Jim_NewStringObj(goi
.interp
,
280 tap
->dotted_name
, -1));
286 static const struct command_registration
287 aice_transport_jtag_subcommand_handlers
[] = {
291 .handler
= handle_aice_init_command
,
292 .help
= "initialize jtag scan chain",
298 .jim_handler
= jim_aice_arp_init
,
299 .help
= "Validates JTAG scan chain against the list of "
303 .name
= "arp_init-reset",
305 .jim_handler
= jim_aice_arp_init_reset
,
306 .help
= "Uses TRST and SRST to try resetting everything on "
307 "the JTAG scan chain, then performs 'jtag arp_init'."
311 .mode
= COMMAND_CONFIG
,
312 .jim_handler
= jim_aice_newtap
,
313 .help
= "Create a new TAP instance named basename.tap_type, "
314 "and appends it to the scan chain.",
315 .usage
= "basename tap_type ['-expected_id' number]"
318 .name
= "tapisenabled",
319 .mode
= COMMAND_EXEC
,
320 .jim_handler
= jim_jtag_tap_enabler
,
321 .help
= "Returns a Tcl boolean (0/1) indicating whether "
322 "the TAP is enabled (1) or not (0).",
327 .mode
= COMMAND_EXEC
,
328 .jim_handler
= jim_jtag_tap_enabler
,
329 .help
= "Try to enable the specified TAP using the "
330 "'tap-enable' TAP event.",
334 .name
= "tapdisable",
335 .mode
= COMMAND_EXEC
,
336 .jim_handler
= jim_jtag_tap_enabler
,
337 .help
= "Try to disable the specified TAP using the "
338 "'tap-disable' TAP event.",
343 .mode
= COMMAND_EXEC
,
344 .jim_handler
= jim_jtag_configure
,
345 .help
= "Provide a Tcl handler for the specified "
347 .usage
= "tap_name '-event' event_name handler",
351 .mode
= COMMAND_EXEC
,
352 .jim_handler
= jim_jtag_configure
,
353 .help
= "Return any Tcl handler for the specified "
355 .usage
= "tap_name '-event' event_name",
360 .jim_handler
= jim_aice_names
,
361 .help
= "Returns list of all JTAG tap names.",
364 .name
= "scan_chain",
365 .handler
= handle_scan_chain_command
,
367 .help
= "print current scan chain configuration",
371 COMMAND_REGISTRATION_DONE
375 static const struct command_registration aice_transport_command_handlers
[] = {
380 .chain
= aice_transport_jtag_subcommand_handlers
,
382 COMMAND_REGISTRATION_DONE
387 static int aice_transport_register_commands(struct command_context
*cmd_ctx
)
389 return register_commands(cmd_ctx
, NULL
,
390 aice_transport_command_handlers
);
394 static int aice_transport_init(struct command_context
*cmd_ctx
)
396 LOG_DEBUG("aice_transport_init");
397 struct target
*t
= get_current_target(cmd_ctx
);
398 struct transport
*transport
;
401 LOG_ERROR("no current target");
405 transport
= get_current_transport();
408 LOG_ERROR("no transport selected");
412 LOG_DEBUG("current transport %s", transport
->name
);
414 return aice_init_targets();
418 static int aice_transport_select(struct command_context
*ctx
)
420 LOG_DEBUG("aice_transport_select");
424 retval
= aice_transport_register_commands(ctx
);
426 if (retval
!= ERROR_OK
)
432 static struct transport aice_jtag_transport
= {
434 .select
= aice_transport_select
,
435 .init
= aice_transport_init
,
438 const char *aice_transports
[] = { "aice_jtag", NULL
};
440 static void aice_constructor(void) __attribute__((constructor
));
441 static void aice_constructor(void)
443 transport_register(&aice_jtag_transport
);