OpenOCD
aice_transport.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 /* project specific includes */
13 #include <jtag/interface.h>
14 #include <jtag/tcl.h>
15 #include <transport/transport.h>
16 #include <target/target.h>
19 #include <string.h>
20 
21 /* */
22 static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi,
23  struct jtag_tap *tap)
24 {
25  jim_wide w;
26  int e = jim_getopt_wide(goi, &w);
27  if (e != JIM_OK) {
28  Jim_SetResultFormatted(goi->interp, "option: %s bad parameter",
29  n->name);
30  return e;
31  }
32 
33  unsigned expected_len = sizeof(uint32_t) * tap->expected_ids_cnt;
34  uint32_t *new_expected_ids = malloc(expected_len + sizeof(uint32_t));
35  if (!new_expected_ids) {
36  Jim_SetResultFormatted(goi->interp, "no memory");
37  return JIM_ERR;
38  }
39 
40  assert(tap->expected_ids);
41  memcpy(new_expected_ids, tap->expected_ids, expected_len);
42 
43  new_expected_ids[tap->expected_ids_cnt] = w;
44 
45  free(tap->expected_ids);
46  tap->expected_ids = new_expected_ids;
47  tap->expected_ids_cnt++;
48 
49  return JIM_OK;
50 }
51 
52 #define NTAP_OPT_EXPECTED_ID 0
53 
54 /* */
55 static int jim_aice_newtap_cmd(struct jim_getopt_info *goi)
56 {
57  struct jtag_tap *tap;
58  int x;
59  int e;
60  struct jim_nvp *n;
61  char *cp;
62  const struct jim_nvp opts[] = {
63  {.name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID},
64  {.name = NULL, .value = -1},
65  };
66 
67  tap = calloc(1, sizeof(struct jtag_tap));
68  if (!tap) {
69  Jim_SetResultFormatted(goi->interp, "no memory");
70  return JIM_ERR;
71  }
72 
73  /*
74  * we expect CHIP + TAP + OPTIONS
75  * */
76  if (goi->argc < 3) {
77  Jim_SetResultFormatted(goi->interp,
78  "Missing CHIP TAP OPTIONS ....");
79  free(tap);
80  return JIM_ERR;
81  }
82 
83  const char *tmp;
84  jim_getopt_string(goi, &tmp, NULL);
85  tap->chip = strdup(tmp);
86 
87  jim_getopt_string(goi, &tmp, NULL);
88  tap->tapname = strdup(tmp);
89 
90  /* name + dot + name + null */
91  x = strlen(tap->chip) + 1 + strlen(tap->tapname) + 1;
92  cp = malloc(x);
93  sprintf(cp, "%s.%s", tap->chip, tap->tapname);
94  tap->dotted_name = cp;
95 
96  LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
97  tap->chip, tap->tapname, tap->dotted_name, goi->argc);
98 
99  while (goi->argc) {
100  e = jim_getopt_nvp(goi, opts, &n);
101  if (e != JIM_OK) {
102  jim_getopt_nvp_unknown(goi, opts, 0);
103  free(cp);
104  free(tap);
105  return e;
106  }
107  LOG_DEBUG("Processing option: %s", n->name);
108  switch (n->value) {
110  e = jim_newtap_expected_id(n, goi, tap);
111  if (e != JIM_OK) {
112  free(cp);
113  free(tap);
114  return e;
115  }
116  break;
117  } /* switch (n->value) */
118  } /* while (goi->argc) */
119 
120  /* default is enabled-after-reset */
121  tap->enabled = !tap->disabled_after_reset;
122 
123  jtag_tap_init(tap);
124  return JIM_OK;
125 }
126 
127 /* */
128 static int jim_aice_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
129 {
130  struct jim_getopt_info goi;
131  jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
132  return jim_aice_newtap_cmd(&goi);
133 }
134 
135 /* */
136 COMMAND_HANDLER(handle_aice_init_command)
137 {
138  if (CMD_ARGC != 0)
140 
141  static bool jtag_initialized;
142  if (jtag_initialized) {
143  LOG_INFO("'jtag init' has already been called");
144  return ERROR_OK;
145  }
146  jtag_initialized = true;
147 
148  LOG_DEBUG("Initializing jtag devices...");
149  return jtag_init(CMD_CTX);
150 }
151 
152 COMMAND_HANDLER(handle_scan_chain_command)
153 {
154  struct jtag_tap *tap;
155  char expected_id[12];
156 
158  tap = jtag_all_taps();
160  " TapName Enabled IdCode Expected IrLen IrCap IrMask");
162  "-- ------------------- -------- ---------- ---------- ----- ----- ------");
163 
164  while (tap) {
165  uint32_t expected, expected_mask, ii;
166 
167  snprintf(expected_id, sizeof(expected_id), "0x%08x",
168  (unsigned)((tap->expected_ids_cnt > 0)
169  ? tap->expected_ids[0]
170  : 0));
171  if (tap->ignore_version)
172  expected_id[2] = '*';
173 
174  expected = buf_get_u32(tap->expected, 0, tap->ir_length);
176 
178  "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x",
179  tap->abs_chain_position,
180  tap->dotted_name,
181  tap->enabled ? 'Y' : 'n',
182  (unsigned int)(tap->idcode),
183  expected_id,
184  (unsigned int)(tap->ir_length),
185  (unsigned int)(expected),
186  (unsigned int)(expected_mask));
187 
188  for (ii = 1; ii < tap->expected_ids_cnt; ii++) {
189  snprintf(expected_id, sizeof(expected_id), "0x%08x",
190  (unsigned) tap->expected_ids[ii]);
191  if (tap->ignore_version)
192  expected_id[2] = '*';
193 
195  " %s",
196  expected_id);
197  }
198 
199  tap = tap->next_tap;
200  }
201 
202  return ERROR_OK;
203 }
204 
205 static int jim_aice_arp_init(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
206 {
207  LOG_DEBUG("No implement: jim_aice_arp_init");
208 
209  return JIM_OK;
210 }
211 
212 /* */
213 static int aice_init_reset(struct command_context *cmd_ctx)
214 {
215  LOG_DEBUG("Initializing with hard TRST+SRST reset");
216 
217  int retval;
219 
220  jtag_add_reset(1, 0); /* TAP_RESET */
222  jtag_add_reset(1, 1);
224  jtag_add_reset(0, 1);
225  }
226  jtag_add_reset(0, 0);
227  retval = jtag_execute_queue();
228  if (retval != ERROR_OK)
229  return retval;
230 
231  return ERROR_OK;
232 }
233 
234 /* */
235 static int jim_aice_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
236 {
237  int e = ERROR_OK;
238  struct jim_getopt_info goi;
239  jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
240  if (goi.argc != 0) {
241  Jim_WrongNumArgs(goi.interp, 1, goi.argv - 1, "(no params)");
242  return JIM_ERR;
243  }
245  e = aice_init_reset(context);
246 
247  if (e != ERROR_OK) {
248  Jim_Obj *obj = Jim_NewIntObj(goi.interp, e);
249  Jim_SetResultFormatted(goi.interp, "error: %#s", obj);
250  return JIM_ERR;
251  }
252  return JIM_OK;
253 }
254 
255 static int jim_aice_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
256 {
257  struct jim_getopt_info goi;
258  jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
259  if (goi.argc != 0) {
260  Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters");
261  return JIM_ERR;
262  }
263  Jim_SetResult(goi.interp, Jim_NewListObj(goi.interp, NULL, 0));
264  struct jtag_tap *tap;
265 
266  for (tap = jtag_all_taps(); tap; tap = tap->next_tap)
267  Jim_ListAppendElement(goi.interp,
268  Jim_GetResult(goi.interp),
269  Jim_NewStringObj(goi.interp,
270  tap->dotted_name, -1));
271 
272  return JIM_OK;
273 }
274 
275 /* */
277  {
278  .name = "init",
279  .mode = COMMAND_ANY,
280  .handler = handle_aice_init_command,
281  .help = "initialize jtag scan chain",
282  .usage = ""
283  },
284  {
285  .name = "arp_init",
286  .mode = COMMAND_ANY,
287  .jim_handler = jim_aice_arp_init,
288  .help = "Validates JTAG scan chain against the list of "
289  "declared TAPs.",
290  },
291  {
292  .name = "arp_init-reset",
293  .mode = COMMAND_ANY,
294  .jim_handler = jim_aice_arp_init_reset,
295  .help = "Uses TRST and SRST to try resetting everything on "
296  "the JTAG scan chain, then performs 'jtag arp_init'."
297  },
298  {
299  .name = "newtap",
300  .mode = COMMAND_CONFIG,
301  .jim_handler = jim_aice_newtap,
302  .help = "Create a new TAP instance named basename.tap_type, "
303  "and appends it to the scan chain.",
304  .usage = "basename tap_type ['-expected_id' number]"
305  },
306  {
307  .name = "tapisenabled",
308  .mode = COMMAND_EXEC,
309  .jim_handler = jim_jtag_tap_enabler,
310  .help = "Returns a Tcl boolean (0/1) indicating whether "
311  "the TAP is enabled (1) or not (0).",
312  .usage = "tap_name",
313  },
314  {
315  .name = "tapenable",
316  .mode = COMMAND_EXEC,
317  .jim_handler = jim_jtag_tap_enabler,
318  .help = "Try to enable the specified TAP using the "
319  "'tap-enable' TAP event.",
320  .usage = "tap_name",
321  },
322  {
323  .name = "tapdisable",
324  .mode = COMMAND_EXEC,
325  .jim_handler = jim_jtag_tap_enabler,
326  .help = "Try to disable the specified TAP using the "
327  "'tap-disable' TAP event.",
328  .usage = "tap_name",
329  },
330  {
331  .name = "configure",
332  .mode = COMMAND_ANY,
333  .jim_handler = jim_jtag_configure,
334  .help = "Provide a Tcl handler for the specified "
335  "TAP event.",
336  .usage = "tap_name '-event' event_name handler",
337  },
338  {
339  .name = "cget",
340  .mode = COMMAND_EXEC,
341  .jim_handler = jim_jtag_configure,
342  .help = "Return any Tcl handler for the specified "
343  "TAP event.",
344  .usage = "tap_name '-event' event_name",
345  },
346  {
347  .name = "names",
348  .mode = COMMAND_ANY,
349  .jim_handler = jim_aice_names,
350  .help = "Returns list of all JTAG tap names.",
351  },
352  {
353  .name = "scan_chain",
354  .handler = handle_scan_chain_command,
355  .mode = COMMAND_ANY,
356  .help = "print current scan chain configuration",
357  .usage = ""
358  },
359 
361 };
362 
363 /* */
365  {
366  .name = "jtag",
367  .mode = COMMAND_ANY,
368  .usage = "",
370  },
372 
373 };
374 
375 /* */
377 {
379 }
380 
381 /* */
382 static int aice_transport_init(struct command_context *cmd_ctx)
383 {
384  LOG_DEBUG("aice_transport_init");
385  struct target *t = get_current_target(cmd_ctx);
386  struct transport *transport;
387 
388  if (!t) {
389  LOG_ERROR("no current target");
390  return ERROR_FAIL;
391  }
392 
394 
395  if (!transport) {
396  LOG_ERROR("no transport selected");
397  return ERROR_FAIL;
398  }
399 
400  LOG_DEBUG("current transport %s", transport->name);
401 
402  return aice_init_targets();
403 }
404 
405 /* */
406 static int aice_transport_select(struct command_context *ctx)
407 {
408  LOG_DEBUG("aice_transport_select");
409 
410  int retval;
411 
412  retval = aice_transport_register_commands(ctx);
413 
414  if (retval != ERROR_OK)
415  return retval;
416 
417  return ERROR_OK;
418 }
419 
420 static struct transport aice_jtag_transport = {
421  .name = "aice_jtag",
422  .select = aice_transport_select,
423  .init = aice_transport_init,
424 };
425 
426 const char *aice_transports[] = { "aice_jtag", NULL };
427 
428 static void aice_constructor(void) __attribute__((constructor));
429 static void aice_constructor(void)
430 {
432 }
int aice_init_targets(void)
int aice_scan_jtag_chain(void)
static int aice_transport_select(struct command_context *ctx)
static int jim_aice_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
static int aice_transport_init(struct command_context *cmd_ctx)
static int aice_init_reset(struct command_context *cmd_ctx)
static int jim_aice_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
static const struct command_registration aice_transport_command_handlers[]
static int aice_transport_register_commands(struct command_context *cmd_ctx)
static const struct command_registration aice_transport_jtag_subcommand_handlers[]
static int jim_aice_arp_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
#define NTAP_OPT_EXPECTED_ID
static int jim_aice_newtap_cmd(struct jim_getopt_info *goi)
static int jim_aice_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi, struct jtag_tap *tap)
const char * aice_transports[]
static struct transport aice_jtag_transport
COMMAND_HANDLER(handle_aice_init_command)
static void aice_constructor(void)
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned first, unsigned num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
Definition: binarybuffer.h:98
struct command_context * current_command_context(Jim_Interp *interp)
Definition: command.c:187
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 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 CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
Definition: command.h:145
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:247
static int register_commands(struct command_context *cmd_ctx, const char *cmd_prefix, const struct command_registration *cmds)
Register one or more commands in the specified context, as children of parent (or top-level commends,...
Definition: command.h:268
@ COMMAND_CONFIG
Definition: command.h:41
@ COMMAND_ANY
Definition: command.h:42
@ COMMAND_EXEC
Definition: command.h:40
struct esp_usb_jtag __attribute__
Definition: armv8.c:804
int jim_getopt_wide(struct jim_getopt_info *goi, jim_wide *puthere)
Remove argv[0] as wide.
Definition: jim-nvp.c:221
int jim_getopt_setup(struct jim_getopt_info *p, Jim_Interp *interp, int argc, Jim_Obj *const *argv)
GetOpt - how to.
Definition: jim-nvp.c:148
int jim_getopt_string(struct jim_getopt_info *goi, const char **puthere, int *len)
Remove argv[0] as string.
Definition: jim-nvp.c:187
int jim_getopt_nvp(struct jim_getopt_info *goi, const struct jim_nvp *nvp, struct jim_nvp **puthere)
Remove argv[0] as NVP.
Definition: jim-nvp.c:236
void jim_getopt_nvp_unknown(struct jim_getopt_info *goi, const struct jim_nvp *nvptable, int hadprefix)
Create an appropriate error message for an NVP.
Definition: jim-nvp.c:252
void jtag_add_reset(int req_tlr_or_trst, int req_srst)
A reset of the TAP state machine can be requested.
Definition: jtag/core.c:758
int jtag_init(struct command_context *cmd_ctx)
Initialize JTAG chain using only a RESET reset.
Definition: jtag/core.c:1664
int jtag_execute_queue(void)
For software FIFO implementations, the queued commands can be executed during this call or earlier.
Definition: jtag/core.c:1037
struct jtag_tap * jtag_all_taps(void)
Definition: jtag/core.c:184
static enum reset_types jtag_reset_config
Definition: jtag/core.c:87
void jtag_tap_init(struct jtag_tap *tap)
Definition: jtag/core.c:1446
enum reset_types jtag_get_reset_config(void)
Definition: jtag/core.c:1734
int jim_jtag_tap_enabler(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Definition: jtag/tcl.c:753
int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
Definition: jtag/tcl.c:791
reset_types
Definition: jtag.h:212
@ RESET_HAS_SRST
Definition: jtag.h:215
@ RESET_SRST_PULLS_TRST
Definition: jtag.h:217
#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
Jim_Interp * interp
Definition: command.h:53
const char * name
Definition: command.h:229
A TCL -ish GetOpt like code.
Definition: jim-nvp.h:135
Jim_Interp * interp
Definition: jim-nvp.h:136
Jim_Obj *const * argv
Definition: jim-nvp.h:138
Name Value Pairs, aka: NVP.
Definition: jim-nvp.h:59
const char * name
Definition: jim-nvp.h:60
int value
Definition: jim-nvp.h:61
Definition: jtag.h:100
int abs_chain_position
Definition: jtag.h:104
uint8_t * expected_mask
Capture-IR expected mask.
Definition: jtag.h:113
char * chip
Definition: jtag.h:101
bool ignore_version
Flag saying whether to ignore version field in expected_ids[].
Definition: jtag.h:125
bool disabled_after_reset
Is this TAP disabled after JTAG reset?
Definition: jtag.h:106
int ir_length
size of instruction register
Definition: jtag.h:109
uint8_t * expected
Capture-IR expected value.
Definition: jtag.h:111
uint8_t expected_ids_cnt
Number of expected identification codes.
Definition: jtag.h:122
char * tapname
Definition: jtag.h:102
bool enabled
Is this TAP currently enabled?
Definition: jtag.h:108
uint32_t * expected_ids
Array of expected identification codes.
Definition: jtag.h:120
struct jtag_tap * next_tap
Definition: jtag.h:137
uint32_t idcode
device identification code
Definition: jtag.h:114
char * dotted_name
Definition: jtag.h:103
Definition: target.h:120
Wrapper for transport lifecycle operations.
Definition: transport.h:35
const char * name
Each transport has a unique name, used to select it from among the alternatives.
Definition: transport.h:41
struct target * get_current_target(struct command_context *cmd_ctx)
Definition: target.c:536
struct transport * get_current_transport(void)
Returns the transport currently being used by this debug or programming session.
Definition: transport.c:157
int transport_register(struct transport *new_transport)
Registers a transport.
Definition: transport.c:129
#define NULL
Definition: usb.h:16