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