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, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
19 ***************************************************************************/
25 #include <jtag/interface.h>
26 #include <jtag/commands.h>
27 #include <transport/transport.h>
28 #include <target/target.h>
29 #include <jtag/aice/aice_transport.h>
30 #include <jtag/drivers/libusb_common.h>
33 #define AICE_KHZ_TO_SPEED_MAP_SIZE 16
34 static int aice_khz_to_speed_map
[AICE_KHZ_TO_SPEED_MAP_SIZE
] = {
53 static const struct aice_port
*aice_port
;
54 static struct aice_port_param_s param
;
55 static uint32_t retry_times
;
56 static uint32_t count_to_check_dbger
;
58 /***************************************************************************/
59 /* External interface implementation */
60 static uint32_t aice_target_id_codes
[AICE_MAX_NUM_CORE
];
61 static uint8_t aice_num_of_target_id_codes
;
63 /***************************************************************************/
65 int aice_init_targets(void)
68 struct target
*target
;
69 struct aice_port_s
*aice
;
71 LOG_DEBUG("aice_init_targets");
73 if (aice_num_of_target_id_codes
== 0) {
74 res
= aice_port
->api
->idcode(aice_target_id_codes
, &aice_num_of_target_id_codes
);
75 if (res
!= ERROR_OK
) {
76 LOG_ERROR("<-- TARGET ERROR! Failed to identify AndesCore "
77 "JTAG Manufacture ID in the JTAG scan chain. "
78 "Failed to access EDM registers. -->");
83 for (target
= all_targets
; target
; target
= target
->next
) {
84 target
->tap
->idcode
= aice_target_id_codes
[target
->tap
->abs_chain_position
];
86 unsigned ii
, limit
= target
->tap
->expected_ids_cnt
;
89 for (ii
= 0; ii
< limit
; ii
++) {
90 uint32_t expected
= target
->tap
->expected_ids
[ii
];
92 /* treat "-expected-id 0" as a "don't-warn" wildcard */
93 if (!expected
|| (target
->tap
->idcode
== expected
)) {
101 ("aice_init_targets: target not found: idcode: %" PRIx32
,
102 target
->tap
->idcode
);
106 aice
= calloc(1, sizeof(struct aice_port_s
));
107 aice
->port
= aice_port
;
108 aice
->coreid
= target
->tap
->abs_chain_position
;
110 target
->tap
->priv
= aice
;
111 target
->tap
->hasidcode
= 1;
117 /***************************************************************************/
118 /* End of External interface implementation */
122 * 2. get/show version number
125 static int aice_init(void)
127 if (ERROR_OK
!= aice_port
->api
->open(¶m
)) {
128 LOG_ERROR("Cannot find AICE Interface! Please check "
129 "connection and permissions.");
130 return ERROR_JTAG_INIT_FAILED
;
133 aice_port
->api
->set_retry_times(retry_times
);
134 aice_port
->api
->set_count_to_check_dbger(count_to_check_dbger
);
136 LOG_INFO("AICE JTAG Interface ready");
141 /* cleanup aice resource
144 static int aice_quit(void)
146 aice_port
->api
->close();
150 static int aice_execute_reset(struct jtag_command
*cmd
)
152 static int last_trst
;
153 int retval
= ERROR_OK
;
155 DEBUG_JTAG_IO("reset trst: %d", cmd
->cmd
.reset
->trst
);
157 if (cmd
->cmd
.reset
->trst
!= last_trst
) {
158 if (cmd
->cmd
.reset
->trst
)
159 retval
= aice_port
->api
->reset();
161 last_trst
= cmd
->cmd
.reset
->trst
;
167 static int aice_execute_command(struct jtag_command
*cmd
)
173 retval
= aice_execute_reset(cmd
);
182 /* aice has no need to implement jtag execution model
184 static int aice_execute_queue(void)
186 struct jtag_command
*cmd
= jtag_command_queue
; /* currently processed command */
192 if (aice_execute_command(cmd
) != ERROR_OK
)
193 retval
= ERROR_JTAG_QUEUE_FAILED
;
201 /* set jtag frequency(base frequency/frequency divider) to your jtag adapter */
202 static int aice_speed(int speed
)
204 return aice_port
->api
->set_jtag_clock(speed
);
207 /* convert jtag adapter frequency(base frequency/frequency divider) to
208 * human readable KHz value */
209 static int aice_speed_div(int speed
, int *khz
)
211 *khz
= aice_khz_to_speed_map
[speed
];
216 /* convert human readable KHz value to jtag adapter frequency
217 * (base frequency/frequency divider) */
218 static int aice_khz(int khz
, int *jtag_speed
)
221 for (i
= 0 ; i
< AICE_KHZ_TO_SPEED_MAP_SIZE
; i
++) {
222 if (khz
== aice_khz_to_speed_map
[i
]) {
224 *jtag_speed
= i
| AICE_TCK_CONTROL_TCK3048
;
231 if (i
== AICE_KHZ_TO_SPEED_MAP_SIZE
) {
232 LOG_INFO("No support the jtag clock: %d", khz
);
233 LOG_INFO("Supported jtag clocks are:");
235 for (i
= 0 ; i
< AICE_KHZ_TO_SPEED_MAP_SIZE
; i
++)
236 LOG_INFO("* %d", aice_khz_to_speed_map
[i
]);
244 /***************************************************************************/
245 /* Command handlers */
246 COMMAND_HANDLER(aice_handle_aice_info_command
)
248 LOG_DEBUG("aice_handle_aice_info_command");
250 command_print(CMD_CTX
, "Description: %s", param
.device_desc
);
251 command_print(CMD_CTX
, "Serial number: %s", param
.serial
);
252 if (strncmp(aice_port
->name
, "aice_pipe", 9) == 0)
253 command_print(CMD_CTX
, "Adapter: %s", param
.adapter_name
);
258 COMMAND_HANDLER(aice_handle_aice_port_command
)
260 LOG_DEBUG("aice_handle_aice_port_command");
263 LOG_ERROR("Need exactly one argument to 'aice port'");
264 return ERROR_COMMAND_SYNTAX_ERROR
;
267 for (const struct aice_port
*l
= aice_port_get_list(); l
->name
; l
++) {
268 if (strcmp(l
->name
, CMD_ARGV
[0]) == 0) {
274 LOG_ERROR("No AICE port '%s' found", CMD_ARGV
[0]);
278 COMMAND_HANDLER(aice_handle_aice_desc_command
)
280 LOG_DEBUG("aice_handle_aice_desc_command");
283 param
.device_desc
= strdup(CMD_ARGV
[0]);
285 LOG_ERROR("expected exactly one argument to aice desc <description>");
290 COMMAND_HANDLER(aice_handle_aice_serial_command
)
292 LOG_DEBUG("aice_handle_aice_serial_command");
295 param
.serial
= strdup(CMD_ARGV
[0]);
297 LOG_ERROR("expected exactly one argument to aice serial <serial-number>");
302 COMMAND_HANDLER(aice_handle_aice_vid_pid_command
)
304 LOG_DEBUG("aice_handle_aice_vid_pid_command");
307 LOG_WARNING("ignoring extra IDs in aice vid_pid (maximum is 1 pair)");
308 return ERROR_COMMAND_SYNTAX_ERROR
;
311 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0], param
.vid
);
312 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[1], param
.pid
);
317 COMMAND_HANDLER(aice_handle_aice_adapter_command
)
319 LOG_DEBUG("aice_handle_aice_adapter_command");
322 param
.adapter_name
= strdup(CMD_ARGV
[0]);
324 LOG_ERROR("expected exactly one argument to aice adapter <adapter-name>");
329 COMMAND_HANDLER(aice_handle_aice_retry_times_command
)
331 LOG_DEBUG("aice_handle_aice_retry_times_command");
334 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], retry_times
);
336 LOG_ERROR("expected exactly one argument to aice retry_times <num_of_retry>");
341 COMMAND_HANDLER(aice_handle_aice_count_to_check_dbger_command
)
343 LOG_DEBUG("aice_handle_aice_count_to_check_dbger_command");
346 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], count_to_check_dbger
);
348 LOG_ERROR("expected exactly one argument to aice count_to_check_dbger "
349 "<count_of_checking>");
354 COMMAND_HANDLER(aice_handle_aice_custom_srst_script_command
)
356 LOG_DEBUG("aice_handle_aice_custom_srst_script_command");
359 aice_port
->api
->set_custom_srst_script(CMD_ARGV
[0]);
366 COMMAND_HANDLER(aice_handle_aice_custom_trst_script_command
)
368 LOG_DEBUG("aice_handle_aice_custom_trst_script_command");
371 aice_port
->api
->set_custom_trst_script(CMD_ARGV
[0]);
378 COMMAND_HANDLER(aice_handle_aice_custom_restart_script_command
)
380 LOG_DEBUG("aice_handle_aice_custom_restart_script_command");
383 aice_port
->api
->set_custom_restart_script(CMD_ARGV
[0]);
390 COMMAND_HANDLER(aice_handle_aice_reset_command
)
392 LOG_DEBUG("aice_handle_aice_reset_command");
394 return aice_port
->api
->reset();
398 static const struct command_registration aice_subcommand_handlers
[] = {
401 .handler
= &aice_handle_aice_info_command
,
402 .mode
= COMMAND_EXEC
,
403 .help
= "show aice info",
404 .usage
= "aice info",
408 .handler
= &aice_handle_aice_port_command
,
409 .mode
= COMMAND_CONFIG
,
410 .help
= "set the port of the AICE",
411 .usage
= "aice port ['aice_pipe'|'aice_usb']",
415 .handler
= &aice_handle_aice_desc_command
,
416 .mode
= COMMAND_CONFIG
,
417 .help
= "set the aice device description",
418 .usage
= "aice desc [desciption string]",
422 .handler
= &aice_handle_aice_serial_command
,
423 .mode
= COMMAND_CONFIG
,
424 .help
= "set the serial number of the AICE device",
425 .usage
= "aice serial [serial string]",
429 .handler
= &aice_handle_aice_vid_pid_command
,
430 .mode
= COMMAND_CONFIG
,
431 .help
= "the vendor and product ID of the AICE device",
432 .usage
= "aice vid_pid (vid pid)*",
436 .handler
= &aice_handle_aice_adapter_command
,
437 .mode
= COMMAND_CONFIG
,
438 .help
= "set the file name of adapter",
439 .usage
= "aice adapter [adapter name]",
442 .name
= "retry_times",
443 .handler
= &aice_handle_aice_retry_times_command
,
444 .mode
= COMMAND_CONFIG
,
445 .help
= "set retry times as AICE timeout",
446 .usage
= "aice retry_times num_of_retry",
449 .name
= "count_to_check_dbger",
450 .handler
= &aice_handle_aice_count_to_check_dbger_command
,
451 .mode
= COMMAND_CONFIG
,
452 .help
= "set retry times as checking $DBGER status",
453 .usage
= "aice count_to_check_dbger count_of_checking",
456 .name
= "custom_srst_script",
457 .handler
= &aice_handle_aice_custom_srst_script_command
,
458 .mode
= COMMAND_CONFIG
,
459 .usage
= "custom_srst_script script_file_name",
460 .help
= "set custom srst script",
463 .name
= "custom_trst_script",
464 .handler
= &aice_handle_aice_custom_trst_script_command
,
465 .mode
= COMMAND_CONFIG
,
466 .usage
= "custom_trst_script script_file_name",
467 .help
= "set custom trst script",
470 .name
= "custom_restart_script",
471 .handler
= &aice_handle_aice_custom_restart_script_command
,
472 .mode
= COMMAND_CONFIG
,
473 .usage
= "custom_restart_script script_file_name",
474 .help
= "set custom restart script",
478 .handler
= &aice_handle_aice_reset_command
,
479 .mode
= COMMAND_EXEC
,
480 .usage
= "aice reset",
481 .help
= "reset AICE",
483 COMMAND_REGISTRATION_DONE
486 static const struct command_registration aice_command_handlers
[] = {
490 .help
= "perform aice management",
491 .usage
= "aice [subcommand]",
492 .chain
= aice_subcommand_handlers
,
494 COMMAND_REGISTRATION_DONE
496 /***************************************************************************/
497 /* End of Command handlers */
499 struct jtag_interface aice_interface
= {
501 .commands
= aice_command_handlers
,
502 .transports
= aice_transports
,
505 .execute_queue
= aice_execute_queue
,
506 .speed
= aice_speed
, /* set interface speed */
507 .speed_div
= aice_speed_div
, /* return readable value */
508 .khz
= aice_khz
, /* convert khz to interface speed value */