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