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  return jtag_execute_queue();
385 }
386 
387 static int ipdbg_shift_data(struct ipdbg_hub *hub, uint32_t dn_data, uint32_t *up_data)
388 {
389  if (!hub)
390  return ERROR_FAIL;
391 
392  struct jtag_tap *tap = hub->tap;
393  if (!tap)
394  return ERROR_FAIL;
395 
397 
401  int retval = jtag_execute_queue();
402 
403  if (up_data && retval == ERROR_OK)
404  *up_data = buf_get_u32(hub->scratch_memory.dr_in_vals, 0, hub->data_register_length);
405 
406  return retval;
407 }
408 
409 static int ipdbg_distribute_data_from_hub(struct ipdbg_hub *hub, uint32_t up)
410 {
411  const bool valid_up_data = up & hub->valid_mask;
412  if (!valid_up_data)
413  return ERROR_OK;
414 
415  const size_t tool = (up >> 8) & hub->tool_mask;
416  if (tool == hub->tool_mask) {
417  const uint8_t xon_cmd = up & 0x00ff;
418  hub->dn_xoff &= ~xon_cmd;
419  LOG_INFO("received xon cmd: %d\n", xon_cmd);
420  return ERROR_OK;
421  }
422 
423  struct connection *conn = hub->connections[tool];
424  if (conn) {
425  struct ipdbg_connection *connection = conn->priv;
426  if (ipdbg_fifo_is_full(&connection->up_fifo)) {
427  int retval = ipdbg_move_buffer_to_connection(conn, &connection->up_fifo);
428  if (retval != ERROR_OK)
429  return retval;
430  }
431  ipdbg_append_to_fifo(&connection->up_fifo, up);
432  }
433  return ERROR_OK;
434 }
435 
436 static void ipdbg_check_for_xoff(struct ipdbg_hub *hub, size_t tool,
437  uint32_t rx_data)
438 {
439  if ((rx_data & hub->xoff_mask) && hub->last_dn_tool != hub->max_tools) {
440  hub->dn_xoff |= BIT(hub->last_dn_tool);
441  LOG_INFO("tool %d sent xoff", hub->last_dn_tool);
442  }
443 
444  hub->last_dn_tool = tool;
445 }
446 
447 static int ipdbg_shift_empty_data(struct ipdbg_hub *hub)
448 {
449  if (!hub)
450  return ERROR_FAIL;
451 
452  struct jtag_tap *tap = hub->tap;
453  if (!tap)
454  return ERROR_FAIL;
455 
456  const size_t dreg_buffer_size = DIV_ROUND_UP(hub->data_register_length, 8);
457  memset(hub->scratch_memory.dr_out_vals, 0, dreg_buffer_size);
458  for (size_t i = 0; i < hub->using_queue_size; ++i) {
460  hub->scratch_memory.dr_in_vals + i * dreg_buffer_size,
463  jtag_add_dr_scan(tap, 1, hub->scratch_memory.fields + i, TAP_IDLE);
464  }
465 
466  int retval = jtag_execute_queue();
467 
468  if (retval == ERROR_OK) {
469  uint32_t up_data;
470  for (size_t i = 0; i < hub->using_queue_size; ++i) {
471  up_data = buf_get_u32(hub->scratch_memory.dr_in_vals +
472  i * dreg_buffer_size, 0,
473  hub->data_register_length);
474  int rv = ipdbg_distribute_data_from_hub(hub, up_data);
475  if (rv != ERROR_OK)
476  retval = rv;
477 
478  if (i == 0) {
479  /* check if xoff sent is only needed on the first transfer which
480  may contain the xoff of the prev down transfer.
481  */
482  ipdbg_check_for_xoff(hub, hub->max_tools, up_data);
483  }
484  }
485  }
486 
487  return retval;
488 }
489 
490 static int ipdbg_jtag_transfer_byte(struct ipdbg_hub *hub, size_t tool, struct ipdbg_connection *connection)
491 {
492  uint32_t dn = hub->valid_mask | ((tool & hub->tool_mask) << 8) |
493  (0x00fful & ipdbg_get_from_fifo(&connection->dn_fifo));
494  uint32_t up = 0;
495  int ret = ipdbg_shift_data(hub, dn, &up);
496  if (ret != ERROR_OK)
497  return ret;
498 
499  ret = ipdbg_distribute_data_from_hub(hub, up);
500  if (ret != ERROR_OK)
501  return ret;
502 
503  ipdbg_check_for_xoff(hub, tool, up);
504 
505  return ERROR_OK;
506 }
507 
508 static int ipdbg_jtag_transfer_bytes(struct ipdbg_hub *hub,
509  size_t tool, struct ipdbg_connection *connection)
510 {
511  if (!hub)
512  return ERROR_FAIL;
513 
514  struct jtag_tap *tap = hub->tap;
515  if (!tap)
516  return ERROR_FAIL;
517 
518  const size_t dreg_buffer_size = DIV_ROUND_UP(hub->data_register_length, 8);
519  size_t num_tx = (connection->dn_fifo.count < hub->using_queue_size) ?
520  connection->dn_fifo.count : hub->using_queue_size;
521 
522  for (size_t i = 0; i < num_tx; ++i) {
523  uint32_t dn_data = hub->valid_mask | ((tool & hub->tool_mask) << 8) |
524  (0x00fful & ipdbg_get_from_fifo(&connection->dn_fifo));
525  buf_set_u32(hub->scratch_memory.dr_out_vals + i * dreg_buffer_size, 0,
526  hub->data_register_length, dn_data);
527 
530  i * dreg_buffer_size,
533  i * dreg_buffer_size);
534  jtag_add_dr_scan(tap, 1, hub->scratch_memory.fields + i, TAP_IDLE);
535  }
536 
537  int retval = jtag_execute_queue();
538 
539  if (retval == ERROR_OK) {
540  uint32_t up_data;
541  for (size_t i = 0; i < num_tx; ++i) {
542  up_data = buf_get_u32(hub->scratch_memory.dr_in_vals +
543  i * dreg_buffer_size,
544  0, hub->data_register_length);
545  int rv = ipdbg_distribute_data_from_hub(hub, up_data);
546  if (rv != ERROR_OK)
547  retval = rv;
548  if (i == 0) {
549  /* check if xoff sent is only needed on the first transfer which
550  may contain the xoff of the prev down transfer.
551  No checks for this channel because this function is only
552  called for channels without enabled flow control.
553  */
554  ipdbg_check_for_xoff(hub, tool, up_data);
555  }
556  }
557  }
558 
559  return retval;
560 }
561 
562 static int ipdbg_polling_callback(void *priv)
563 {
564  struct ipdbg_hub *hub = priv;
565 
566  int ret = ipdbg_shift_vir(hub);
567  if (ret != ERROR_OK)
568  return ret;
569 
570  ret = ipdbg_shift_instr(hub, hub->user_instruction);
571  if (ret != ERROR_OK)
572  return ret;
573 
574  /* transfer dn buffers to jtag-hub */
575  for (size_t tool = 0; tool < hub->max_tools; ++tool) {
576  struct connection *conn = hub->connections[tool];
577  if (conn && conn->priv) {
578  struct ipdbg_connection *connection = conn->priv;
579  while (((hub->dn_xoff & BIT(tool)) == 0) && !ipdbg_fifo_is_empty(&connection->dn_fifo)) {
580  if (hub->flow_control_enabled & BIT(tool))
581  ret = ipdbg_jtag_transfer_byte(hub, tool, connection);
582  else
583  ret = ipdbg_jtag_transfer_bytes(hub, tool, connection);
584  if (ret != ERROR_OK)
585  return ret;
586  }
587  }
588  }
589 
590  /* some transfers to get data from jtag-hub in case there is no dn data */
591  ret = ipdbg_shift_empty_data(hub);
592  if (ret != ERROR_OK)
593  return ret;
594 
595  /* write from up fifos to sockets */
596  for (size_t tool = 0; tool < hub->max_tools; ++tool) {
597  struct connection *conn = hub->connections[tool];
598  if (conn && conn->priv) {
599  struct ipdbg_connection *connection = conn->priv;
600  int retval = ipdbg_move_buffer_to_connection(conn, &connection->up_fifo);
601  if (retval != ERROR_OK)
602  return retval;
603  }
604  }
605 
606  return ERROR_OK;
607 }
608 
610 {
611  uint32_t up_data;
612 
613  /* on older implementations the flow_control_enable_word is not sent to us.
614  so we don't know -> assume it's enabled on all channels */
615  hub->flow_control_enabled = 0x7f;
616 
617  int ret = ipdbg_shift_data(hub, 0UL, &up_data);
618  if (ret != ERROR_OK)
619  return ret;
620 
621  const bool valid_up_data = up_data & hub->valid_mask;
622  if (valid_up_data) {
623  const size_t tool = (up_data >> 8) & hub->tool_mask;
624  /* the first valid data from hub is flow_control_enable_word */
625  if (tool == hub->tool_mask)
626  hub->flow_control_enabled = up_data & 0x007f;
627  else
628  ipdbg_distribute_data_from_hub(hub, up_data);
629  }
630 
631  LOG_INFO("Flow control enabled on IPDBG JTAG Hub: 0x%02x", hub->flow_control_enabled);
632 
633  return ERROR_OK;
634 }
635 
637 {
638  struct ipdbg_hub *hub = service->hub;
639  hub->connections[service->tool] = connection;
640  hub->active_connections++;
641  if (hub->active_connections > 1) {
642  /* hub is already initialized */
643  return ERROR_OK;
644  }
645 
646  const uint32_t reset_hub = hub->valid_mask | ((hub->max_tools) << 8);
647 
648  int ret = ipdbg_shift_vir(hub);
649  if (ret != ERROR_OK)
650  return ret;
651 
652  ret = ipdbg_shift_instr(hub, hub->user_instruction);
653  if (ret != ERROR_OK)
654  return ret;
655 
656  ret = ipdbg_shift_data(hub, reset_hub, NULL);
657  hub->last_dn_tool = hub->tool_mask;
658  hub->dn_xoff = 0;
659  if (ret != ERROR_OK)
660  return ret;
661 
663  if (ret != ERROR_OK)
664  return ret;
665 
666  LOG_INFO("IPDBG start_polling");
667 
668  const int time_ms = 20;
669  const int periodic = 1;
670  return target_register_timer_callback(ipdbg_polling_callback, time_ms, periodic, hub);
671 }
672 
674 {
675  struct ipdbg_hub *hub = service->hub;
676  hub->connections[service->tool] = NULL;
677  hub->active_connections--;
678  if (hub->active_connections == 0) {
679  LOG_INFO("IPDBG stop_polling");
680 
682  }
683 
684  return ERROR_OK;
685 }
686 
688 {
690  connection->priv = &service->connection;
691  /* initialize ipdbg connection information */
692  ipdbg_init_fifo(&service->connection.up_fifo);
693  ipdbg_init_fifo(&service->connection.dn_fifo);
694 
695  int retval = ipdbg_start_polling(service, connection);
696  if (retval != ERROR_OK) {
697  LOG_ERROR("BUG: ipdbg_start_polling failed");
698  return retval;
699  }
700 
702  conn->closed = false;
703 
704  LOG_INFO("New IPDBG Connection");
705 
706  return ERROR_OK;
707 }
708 
710 {
712  struct ipdbg_fifo *fifo = &conn->dn_fifo;
713 
714  if (ipdbg_fifo_is_full(fifo))
715  return ERROR_OK;
716 
717  ipdbg_zero_rd_idx(fifo);
718  int bytes_read = connection_read(connection, fifo->buffer + fifo->count, IPDBG_BUFFER_SIZE - fifo->count);
719  if (bytes_read <= 0) {
720  if (bytes_read < 0)
721  LOG_ERROR("error during read: %s", strerror(errno));
723  }
724 
725  fifo->count += bytes_read;
726 
727  return ERROR_OK;
728 }
729 
731 {
733  conn->closed = true;
734  LOG_INFO("Closed IPDBG Connection");
735 
737 }
738 
739 static const struct service_driver ipdbg_service_driver = {
740  .name = "ipdbg",
741  .new_connection_during_keep_alive_handler = NULL,
742  .new_connection_handler = ipdbg_on_new_connection,
743  .input_handler = ipdbg_on_connection_input,
744  .connection_closed_handler = ipdbg_on_connection_closed,
745  .keep_client_alive_handler = NULL,
746 };
747 
748 static struct ipdbg_hub *ipdbg_get_hub_by_name(const char *name)
749 {
750  struct ipdbg_hub *hub = NULL;
751  for (hub = ipdbg_first_hub; hub; hub = hub->next) {
752  if (strcmp(hub->name, name) == 0)
753  break;
754  }
755  return hub;
756 };
757 
759 {
760  int retval = ipdbg_remove_service(service);
761  if (retval != ERROR_OK) {
762  LOG_ERROR("BUG: ipdbg_remove_service failed");
763  return retval;
764  }
765 
766  char port_str_buffer[IPDBG_TCP_PORT_STR_MAX_LENGTH];
767  snprintf(port_str_buffer, IPDBG_TCP_PORT_STR_MAX_LENGTH, "%u", service->port);
768  retval = remove_service("ipdbg", port_str_buffer);
769  /* The ipdbg_service structure is freed by server.c:remove_service().
770  There the "priv" pointer is freed.*/
771  if (retval != ERROR_OK) {
772  LOG_ERROR("BUG: remove_service failed");
773  return retval;
774  }
775  return ERROR_OK;
776 }
777 
779 {
780  int retval = ERROR_OK;
781  for (struct ipdbg_hub *hub = ipdbg_first_hub; hub;) {
782  for (uint8_t tool = 0; tool < hub->max_tools; ++tool) {
784  if (service) {
785  int new_retval = ipdbg_stop_service(service);
786  if (new_retval != ERROR_OK)
787  retval = new_retval;
788  hub->active_services--;
789  }
790  }
791  struct ipdbg_hub *next_hub = hub->next;
792  int new_retval = ipdbg_remove_hub(hub);
793  if (new_retval != ERROR_OK)
794  retval = new_retval;
795  ipdbg_free_hub(hub);
796  hub = next_hub;
797  }
798  return retval;
799 }
800 
801 static int ipdbg_start(struct ipdbg_hub *hub, uint16_t port, uint8_t tool)
802 {
803  LOG_INFO("starting ipdbg service on port %d for tool %d", port, tool);
804 
805  struct ipdbg_service *service = NULL;
806  int retval = ipdbg_create_service(hub, tool, &service, port);
807 
808  if (retval != ERROR_OK || !service) {
809  if (hub->active_services == 0 && hub->active_connections == 0)
811  return ERROR_FAIL;
812  }
813 
814  char port_str_buffer[IPDBG_TCP_PORT_STR_MAX_LENGTH];
815  snprintf(port_str_buffer, IPDBG_TCP_PORT_STR_MAX_LENGTH, "%u", port);
816  retval = add_service(&ipdbg_service_driver, port_str_buffer, 1, service);
817  if (retval != ERROR_OK) {
818  free(service);
819  return retval;
820  }
822  hub->active_services++;
823  return ERROR_OK;
824 }
825 
826 COMMAND_HANDLER(handle_ipdbg_start_command)
827 {
828  struct ipdbg_hub *hub = CMD_DATA;
829 
830  uint16_t port = 4242;
831  uint8_t tool = 1;
832 
835 
836  for (unsigned int i = 0; i < CMD_ARGC; ++i) {
837  if (strcmp(CMD_ARGV[i], "-port") == 0) {
838  COMMAND_PARSE_ADDITIONAL_NUMBER(u16, i, port, "port number");
839  } else if (strcmp(CMD_ARGV[i], "-tool") == 0) {
840  COMMAND_PARSE_ADDITIONAL_NUMBER(u8, i, tool, "tool");
841  } else {
842  command_print(CMD, "Unknown argument: %s", CMD_ARGV[i]);
843  return ERROR_FAIL;
844  }
845  }
846 
847  return ipdbg_start(hub, port, tool);
848 }
849 
850 static int ipdbg_stop(struct ipdbg_hub *hub, uint8_t tool)
851 {
853  if (!service) {
854  LOG_ERROR("No service for hub '%s'/tool %d found", hub->name, tool);
855  return ERROR_FAIL;
856  }
857 
858  int retval = ipdbg_stop_service(service);
859  hub->active_services--;
860 
861  LOG_INFO("stopped ipdbg service for tool %d", tool);
862  return retval;
863 }
864 
865 COMMAND_HANDLER(handle_ipdbg_stop_command)
866 {
867  struct ipdbg_hub *hub = CMD_DATA;
868 
869  uint8_t tool = 1;
870 
873 
874  for (unsigned int i = 0; i < CMD_ARGC; ++i) {
875  if (strcmp(CMD_ARGV[i], "-tool") == 0) {
876  COMMAND_PARSE_ADDITIONAL_NUMBER(u8, i, tool, "tool");
877  } else {
878  command_print(CMD, "Unknown argument: %s", CMD_ARGV[i]);
879  return ERROR_FAIL;
880  }
881  }
882 
883  return ipdbg_stop(hub, tool);
884 }
885 
886 static COMMAND_HELPER(ipdbg_config_queuing, struct ipdbg_hub *hub, unsigned int size)
887 {
888  if (!hub)
889  return ERROR_FAIL;
890 
891  if (hub->active_connections) {
892  command_print(CMD, "Configuration change not allowed when hub has active connections");
893  return ERROR_FAIL;
894  }
895 
896  if (size == 0 || size > IPDBG_SCRATCH_MEMORY_SIZE) {
897  command_print(CMD, "queuing size out of range! Must be 0 < size <= %d", IPDBG_SCRATCH_MEMORY_SIZE);
899  }
900 
901  hub->using_queue_size = size;
902  return ERROR_OK;
903 }
904 
905 COMMAND_HANDLER(handle_ipdbg_cfg_queuing_command)
906 {
907  struct ipdbg_hub *hub = CMD_DATA;
908 
909  unsigned int size;
910 
913 
914  for (unsigned int i = 0; i < CMD_ARGC; ++i) {
915  if (strcmp(CMD_ARGV[i], "-size") == 0) {
916  COMMAND_PARSE_ADDITIONAL_NUMBER(uint, i, size, "size");
917  } else {
918  command_print(CMD, "Unknown argument: %s", CMD_ARGV[i]);
919  return ERROR_FAIL;
920  }
921  }
922 
923  return CALL_COMMAND_HANDLER(ipdbg_config_queuing, hub, size);
924 }
925 
926 static const struct command_registration ipdbg_hub_subcommand_handlers[] = {
927  {
928  .name = "start",
929  .mode = COMMAND_EXEC,
930  .handler = handle_ipdbg_start_command,
931  .help = "Starts a IPDBG Host server.",
932  .usage = "-tool number -port port"
933  }, {
934  .name = "stop",
935  .mode = COMMAND_EXEC,
936  .handler = handle_ipdbg_stop_command,
937  .help = "Stops a IPDBG Host server.",
938  .usage = "-tool number"
939  }, {
940  .name = "queuing",
941  .handler = handle_ipdbg_cfg_queuing_command,
942  .mode = COMMAND_ANY,
943  .help = "configures queuing between IPDBG Host and Hub.",
944  .usage = "-size size",
945  },
947 };
948 
950 {
951  Jim_Interp *interp = CMD_CTX->interp;
952 
953  /* does this command exist? */
954  Jim_Cmd *jcmd = Jim_GetCommand(interp, Jim_NewStringObj(interp, hub->name, -1), JIM_NONE);
955  if (jcmd) {
956  LOG_ERROR("cannot create Hub because a command with name '%s' already exists", hub->name);
957  return ERROR_FAIL;
958  }
959 
960  const struct command_registration obj_commands[] = {
961  {
962  .name = hub->name,
963  .mode = COMMAND_EXEC,
964  .help = "IPDBG Hub command group.",
965  .usage = "",
967  },
969  };
970 
971  return register_commands_with_data(CMD_CTX, NULL, obj_commands, hub);
972 }
973 
974 static int ipdbg_create_hub(struct jtag_tap *tap, uint32_t user_instruction, uint8_t data_register_length,
975  struct ipdbg_virtual_ir_info *virtual_ir, const char *name, struct command_invocation *cmd)
976 {
978  if (!new_hub)
979  return ERROR_FAIL;
980 
981  if (virtual_ir)
983  new_hub->tap = tap;
986  new_hub->valid_mask = BIT(data_register_length - 1);
987  new_hub->xoff_mask = BIT(data_register_length - 2);
988  new_hub->tool_mask = (new_hub->xoff_mask - 1) >> 8;
989  new_hub->last_dn_tool = new_hub->tool_mask;
992 
993  int retval = ipdbg_register_hub_command(new_hub, cmd);
994  if (retval != ERROR_OK) {
995  LOG_ERROR("Creating hub failed");
996  ipdbg_free_hub(new_hub);
997  return ERROR_FAIL;
998  }
999 
1000  ipdbg_add_hub(new_hub);
1001 
1002  return ERROR_OK;
1003 }
1004 
1005 COMMAND_HANDLER(handle_ipdbg_create_hub_command)
1006 {
1007  struct jtag_tap *tap = NULL;
1008  uint32_t user_instruction = 0x00;
1009  uint8_t data_register_length = IPDBG_MAX_DR_LENGTH;
1010  bool has_virtual_ir = false;
1011  uint32_t virtual_ir_instruction = 0x00e;
1012  uint32_t virtual_ir_length = 5;
1013  uint32_t virtual_ir_value = 0x11;
1014  struct ipdbg_virtual_ir_info *virtual_ir = NULL;
1015  int user_num = 1;
1016  bool hub_configured = false;
1017 
1018  if (CMD_ARGC < IPDBG_MIN_NUM_OF_CREATE_OPTIONS || CMD_ARGC > IPDBG_MAX_NUM_OF_CREATE_OPTIONS)
1020 
1021  const char *hub_name = CMD_ARGV[0];
1022 
1023  for (unsigned int i = 1; i < CMD_ARGC; ++i) {
1024  if (strcmp(CMD_ARGV[i], "-tap") == 0) {
1025  if (i + 1 >= CMD_ARGC || CMD_ARGV[i + 1][0] == '-') {
1026  command_print(CMD, "no TAP name given");
1027  return ERROR_FAIL;
1028  }
1029  tap = jtag_tap_by_string(CMD_ARGV[i + 1]);
1030  if (!tap) {
1031  command_print(CMD, "Tap %s unknown", CMD_ARGV[i + 1]);
1032  return ERROR_FAIL;
1033  }
1034  ++i;
1035  } else if (strcmp(CMD_ARGV[i], "-ir") == 0) {
1036  COMMAND_PARSE_ADDITIONAL_NUMBER(u32, i, user_instruction, "ir_value to select hub");
1037  hub_configured = true;
1038  COMMAND_PARSE_OPTIONAL_NUMBER(u8, i, data_register_length);
1039  if (data_register_length < IPDBG_MIN_DR_LENGTH ||
1040  data_register_length > IPDBG_MAX_DR_LENGTH) {
1041  command_print(CMD, "length of \"user\"-data register must be at least %d and at most %d.",
1043  return ERROR_FAIL;
1044  }
1045  } else if (strcmp(CMD_ARGV[i], "-pld") == 0) {
1046  ++i;
1047  if (i >= CMD_ARGC || CMD_ARGV[i][0] == '-')
1050  if (!device || !device->driver) {
1051  command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[i]);
1052  return ERROR_FAIL;
1053  }
1054  COMMAND_PARSE_OPTIONAL_NUMBER(int, i, user_num);
1055  struct pld_ipdbg_hub pld_hub;
1056  struct pld_driver *driver = device->driver;
1057  if (!driver->get_ipdbg_hub) {
1058  command_print(CMD, "pld driver has no ipdbg support");
1059  return ERROR_FAIL;
1060  }
1061  if (driver->get_ipdbg_hub(user_num, device, &pld_hub) != ERROR_OK) {
1062  command_print(CMD, "unable to retrieve hub from pld driver");
1063  return ERROR_FAIL;
1064  }
1065  if (!pld_hub.tap) {
1066  command_print(CMD, "no tap received from pld driver");
1067  return ERROR_FAIL;
1068  }
1069  hub_configured = true;
1070  user_instruction = pld_hub.user_ir_code;
1071  tap = pld_hub.tap;
1072 
1073  } else if (strcmp(CMD_ARGV[i], "-vir") == 0) {
1074  COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, virtual_ir_value);
1075  COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, virtual_ir_length);
1076  COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, virtual_ir_instruction);
1077  has_virtual_ir = true;
1078  } else {
1079  command_print(CMD, "Unknown argument: %s", CMD_ARGV[i]);
1080  return ERROR_FAIL;
1081  }
1082  }
1083  if (!tap) {
1084  command_print(CMD, "no valid tap selected");
1085  return ERROR_FAIL;
1086  }
1087 
1088  if (!hub_configured) {
1089  command_print(CMD, "hub not configured correctly");
1090  return ERROR_FAIL;
1091  }
1092 
1093  if (ipdbg_get_hub_by_name(hub_name)) {
1094  LOG_ERROR("IPDBG hub with name '%s' already exists", hub_name);
1095  return ERROR_FAIL;
1096  }
1097 
1098  if (has_virtual_ir) {
1099  virtual_ir = calloc(1, sizeof(struct ipdbg_virtual_ir_info));
1100  if (!virtual_ir) {
1101  LOG_ERROR("Out of memory");
1102  return ERROR_FAIL;
1103  }
1104  virtual_ir->instruction = virtual_ir_instruction;
1105  virtual_ir->length = virtual_ir_length;
1106  virtual_ir->value = virtual_ir_value;
1107  }
1108 
1109  if (ipdbg_find_hub(tap, user_instruction, virtual_ir)) {
1110  LOG_ERROR("IPDBG hub for given TAP and user-instruction already exists");
1111  free(virtual_ir);
1112  return ERROR_FAIL;
1113  }
1114 
1115  return ipdbg_create_hub(tap, user_instruction, data_register_length, virtual_ir, hub_name, cmd);
1116 }
1117 
1118 static const struct command_registration ipdbg_config_command_handlers[] = {
1119  {
1120  .name = "create-hub",
1121  .mode = COMMAND_ANY,
1122  .handler = handle_ipdbg_create_hub_command,
1123  .help = "create a IPDBG Hub",
1124  .usage = "name.ipdbghub (-tap device.tap -ir ir_value [dr_length] |"
1125  " -pld name.pld [user]) [-vir [vir_value [length [instr_code]]]]",
1126  },
1128 };
1129 
1130 static const struct command_registration ipdbg_command_handlers[] = {
1131  {
1132  .name = "ipdbg",
1133  .mode = COMMAND_ANY,
1134  .help = "IPDBG Hub/Host commands.",
1135  .usage = "",
1137  },
1139 };
1141 {
1142  return register_commands(cmd_ctx, NULL, ipdbg_command_handlers);
1143 }
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:389
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:146
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
Definition: command.h:123
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:161
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:318
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:405
#define CMD_DATA
Use this macro to access the invoked command handler's data pointer, rather than accessing the variab...
Definition: command.h:181
#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:470
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:156
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
Definition: command.h:151
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:256
#define ERROR_COMMAND_ARGUMENT_INVALID
Definition: command.h:407
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:277
#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:492
@ COMMAND_ANY
Definition: command.h:42
@ COMMAND_EXEC
Definition: command.h:40
uint32_t size
Size of dw_spi_transaction::buffer.
Definition: dw-spi-helper.h:4
static struct esp_usb_jtag * priv
Definition: esp_usb_jtag.c:219
COMMAND_HANDLER(handle_ipdbg_start_command)
Definition: ipdbg.c:826
static const struct command_registration ipdbg_hub_subcommand_handlers[]
Definition: ipdbg.c:926
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:562
#define IPDBG_BUFFER_SIZE
Definition: ipdbg.c:17
static int ipdbg_stop(struct ipdbg_hub *hub, uint8_t tool)
Definition: ipdbg.c:850
#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:1118
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:609
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:387
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:709
int ipdbg_register_commands(struct command_context *cmd_ctx)
Definition: ipdbg.c:1140
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:687
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:801
#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:490
#define IPDBG_MAX_DR_LENGTH
Definition: ipdbg.c:24
static const struct command_registration ipdbg_command_handlers[]
Definition: ipdbg.c:1130
static int ipdbg_start_polling(struct ipdbg_service *service, struct connection *connection)
Definition: ipdbg.c:636
static const struct service_driver ipdbg_service_driver
Definition: ipdbg.c:739
static int ipdbg_stop_service(struct ipdbg_service *service)
Definition: ipdbg.c:758
static int ipdbg_stop_polling(struct ipdbg_service *service)
Definition: ipdbg.c:673
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:730
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:886
static void ipdbg_append_to_fifo(struct ipdbg_fifo *fifo, char data)
Definition: ipdbg.c:114
int ipdbg_server_free(void)
Definition: ipdbg.c:778
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:447
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:974
#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:409
static void ipdbg_check_for_xoff(struct ipdbg_hub *hub, size_t tool, uint32_t rx_data)
Definition: ipdbg.c:436
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:949
static struct ipdbg_hub * ipdbg_get_hub_by_name(const char *name)
Definition: ipdbg.c:748
static int ipdbg_jtag_transfer_bytes(struct ipdbg_hub *hub, size_t tool, struct ipdbg_connection *connection)
Definition: ipdbg.c:508
#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:238
int jtag_execute_queue(void)
For software FIFO implementations, the queued commands can be executed during this call or earlier.
Definition: jtag/core.c:1045
void jtag_add_dr_scan(struct jtag_tap *active, int in_num_fields, const struct scan_field *in_fields, enum tap_state state)
Generate a DR SCAN using the fields passed to the function.
Definition: jtag/core.c:452
void jtag_add_ir_scan(struct jtag_tap *active, struct scan_field *in_fields, enum tap_state state)
Generate an IR SCAN with a list of scan fields with one entry for each enabled TAP.
Definition: jtag/core.c:375
The JTAG interface can be implemented with a software or hardware fifo.
@ TAP_IDLE
Definition: jtag.h:53
#define ERROR_FAIL
Definition: log.h:188
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define LOG_INFO(expr ...)
Definition: log.h:141
#define ERROR_OK
Definition: log.h:182
struct pld_device * get_pld_device_by_name_or_numstr(const char *str)
Definition: pld.c:56
int connection_write(struct connection *connection, const void *data, int len)
Definition: server.c:741
int connection_read(struct connection *connection, void *data, int len)
Definition: server.c:753
int remove_service(const char *name, const char *port)
Definition: server.c:376
int add_service(const struct service_driver *driver, const char *port, int max_connections, void *priv)
Definition: server.c:206
#define ERROR_SERVER_REMOTE_CLOSED
Definition: server.h:121
#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:239
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:68
struct service * next
Definition: server.h:84
void * priv
Definition: server.h:83
char * port
Definition: server.h:71
int target_unregister_timer_callback(int(*callback)(void *priv), void *priv)
Definition: target.c:1778
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:1688
#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