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 
242 /***************************************************************************/
243 /* Command handlers */
244 COMMAND_HANDLER(aice_handle_aice_info_command)
245 {
246  LOG_DEBUG("aice_handle_aice_info_command");
247 
248  command_print(CMD_CTX, "Description: %s", param.device_desc);
249  command_print(CMD_CTX, "Serial number: %s", param.serial);
250  if (strncmp(aice_port->name, "aice_pipe", 9) == 0)
251  command_print(CMD_CTX, "Adapter: %s", param.adapter_name);
252 
253  return ERROR_OK;
254 }
255 
256 COMMAND_HANDLER(aice_handle_aice_port_command)
257 {
258  LOG_DEBUG("aice_handle_aice_port_command");
259 
260  if (CMD_ARGC != 1) {
261  LOG_ERROR("Need exactly one argument to 'aice port'");
263  }
264 
265  for (const struct aice_port *l = aice_port_get_list(); l->name; l++) {
266  if (strcmp(l->name, CMD_ARGV[0]) == 0) {
267  aice_port = l;
268  return ERROR_OK;
269  }
270  }
271 
272  LOG_ERROR("No AICE port '%s' found", CMD_ARGV[0]);
273  return ERROR_FAIL;
274 }
275 
276 COMMAND_HANDLER(aice_handle_aice_desc_command)
277 {
278  LOG_DEBUG("aice_handle_aice_desc_command");
279 
280  if (CMD_ARGC == 1)
281  param.device_desc = strdup(CMD_ARGV[0]);
282  else
283  LOG_ERROR("expected exactly one argument to aice desc <description>");
284 
285  return ERROR_OK;
286 }
287 
288 COMMAND_HANDLER(aice_handle_aice_serial_command)
289 {
290  LOG_DEBUG("aice_handle_aice_serial_command");
291 
292  if (CMD_ARGC == 1)
293  param.serial = strdup(CMD_ARGV[0]);
294  else
295  LOG_ERROR("expected exactly one argument to aice serial <serial-number>");
296 
297  return ERROR_OK;
298 }
299 
300 COMMAND_HANDLER(aice_handle_aice_vid_pid_command)
301 {
302  LOG_DEBUG("aice_handle_aice_vid_pid_command");
303 
304  if (CMD_ARGC != 2) {
305  LOG_WARNING("ignoring extra IDs in aice vid_pid (maximum is 1 pair)");
307  }
308 
311 
312  return ERROR_OK;
313 }
314 
315 COMMAND_HANDLER(aice_handle_aice_adapter_command)
316 {
317  LOG_DEBUG("aice_handle_aice_adapter_command");
318 
319  if (CMD_ARGC == 1)
320  param.adapter_name = strdup(CMD_ARGV[0]);
321  else
322  LOG_ERROR("expected exactly one argument to aice adapter <adapter-name>");
323 
324  return ERROR_OK;
325 }
326 
327 COMMAND_HANDLER(aice_handle_aice_retry_times_command)
328 {
329  LOG_DEBUG("aice_handle_aice_retry_times_command");
330 
331  if (CMD_ARGC == 1)
333  else
334  LOG_ERROR("expected exactly one argument to aice retry_times <num_of_retry>");
335 
336  return ERROR_OK;
337 }
338 
339 COMMAND_HANDLER(aice_handle_aice_count_to_check_dbger_command)
340 {
341  LOG_DEBUG("aice_handle_aice_count_to_check_dbger_command");
342 
343  if (CMD_ARGC == 1)
345  else
346  LOG_ERROR("expected exactly one argument to aice count_to_check_dbger "
347  "<count_of_checking>");
348 
349  return ERROR_OK;
350 }
351 
352 COMMAND_HANDLER(aice_handle_aice_custom_srst_script_command)
353 {
354  LOG_DEBUG("aice_handle_aice_custom_srst_script_command");
355 
356  if (CMD_ARGC > 0) {
357  aice_port->api->set_custom_srst_script(CMD_ARGV[0]);
358  return ERROR_OK;
359  }
360 
361  return ERROR_FAIL;
362 }
363 
364 COMMAND_HANDLER(aice_handle_aice_custom_trst_script_command)
365 {
366  LOG_DEBUG("aice_handle_aice_custom_trst_script_command");
367 
368  if (CMD_ARGC > 0) {
369  aice_port->api->set_custom_trst_script(CMD_ARGV[0]);
370  return ERROR_OK;
371  }
372 
373  return ERROR_FAIL;
374 }
375 
376 COMMAND_HANDLER(aice_handle_aice_custom_restart_script_command)
377 {
378  LOG_DEBUG("aice_handle_aice_custom_restart_script_command");
379 
380  if (CMD_ARGC > 0) {
381  aice_port->api->set_custom_restart_script(CMD_ARGV[0]);
382  return ERROR_OK;
383  }
384 
385  return ERROR_FAIL;
386 }
387 
388 COMMAND_HANDLER(aice_handle_aice_reset_command)
389 {
390  LOG_DEBUG("aice_handle_aice_reset_command");
391 
392  return aice_port->api->reset();
393 }
394 
395 
397  {
398  .name = "info",
399  .handler = &aice_handle_aice_info_command,
400  .mode = COMMAND_EXEC,
401  .help = "show aice info",
402  .usage = "aice info",
403  },
404  {
405  .name = "port",
406  .handler = &aice_handle_aice_port_command,
407  .mode = COMMAND_CONFIG,
408  .help = "set the port of the AICE",
409  .usage = "aice port ['aice_pipe'|'aice_usb']",
410  },
411  {
412  .name = "desc",
413  .handler = &aice_handle_aice_desc_command,
414  .mode = COMMAND_CONFIG,
415  .help = "set the aice device description",
416  .usage = "aice desc [desciption string]",
417  },
418  {
419  .name = "serial",
420  .handler = &aice_handle_aice_serial_command,
421  .mode = COMMAND_CONFIG,
422  .help = "set the serial number of the AICE device",
423  .usage = "aice serial [serial string]",
424  },
425  {
426  .name = "vid_pid",
427  .handler = &aice_handle_aice_vid_pid_command,
428  .mode = COMMAND_CONFIG,
429  .help = "the vendor and product ID of the AICE device",
430  .usage = "aice vid_pid (vid pid)*",
431  },
432  {
433  .name = "adapter",
434  .handler = &aice_handle_aice_adapter_command,
435  .mode = COMMAND_CONFIG,
436  .help = "set the file name of adapter",
437  .usage = "aice adapter [adapter name]",
438  },
439  {
440  .name = "retry_times",
441  .handler = &aice_handle_aice_retry_times_command,
442  .mode = COMMAND_CONFIG,
443  .help = "set retry times as AICE timeout",
444  .usage = "aice retry_times num_of_retry",
445  },
446  {
447  .name = "count_to_check_dbger",
448  .handler = &aice_handle_aice_count_to_check_dbger_command,
449  .mode = COMMAND_CONFIG,
450  .help = "set retry times as checking $DBGER status",
451  .usage = "aice count_to_check_dbger count_of_checking",
452  },
453  {
454  .name = "custom_srst_script",
455  .handler = &aice_handle_aice_custom_srst_script_command,
456  .mode = COMMAND_CONFIG,
457  .usage = "custom_srst_script script_file_name",
458  .help = "set custom srst script",
459  },
460  {
461  .name = "custom_trst_script",
462  .handler = &aice_handle_aice_custom_trst_script_command,
463  .mode = COMMAND_CONFIG,
464  .usage = "custom_trst_script script_file_name",
465  .help = "set custom trst script",
466  },
467  {
468  .name = "custom_restart_script",
469  .handler = &aice_handle_aice_custom_restart_script_command,
470  .mode = COMMAND_CONFIG,
471  .usage = "custom_restart_script script_file_name",
472  .help = "set custom restart script",
473  },
474  {
475  .name = "reset",
476  .handler = &aice_handle_aice_reset_command,
477  .mode = COMMAND_EXEC,
478  .usage = "aice reset",
479  .help = "reset AICE",
480  },
482 };
483 
485  {
486  .name = "aice",
487  .mode = COMMAND_ANY,
488  .help = "perform aice management",
489  .usage = "aice [subcommand]",
490  .chain = aice_subcommand_handlers,
491  },
493 };
494 /***************************************************************************/
495 /* End of Command handlers */
496 
498  .name = "aice",
499  .commands = aice_command_handlers,
500  .transports = aice_transports,
501  .init = aice_init,
502  .quit = aice_quit,
503  .execute_queue = aice_execute_queue,
504  .speed = aice_speed, /* set interface speed */
505  .speed_div = aice_speed_div, /* return readable value */
506  .khz = aice_khz, /* convert khz to interface speed value */
507 };
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:159
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:126
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:121
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:378
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:222
#define LOG_ERROR(expr...)
Definition: log.h:129
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:338
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:203
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
Definition: command.h:116
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:603
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:599