sysfsgpio: give time to udev to change gpio permission
[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 <jtag/drivers/libusb_common.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 (ERROR_OK != aice_port->api->open(&param)) {
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 (8 <= i)
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 (uint32_t i = 0; i < num_of_idcode; i++)
257                 LOG_DEBUG("id_codes[%d] = 0x%x", 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", param.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_serial_command)
313 {
314         LOG_DEBUG("aice_handle_aice_serial_command");
315
316         if (CMD_ARGC == 1)
317                 param.serial = strdup(CMD_ARGV[0]);
318         else
319                 LOG_ERROR("expected exactly one argument to aice serial <serial-number>");
320
321         return ERROR_OK;
322 }
323
324 COMMAND_HANDLER(aice_handle_aice_vid_pid_command)
325 {
326         LOG_DEBUG("aice_handle_aice_vid_pid_command");
327
328         if (CMD_ARGC != 2) {
329                 LOG_WARNING("ignoring extra IDs in aice vid_pid (maximum is 1 pair)");
330                 return ERROR_COMMAND_SYNTAX_ERROR;
331         }
332
333         COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], param.vid);
334         COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], param.pid);
335
336         return ERROR_OK;
337 }
338
339 COMMAND_HANDLER(aice_handle_aice_adapter_command)
340 {
341         LOG_DEBUG("aice_handle_aice_adapter_command");
342
343         if (CMD_ARGC == 1)
344                 param.adapter_name = strdup(CMD_ARGV[0]);
345         else
346                 LOG_ERROR("expected exactly one argument to aice adapter <adapter-name>");
347
348         return ERROR_OK;
349 }
350
351 COMMAND_HANDLER(aice_handle_aice_retry_times_command)
352 {
353         LOG_DEBUG("aice_handle_aice_retry_times_command");
354
355         if (CMD_ARGC == 1)
356                 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], retry_times);
357         else
358                 LOG_ERROR("expected exactly one argument to aice retry_times <num_of_retry>");
359
360         return ERROR_OK;
361 }
362
363 COMMAND_HANDLER(aice_handle_aice_count_to_check_dbger_command)
364 {
365         LOG_DEBUG("aice_handle_aice_count_to_check_dbger_command");
366
367         if (CMD_ARGC == 1)
368                 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], count_to_check_dbger);
369         else
370                 LOG_ERROR("expected exactly one argument to aice count_to_check_dbger "
371                                 "<count_of_checking>");
372
373         return ERROR_OK;
374 }
375
376 COMMAND_HANDLER(aice_handle_aice_custom_srst_script_command)
377 {
378         LOG_DEBUG("aice_handle_aice_custom_srst_script_command");
379
380         if (CMD_ARGC > 0) {
381                 aice_port->api->set_custom_srst_script(CMD_ARGV[0]);
382                 return ERROR_OK;
383         }
384
385         return ERROR_FAIL;
386 }
387
388 COMMAND_HANDLER(aice_handle_aice_custom_trst_script_command)
389 {
390         LOG_DEBUG("aice_handle_aice_custom_trst_script_command");
391
392         if (CMD_ARGC > 0) {
393                 aice_port->api->set_custom_trst_script(CMD_ARGV[0]);
394                 return ERROR_OK;
395         }
396
397         return ERROR_FAIL;
398 }
399
400 COMMAND_HANDLER(aice_handle_aice_custom_restart_script_command)
401 {
402         LOG_DEBUG("aice_handle_aice_custom_restart_script_command");
403
404         if (CMD_ARGC > 0) {
405                 aice_port->api->set_custom_restart_script(CMD_ARGV[0]);
406                 return ERROR_OK;
407         }
408
409         return ERROR_FAIL;
410 }
411
412 COMMAND_HANDLER(aice_handle_aice_reset_command)
413 {
414         LOG_DEBUG("aice_handle_aice_reset_command");
415
416         return aice_port->api->reset();
417 }
418
419
420 static const struct command_registration aice_subcommand_handlers[] = {
421         {
422                 .name = "info",
423                 .handler = &aice_handle_aice_info_command,
424                 .mode = COMMAND_EXEC,
425                 .help = "show aice info",
426                 .usage = "aice info",
427         },
428         {
429                 .name = "port",
430                 .handler = &aice_handle_aice_port_command,
431                 .mode = COMMAND_CONFIG,
432                 .help = "set the port of the AICE",
433                 .usage = "aice port ['aice_pipe'|'aice_usb']",
434         },
435         {
436                 .name = "desc",
437                 .handler = &aice_handle_aice_desc_command,
438                 .mode = COMMAND_CONFIG,
439                 .help = "set the aice device description",
440                 .usage = "aice desc [desciption string]",
441         },
442         {
443                 .name = "serial",
444                 .handler = &aice_handle_aice_serial_command,
445                 .mode = COMMAND_CONFIG,
446                 .help = "set the serial number of the AICE device",
447                 .usage = "aice serial [serial string]",
448         },
449         {
450                 .name = "vid_pid",
451                 .handler = &aice_handle_aice_vid_pid_command,
452                 .mode = COMMAND_CONFIG,
453                 .help = "the vendor and product ID of the AICE device",
454                 .usage = "aice vid_pid (vid pid)*",
455         },
456         {
457                 .name = "adapter",
458                 .handler = &aice_handle_aice_adapter_command,
459                 .mode = COMMAND_CONFIG,
460                 .help = "set the file name of adapter",
461                 .usage = "aice adapter [adapter name]",
462         },
463         {
464                 .name = "retry_times",
465                 .handler = &aice_handle_aice_retry_times_command,
466                 .mode = COMMAND_CONFIG,
467                 .help = "set retry times as AICE timeout",
468                 .usage = "aice retry_times num_of_retry",
469         },
470         {
471                 .name = "count_to_check_dbger",
472                 .handler = &aice_handle_aice_count_to_check_dbger_command,
473                 .mode = COMMAND_CONFIG,
474                 .help = "set retry times as checking $DBGER status",
475                 .usage = "aice count_to_check_dbger count_of_checking",
476         },
477         {
478                 .name = "custom_srst_script",
479                 .handler = &aice_handle_aice_custom_srst_script_command,
480                 .mode = COMMAND_CONFIG,
481                 .usage = "custom_srst_script script_file_name",
482                 .help = "set custom srst script",
483         },
484         {
485                 .name = "custom_trst_script",
486                 .handler = &aice_handle_aice_custom_trst_script_command,
487                 .mode = COMMAND_CONFIG,
488                 .usage = "custom_trst_script script_file_name",
489                 .help = "set custom trst script",
490         },
491         {
492                 .name = "custom_restart_script",
493                 .handler = &aice_handle_aice_custom_restart_script_command,
494                 .mode = COMMAND_CONFIG,
495                 .usage = "custom_restart_script script_file_name",
496                 .help = "set custom restart script",
497         },
498         {
499                 .name = "reset",
500                 .handler = &aice_handle_aice_reset_command,
501                 .mode = COMMAND_EXEC,
502                 .usage = "aice reset",
503                 .help = "reset AICE",
504         },
505         COMMAND_REGISTRATION_DONE
506 };
507
508 static const struct command_registration aice_command_handlers[] = {
509         {
510                 .name = "aice",
511                 .mode = COMMAND_ANY,
512                 .help = "perform aice management",
513                 .usage = "aice [subcommand]",
514                 .chain = aice_subcommand_handlers,
515         },
516         COMMAND_REGISTRATION_DONE
517 };
518 /***************************************************************************/
519 /* End of Command handlers */
520
521 struct jtag_interface aice_interface = {
522         .name = "aice",
523         .commands = aice_command_handlers,
524         .transports = aice_transports,
525         .init = aice_init,
526         .quit = aice_quit,
527         .execute_queue = aice_execute_queue,
528         .speed = aice_speed,            /* set interface speed */
529         .speed_div = aice_speed_div,    /* return readable value */
530         .khz = aice_khz,                /* convert khz to interface speed value */
531 };