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/+/7981
-- gerrit commit d521c7688ac8ddf5b04f8fc0a14e6c7330368aef Author: Daniel Anselmi <danse...@gmx.ch> Date: Sun Mar 12 01:43:32 2023 +0100 ipdbg: improve queuing Reduce latency for small amounts of data by using a short queue first and append a transfer with a longer queue if first transfer was fully occupied. This was needed with slow JTAG links (bitbang to VHDL cosimulation) and sigrok/pulseview. Change-Id: Ie440993b27c3385e6928e8e290e35fc7b2ae3a00 Signed-off-by: Daniel Anselmi <danse...@gmx.ch> diff --git a/src/server/ipdbg.c b/src/server/ipdbg.c index bdc5d17e99..34ca48f75c 100644 --- a/src/server/ipdbg.c +++ b/src/server/ipdbg.c @@ -21,6 +21,8 @@ #define IPDBG_MAX_DR_LENGTH 13 #define IPDBG_TCP_PORT_STR_MAX_LENGTH 6 #define IPDBG_SCRATCH_MEMORY_SIZE 1024 +#define IPDBG_SMALL_QUEUE 16 +#define IPDBG_LARGE_QUEUE IPDBG_SCRATCH_MEMORY_SIZE /* parameters for starting / stopping ipdbg server */ struct ipdbg_command_args { @@ -476,18 +478,15 @@ static void ipdbg_check_for_xoff(struct ipdbg_hub *hub, size_t tool, hub->last_dn_tool = tool; } -static int ipdbg_shift_empty_data(struct ipdbg_hub *hub) +static int ipdbg_shift_empty_data_len(struct ipdbg_hub *hub, size_t len, bool check_xoff, bool *rx_full) { - if (!hub) - return ERROR_FAIL; - struct jtag_tap *tap = hub->tap; if (!tap) return ERROR_FAIL; 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 < hub->using_queue_size; ++i) { + for (size_t i = 0; i < len; ++i) { ipdbg_init_scan_field(hub->scratch_memory.fields + i, hub->scratch_memory.dr_in_vals + i * dreg_buffer_size, hub->data_register_length, @@ -497,17 +496,20 @@ static int ipdbg_shift_empty_data(struct ipdbg_hub *hub) int retval = jtag_execute_queue(); + *rx_full = false; if (retval == ERROR_OK) { uint32_t up_data; - for (size_t i = 0; i < hub->using_queue_size; ++i) { + *rx_full = true; + for (size_t i = 0; i < len; ++i) { up_data = buf_get_u32(hub->scratch_memory.dr_in_vals + i * dreg_buffer_size, 0, hub->data_register_length); + *rx_full = *rx_full && (up_data & hub->valid_mask); int rv = ipdbg_distribute_data_from_hub(hub, up_data); if (rv != ERROR_OK) retval = rv; - if (i == 0) { + if (i == 0 && check_xoff) { /* check if xoff sent is only needed on the first transfer which may contain the xoff of the prev down transfer. */ @@ -519,6 +521,25 @@ static int ipdbg_shift_empty_data(struct ipdbg_hub *hub) return retval; } +static int ipdbg_shift_empty_data(struct ipdbg_hub *hub) +{ + if (!hub) + return ERROR_FAIL; + + /* try short first */ + int retval = ERROR_OK; + bool check_xoff = true; + bool rx_full = true; + if (hub->using_queue_size >= IPDBG_SMALL_QUEUE) { + retval = ipdbg_shift_empty_data_len(hub, IPDBG_SMALL_QUEUE, check_xoff, &rx_full); + check_xoff = false; + } + if (retval == ERROR_OK && rx_full) + retval = ipdbg_shift_empty_data_len(hub, hub->using_queue_size, check_xoff, &rx_full); + + return retval; +} + static int ipdbg_jtag_transfer_byte(struct ipdbg_hub *hub, size_t tool, struct ipdbg_connection *connection) { uint32_t dn = hub->valid_mask | ((tool & hub->tool_mask) << 8) | --