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