jtag/aice: switch to command 'adapter serial'
[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, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include <jtag/adapter.h>
24 #include <jtag/interface.h>
25 #include <jtag/commands.h>
26 #include <transport/transport.h>
27 #include <target/target.h>
28 #include <jtag/aice/aice_transport.h>
29 #include "aice_usb.h"
30
31 #define AICE_KHZ_TO_SPEED_MAP_SIZE 16
32 static const int aice_khz_to_speed_map[AICE_KHZ_TO_SPEED_MAP_SIZE] = {
33 30000,
34 15000,
35 7500,
36 3750,
37 1875,
38 937,
39 468,
40 234,
41 48000,
42 24000,
43 12000,
44 6000,
45 3000,
46 1500,
47 750,
48 375,
49 };
50
51 static const struct aice_port *aice_port;
52 static struct aice_port_param_s param;
53 static uint32_t retry_times;
54 static uint32_t count_to_check_dbger;
55
56 /***************************************************************************/
57 /* External interface implementation */
58 static uint32_t aice_target_id_codes[AICE_MAX_NUM_CORE];
59 static uint8_t aice_num_of_target_id_codes;
60
61 /***************************************************************************/
62 /* AICE operations */
63 int aice_init_targets(void)
64 {
65 int res;
66 struct target *target;
67 struct aice_port_s *aice;
68
69 LOG_DEBUG("aice_init_targets");
70
71 if (aice_num_of_target_id_codes == 0) {
72 res = aice_port->api->idcode(aice_target_id_codes, &aice_num_of_target_id_codes);
73 if (res != ERROR_OK) {
74 LOG_ERROR("<-- TARGET ERROR! Failed to identify AndesCore "
75 "JTAG Manufacture ID in the JTAG scan chain. "
76 "Failed to access EDM registers. -->");
77 return res;
78 }
79 }
80
81 for (target = all_targets; target; target = target->next) {
82 target->tap->idcode = aice_target_id_codes[target->tap->abs_chain_position];
83
84 unsigned ii, limit = target->tap->expected_ids_cnt;
85 int found = 0;
86
87 for (ii = 0; ii < limit; ii++) {
88 uint32_t expected = target->tap->expected_ids[ii];
89
90 /* treat "-expected-id 0" as a "don't-warn" wildcard */
91 if (!expected || (target->tap->idcode == expected)) {
92 found = 1;
93 break;
94 }
95 }
96
97 if (found == 0) {
98 LOG_ERROR
99 ("aice_init_targets: target not found: idcode: %" PRIx32,
100 target->tap->idcode);
101 return ERROR_FAIL;
102 }
103
104 aice = calloc(1, sizeof(struct aice_port_s));
105 aice->port = aice_port;
106 aice->coreid = target->tap->abs_chain_position;
107
108 target->tap->priv = aice;
109 target->tap->hasidcode = 1;
110 }
111
112 return ERROR_OK;
113 }
114
115 /***************************************************************************/
116 /* End of External interface implementation */
117
118 /* initial aice
119 * 1. open usb
120 * 2. get/show version number
121 * 3. reset
122 */
123 static int aice_init(void)
124 {
125 if (aice_port->api->open(&param) != ERROR_OK) {
126 LOG_ERROR("Cannot find AICE Interface! Please check "
127 "connection and permissions.");
128 return ERROR_JTAG_INIT_FAILED;
129 }
130
131 aice_port->api->set_retry_times(retry_times);
132 aice_port->api->set_count_to_check_dbger(count_to_check_dbger);
133
134 LOG_INFO("AICE JTAG Interface ready");
135
136 return ERROR_OK;
137 }
138
139 /* cleanup aice resource
140 * close usb
141 */
142 static int aice_quit(void)
143 {
144 aice_port->api->close();
145 return ERROR_OK;
146 }
147
148 static int aice_execute_reset(struct jtag_command *cmd)
149 {
150 static int last_trst;
151 int retval = ERROR_OK;
152
153 LOG_DEBUG_IO("reset trst: %d", cmd->cmd.reset->trst);
154
155 if (cmd->cmd.reset->trst != last_trst) {
156 if (cmd->cmd.reset->trst)
157 retval = aice_port->api->reset();
158
159 last_trst = cmd->cmd.reset->trst;
160 }
161
162 return retval;
163 }
164
165 static int aice_execute_command(struct jtag_command *cmd)
166 {
167 int retval;
168
169 switch (cmd->type) {
170 case JTAG_RESET:
171 retval = aice_execute_reset(cmd);
172 break;
173 default:
174 retval = ERROR_OK;
175 break;
176 }
177 return retval;
178 }
179
180 /* aice has no need to implement jtag execution model
181 */
182 static int aice_execute_queue(void)
183 {
184 struct jtag_command *cmd = jtag_command_queue; /* currently processed command */
185 int retval;
186
187 retval = ERROR_OK;
188
189 while (cmd) {
190 if (aice_execute_command(cmd) != ERROR_OK)
191 retval = ERROR_JTAG_QUEUE_FAILED;
192
193 cmd = cmd->next;
194 }
195
196 return retval;
197 }
198
199 /* set jtag frequency(base frequency/frequency divider) to your jtag adapter */
200 static int aice_speed(int speed)
201 {
202 return aice_port->api->set_jtag_clock(speed);
203 }
204
205 /* convert jtag adapter frequency(base frequency/frequency divider) to
206 * human readable KHz value */
207 static int aice_speed_div(int speed, int *khz)
208 {
209 *khz = aice_khz_to_speed_map[speed];
210
211 return ERROR_OK;
212 }
213
214 /* convert human readable KHz value to jtag adapter frequency
215 * (base frequency/frequency divider) */
216 static int aice_khz(int khz, int *jtag_speed)
217 {
218 int i;
219 for (i = 0 ; i < AICE_KHZ_TO_SPEED_MAP_SIZE ; i++) {
220 if (khz == aice_khz_to_speed_map[i]) {
221 if (i >= 8)
222 *jtag_speed = i | AICE_TCK_CONTROL_TCK3048;
223 else
224 *jtag_speed = i;
225 break;
226 }
227 }
228
229 if (i == AICE_KHZ_TO_SPEED_MAP_SIZE) {
230 LOG_INFO("No support the jtag clock: %d", khz);
231 LOG_INFO("Supported jtag clocks are:");
232
233 for (i = 0 ; i < AICE_KHZ_TO_SPEED_MAP_SIZE ; i++)
234 LOG_INFO("* %d", aice_khz_to_speed_map[i]);
235
236 return ERROR_FAIL;
237 }
238
239 return ERROR_OK;
240 }
241
242 int aice_scan_jtag_chain(void)
243 {
244 LOG_DEBUG("=== %s ===", __func__);
245 uint8_t num_of_idcode = 0;
246 struct target *target;
247
248 int res = aice_port->api->idcode(aice_target_id_codes, &num_of_idcode);
249 if (res != ERROR_OK) {
250 LOG_ERROR("<-- TARGET ERROR! Failed to identify AndesCore "
251 "JTAG Manufacture ID in the JTAG scan chain. "
252 "Failed to access EDM registers. -->");
253 return res;
254 }
255
256 for (unsigned int i = 0; i < num_of_idcode; i++)
257 LOG_DEBUG("id_codes[%u] = 0x%" PRIx32, i, aice_target_id_codes[i]);
258
259 /* Update tap idcode */
260 for (target = all_targets; target; target = target->next)
261 target->tap->idcode = aice_target_id_codes[target->tap->abs_chain_position];
262
263 return ERROR_OK;
264 }
265
266 /***************************************************************************/
267 /* Command handlers */
268 COMMAND_HANDLER(aice_handle_aice_info_command)
269 {
270 LOG_DEBUG("aice_handle_aice_info_command");
271
272 command_print(CMD, "Description: %s", param.device_desc);
273 command_print(CMD, "Serial number: %s", adapter_get_required_serial());
274 if (strncmp(aice_port->name, "aice_pipe", 9) == 0)
275 command_print(CMD, "Adapter: %s", param.adapter_name);
276
277 return ERROR_OK;
278 }
279
280 COMMAND_HANDLER(aice_handle_aice_port_command)
281 {
282 LOG_DEBUG("aice_handle_aice_port_command");
283
284 if (CMD_ARGC != 1) {
285 LOG_ERROR("Need exactly one argument to 'aice port'");
286 return ERROR_COMMAND_SYNTAX_ERROR;
287 }
288
289 for (const struct aice_port *l = aice_port_get_list(); l->name; l++) {
290 if (strcmp(l->name, CMD_ARGV[0]) == 0) {
291 aice_port = l;
292 return ERROR_OK;
293 }
294 }
295
296 LOG_ERROR("No AICE port '%s' found", CMD_ARGV[0]);
297 return ERROR_FAIL;
298 }
299
300 COMMAND_HANDLER(aice_handle_aice_desc_command)
301 {
302 LOG_DEBUG("aice_handle_aice_desc_command");
303
304 if (CMD_ARGC == 1)
305 param.device_desc = strdup(CMD_ARGV[0]);
306 else
307 LOG_ERROR("expected exactly one argument to aice desc <description>");
308
309 return ERROR_OK;
310 }
311
312 COMMAND_HANDLER(aice_handle_aice_vid_pid_command)
313 {
314 LOG_DEBUG("aice_handle_aice_vid_pid_command");
315
316 if (CMD_ARGC != 2) {
317 LOG_WARNING("ignoring extra IDs in aice vid_pid (maximum is 1 pair)");
318 return ERROR_COMMAND_SYNTAX_ERROR;
319 }
320
321 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], param.vid);
322 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], param.pid);
323
324 return ERROR_OK;
325 }
326
327 COMMAND_HANDLER(aice_handle_aice_adapter_command)
328 {
329 LOG_DEBUG("aice_handle_aice_adapter_command");
330
331 if (CMD_ARGC == 1)
332 param.adapter_name = strdup(CMD_ARGV[0]);
333 else
334 LOG_ERROR("expected exactly one argument to aice adapter <adapter-name>");
335
336 return ERROR_OK;
337 }
338
339 COMMAND_HANDLER(aice_handle_aice_retry_times_command)
340 {
341 LOG_DEBUG("aice_handle_aice_retry_times_command");
342
343 if (CMD_ARGC == 1)
344 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], retry_times);
345 else
346 LOG_ERROR("expected exactly one argument to aice retry_times <num_of_retry>");
347
348 return ERROR_OK;
349 }
350
351 COMMAND_HANDLER(aice_handle_aice_count_to_check_dbger_command)
352 {
353 LOG_DEBUG("aice_handle_aice_count_to_check_dbger_command");
354
355 if (CMD_ARGC == 1)
356 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], count_to_check_dbger);
357 else
358 LOG_ERROR("expected exactly one argument to aice count_to_check_dbger "
359 "<count_of_checking>");
360
361 return ERROR_OK;
362 }
363
364 COMMAND_HANDLER(aice_handle_aice_custom_srst_script_command)
365 {
366 LOG_DEBUG("aice_handle_aice_custom_srst_script_command");
367
368 if (CMD_ARGC > 0) {
369 aice_port->api->set_custom_srst_script(CMD_ARGV[0]);
370 return ERROR_OK;
371 }
372
373 return ERROR_FAIL;
374 }
375
376 COMMAND_HANDLER(aice_handle_aice_custom_trst_script_command)
377 {
378 LOG_DEBUG("aice_handle_aice_custom_trst_script_command");
379
380 if (CMD_ARGC > 0) {
381 aice_port->api->set_custom_trst_script(CMD_ARGV[0]);
382 return ERROR_OK;
383 }
384
385 return ERROR_FAIL;
386 }
387
388 COMMAND_HANDLER(aice_handle_aice_custom_restart_script_command)
389 {
390 LOG_DEBUG("aice_handle_aice_custom_restart_script_command");
391
392 if (CMD_ARGC > 0) {
393 aice_port->api->set_custom_restart_script(CMD_ARGV[0]);
394 return ERROR_OK;
395 }
396
397 return ERROR_FAIL;
398 }
399
400 COMMAND_HANDLER(aice_handle_aice_reset_command)
401 {
402 LOG_DEBUG("aice_handle_aice_reset_command");
403
404 return aice_port->api->reset();
405 }
406
407
408 static const struct command_registration aice_subcommand_handlers[] = {
409 {
410 .name = "info",
411 .handler = &aice_handle_aice_info_command,
412 .mode = COMMAND_EXEC,
413 .help = "show aice info",
414 .usage = "",
415 },
416 {
417 .name = "port",
418 .handler = &aice_handle_aice_port_command,
419 .mode = COMMAND_CONFIG,
420 .help = "set the port of the AICE",
421 .usage = "['aice_pipe'|'aice_usb']",
422 },
423 {
424 .name = "desc",
425 .handler = &aice_handle_aice_desc_command,
426 .mode = COMMAND_CONFIG,
427 .help = "set the aice device description",
428 .usage = "[description string]",
429 },
430 {
431 .name = "vid_pid",
432 .handler = &aice_handle_aice_vid_pid_command,
433 .mode = COMMAND_CONFIG,
434 .help = "the vendor and product ID of the AICE device",
435 .usage = "(vid pid)*",
436 },
437 {
438 .name = "adapter",
439 .handler = &aice_handle_aice_adapter_command,
440 .mode = COMMAND_CONFIG,
441 .help = "set the file name of adapter",
442 .usage = "[adapter name]",
443 },
444 {
445 .name = "retry_times",
446 .handler = &aice_handle_aice_retry_times_command,
447 .mode = COMMAND_CONFIG,
448 .help = "set retry times as AICE timeout",
449 .usage = "num_of_retry",
450 },
451 {
452 .name = "count_to_check_dbger",
453 .handler = &aice_handle_aice_count_to_check_dbger_command,
454 .mode = COMMAND_CONFIG,
455 .help = "set retry times as checking $DBGER status",
456 .usage = "count_of_checking",
457 },
458 {
459 .name = "custom_srst_script",
460 .handler = &aice_handle_aice_custom_srst_script_command,
461 .mode = COMMAND_CONFIG,
462 .usage = "script_file_name",
463 .help = "set custom srst script",
464 },
465 {
466 .name = "custom_trst_script",
467 .handler = &aice_handle_aice_custom_trst_script_command,
468 .mode = COMMAND_CONFIG,
469 .usage = "script_file_name",
470 .help = "set custom trst script",
471 },
472 {
473 .name = "custom_restart_script",
474 .handler = &aice_handle_aice_custom_restart_script_command,
475 .mode = COMMAND_CONFIG,
476 .usage = "script_file_name",
477 .help = "set custom restart script",
478 },
479 {
480 .name = "reset",
481 .handler = &aice_handle_aice_reset_command,
482 .mode = COMMAND_EXEC,
483 .usage = "",
484 .help = "reset AICE",
485 },
486 COMMAND_REGISTRATION_DONE
487 };
488
489 static const struct command_registration aice_command_handlers[] = {
490 {
491 .name = "aice",
492 .mode = COMMAND_ANY,
493 .help = "perform aice management",
494 .usage = "[subcommand]",
495 .chain = aice_subcommand_handlers,
496 },
497 COMMAND_REGISTRATION_DONE
498 };
499 /***************************************************************************/
500 /* End of Command handlers */
501
502 static struct jtag_interface aice_interface = {
503 .execute_queue = aice_execute_queue,
504 };
505
506 struct adapter_driver aice_adapter_driver = {
507 .name = "aice",
508 .transports = aice_transports,
509 .commands = aice_command_handlers,
510
511 .init = aice_init,
512 .quit = aice_quit,
513 .speed = aice_speed, /* set interface speed */
514 .khz = aice_khz, /* convert khz to interface speed value */
515 .speed_div = aice_speed_div, /* return readable value */
516
517 .jtag_ops = &aice_interface,
518 };

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)