OpenOCD
ipdbg.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Copyright (C) 2020 by Daniel Anselmi <danselmi@gmx.ch> */
3 
4 #ifdef HAVE_CONFIG_H
5 #include "config.h"
6 #endif
7 
8 #include <helper/bits.h>
9 #include <helper/time_support.h>
10 #include <jtag/jtag.h>
11 #include <server/server.h>
12 #include <target/target.h>
13 #include <pld/pld.h>
14 
15 #include "ipdbg.h"
16 
17 #define IPDBG_BUFFER_SIZE 16384
18 #define IPDBG_MIN_NUM_OF_CREATE_OPTIONS 3
19 #define IPDBG_MAX_NUM_OF_CREATE_OPTIONS 10
20 #define IPDBG_NUM_OF_START_OPTIONS 4
21 #define IPDBG_NUM_OF_STOP_OPTIONS 2
22 #define IPDBG_NUM_OF_QUEUE_OPTIONS 2
23 #define IPDBG_MIN_DR_LENGTH 11
24 #define IPDBG_MAX_DR_LENGTH 13
25 #define IPDBG_TCP_PORT_STR_MAX_LENGTH 6
26 #define IPDBG_SCRATCH_MEMORY_SIZE 1024
27 
28 /* private connection data for IPDBG */
29 struct ipdbg_fifo {
30  size_t count;
31  size_t rd_idx;
33 };
34 
36  struct ipdbg_fifo dn_fifo;
37  struct ipdbg_fifo up_fifo;
38  bool closed;
39 };
40 
41 struct ipdbg_service {
42  struct ipdbg_hub *hub;
44  uint16_t port;
46  uint8_t tool;
47 };
48 
50  uint32_t instruction;
51  uint32_t length;
52  uint32_t value;
53 };
54 
56  uint8_t *dr_out_vals;
57  uint8_t *dr_in_vals;
58  uint8_t *vir_out_val;
59  struct scan_field *fields;
60 };
61 
62 struct ipdbg_hub {
63  uint32_t user_instruction;
64  uint32_t max_tools;
66  uint32_t active_services;
67  uint32_t valid_mask;
68  uint32_t xoff_mask;
69  uint32_t tool_mask;
70  uint32_t last_dn_tool;
71  char *name;
73  struct ipdbg_hub *next;
74  struct jtag_tap *tap;
77  uint8_t dn_xoff;
81 };
82 
83 static struct ipdbg_hub *ipdbg_first_hub;
84 
86 
87 static void ipdbg_init_fifo(struct ipdbg_fifo *fifo)
88 {
89  fifo->count = 0;
90  fifo->rd_idx = 0;
91 }
92 
93 static bool ipdbg_fifo_is_empty(struct ipdbg_fifo *fifo)
94 {
95  return fifo->count == 0;
96 }
97 
98 static bool ipdbg_fifo_is_full(struct ipdbg_fifo *fifo)
99 {
100  return fifo->count == IPDBG_BUFFER_SIZE;
101 }
102 
103 static void ipdbg_zero_rd_idx(struct ipdbg_fifo *fifo)
104 {
105  if (fifo->rd_idx == 0)
106  return;
107 
108  size_t ri = fifo->rd_idx;
109  for (size_t idx = 0; idx < fifo->count; ++idx)
110  fifo->buffer[idx] = fifo->buffer[ri++];
111  fifo->rd_idx = 0;
112 }
113 
114 static void ipdbg_append_to_fifo(struct ipdbg_fifo *fifo, char data)
115 {
116  if (ipdbg_fifo_is_full(fifo))
117  return;
118 
119  ipdbg_zero_rd_idx(fifo);
120  fifo->buffer[fifo->count++] = data;
121 }
122 
123 static char ipdbg_get_from_fifo(struct ipdbg_fifo *fifo)
124 {
125  if (ipdbg_fifo_is_empty(fifo))
126  return 0;
127 
128  fifo->count--;
129  return fifo->buffer[fifo->rd_idx++];
130 }
131 
133 {
134  if (ipdbg_fifo_is_empty(fifo))
135  return ERROR_OK;
136 
137  struct ipdbg_connection *connection = conn->priv;
138  if (connection->closed)
140 
141  ipdbg_zero_rd_idx(fifo);
142  size_t bytes_written = connection_write(conn, fifo->buffer, fifo->count);
143  if (bytes_written != fifo->count) {
144  LOG_ERROR("error during write: %zu != %zu", bytes_written, fifo->count);
145  connection->closed = true;
147  }
148 
149  fifo->count -= bytes_written;
150 
151  return ERROR_OK;
152 }
153 
154 static int ipdbg_max_tools_from_data_register_length(uint8_t data_register_length)
155 {
156  int max_tools = 1;
157  data_register_length -= 10; /* 8 bit payload, 1 xoff-flag, 1 valid-flag; remaining bits used to select tool*/
158  while (data_register_length--)
159  max_tools *= 2;
160 
161  /* last tool is used to reset JtagCDC and transfer "XON" to host*/
162  return max_tools - 1;
163 }
164 
165 static struct ipdbg_service *ipdbg_find_service(struct ipdbg_hub *hub, uint8_t tool)
166 {
167  struct ipdbg_service *service;
169  if (service->hub == hub && service->tool == tool)
170  break;
171  }
172  return service;
173 }
174 
176 {
177  struct ipdbg_service *iservice;
178  if (ipdbg_first_service) {
179  for (iservice = ipdbg_first_service; iservice->next; iservice = iservice->next)
180  ;
181  iservice->next = service;
182  } else
184 }
185 
186 static int ipdbg_create_service(struct ipdbg_hub *hub, uint8_t tool, struct ipdbg_service **service, uint16_t port)
187 {
188  *service = calloc(1, sizeof(struct ipdbg_service));
189  if (!*service) {
190  LOG_ERROR("Out of memory");
191  return ERROR_FAIL;
192  }
193 
194  (*service)->hub = hub;
195  (*service)->tool = tool;
196  (*service)->port = port;
197 
198  return ERROR_OK;
199 }
200 
202 {
203  if (!ipdbg_first_service)
204  return ERROR_FAIL;
205 
206  if (service == ipdbg_first_service) {
208  return ERROR_OK;
209  }
210 
211  for (struct ipdbg_service *iservice = ipdbg_first_service; iservice->next; iservice = iservice->next) {
212  if (service == iservice->next) {
213  iservice->next = service->next;
214  return ERROR_OK;
215  }
216  }
217  return ERROR_FAIL;
218 }
219 
220 static struct ipdbg_hub *ipdbg_find_hub(struct jtag_tap *tap,
222 {
223  struct ipdbg_hub *hub = NULL;
224  for (hub = ipdbg_first_hub; hub; hub = hub->next) {
225  if (hub->tap == tap && hub->user_instruction == user_instruction) {
226  if ((!virtual_ir && !hub->virtual_ir) ||
227  (virtual_ir && hub->virtual_ir &&
229  virtual_ir->length == hub->virtual_ir->length &&
230  virtual_ir->value == hub->virtual_ir->value)) {
231  break;
232  }
233  }
234  }
235  return hub;
236 }
237 
238 static void ipdbg_add_hub(struct ipdbg_hub *hub)
239 {
240  struct ipdbg_hub *ihub;
241  if (ipdbg_first_hub) {
242  for (ihub = ipdbg_first_hub; ihub->next; ihub = ihub->next)
243  ;
244  ihub->next = hub;
245  } else {
246  ipdbg_first_hub = hub;
247  }
248 }
249 
250 static int ipdbg_remove_hub(struct ipdbg_hub *hub)
251 {
252  if (!ipdbg_first_hub)
253  return ERROR_FAIL;
254  if (hub == ipdbg_first_hub) {
256  return ERROR_OK;
257  }
258 
259  for (struct ipdbg_hub *ihub = ipdbg_first_hub; ihub->next; ihub = ihub->next) {
260  if (hub == ihub->next) {
261  ihub->next = hub->next;
262  return ERROR_OK;
263  }
264  }
265 
266  return ERROR_FAIL;
267 }
268 
269 static void ipdbg_free_hub(struct ipdbg_hub *hub)
270 {
271  if (!hub)
272  return;
273  free(hub->connections);
274  free(hub->virtual_ir);
275  free(hub->name);
276  free(hub->scratch_memory.dr_out_vals);
277  free(hub->scratch_memory.dr_in_vals);
278  free(hub->scratch_memory.fields);
279  free(hub->scratch_memory.vir_out_val);
280  free(hub);
281 }
282 
284  const char *name)
285 {
286  struct ipdbg_hub *new_hub = calloc(1, sizeof(struct ipdbg_hub));
287  if (!new_hub) {
288  free(virtual_ir);
289  LOG_ERROR("Out of memory");
290  return NULL;
291  }
292 
293  new_hub->name = strdup(name);
294  if (!new_hub->name) {
295  free(new_hub);
296  free(virtual_ir);
297  LOG_ERROR("Out of memory");
298  return NULL;
299  }
300 
301  const size_t dreg_buffer_size = DIV_ROUND_UP(data_register_length, 8);
303 
304  new_hub->scratch_memory.dr_out_vals = calloc(IPDBG_SCRATCH_MEMORY_SIZE, dreg_buffer_size);
305  new_hub->scratch_memory.dr_in_vals = calloc(IPDBG_SCRATCH_MEMORY_SIZE, dreg_buffer_size);
306  new_hub->scratch_memory.fields = calloc(IPDBG_SCRATCH_MEMORY_SIZE, sizeof(struct scan_field));
307  new_hub->connections = calloc(max_tools, sizeof(struct connection *));
308 
309  if (virtual_ir) {
310  new_hub->virtual_ir = virtual_ir;
311  new_hub->scratch_memory.vir_out_val = calloc(1, DIV_ROUND_UP(virtual_ir->length, 8));
312  }
313 
314  if (!new_hub->scratch_memory.dr_out_vals || !new_hub->scratch_memory.dr_in_vals ||
315  !new_hub->scratch_memory.fields || (virtual_ir && !new_hub->scratch_memory.vir_out_val) ||
316  !new_hub->connections) {
317  ipdbg_free_hub(new_hub);
318  LOG_ERROR("Out of memory");
319  return NULL;
320  }
321 
322  return new_hub;
323 }
324 
325 static void ipdbg_init_scan_field(struct scan_field *fields, uint8_t *in_value, int num_bits, const uint8_t *out_value)
326 {
327  fields->check_mask = NULL;
328  fields->check_value = NULL;
329  fields->in_value = in_value;
330  fields->num_bits = num_bits;
331  fields->out_value = out_value;
332 }
333 
334 static int ipdbg_shift_instr(struct ipdbg_hub *hub, uint32_t instr)
335 {
336  if (!hub)
337  return ERROR_FAIL;
338 
339  struct jtag_tap *tap = hub->tap;
340  if (!tap)
341  return ERROR_FAIL;
342 
343  if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) == instr) {
344  /* there is already the requested instruction in the ir */
345  return ERROR_OK;
346  }
347 
348  uint8_t *ir_out_val = calloc(DIV_ROUND_UP(tap->ir_length, 8), 1);
349  if (!ir_out_val) {
350  LOG_ERROR("Out of memory");
351  return ERROR_FAIL;
352  }
353  buf_set_u32(ir_out_val, 0, tap->ir_length, instr);
354 
355  struct scan_field fields;
356  ipdbg_init_scan_field(&fields, NULL, tap->ir_length, ir_out_val);
357  jtag_add_ir_scan(tap, &fields, TAP_IDLE);
358  int retval = jtag_execute_queue();
359 
360  free(ir_out_val);
361 
362  return retval;
363 }
364 
365 static int ipdbg_shift_vir(struct ipdbg_hub *hub)
366 {
367  if (!hub)
368  return ERROR_FAIL;
369 
370  if (!hub->virtual_ir)
371  return ERROR_OK;
372 
373  int retval = ipdbg_shift_instr(hub, hub->virtual_ir->instruction);
374  if (retval != ERROR_OK)
375  return retval;
376 
377  struct jtag_tap *tap = hub->tap;
378  if (!tap)
379  return ERROR_FAIL;
380 
384  retval = jtag_execute_queue();
385 
386  return retval;
387 }
388 
389 static int ipdbg_shift_data(struct ipdbg_hub *hub, uint32_t dn_data, uint32_t *up_data)
390 {
391  if (!hub)
392  return ERROR_FAIL;
393 
394  struct jtag_tap *tap = hub->tap;
395  if (!tap)
396  return ERROR_FAIL;
397 
399 
403  int retval = jtag_execute_queue();
404 
405  if (up_data && retval == ERROR_OK)
406  *up_data = buf_get_u32(hub->scratch_memory.dr_in_vals, 0, hub->data_register_length);
407 
408  return retval;
409 }
410 
411 static int ipdbg_distribute_data_from_hub(struct ipdbg_hub *hub, uint32_t up)
412 {
413  const bool valid_up_data = up & hub->valid_mask;
414  if (!valid_up_data)
415  return ERROR_OK;
416 
417  const size_t tool = (up >> 8) & hub->tool_mask;
418  if (tool == hub->tool_mask) {
419  const uint8_t xon_cmd = up & 0x00ff;
420  hub->dn_xoff &= ~xon_cmd;
421  LOG_INFO("received xon cmd: %d\n", xon_cmd);
422  return ERROR_OK;
423  }
424 
425  struct connection *conn = hub->connections[tool];
426  if (conn) {
427  struct ipdbg_connection *connection = conn->priv;
428  if (ipdbg_fifo_is_full(&connection->up_fifo)) {
429  int retval = ipdbg_move_buffer_to_connection(conn, &connection->up_fifo);
430  if (retval != ERROR_OK)
431  return retval;
432  }
433  ipdbg_append_to_fifo(&connection->up_fifo, up);
434  }
435  return ERROR_OK;
436 }
437 
438 static void ipdbg_check_for_xoff(struct ipdbg_hub *hub, size_t tool,
439  uint32_t rx_data)
440 {
441  if ((rx_data & hub->xoff_mask) && hub->last_dn_tool != hub->max_tools) {
442  hub->dn_xoff |= BIT(hub->last_dn_tool);
443  LOG_INFO("tool %d sent xoff", hub->last_dn_tool);
444  }
445 
446  hub->last_dn_tool = tool;
447 }
448 
449 static int ipdbg_shift_empty_data(struct ipdbg_hub *hub)
450 {
451  if (!hub)
452  return ERROR_FAIL;
453 
454  struct jtag_tap *tap = hub->tap;
455  if (!tap)
456  return ERROR_FAIL;
457 
458  const size_t dreg_buffer_size = DIV_ROUND_UP(hub->data_register_length, 8);
459  memset(hub->scratch_memory.dr_out_vals, 0, dreg_buffer_size);
460  for (size_t i = 0; i < hub->using_queue_size; ++i) {
462  hub->scratch_memory.dr_in_vals + i * dreg_buffer_size,
465  jtag_add_dr_scan(tap, 1, hub->scratch_memory.fields + i, TAP_IDLE);
466  }
467 
468  int retval = jtag_execute_queue();
469 
470  if (retval == ERROR_OK) {
471  uint32_t up_data;
472  for (size_t i = 0; i < hub->using_queue_size; ++i) {
473  up_data = buf_get_u32(hub->scratch_memory.dr_in_vals +
474  i * dreg_buffer_size, 0,
475  hub->data_register_length);
476  int rv = ipdbg_distribute_data_from_hub(hub, up_data);
477  if (rv != ERROR_OK)
478  retval = rv;
479 
480  if (i == 0) {
481  /* check if xoff sent is only needed on the first transfer which
482  may contain the xoff of the prev down transfer.
483  */
484  ipdbg_check_for_xoff(hub, hub->max_tools, up_data);
485  }
486  }
487  }
488 
489  return retval;
490 }
491 
492 static int ipdbg_jtag_transfer_byte(struct ipdbg_hub *hub, size_t tool, struct ipdbg_connection *connection)
493 {
494  uint32_t dn = hub->valid_mask | ((tool & hub->tool_mask) << 8) |
495  (0x00fful & ipdbg_get_from_fifo(&connection->dn_fifo));
496  uint32_t up = 0;
497  int ret = ipdbg_shift_data(hub, dn, &up);
498  if (ret != ERROR_OK)
499  return ret;
500 
501  ret = ipdbg_distribute_data_from_hub(hub, up);
502  if (ret != ERROR_OK)
503  return ret;
504 
505  ipdbg_check_for_xoff(hub, tool, up);
506 
507  return ERROR_OK;
508 }
509 
510 static int ipdbg_jtag_transfer_bytes(struct ipdbg_hub *hub,
511  size_t tool, struct ipdbg_connection *connection)
512 {
513  if (!hub)
514  return ERROR_FAIL;
515 
516  struct jtag_tap *tap = hub->tap;
517  if (!tap)
518  return ERROR_FAIL;
519 
520  const size_t dreg_buffer_size = DIV_ROUND_UP(hub->data_register_length, 8);
521  size_t num_tx = (connection->dn_fifo.count < hub->using_queue_size) ?
522  connection->dn_fifo.count : hub->using_queue_size;
523 
524  for (size_t i = 0; i < num_tx; ++i) {
525  uint32_t dn_data = hub->valid_mask | ((tool & hub->tool_mask) << 8) |
526  (0x00fful & ipdbg_get_from_fifo(&connection->dn_fifo));
527  buf_set_u32(hub->scratch_memory.dr_out_vals + i * dreg_buffer_size, 0,
528  hub->data_register_length, dn_data);
529 
532  i * dreg_buffer_size,
535  i * dreg_buffer_size);
536  jtag_add_dr_scan(tap, 1, hub->scratch_memory.fields + i, TAP_IDLE);
537  }
538 
539  int retval = jtag_execute_queue();
540 
541  if (retval == ERROR_OK) {
542  uint32_t up_data;
543  for (size_t i = 0; i < num_tx; ++i) {
544  up_data = buf_get_u32(hub->scratch_memory.dr_in_vals +
545  i * dreg_buffer_size,
546  0, hub->data_register_length);
547  int rv = ipdbg_distribute_data_from_hub(hub, up_data);
548  if (rv != ERROR_OK)
549  retval = rv;
550  if (i == 0) {
551  /* check if xoff sent is only needed on the first transfer which
552  may contain the xoff of the prev down transfer.
553  No checks for this channel because this function is only
554  called for channels without enabled flow control.
555  */
556  ipdbg_check_for_xoff(hub, tool, up_data);
557  }
558  }
559  }
560 
561  return retval;
562 }
563 
564 static int ipdbg_polling_callback(void *priv)
565 {
566  struct ipdbg_hub *hub = priv;
567 
568  int ret = ipdbg_shift_vir(hub);
569  if (ret != ERROR_OK)
570  return ret;
571 
572  ret = ipdbg_shift_instr(hub, hub->user_instruction);
573  if (ret != ERROR_OK)
574  return ret;
575 
576  /* transfer dn buffers to jtag-hub */
577  for (size_t tool = 0; tool < hub->max_tools; ++tool) {
578  struct connection *conn = hub->connections[tool];
579  if (conn && conn->priv) {
580  struct ipdbg_connection *connection = conn->priv;
581  while (((hub->dn_xoff & BIT(tool)) == 0) && !ipdbg_fifo_is_empty(&connection->dn_fifo)) {
582  if (hub->flow_control_enabled & BIT(tool))
583  ret = ipdbg_jtag_transfer_byte(hub, tool, connection);
584  else
585  ret = ipdbg_jtag_transfer_bytes(hub, tool, connection);
586  if (ret != ERROR_OK)
587  return ret;
588  }
589  }
590  }
591 
592  /* some transfers to get data from jtag-hub in case there is no dn data */
593  ret = ipdbg_shift_empty_data(hub);
594  if (ret != ERROR_OK)
595  return ret;
596 
597  /* write from up fifos to sockets */
598  for (size_t tool = 0; tool < hub->max_tools; ++tool) {
599  struct connection *conn = hub->connections[tool];
600  if (conn && conn->priv) {
601  struct ipdbg_connection *connection = conn->priv;
602  int retval = ipdbg_move_buffer_to_connection(conn, &connection->up_fifo);
603  if (retval != ERROR_OK)
604  return retval;
605  }
606  }
607 
608  return ERROR_OK;
609 }
610 
612 {
613  uint32_t up_data;
614 
615  /* on older implementations the flow_control_enable_word is not sent to us.
616  so we don't know -> assume it's enabled on all channels */
617  hub->flow_control_enabled = 0x7f;
618 
619  int ret = ipdbg_shift_data(hub, 0UL, &up_data);
620  if (ret != ERROR_OK)
621  return ret;
622 
623  const bool valid_up_data = up_data & hub->valid_mask;
624  if (valid_up_data) {
625  const size_t tool = (up_data >> 8) & hub->tool_mask;
626  /* the first valid data from hub is flow_control_enable_word */
627  if (tool == hub->tool_mask)
628  hub->flow_control_enabled = up_data & 0x007f;
629  else
630  ipdbg_distribute_data_from_hub(hub, up_data);
631  }
632 
633  LOG_INFO("Flow control enabled on IPDBG JTAG Hub: 0x%02x", hub->flow_control_enabled);
634 
635  return ERROR_OK;
636 }
637 
639 {
640  struct ipdbg_hub *hub = service->hub;
641  hub->connections[service->tool] = connection;
642  hub->active_connections++;
643  if (hub->active_connections > 1) {
644  /* hub is already initialized */
645  return ERROR_OK;
646  }
647 
648  const uint32_t reset_hub = hub->valid_mask | ((hub->max_tools) << 8);
649 
650  int ret = ipdbg_shift_vir(hub);
651  if (ret != ERROR_OK)
652  return ret;
653 
654  ret = ipdbg_shift_instr(hub, hub->user_instruction);
655  if (ret != ERROR_OK)
656  return ret;
657 
658  ret = ipdbg_shift_data(hub, reset_hub, NULL);
659  hub->last_dn_tool = hub->tool_mask;
660  hub->dn_xoff = 0;
661  if (ret != ERROR_OK)
662  return ret;
663 
665  if (ret != ERROR_OK)
666  return ret;
667 
668  LOG_INFO("IPDBG start_polling");
669 
670  const int time_ms = 20;
671  const int periodic = 1;
672  return target_register_timer_callback(ipdbg_polling_callback, time_ms, periodic, hub);
673 }
674 
676 {
677  struct ipdbg_hub *hub = service->hub;
678  hub->connections[service->tool] = NULL;
679  hub->active_connections--;
680  if (hub->active_connections == 0) {
681  LOG_INFO("IPDBG stop_polling");
682 
684  }
685 
686  return ERROR_OK;
687 }
688 
690 {
692  connection->priv = &service->connection;
693  /* initialize ipdbg connection information */
694  ipdbg_init_fifo(&service->connection.up_fifo);
695  ipdbg_init_fifo(&service->connection.dn_fifo);
696 
697  int retval = ipdbg_start_polling(service, connection);
698  if (retval != ERROR_OK) {
699  LOG_ERROR("BUG: ipdbg_start_polling failed");
700  return retval;
701  }
702 
704  conn->closed = false;
705 
706  LOG_INFO("New IPDBG Connection");
707 
708  return ERROR_OK;
709 }
710 
712 {
714  struct ipdbg_fifo *fifo = &conn->dn_fifo;
715 
716  if (ipdbg_fifo_is_full(fifo))
717  return ERROR_OK;
718 
719  ipdbg_zero_rd_idx(fifo);
720  int bytes_read = connection_read(connection, fifo->buffer + fifo->count, IPDBG_BUFFER_SIZE - fifo->count);
721  if (bytes_read <= 0) {
722  if (bytes_read < 0)
723  LOG_ERROR("error during read: %s", strerror(errno));
725  }
726 
727  fifo->count += bytes_read;
728 
729  return ERROR_OK;
730 }
731 
733 {
735  conn->closed = true;
736  LOG_INFO("Closed IPDBG Connection");
737 
739 }
740 
741 static const struct service_driver ipdbg_service_driver = {
742  .name = "ipdbg",
743  .new_connection_during_keep_alive_handler = NULL,
744  .new_connection_handler = ipdbg_on_new_connection,
745  .input_handler = ipdbg_on_connection_input,
746  .connection_closed_handler = ipdbg_on_connection_closed,
747  .keep_client_alive_handler = NULL,
748 };
749 
750 static struct ipdbg_hub *ipdbg_get_hub_by_name(const char *name)
751 {
752  struct ipdbg_hub *hub = NULL;
753  for (hub = ipdbg_first_hub; hub; hub = hub->next) {
754  if (strcmp(hub->name, name) == 0)
755  break;
756  }
757  return hub;
758 };
759 
761 {
762  int retval = ipdbg_remove_service(service);
763  if (retval != ERROR_OK) {
764  LOG_ERROR("BUG: ipdbg_remove_service failed");
765  return retval;
766  }
767 
768  char port_str_buffer[IPDBG_TCP_PORT_STR_MAX_LENGTH];
769  snprintf(port_str_buffer, IPDBG_TCP_PORT_STR_MAX_LENGTH, "%u", service->port);
770  retval = remove_service("ipdbg", port_str_buffer);
771  /* The ipdbg_service structure is freed by server.c:remove_service().
772  There the "priv" pointer is freed.*/
773  if (retval != ERROR_OK) {
774  LOG_ERROR("BUG: remove_service failed");
775  return retval;
776  }
777  return ERROR_OK;
778 }
779 
781 {
782  int retval = ERROR_OK;
783  for (struct ipdbg_hub *hub = ipdbg_first_hub; hub;) {
784  for (uint8_t tool = 0; tool < hub->max_tools; ++tool) {
786  if (service) {
787  int new_retval = ipdbg_stop_service(service);
788  if (new_retval != ERROR_OK)
789  retval = new_retval;
790  hub->active_services--;
791  }
792  }
793  struct ipdbg_hub *next_hub = hub->next;
794  int new_retval = ipdbg_remove_hub(hub);
795  if (new_retval != ERROR_OK)
796  retval = new_retval;
797  ipdbg_free_hub(hub);
798  hub = next_hub;
799  }
800  return retval;
801 }
802 
803 static int ipdbg_start(struct ipdbg_hub *hub, uint16_t port, uint8_t tool)
804 {
805  LOG_INFO("starting ipdbg service on port %d for tool %d", port, tool);
806 
807  struct ipdbg_service *service = NULL;
808  int retval = ipdbg_create_service(hub, tool, &service, port);
809 
810  if (retval != ERROR_OK || !service) {
811  if (hub->active_services == 0 && hub->active_connections == 0)
813  return ERROR_FAIL;
814  }
815 
816  char port_str_buffer[IPDBG_TCP_PORT_STR_MAX_LENGTH];
817  snprintf(port_str_buffer, IPDBG_TCP_PORT_STR_MAX_LENGTH, "%u", port);
818  retval = add_service(&ipdbg_service_driver, port_str_buffer, 1, service);
819  if (retval != ERROR_OK) {
820  free(service);
821  return retval;
822  }
824  hub->active_services++;
825  return ERROR_OK;
826 }
827 
828 COMMAND_HANDLER(handle_ipdbg_start_command)
829 {
830  struct ipdbg_hub *hub = CMD_DATA;
831 
832  uint16_t port = 4242;
833  uint8_t tool = 1;
834 
837 
838  for (unsigned int i = 0; i < CMD_ARGC; ++i) {
839  if (strcmp(CMD_ARGV[i], "-port") == 0) {
840  COMMAND_PARSE_ADDITIONAL_NUMBER(u16, i, port, "port number");
841  } else if (strcmp(CMD_ARGV[i], "-tool") == 0) {
842  COMMAND_PARSE_ADDITIONAL_NUMBER(u8, i, tool, "tool");
843  } else {
844  command_print(CMD, "Unknown argument: %s", CMD_ARGV[i]);
845  return ERROR_FAIL;
846  }
847  }
848 
849  return ipdbg_start(hub, port, tool);
850 }
851 
852 static int ipdbg_stop(struct ipdbg_hub *hub, uint8_t tool)
853 {
855  if (!service) {
856  LOG_ERROR("No service for hub '%s'/tool %d found", hub->name, tool);
857  return ERROR_FAIL;
858  }
859 
860  int retval = ipdbg_stop_service(service);
861  hub->active_services--;
862 
863  LOG_INFO("stopped ipdbg service for tool %d", tool);
864  return retval;
865 }
866 
867 COMMAND_HANDLER(handle_ipdbg_stop_command)
868 {
869  struct ipdbg_hub *hub = CMD_DATA;
870 
871  uint8_t tool = 1;
872 
875 
876  for (unsigned int i = 0; i < CMD_ARGC; ++i) {
877  if (strcmp(CMD_ARGV[i], "-tool") == 0) {
878  COMMAND_PARSE_ADDITIONAL_NUMBER(u8, i, tool, "tool");
879  } else {
880  command_print(CMD, "Unknown argument: %s", CMD_ARGV[i]);
881  return ERROR_FAIL;
882  }
883  }
884 
885  return ipdbg_stop(hub, tool);
886 }
887 
889  {
890  .name = "start",
891  .mode = COMMAND_EXEC,
892  .handler = handle_ipdbg_start_command,
893  .help = "Starts a IPDBG Host server.",
894  .usage = "-tool number -port port"
895  }, {
896  .name = "stop",
897  .mode = COMMAND_EXEC,
898  .handler = handle_ipdbg_stop_command,
899  .help = "Stops a IPDBG Host server.",
900  .usage = "-tool number"
901  },
903 };
904 
905 static COMMAND_HELPER(ipdbg_config_queuing, struct ipdbg_hub *hub, unsigned int size)
906 {
907  if (!hub)
908  return ERROR_FAIL;
909 
910  if (hub->active_connections) {
911  command_print(CMD, "Configuration change not allowed when hub has active connections");
912  return ERROR_FAIL;
913  }
914 
915  if (size == 0 || size > IPDBG_SCRATCH_MEMORY_SIZE) {
916  command_print(CMD, "queuing size out of range! Must be 0 < size <= %d", IPDBG_SCRATCH_MEMORY_SIZE);
918  }
919 
920  hub->using_queue_size = size;
921  return ERROR_OK;
922 }
923 
924 COMMAND_HANDLER(handle_ipdbg_cfg_queuing_command)
925 {
926  struct ipdbg_hub *hub = CMD_DATA;
927 
928  unsigned int size;
929 
932 
933  for (unsigned int i = 0; i < CMD_ARGC; ++i) {
934  if (strcmp(CMD_ARGV[i], "-size") == 0) {
935  COMMAND_PARSE_ADDITIONAL_NUMBER(uint, i, size, "size");
936  } else {
937  command_print(CMD, "Unknown argument: %s", CMD_ARGV[i]);
938  return ERROR_FAIL;
939  }
940  }
941 
942  return CALL_COMMAND_HANDLER(ipdbg_config_queuing, hub, size);
943 }
944 
945 static const struct command_registration ipdbg_hub_subcommand_handlers[] = {
946  {
947  .name = "ipdbg",
948  .mode = COMMAND_EXEC,
949  .help = "IPDBG Hub commands.",
950  .usage = "",
952  },
953  {
954  .name = "queuing",
955  .handler = handle_ipdbg_cfg_queuing_command,
956  .mode = COMMAND_ANY,
957  .help = "configures queuing between IPDBG Host and Hub.",
958  .usage = "-size size",
959  },
961 };
962 
964 {
965  Jim_Interp *interp = CMD_CTX->interp;
966 
967  /* does this command exist? */
968  Jim_Cmd *jcmd = Jim_GetCommand(interp, Jim_NewStringObj(interp, hub->name, -1), JIM_NONE);
969  if (jcmd) {
970  LOG_ERROR("cannot create Hub because a command with name '%s' already exists", hub->name);
971  return ERROR_FAIL;
972  }
973 
974  const struct command_registration obj_commands[] = {
975  {
976  .name = hub->name,
977  .mode = COMMAND_EXEC,
978  .help = "IPDBG Hub command group.",
979  .usage = "",
981  },
983  };
984 
985  return register_commands_with_data(CMD_CTX, NULL, obj_commands, hub);
986 }
987 
988 static int ipdbg_create_hub(struct jtag_tap *tap, uint32_t user_instruction, uint8_t data_register_length,
989  struct ipdbg_virtual_ir_info *virtual_ir, const char *name, struct command_invocation *cmd)
990 {
992  if (!new_hub)
993  return ERROR_FAIL;
994 
995  if (virtual_ir)
997  new_hub->tap = tap;
1000  new_hub->valid_mask = BIT(data_register_length - 1);
1001  new_hub->xoff_mask = BIT(data_register_length - 2);
1002  new_hub->tool_mask = (new_hub->xoff_mask - 1) >> 8;
1003  new_hub->last_dn_tool = new_hub->tool_mask;
1006 
1007  int retval = ipdbg_register_hub_command(new_hub, cmd);
1008  if (retval != ERROR_OK) {
1009  LOG_ERROR("Creating hub failed");
1010  ipdbg_free_hub(new_hub);
1011  return ERROR_FAIL;
1012  }
1013 
1014  ipdbg_add_hub(new_hub);
1015 
1016  return ERROR_OK;
1017 }
1018 
1019 COMMAND_HANDLER(handle_ipdbg_create_hub_command)
1020 {
1021  struct jtag_tap *tap = NULL;
1022  uint32_t user_instruction = 0x00;
1023  uint8_t data_register_length = IPDBG_MAX_DR_LENGTH;
1024  bool has_virtual_ir = false;
1025  uint32_t virtual_ir_instruction = 0x00e;
1026  uint32_t virtual_ir_length = 5;
1027  uint32_t virtual_ir_value = 0x11;
1028  struct ipdbg_virtual_ir_info *virtual_ir = NULL;
1029  int user_num = 1;
1030  bool hub_configured = false;
1031 
1032  if (CMD_ARGC < IPDBG_MIN_NUM_OF_CREATE_OPTIONS || CMD_ARGC > IPDBG_MAX_NUM_OF_CREATE_OPTIONS)
1034 
1035  const char *hub_name = CMD_ARGV[0];
1036 
1037  for (unsigned int i = 1; i < CMD_ARGC; ++i) {
1038  if (strcmp(CMD_ARGV[i], "-tap") == 0) {
1039  if (i + 1 >= CMD_ARGC || CMD_ARGV[i + 1][0] == '-') {
1040  command_print(CMD, "no TAP name given");
1041  return ERROR_FAIL;
1042  }
1043  tap = jtag_tap_by_string(CMD_ARGV[i + 1]);
1044  if (!tap) {
1045  command_print(CMD, "Tap %s unknown", CMD_ARGV[i + 1]);
1046  return ERROR_FAIL;
1047  }
1048  ++i;
1049  } else if (strcmp(CMD_ARGV[i], "-ir") == 0) {
1050  COMMAND_PARSE_ADDITIONAL_NUMBER(u32, i, user_instruction, "ir_value to select hub");
1051  hub_configured = true;
1052  COMMAND_PARSE_OPTIONAL_NUMBER(u8, i, data_register_length);
1053  if (data_register_length < IPDBG_MIN_DR_LENGTH ||
1054  data_register_length > IPDBG_MAX_DR_LENGTH) {
1055  command_print(CMD, "length of \"user\"-data register must be at least %d and at most %d.",
1057  return ERROR_FAIL;
1058  }
1059  } else if (strcmp(CMD_ARGV[i], "-pld") == 0) {
1060  ++i;
1061  if (i >= CMD_ARGC || CMD_ARGV[i][0] == '-')
1064  if (!device || !device->driver) {
1065  command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[i]);
1066  return ERROR_FAIL;
1067  }
1068  COMMAND_PARSE_OPTIONAL_NUMBER(int, i, user_num);
1069  struct pld_ipdbg_hub pld_hub;
1070  struct pld_driver *driver = device->driver;
1071  if (!driver->get_ipdbg_hub) {
1072  command_print(CMD, "pld driver has no ipdbg support");
1073  return ERROR_FAIL;
1074  }
1075  if (driver->get_ipdbg_hub(user_num, device, &pld_hub) != ERROR_OK) {
1076  command_print(CMD, "unable to retrieve hub from pld driver");
1077  return ERROR_FAIL;
1078  }
1079  if (!pld_hub.tap) {
1080  command_print(CMD, "no tap received from pld driver");
1081  return ERROR_FAIL;
1082  }
1083  hub_configured = true;
1084  user_instruction = pld_hub.user_ir_code;
1085  tap = pld_hub.tap;
1086 
1087  } else if (strcmp(CMD_ARGV[i], "-vir") == 0) {
1088  COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, virtual_ir_value);
1089  COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, virtual_ir_length);
1090  COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, virtual_ir_instruction);
1091  has_virtual_ir = true;
1092  } else {
1093  command_print(CMD, "Unknown argument: %s", CMD_ARGV[i]);
1094  return ERROR_FAIL;
1095  }
1096  }
1097  if (!tap) {
1098  command_print(CMD, "no valid tap selected");
1099  return ERROR_FAIL;
1100  }
1101 
1102  if (!hub_configured) {
1103  command_print(CMD, "hub not configured correctly");
1104  return ERROR_FAIL;
1105  }
1106 
1107  if (ipdbg_get_hub_by_name(hub_name)) {
1108  LOG_ERROR("IPDBG hub with name '%s' already exists", hub_name);
1109  return ERROR_FAIL;
1110  }
1111 
1112  if (has_virtual_ir) {
1113  virtual_ir = calloc(1, sizeof(struct ipdbg_virtual_ir_info));
1114  if (!virtual_ir) {
1115  LOG_ERROR("Out of memory");
1116  return ERROR_FAIL;
1117  }
1118  virtual_ir->instruction = virtual_ir_instruction;
1119  virtual_ir->length = virtual_ir_length;
1120  virtual_ir->value = virtual_ir_value;
1121  }
1122 
1123  if (ipdbg_find_hub(tap, user_instruction, virtual_ir)) {
1124  LOG_ERROR("IPDBG hub for given TAP and user-instruction already exists");
1125  free(virtual_ir);
1126  return ERROR_FAIL;
1127  }
1128 
1129  return ipdbg_create_hub(tap, user_instruction, data_register_length, virtual_ir, hub_name, cmd);
1130 }
1131 
1132 static const struct command_registration ipdbg_config_command_handlers[] = {
1133  {
1134  .name = "create-hub",
1135  .mode = COMMAND_ANY,
1136  .handler = handle_ipdbg_create_hub_command,
1137  .help = "create a IPDBG Hub",
1138  .usage = "name.ipdbghub (-tap device.tap -ir ir_value [dr_length] |"
1139  " -pld name.pld [user]) [-vir [vir_value [length [instr_code]]]]",
1140  },
1142 };
1143 
1144 static const struct command_registration ipdbg_command_handlers[] = {
1145  {
1146  .name = "ipdbg",
1147  .mode = COMMAND_ANY,
1148  .help = "IPDBG Hub/Host commands.",
1149  .usage = "",
1151  },
1153 };
1154 
1156 {
1157  return register_commands(cmd_ctx, NULL, ipdbg_command_handlers);
1158 }
const char * name
Definition: armv4_5.c:76
static const struct device_t * device
Definition: at91rm9200.c:94
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
Definition: binarybuffer.h:104
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:34
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:443
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:141
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
Definition: command.h:118
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:156
static int register_commands_with_data(struct command_context *cmd_ctx, const char *cmd_prefix, const struct command_registration *cmds, void *data)
Register one or more commands, as register_commands(), plus specify a pointer to command private data...
Definition: command.h:315
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:402
#define CMD_DATA
Use this macro to access the invoked command handler's data pointer, rather than accessing the variab...
Definition: command.h:176
#define COMMAND_PARSE_ADDITIONAL_NUMBER(type, argn, out, name_str)
parses the command argument at position argn into out as a type, or prints a command error referring ...
Definition: command.h:467
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:151
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
Definition: command.h:146
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:253
#define ERROR_COMMAND_ARGUMENT_INVALID
Definition: command.h:404
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:274
#define COMMAND_PARSE_OPTIONAL_NUMBER(type, argn, out)
parses the command argument at position argn into out as a type if the argument argn does not start w...
Definition: command.h:489
@ COMMAND_ANY
Definition: command.h:42
@ COMMAND_EXEC
Definition: command.h:40
static struct esp_usb_jtag * priv
Definition: esp_usb_jtag.c:219
COMMAND_HANDLER(handle_ipdbg_start_command)
Definition: ipdbg.c:828
static const struct command_registration ipdbg_hub_subcommand_handlers[]
Definition: ipdbg.c:945
static int ipdbg_create_service(struct ipdbg_hub *hub, uint8_t tool, struct ipdbg_service **service, uint16_t port)
Definition: ipdbg.c:186
static void ipdbg_add_service(struct ipdbg_service *service)
Definition: ipdbg.c:175
static int ipdbg_remove_service(struct ipdbg_service *service)
Definition: ipdbg.c:201
static int ipdbg_polling_callback(void *priv)
Definition: ipdbg.c:564
#define IPDBG_BUFFER_SIZE
Definition: ipdbg.c:17
static int ipdbg_stop(struct ipdbg_hub *hub, uint8_t tool)
Definition: ipdbg.c:852
#define IPDBG_NUM_OF_QUEUE_OPTIONS
Definition: ipdbg.c:22
static bool ipdbg_fifo_is_empty(struct ipdbg_fifo *fifo)
Definition: ipdbg.c:93
static struct ipdbg_hub * ipdbg_first_hub
Definition: ipdbg.c:83
#define IPDBG_SCRATCH_MEMORY_SIZE
Definition: ipdbg.c:26
static int ipdbg_shift_vir(struct ipdbg_hub *hub)
Definition: ipdbg.c:365
static struct ipdbg_hub * ipdbg_find_hub(struct jtag_tap *tap, uint32_t user_instruction, struct ipdbg_virtual_ir_info *virtual_ir)
Definition: ipdbg.c:220
static struct ipdbg_service * ipdbg_find_service(struct ipdbg_hub *hub, uint8_t tool)
Definition: ipdbg.c:165
static void ipdbg_free_hub(struct ipdbg_hub *hub)
Definition: ipdbg.c:269
static const struct command_registration ipdbg_config_command_handlers[]
Definition: ipdbg.c:1132
static int ipdbg_shift_instr(struct ipdbg_hub *hub, uint32_t instr)
Definition: ipdbg.c:334
static int ipdbg_get_flow_control_info_from_hub(struct ipdbg_hub *hub)
Definition: ipdbg.c:611
static int ipdbg_move_buffer_to_connection(struct connection *conn, struct ipdbg_fifo *fifo)
Definition: ipdbg.c:132
#define IPDBG_TCP_PORT_STR_MAX_LENGTH
Definition: ipdbg.c:25
static int ipdbg_shift_data(struct ipdbg_hub *hub, uint32_t dn_data, uint32_t *up_data)
Definition: ipdbg.c:389
static void ipdbg_init_fifo(struct ipdbg_fifo *fifo)
Definition: ipdbg.c:87
#define IPDBG_NUM_OF_START_OPTIONS
Definition: ipdbg.c:20
static int ipdbg_on_connection_input(struct connection *connection)
Definition: ipdbg.c:711
int ipdbg_register_commands(struct command_context *cmd_ctx)
Definition: ipdbg.c:1155
static int ipdbg_remove_hub(struct ipdbg_hub *hub)
Definition: ipdbg.c:250
static int ipdbg_on_new_connection(struct connection *connection)
Definition: ipdbg.c:689
static void ipdbg_add_hub(struct ipdbg_hub *hub)
Definition: ipdbg.c:238
static int ipdbg_start(struct ipdbg_hub *hub, uint16_t port, uint8_t tool)
Definition: ipdbg.c:803
#define IPDBG_MIN_DR_LENGTH
Definition: ipdbg.c:23
static int ipdbg_jtag_transfer_byte(struct ipdbg_hub *hub, size_t tool, struct ipdbg_connection *connection)
Definition: ipdbg.c:492
#define IPDBG_MAX_DR_LENGTH
Definition: ipdbg.c:24
static const struct command_registration ipdbg_command_handlers[]
Definition: ipdbg.c:1144
static int ipdbg_start_polling(struct ipdbg_service *service, struct connection *connection)
Definition: ipdbg.c:638
static const struct service_driver ipdbg_service_driver
Definition: ipdbg.c:741
static int ipdbg_stop_service(struct ipdbg_service *service)
Definition: ipdbg.c:760
static int ipdbg_stop_polling(struct ipdbg_service *service)
Definition: ipdbg.c:675
static bool ipdbg_fifo_is_full(struct ipdbg_fifo *fifo)
Definition: ipdbg.c:98
static int ipdbg_on_connection_closed(struct connection *connection)
Definition: ipdbg.c:732
static int ipdbg_max_tools_from_data_register_length(uint8_t data_register_length)
Definition: ipdbg.c:154
static void ipdbg_zero_rd_idx(struct ipdbg_fifo *fifo)
Definition: ipdbg.c:103
static COMMAND_HELPER(ipdbg_config_queuing, struct ipdbg_hub *hub, unsigned int size)
Definition: ipdbg.c:905
static void ipdbg_append_to_fifo(struct ipdbg_fifo *fifo, char data)
Definition: ipdbg.c:114
static const struct command_registration ipdbg_hostserver_subcommand_handlers[]
Definition: ipdbg.c:888
int ipdbg_server_free(void)
Definition: ipdbg.c:780
static void ipdbg_init_scan_field(struct scan_field *fields, uint8_t *in_value, int num_bits, const uint8_t *out_value)
Definition: ipdbg.c:325
static int ipdbg_shift_empty_data(struct ipdbg_hub *hub)
Definition: ipdbg.c:449
static int ipdbg_create_hub(struct jtag_tap *tap, uint32_t user_instruction, uint8_t data_register_length, struct ipdbg_virtual_ir_info *virtual_ir, const char *name, struct command_invocation *cmd)
Definition: ipdbg.c:988
#define IPDBG_NUM_OF_STOP_OPTIONS
Definition: ipdbg.c:21
static struct ipdbg_service * ipdbg_first_service
Definition: ipdbg.c:85
static char ipdbg_get_from_fifo(struct ipdbg_fifo *fifo)
Definition: ipdbg.c:123
static int ipdbg_distribute_data_from_hub(struct ipdbg_hub *hub, uint32_t up)
Definition: ipdbg.c:411
static void ipdbg_check_for_xoff(struct ipdbg_hub *hub, size_t tool, uint32_t rx_data)
Definition: ipdbg.c:438
static struct ipdbg_hub * ipdbg_allocate_hub(uint8_t data_register_length, struct ipdbg_virtual_ir_info *virtual_ir, const char *name)
Definition: ipdbg.c:283
static int ipdbg_register_hub_command(struct ipdbg_hub *hub, struct command_invocation *cmd)
Definition: ipdbg.c:963
static struct ipdbg_hub * ipdbg_get_hub_by_name(const char *name)
Definition: ipdbg.c:750
static int ipdbg_jtag_transfer_bytes(struct ipdbg_hub *hub, size_t tool, struct ipdbg_connection *connection)
Definition: ipdbg.c:510
#define IPDBG_MAX_NUM_OF_CREATE_OPTIONS
Definition: ipdbg.c:19
struct jtag_tap * jtag_tap_by_string(const char *s)
Definition: jtag/core.c:243
int jtag_execute_queue(void)
For software FIFO implementations, the queued commands can be executed during this call or earlier.
Definition: jtag/core.c:1043
void jtag_add_ir_scan(struct jtag_tap *active, struct scan_field *in_fields, tap_state_t state)
Generate an IR SCAN with a list of scan fields with one entry for each enabled TAP.
Definition: jtag/core.c:380
void jtag_add_dr_scan(struct jtag_tap *active, int in_num_fields, const struct scan_field *in_fields, tap_state_t state)
Generate a DR SCAN using the fields passed to the function.
Definition: jtag/core.c:457
The JTAG interface can be implemented with a software or hardware fifo.
@ TAP_IDLE
Definition: jtag.h:53
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_INFO(expr ...)
Definition: log.h:126
#define ERROR_OK
Definition: log.h:164
struct pld_device * get_pld_device_by_name_or_numstr(const char *str)
Definition: pld.c:56
size_t size
Size of the control block search area.
Definition: rtt/rtt.c:30
int connection_write(struct connection *connection, const void *data, int len)
Definition: server.c:732
int connection_read(struct connection *connection, void *data, int len)
Definition: server.c:744
int remove_service(const char *name, const char *port)
Definition: server.c:355
int add_service(const struct service_driver *driver, const char *port, int max_connections, void *priv)
Definition: server.c:198
#define ERROR_SERVER_REMOTE_CLOSED
Definition: server.h:119
#define BIT(nr)
Definition: stm32l4x.h:18
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Definition: command.h:76
const char * name
Definition: command.h:235
void * priv
Definition: server.h:43
struct service * service
Definition: server.h:41
struct ipdbg_fifo up_fifo
Definition: ipdbg.c:37
struct ipdbg_fifo dn_fifo
Definition: ipdbg.c:36
bool closed
Definition: ipdbg.c:38
size_t count
Definition: ipdbg.c:30
size_t rd_idx
Definition: ipdbg.c:31
char buffer[IPDBG_BUFFER_SIZE]
Definition: ipdbg.c:32
uint8_t * vir_out_val
Definition: ipdbg.c:58
struct scan_field * fields
Definition: ipdbg.c:59
uint8_t * dr_out_vals
Definition: ipdbg.c:56
uint8_t * dr_in_vals
Definition: ipdbg.c:57
uint32_t active_services
Definition: ipdbg.c:66
struct ipdbg_hub * next
Definition: ipdbg.c:73
uint32_t last_dn_tool
Definition: ipdbg.c:70
uint32_t valid_mask
Definition: ipdbg.c:67
uint8_t dn_xoff
Definition: ipdbg.c:77
uint32_t max_tools
Definition: ipdbg.c:64
struct ipdbg_virtual_ir_info * virtual_ir
Definition: ipdbg.c:79
struct jtag_tap * tap
Definition: ipdbg.c:74
uint32_t tool_mask
Definition: ipdbg.c:69
size_t using_queue_size
Definition: ipdbg.c:72
struct ipdbg_hub_scratch_memory scratch_memory
Definition: ipdbg.c:80
struct connection ** connections
Definition: ipdbg.c:75
uint32_t xoff_mask
Definition: ipdbg.c:68
uint8_t flow_control_enabled
Definition: ipdbg.c:78
char * name
Definition: ipdbg.c:71
uint8_t data_register_length
Definition: ipdbg.c:76
uint32_t active_connections
Definition: ipdbg.c:65
uint32_t user_instruction
Definition: ipdbg.c:63
struct ipdbg_hub * hub
Definition: ipdbg.c:42
uint8_t tool
Definition: ipdbg.c:46
uint16_t port
Definition: ipdbg.c:44
struct ipdbg_service * next
Definition: ipdbg.c:43
uint32_t value
Definition: ipdbg.c:52
uint32_t length
Definition: ipdbg.c:51
uint32_t instruction
Definition: ipdbg.c:50
Definition: jtag.h:101
uint8_t * cur_instr
current instruction
Definition: jtag.h:132
unsigned int ir_length
size of instruction register
Definition: jtag.h:110
Definition: pld.h:48
Definition: pld.h:31
int(* get_ipdbg_hub)(int user_num, struct pld_device *pld_device, struct pld_ipdbg_hub *hub)
Definition: pld.h:36
unsigned int user_ir_code
Definition: pld.h:20
struct jtag_tap * tap
Definition: pld.h:19
This structure defines a single scan field in the scan.
Definition: jtag.h:87
uint8_t * in_value
A pointer to a 32-bit memory location for data scanned out.
Definition: jtag.h:93
uint8_t * check_value
The value used to check the data scanned out.
Definition: jtag.h:96
const uint8_t * out_value
A pointer to value to be scanned into the device.
Definition: jtag.h:91
unsigned int num_bits
The number of bits this field specifies.
Definition: jtag.h:89
uint8_t * check_mask
The mask to go with check_value.
Definition: jtag.h:98
const char * name
the name of the server
Definition: server.h:49
Definition: server.h:67
struct service * next
Definition: server.h:82
void * priv
Definition: server.h:81
char * port
Definition: server.h:70
int target_unregister_timer_callback(int(*callback)(void *priv), void *priv)
Definition: target.c:1748
int target_register_timer_callback(int(*callback)(void *priv), unsigned int time_ms, enum target_timer_type type, void *priv)
The period is very approximate, the callback can happen much more often or much more rarely than spec...
Definition: target.c:1658
#define DIV_ROUND_UP(m, n)
Rounds m up to the nearest multiple of n using division.
Definition: types.h:79
#define NULL
Definition: usb.h:16
uint8_t cmd
Definition: vdebug.c:1