This is an automated email from Gerrit. "Daniel Anselmi <danse...@gmx.ch>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7980
-- gerrit commit 5e681cd670fe449a0fbdbee9c390cc3325b7e0b1 Author: Daniel Anselmi <danse...@gmx.ch> Date: Fri Mar 31 14:35:19 2023 +0200 ipdbg: configurable queuing between JTAG-Host and JTAG-Hub Change-Id: I7941de02a968ccab730bfebd3483b8c3b84d7e53 Signed-off-by: Daniel Anselmi <danse...@gmx.ch> diff --git a/doc/openocd.texi b/doc/openocd.texi index d527522749..ae6c42fe39 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -12049,6 +12049,24 @@ ipdbg stop -tap 10m50.tap -hub 0x00C -vir -port 60000 -tool 1 @end example Stops the server for tool 1 (data_up_1/data_down_1). +@deffn {Command} {ipdbg queuing} @option{-tap @var{tapname}} @option{-hub @var{ir_value}} [@option{-vir [@var{vir_value} [@var{length} [@var{instr_code}]]]}] -size @var{size} +Configure the queuing between IPDBG JTAG-Host and Hub. Arguments can be specified in any order. + +@itemize @bullet +@item @option{-size @var{size}} max number of transfers int the queue. +@end itemize +For a description of the other arguments look at @command{ipdbg start}. +@end deffn +@example +ipdbg queuing -tap bitbang.tap -hub 0x02 -size 32 +@end example +Send a maximum of 32 transfers to the queue before executing them. + +@example +ipdbg queuing -pld 0 -size 32 +@end example +Send a maximum of 32 transfers to the queue before executing them, using the pld driver to get tap/instruction for pld 0. + @node Utility Commands @chapter Utility Commands diff --git a/src/server/ipdbg.c b/src/server/ipdbg.c index 8e36441b36..bdc5d17e99 100644 --- a/src/server/ipdbg.c +++ b/src/server/ipdbg.c @@ -21,12 +21,11 @@ #define IPDBG_MAX_DR_LENGTH 13 #define IPDBG_TCP_PORT_STR_MAX_LENGTH 6 #define IPDBG_SCRATCH_MEMORY_SIZE 1024 -#define IPDBG_EMPTY_DOWN_TRANSFERS 1024 -#define IPDBG_CONSECUTIVE_UP_TRANSFERS 1024 /* parameters for starting / stopping ipdbg server */ struct ipdbg_command_args { struct jtag_tap *tap; + size_t size; uint32_t user_instruction; uint32_t virtual_ir_instruction; uint32_t virtual_ir_length; @@ -82,6 +81,7 @@ struct ipdbg_hub { uint32_t xoff_mask; uint32_t tool_mask; uint32_t last_dn_tool; + size_t using_queue_size; struct ipdbg_hub *next; struct jtag_tap *tap; struct connection **connections; @@ -299,6 +299,7 @@ static int ipdbg_create_hub(struct jtag_tap *tap, uint32_t user_instruction, uin new_hub->tool_mask = (new_hub->xoff_mask - 1) >> 8; new_hub->last_dn_tool = new_hub->tool_mask; new_hub->virtual_ir = virtual_ir; + new_hub->using_queue_size = IPDBG_SCRATCH_MEMORY_SIZE; *hub = new_hub; return ERROR_OK; @@ -484,13 +485,9 @@ static int ipdbg_shift_empty_data(struct ipdbg_hub *hub) if (!tap) return ERROR_FAIL; -#if IPDBG_SCRATCH_MEMORY_SIZE < IPDBG_EMPTY_DOWN_TRANSFERS -#error "scratch Memory must be at least IPDBG_EMPTY_DOWN_TRANSFERS" -#endif - const size_t dreg_buffer_size = DIV_ROUND_UP(hub->data_register_length, 8); memset(hub->scratch_memory.dr_out_vals, 0, dreg_buffer_size); - for (size_t i = 0; i < IPDBG_EMPTY_DOWN_TRANSFERS; ++i) { + for (size_t i = 0; i < hub->using_queue_size; ++i) { ipdbg_init_scan_field(hub->scratch_memory.fields + i, hub->scratch_memory.dr_in_vals + i * dreg_buffer_size, hub->data_register_length, @@ -502,7 +499,7 @@ static int ipdbg_shift_empty_data(struct ipdbg_hub *hub) if (retval == ERROR_OK) { uint32_t up_data; - for (size_t i = 0; i < IPDBG_EMPTY_DOWN_TRANSFERS; ++i) { + for (size_t i = 0; i < hub->using_queue_size; ++i) { up_data = buf_get_u32(hub->scratch_memory.dr_in_vals + i * dreg_buffer_size, 0, hub->data_register_length); @@ -550,13 +547,9 @@ static int ipdbg_jtag_transfer_bytes(struct ipdbg_hub *hub, if (!tap) return ERROR_FAIL; -#if IPDBG_SCRATCH_MEMORY_SIZE < IPDBG_CONSECUTIVE_UP_TRANSFERS -#error "scratch Memory must be at least IPDBG_CONSECUTIVE_UP_TRANSFERS" -#endif - const size_t dreg_buffer_size = DIV_ROUND_UP(hub->data_register_length, 8); - size_t num_tx = (connection->dn_fifo.count < IPDBG_CONSECUTIVE_UP_TRANSFERS) ? - connection->dn_fifo.count : IPDBG_CONSECUTIVE_UP_TRANSFERS; + size_t num_tx = (connection->dn_fifo.count < hub->using_queue_size) ? + connection->dn_fifo.count : hub->using_queue_size; for (size_t i = 0; i < num_tx; ++i) { uint32_t dn_data = hub->valid_mask | ((tool & hub->tool_mask) << 8) | @@ -881,9 +874,31 @@ static int ipdbg_parse_tap(struct command_invocation *cmd, unsigned int i, struc return ERROR_OK; } +static int ipdbg_config_queuing(struct ipdbg_command_args *command_args, + struct ipdbg_virtual_ir_info *virtual_ir) +{ + struct ipdbg_hub *hub = ipdbg_find_hub(command_args->tap, command_args->user_instruction, virtual_ir); + if (!hub) + return ERROR_FAIL; + + if (hub->active_connections) { + LOG_ERROR("Configuration change not allowed when hub has active connections"); + return ERROR_FAIL; + } + + if (command_args->size == 0 || command_args->size > IPDBG_SCRATCH_MEMORY_SIZE) { + LOG_ERROR("queuing size out of range! Must be 0 < size <= %d", IPDBG_SCRATCH_MEMORY_SIZE); + return ERROR_FAIL; + } + + hub->using_queue_size = command_args->size; + return ERROR_OK; +} + static void ipdbg_init_command_arg_defaults(struct ipdbg_command_args *command_args) { command_args->tap = NULL; + command_args->size = 0; command_args->user_instruction = 0x00; command_args->virtual_ir_instruction = 0x00e; command_args->virtual_ir_value = 0x11; @@ -967,6 +982,8 @@ static int ipdbg_parse_options(struct command_invocation *cmd, struct ipdbg_comm COMMAND_PARSE_ADDITIONAL_NUMBER(u16, i, command_args->port, "port number"); } else if (strcmp(CMD_ARGV[i], "-tool") == 0) { COMMAND_PARSE_ADDITIONAL_NUMBER(u8, i, command_args->tool, "tool"); + } else if (strcmp(CMD_ARGV[i], "-size") == 0) { + COMMAND_PARSE_ADDITIONAL_NUMBER(ulong, i, command_args->size, "size"); } else { command_print(CMD, "Unknown argument: %s", CMD_ARGV[i]); return ERROR_FAIL; @@ -1060,6 +1077,34 @@ COMMAND_HANDLER(handle_ipdbg_stop_command) return retval; } +COMMAND_HANDLER(handle_ipdbg_cfg_queuing_command) +{ + int retval; + struct ipdbg_command_args command_args; + ipdbg_init_command_arg_defaults(&command_args); + + if (CMD_ARGC < IPDBG_MIN_NUM_OF_OPTIONS || CMD_ARGC > IPDBG_MAX_NUM_OF_OPTIONS) + return ERROR_COMMAND_SYNTAX_ERROR; + + retval = ipdbg_parse_options(CMD, &command_args); + if (retval != ERROR_OK) + return retval; + + retval = ipdbg_check_required_arguments(CMD, &command_args); + if (retval != ERROR_OK) + return retval; + + struct ipdbg_virtual_ir_info *virtual_ir = NULL; + if (command_args.has_virtual_ir) { + virtual_ir = ipdbg_alloc_virtual_ir(&command_args); + if (!virtual_ir) + return ERROR_FAIL; + } + retval = ipdbg_config_queuing(&command_args, virtual_ir); + free(virtual_ir); + return retval; +} + static const struct command_registration ipdbg_subcommand_handlers[] = { { .name = "start", @@ -1075,6 +1120,13 @@ static const struct command_registration ipdbg_subcommand_handlers[] = { .help = "Stops an IPDBG JTAG-Host server.", .usage = "-tap device.tap -hub ir_value [dr_length]" " [-tool number] [-vir [vir_value [length [instr_code]]]]", + }, { + .name = "queuing", + .handler = handle_ipdbg_cfg_queuing_command, + .mode = COMMAND_EXEC, + .help = "configures queuing between IPDBG JTAG-Host and Hub.", + .usage = "-tap device.tap -hub ir_value [dr_length]" + " [-tool number] [-vir [vir_value [length [instr_code]]]] -size size", }, COMMAND_REGISTRATION_DONE }; --