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
96 return fifo->
count == 0;
110 for (
size_t idx = 0; idx < fifo->
count; ++idx)
144 if (bytes_written != fifo->
count) {
145 LOG_ERROR(
"error during write: %zu != %zu", bytes_written, fifo->
count);
150 fifo->
count -= bytes_written;
158 data_register_length -= 10;
159 while (data_register_length--)
163 return max_tools - 1;
195 (*service)->hub =
hub;
196 (*service)->tool =
tool;
197 (*service)->port =
port;
261 if (hub == ihub->
next) {
262 ihub->next = hub->
next;
295 if (!new_hub->
name) {
412 const bool valid_up_data = up & hub->
valid_mask;
416 const size_t tool = (up >> 8) & hub->
tool_mask;
418 const uint8_t xon_cmd = up & 0x00ff;
420 LOG_INFO(
"received xon cmd: %d\n", xon_cmd);
473 i * dreg_buffer_size, 0,
523 for (
size_t i = 0; i < num_tx; ++i) {
531 i * dreg_buffer_size,
534 i * dreg_buffer_size);
542 for (
size_t i = 0; i < num_tx; ++i) {
544 i * dreg_buffer_size,
576 for (
size_t tool = 0; tool < hub->
max_tools; ++tool) {
597 for (
size_t tool = 0; tool < hub->
max_tools; ++tool) {
622 const bool valid_up_data = up_data & hub->
valid_mask;
624 const size_t tool = (up_data >> 8) & hub->
tool_mask;
669 const int time_ms = 20;
670 const int periodic = 1;
698 LOG_ERROR(
"BUG: ipdbg_start_polling failed");
703 conn->closed =
false;
720 if (bytes_read <= 0) {
722 LOG_ERROR(
"error during read: %s", strerror(errno));
726 fifo->
count += bytes_read;
735 LOG_INFO(
"Closed IPDBG Connection");
742 .new_connection_during_keep_alive_handler =
NULL,
746 .keep_client_alive_handler =
NULL,
763 LOG_ERROR(
"BUG: ipdbg_remove_service failed");
783 for (uint8_t tool = 0; tool < hub->max_tools; ++tool) {
804 LOG_INFO(
"starting ipdbg service on port %d for tool %d", port, tool);
831 uint16_t port = 4242;
837 for (
unsigned int i = 0; i <
CMD_ARGC; ++i) {
838 if (strcmp(
CMD_ARGV[i],
"-port") == 0) {
840 }
else if (strcmp(
CMD_ARGV[i],
"-tool") == 0) {
875 for (
unsigned int i = 0; i <
CMD_ARGC; ++i) {
876 if (strcmp(
CMD_ARGV[i],
"-tool") == 0) {
893 command_print(
CMD,
"Configuration change not allowed when hub has active connections");
915 for (
unsigned int i = 0; i <
CMD_ARGC; ++i) {
916 if (strcmp(
CMD_ARGV[i],
"-size") == 0) {
941 service->connection.closed ?
"listening" :
"connected");
953 .handler = handle_ipdbg_start_command,
954 .help =
"Starts a IPDBG Host server",
955 .usage =
"-tool number -port port"
959 .handler = handle_ipdbg_stop_command,
960 .help =
"Stops a IPDBG Host server",
961 .usage =
"-tool number"
964 .handler = handle_ipdbg_cfg_queuing_command,
966 .help =
"configures queuing between IPDBG Host and Hub",
967 .usage =
"-size size",
970 .handler = handle_ipdbg_hub_services_command,
972 .help =
"List services of IPDBG Hub",
980 Jim_Interp *interp =
CMD_CTX->interp;
983 Jim_Cmd *jcmd = Jim_GetCommand(interp, Jim_NewStringObj(interp, hub->
name, -1), JIM_NONE);
985 LOG_ERROR(
"cannot create Hub because a command with name '%s' already exists", hub->
name);
993 .help =
"IPDBG Hub command group",
1037 uint32_t user_instruction = 0x00;
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;
1045 bool hub_configured =
false;
1050 const char *hub_name =
CMD_ARGV[0];
1052 for (
unsigned int i = 1; i <
CMD_ARGC; ++i) {
1053 if (strcmp(
CMD_ARGV[i],
"-tap") == 0) {
1064 }
else if (strcmp(
CMD_ARGV[i],
"-ir") == 0) {
1066 hub_configured =
true;
1070 command_print(
CMD,
"length of \"user\"-data register must be at least %d and at most %d.",
1074 }
else if (strcmp(
CMD_ARGV[i],
"-pld") == 0) {
1098 hub_configured =
true;
1102 }
else if (strcmp(
CMD_ARGV[i],
"-vir") == 0) {
1106 has_virtual_ir =
true;
1117 if (!hub_configured) {
1123 LOG_ERROR(
"IPDBG hub with name '%s' already exists", hub_name);
1127 if (has_virtual_ir) {
1134 virtual_ir->
length = virtual_ir_length;
1135 virtual_ir->
value = virtual_ir_value;
1139 LOG_ERROR(
"IPDBG hub for given TAP and user-instruction already exists");
1144 return ipdbg_create_hub(tap, user_instruction, data_register_length, virtual_ir, hub_name,
cmd);
1171 if (!escaped_name) {
1180 service->connection.closed ?
"listening" :
"connected");
1191 .
name =
"create-hub",
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]]]]",
1200 .handler = handle_ipdbg_names_command,
1201 .help =
"list all created IPDBG Hubs",
1206 .handler = handle_ipdbg_services_command,
1207 .help =
"list all services",
1217 .help =
"IPDBG Hub/Host commands",
static const struct device_t * device
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.
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.
void command_print(struct command_invocation *cmd, const char *format,...)
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
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...
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_DATA
Use this macro to access the invoked command handler's data pointer, rather than accessing the variab...
#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 ...
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
#define ERROR_COMMAND_ARGUMENT_INVALID
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,...
#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...
uint32_t size
Size of dw_spi_transaction::buffer.
static struct esp_usb_jtag * priv
COMMAND_HANDLER(handle_ipdbg_start_command)
static const struct command_registration ipdbg_hub_subcommand_handlers[]
static int ipdbg_create_service(struct ipdbg_hub *hub, uint8_t tool, struct ipdbg_service **service, uint16_t port)
static void ipdbg_add_service(struct ipdbg_service *service)
static int ipdbg_remove_service(struct ipdbg_service *service)
static int ipdbg_polling_callback(void *priv)
#define IPDBG_BUFFER_SIZE
static int ipdbg_stop(struct ipdbg_hub *hub, uint8_t tool)
#define IPDBG_NUM_OF_QUEUE_OPTIONS
static bool ipdbg_fifo_is_empty(struct ipdbg_fifo *fifo)
static struct ipdbg_hub * ipdbg_first_hub
#define IPDBG_SCRATCH_MEMORY_SIZE
static int ipdbg_shift_vir(struct ipdbg_hub *hub)
static struct ipdbg_hub * ipdbg_find_hub(struct jtag_tap *tap, uint32_t user_instruction, struct ipdbg_virtual_ir_info *virtual_ir)
static struct ipdbg_service * ipdbg_find_service(struct ipdbg_hub *hub, uint8_t tool)
static void ipdbg_free_hub(struct ipdbg_hub *hub)
static const struct command_registration ipdbg_config_command_handlers[]
static int ipdbg_shift_instr(struct ipdbg_hub *hub, uint32_t instr)
static int ipdbg_get_flow_control_info_from_hub(struct ipdbg_hub *hub)
static int ipdbg_move_buffer_to_connection(struct connection *conn, struct ipdbg_fifo *fifo)
#define IPDBG_TCP_PORT_STR_MAX_LENGTH
static int ipdbg_shift_data(struct ipdbg_hub *hub, uint32_t dn_data, uint32_t *up_data)
static void ipdbg_init_fifo(struct ipdbg_fifo *fifo)
#define IPDBG_NUM_OF_START_OPTIONS
static int ipdbg_on_connection_input(struct connection *connection)
int ipdbg_register_commands(struct command_context *cmd_ctx)
static int ipdbg_remove_hub(struct ipdbg_hub *hub)
static int ipdbg_on_new_connection(struct connection *connection)
static void ipdbg_add_hub(struct ipdbg_hub *hub)
static int ipdbg_start(struct ipdbg_hub *hub, uint16_t port, uint8_t tool)
#define IPDBG_MIN_DR_LENGTH
static int ipdbg_jtag_transfer_byte(struct ipdbg_hub *hub, size_t tool, struct ipdbg_connection *connection)
#define IPDBG_MAX_DR_LENGTH
static const struct command_registration ipdbg_command_handlers[]
static int ipdbg_start_polling(struct ipdbg_service *service, struct connection *connection)
static const struct service_driver ipdbg_service_driver
static int ipdbg_stop_service(struct ipdbg_service *service)
static int ipdbg_stop_polling(struct ipdbg_service *service)
static bool ipdbg_fifo_is_full(struct ipdbg_fifo *fifo)
static int ipdbg_on_connection_closed(struct connection *connection)
static int ipdbg_max_tools_from_data_register_length(uint8_t data_register_length)
static void ipdbg_zero_rd_idx(struct ipdbg_fifo *fifo)
static COMMAND_HELPER(ipdbg_config_queuing, struct ipdbg_hub *hub, unsigned int size)
static void ipdbg_append_to_fifo(struct ipdbg_fifo *fifo, char data)
int ipdbg_server_free(void)
static void ipdbg_init_scan_field(struct scan_field *fields, uint8_t *in_value, int num_bits, const uint8_t *out_value)
static int ipdbg_shift_empty_data(struct ipdbg_hub *hub)
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)
#define IPDBG_NUM_OF_STOP_OPTIONS
static struct ipdbg_service * ipdbg_first_service
static char ipdbg_get_from_fifo(struct ipdbg_fifo *fifo)
static int ipdbg_distribute_data_from_hub(struct ipdbg_hub *hub, uint32_t up)
static void ipdbg_check_for_xoff(struct ipdbg_hub *hub, size_t tool, uint32_t rx_data)
static struct ipdbg_hub * ipdbg_allocate_hub(uint8_t data_register_length, struct ipdbg_virtual_ir_info *virtual_ir, const char *name)
static int ipdbg_register_hub_command(struct ipdbg_hub *hub, struct command_invocation *cmd)
static struct ipdbg_hub * ipdbg_get_hub_by_name(const char *name)
static int ipdbg_jtag_transfer_bytes(struct ipdbg_hub *hub, size_t tool, struct ipdbg_connection *connection)
#define IPDBG_MAX_NUM_OF_CREATE_OPTIONS
static struct jaylink_connection conn
struct jtag_tap * jtag_tap_by_string(const char *s)
int jtag_execute_queue(void)
For software FIFO implementations, the queued commands can be executed during this call or earlier.
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.
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.
The JTAG interface can be implemented with a software or hardware fifo.
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
struct pld_device * get_pld_device_by_name_or_numstr(const char *str)
int connection_write(struct connection *connection, const void *data, int len)
int connection_read(struct connection *connection, void *data, int len)
int remove_service(const char *name, const char *port)
int add_service(const struct service_driver *driver, const char *port, int max_connections, void *priv)
#define ERROR_SERVER_REMOTE_CLOSED
When run_command is called, a new instance will be created on the stack, filled with the proper value...
struct ipdbg_fifo up_fifo
struct ipdbg_fifo dn_fifo
char buffer[IPDBG_BUFFER_SIZE]
struct scan_field * fields
struct ipdbg_virtual_ir_info * virtual_ir
struct ipdbg_hub_scratch_memory scratch_memory
struct connection ** connections
uint8_t flow_control_enabled
uint8_t data_register_length
uint32_t active_connections
uint32_t user_instruction
struct ipdbg_service * next
uint8_t * cur_instr
current instruction
unsigned int ir_length
size of instruction register
int(* get_ipdbg_hub)(int user_num, struct pld_device *pld_device, struct pld_ipdbg_hub *hub)
unsigned int user_ir_code
This structure defines a single scan field in the scan.
uint8_t * in_value
A pointer to a 32-bit memory location for data scanned out.
uint8_t * check_value
The value used to check the data scanned out.
const uint8_t * out_value
A pointer to value to be scanned into the device.
unsigned int num_bits
The number of bits this field specifies.
uint8_t * check_mask
The mask to go with check_value.
const char * name
the name of the server
char * port
The 'port', which can be an integer for TCP, or 'disabled', 'pipe' (stdin/out) or a FIFO path.
int target_unregister_timer_callback(int(*callback)(void *priv), void *priv)
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...
char * tcl_escape_alloc(Jim_Interp *interp, const char *s)
Convert a C string to a string that can be used for Tcl list.
#define DIV_ROUND_UP(m, n)
Rounds m up to the nearest multiple of n using division.