838b54faaf994ebfab045176fcddcf76ed767d2a
[openocd.git] / src / jtag / aice / aice_interface.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 #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>
31 #include "aice_usb.h"
32
33 #define AICE_KHZ_TO_SPEED_MAP_SIZE 16
34 static int aice_khz_to_speed_map[AICE_KHZ_TO_SPEED_MAP_SIZE] = {
35 30000,
36 15000,
37 7500,
38 3750,
39 1875,
40 937,
41 468,
42 234,
43 48000,
44 24000,
45 12000,
46 6000,
47 3000,
48 1500,
49 750,
50 375,
51 };
52
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;
57
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;
62
63 /***************************************************************************/
64 /* AICE operations */
65 int aice_init_targets(void)
66 {
67 int res;
68 struct target *target;
69 struct aice_port_s *aice;
70
71 LOG_DEBUG("aice_init_targets");
72
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. -->");
79 return res;
80 }
81 }
82
83 for (target = all_targets; target; target = target->next) {
84 target->tap->idcode = aice_target_id_codes[target->tap->abs_chain_position];
85
86 unsigned ii, limit = target->tap->expected_ids_cnt;
87 int found = 0;
88
89 for (ii = 0; ii < limit; ii++) {
90 uint32_t expected = target->tap->expected_ids[ii];
91
92 /* treat "-expected-id 0" as a "don't-warn" wildcard */
93 if (!expected || (target->tap->idcode == expected)) {
94 found = 1;
95 break;
96 }
97 }
98
99 if (found == 0) {
100 LOG_ERROR
101 ("aice_init_targets: target not found: idcode: %" PRIx32,
102 target->tap->idcode);
103 return ERROR_FAIL;
104 }
105
106 aice = calloc(1, sizeof(struct aice_port_s));
107 aice->port = aice_port;
108 aice->coreid = target->tap->abs_chain_position;
109
110 target->tap->priv = aice;
111 target->tap->hasidcode = 1;
112 }
113
114 return ERROR_OK;
115 }
116
117 /***************************************************************************/
118 /* End of External interface implementation */
119
120 /* initial aice
121 * 1. open usb
122 * 2. get/show version number
123 * 3. reset
124 */
125 static int aice_init(void)
126 {
127 if (ERROR_OK != aice_port->api->open(&param)) {
128 LOG_ERROR("Cannot find AICE Interface! Please check "
129 "connection and permissions.");
130 return ERROR_JTAG_INIT_FAILED;
131 }
132
133 aice_port->api->set_retry_times(retry_times);
134 aice_port->api->set_count_to_check_dbger(count_to_check_dbger);
135
136 LOG_INFO("AICE JTAG Interface ready");
137
138 return ERROR_OK;
139 }
140
141 /* cleanup aice resource
142 * close usb
143 */
144 static int aice_quit(void)
145 {
146 aice_port->api->close();
147 return ERROR_OK;
148 }
149
150 static int aice_execute_reset(struct jtag_command *cmd)
151 {
152 static int last_trst;
153 int retval = ERROR_OK;
154
155 DEBUG_JTAG_IO("reset trst: %d", cmd->cmd.reset->trst);
156
157 if (cmd->cmd.reset->trst != last_trst) {
158 if (cmd->cmd.reset->trst)
159 retval = aice_port->api->reset();
160
161 last_trst = cmd->cmd.reset->trst;
162 }
163
164 return retval;
165 }
166
167 static int aice_execute_command(struct jtag_command *cmd)
168 {
169 int retval;
170
171 switch (cmd->type) {
172 case JTAG_RESET:
173 retval = aice_execute_reset(cmd);
174 break;
175 default:
176 retval = ERROR_OK;
177 break;
178 }
179 return retval;
180 }
181
182 /* aice has no need to implement jtag execution model
183 */
184 static int aice_execute_queue(void)
185 {
186 struct jtag_command *cmd = jtag_command_queue; /* currently processed command */
187 int retval;
188
189 retval = ERROR_OK;
190
191 while (cmd) {
192 if (aice_execute_command(cmd) != ERROR_OK)
193 retval = ERROR_JTAG_QUEUE_FAILED;
194
195 cmd = cmd->next;
196 }
197
198 return retval;
199 }
200
201 /* set jtag frequency(base frequency/frequency divider) to your jtag adapter */
202 static int aice_speed(int speed)
203 {
204 return aice_port->api->set_jtag_clock(speed);
205 }
206
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)
210 {
211 *khz = aice_khz_to_speed_map[speed];
212
213 return ERROR_OK;
214 }
215
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)
219 {
220 int i;
221 for (i = 0 ; i < AICE_KHZ_TO_SPEED_MAP_SIZE ; i++) {
222 if (khz == aice_khz_to_speed_map[i]) {
223 if (8 <= i)
224 *jtag_speed = i | AICE_TCK_CONTROL_TCK3048;
225 else
226 *jtag_speed = i;
227 break;
228 }
229 }
230
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:");
234
235 for (i = 0 ; i < AICE_KHZ_TO_SPEED_MAP_SIZE ; i++)
236 LOG_INFO("* %d", aice_khz_to_speed_map[i]);
237
238 return ERROR_FAIL;
239 }
240
241 return ERROR_OK;
242 }
243
244 /***************************************************************************/
245 /* Command handlers */
246 COMMAND_HANDLER(aice_handle_aice_info_command)
247 {
248 LOG_DEBUG("aice_handle_aice_info_command");
249
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);
254
255 return ERROR_OK;
256 }
257
258 COMMAND_HANDLER(aice_handle_aice_port_command)
259 {
260 LOG_DEBUG("aice_handle_aice_port_command");
261
262 if (CMD_ARGC != 1) {
263 LOG_ERROR("Need exactly one argument to 'aice port'");
264 return ERROR_COMMAND_SYNTAX_ERROR;
265 }
266
267 for (const struct aice_port *l = aice_port_get_list(); l->name; l++) {
268 if (strcmp(l->name, CMD_ARGV[0]) == 0) {
269 aice_port = l;
270 return ERROR_OK;
271 }
272 }
273
274 LOG_ERROR("No AICE port '%s' found", CMD_ARGV[0]);
275 return ERROR_FAIL;
276 }
277
278 COMMAND_HANDLER(aice_handle_aice_desc_command)
279 {
280 LOG_DEBUG("aice_handle_aice_desc_command");
281
282 if (CMD_ARGC == 1)
283 param.device_desc = strdup(CMD_ARGV[0]);
284 else
285 LOG_ERROR("expected exactly one argument to aice desc <description>");
286
287 return ERROR_OK;
288 }
289
290 COMMAND_HANDLER(aice_handle_aice_serial_command)
291 {
292 LOG_DEBUG("aice_handle_aice_serial_command");
293
294 if (CMD_ARGC == 1)
295 param.serial = strdup(CMD_ARGV[0]);
296 else
297 LOG_ERROR("expected exactly one argument to aice serial <serial-number>");
298
299 return ERROR_OK;
300 }
301
302 COMMAND_HANDLER(aice_handle_aice_vid_pid_command)
303 {
304 LOG_DEBUG("aice_handle_aice_vid_pid_command");
305
306 if (CMD_ARGC != 2) {
307 LOG_WARNING("ignoring extra IDs in aice vid_pid (maximum is 1 pair)");
308 return ERROR_COMMAND_SYNTAX_ERROR;
309 }
310
311 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], param.vid);
312 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], param.pid);
313
314 return ERROR_OK;
315 }
316
317 COMMAND_HANDLER(aice_handle_aice_adapter_command)
318 {
319 LOG_DEBUG("aice_handle_aice_adapter_command");
320
321 if (CMD_ARGC == 1)
322 param.adapter_name = strdup(CMD_ARGV[0]);
323 else
324 LOG_ERROR("expected exactly one argument to aice adapter <adapter-name>");
325
326 return ERROR_OK;
327 }
328
329 COMMAND_HANDLER(aice_handle_aice_retry_times_command)
330 {
331 LOG_DEBUG("aice_handle_aice_retry_times_command");
332
333 if (CMD_ARGC == 1)
334 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], retry_times);
335 else
336 LOG_ERROR("expected exactly one argument to aice retry_times <num_of_retry>");
337
338 return ERROR_OK;
339 }
340
341 COMMAND_HANDLER(aice_handle_aice_count_to_check_dbger_command)
342 {
343 LOG_DEBUG("aice_handle_aice_count_to_check_dbger_command");
344
345 if (CMD_ARGC == 1)
346 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], count_to_check_dbger);
347 else
348 LOG_ERROR("expected exactly one argument to aice count_to_check_dbger "
349 "<count_of_checking>");
350
351 return ERROR_OK;
352 }
353
354 COMMAND_HANDLER(aice_handle_aice_custom_srst_script_command)
355 {
356 LOG_DEBUG("aice_handle_aice_custom_srst_script_command");
357
358 if (CMD_ARGC > 0) {
359 aice_port->api->set_custom_srst_script(CMD_ARGV[0]);
360 return ERROR_OK;
361 }
362
363 return ERROR_FAIL;
364 }
365
366 COMMAND_HANDLER(aice_handle_aice_custom_trst_script_command)
367 {
368 LOG_DEBUG("aice_handle_aice_custom_trst_script_command");
369
370 if (CMD_ARGC > 0) {
371 aice_port->api->set_custom_trst_script(CMD_ARGV[0]);
372 return ERROR_OK;
373 }
374
375 return ERROR_FAIL;
376 }
377
378 COMMAND_HANDLER(aice_handle_aice_custom_restart_script_command)
379 {
380 LOG_DEBUG("aice_handle_aice_custom_restart_script_command");
381
382 if (CMD_ARGC > 0) {
383 aice_port->api->set_custom_restart_script(CMD_ARGV[0]);
384 return ERROR_OK;
385 }
386
387 return ERROR_FAIL;
388 }
389
390 COMMAND_HANDLER(aice_handle_aice_reset_command)
391 {
392 LOG_DEBUG("aice_handle_aice_reset_command");
393
394 return aice_port->api->reset();
395 }
396
397
398 static const struct command_registration aice_subcommand_handlers[] = {
399 {
400 .name = "info",
401 .handler = &aice_handle_aice_info_command,
402 .mode = COMMAND_EXEC,
403 .help = "show aice info",
404 .usage = "aice info",
405 },
406 {
407 .name = "port",
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']",
412 },
413 {
414 .name = "desc",
415 .handler = &aice_handle_aice_desc_command,
416 .mode = COMMAND_CONFIG,
417 .help = "set the aice device description",
418 .usage = "aice desc [desciption string]",
419 },
420 {
421 .name = "serial",
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]",
426 },
427 {
428 .name = "vid_pid",
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)*",
433 },
434 {
435 .name = "adapter",
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]",
440 },
441 {
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",
447 },
448 {
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",
454 },
455 {
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",
461 },
462 {
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",
468 },
469 {
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",
475 },
476 {
477 .name = "reset",
478 .handler = &aice_handle_aice_reset_command,
479 .mode = COMMAND_EXEC,
480 .usage = "aice reset",
481 .help = "reset AICE",
482 },
483 COMMAND_REGISTRATION_DONE
484 };
485
486 static const struct command_registration aice_command_handlers[] = {
487 {
488 .name = "aice",
489 .mode = COMMAND_ANY,
490 .help = "perform aice management",
491 .usage = "aice [subcommand]",
492 .chain = aice_subcommand_handlers,
493 },
494 COMMAND_REGISTRATION_DONE
495 };
496 /***************************************************************************/
497 /* End of Command handlers */
498
499 struct jtag_interface aice_interface = {
500 .name = "aice",
501 .commands = aice_command_handlers,
502 .transports = aice_transports,
503 .init = aice_init,
504 .quit = aice_quit,
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 */
509 };

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)