OpenOCD
aice_interface.c
Go to the documentation of this file.
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>
29 #include "aice_usb.h"
30 
31 #define AICE_KHZ_TO_SPEED_MAP_SIZE 16
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 */
60 
61 /***************************************************************************/
62 /* AICE operations */
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) {
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) {
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);
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  DEBUG_JTAG_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 {
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 
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)
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_CTX, "Description: %s", param.device_desc);
273  command_print(CMD_CTX, "Serial number: %s", param.serial);
274  if (strncmp(aice_port->name, "aice_pipe", 9) == 0)
275  command_print(CMD_CTX, "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'");
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)");
331  }
332 
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)
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)
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 
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  },
506 };
507 
509  {
510  .name = "aice",
511  .mode = COMMAND_ANY,
512  .help = "perform aice management",
513  .usage = "aice [subcommand]",
514  .chain = aice_subcommand_handlers,
515  },
517 };
518 /***************************************************************************/
519 /* End of Command handlers */
520 
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 };
int aice_scan_jtag_chain(void)
uint32_t idcode
device identification code
Definition: jtag.h:135
#define LOG_DEBUG(expr...)
Definition: log.h:115
int(* set_custom_restart_script)(const char *script)
Definition: aice_port.h:207
Represents a driver for a debugging interface.
Definition: interface.h:198
const char * name
Definition: aice_port.h:227
static int jtag_speed
Definition: jtag/core.c:127
static const struct command_registration aice_command_handlers[]
int abs_chain_position
Definition: jtag.h:125
static int aice_quit(void)
#define LOG_INFO(expr...)
Definition: log.h:123
const char * aice_transports[]
static int aice_speed_div(int speed, int *khz)
#define DEBUG_JTAG_IO(expr...)
Definition: jtag.h:32
static uint32_t aice_target_id_codes[AICE_MAX_NUM_CORE]
int(* set_custom_srst_script)(const char *script)
Definition: aice_port.h:201
#define ERROR_FAIL
Definition: log.h:150
int(* set_custom_trst_script)(const char *script)
Definition: aice_port.h:204
void * priv
Definition: jtag.h:157
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:138
static int aice_khz(int khz, int *jtag_speed)
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:133
union jtag_command_container cmd
Definition: commands.h:158
COMMAND_HANDLER(aice_handle_aice_info_command)
static const int aice_khz_to_speed_map[AICE_KHZ_TO_SPEED_MAP_SIZE]
uint32_t * expected_ids
Array of expected identification codes.
Definition: jtag.h:141
static int aice_execute_reset(struct jtag_command *cmd)
#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:403
struct target * all_targets
const char *const name
The name of the JTAG interface driver.
Definition: interface.h:200
int(* set_jtag_clock)(uint32_t a_clock)
Definition: aice_port.h:140
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:239
#define LOG_ERROR(expr...)
Definition: log.h:129
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:363
int aice_init_targets(void)
#define AICE_TCK_CONTROL_TCK3048
Definition: aice_usb.h:73
char * adapter_name
Definition: aice_port.h:116
const struct aice_port * aice_port_get_list(void)
Definition: aice_port.c:42
static int aice_execute_command(struct jtag_command *cmd)
const char * name
Definition: command.h:220
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
Definition: command.h:128
static int aice_speed(int speed)
static uint32_t retry_times
uint8_t expected_ids_cnt
Number of expected identification codes.
Definition: jtag.h:143
const char * serial
Definition: aice_port.h:110
const char * device_desc
Definition: aice_port.h:108
struct aice_port_api_s *const api
Definition: aice_port.h:231
#define AICE_MAX_NUM_CORE
Definition: aice_port.h:24
static uint32_t count_to_check_dbger
const struct aice_port * port
Definition: aice_port.h:123
int(* set_count_to_check_dbger)(uint32_t count_to_check)
Definition: aice_port.h:210
enum jtag_command_type type
Definition: commands.h:159
void command_print(struct command_context *context, const char *format,...)
Definition: command.c:528
static int aice_execute_queue(void)
#define AICE_KHZ_TO_SPEED_MAP_SIZE
int(* set_retry_times)(uint32_t a_retry_times)
Definition: aice_port.h:189
struct target * next
Definition: target.h:177
static struct aice_port_param_s param
int(* idcode)(uint32_t *idcode, uint8_t *num_of_idcode)
Definition: aice_port.h:138
int(* close)(void)
Definition: aice_port.h:134
struct jtag_command * next
Definition: commands.h:160
#define ERROR_OK
Definition: log.h:144
uint32_t coreid
Definition: aice_port.h:121
struct jtag_tap * tap
Definition: target.h:130
bool hasidcode
not all devices have idcode, we'll discover this during chain examination
Definition: jtag.h:138
int(* reset)(void)
Definition: aice_port.h:136
static const struct command_registration aice_subcommand_handlers[]
#define ERROR_JTAG_QUEUE_FAILED
Definition: jtag.h:601
static uint8_t aice_num_of_target_id_codes
int(* open)(struct aice_port_param_s *param)
Definition: aice_port.h:132
struct jtag_interface aice_interface
struct reset_command * reset
Definition: commands.h:129
static int aice_init(void)
static const struct aice_port * aice_port
int trst
Set TRST output: 0 = deassert, 1 = assert, -1 = no change.
Definition: commands.h:85
#define LOG_WARNING(expr...)
Definition: log.h:126
Definition: target.h:126
struct jtag_command * jtag_command_queue
The current queue of jtag_command_s structures.
Definition: commands.c:46
#define ERROR_JTAG_INIT_FAILED
Definition: jtag.h:597