From: OpenOCD-Gerrit <ope...@us...> - 2021-06-13 18:59:09
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via f2958fc04bd879393fa743860478834e234f05d0 (commit) from 076b4d708e14a830cffee64d39ad0a1940e13e2f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f2958fc04bd879393fa743860478834e234f05d0 Author: Tim Newsome <ti...@si...> Date: Fri May 28 13:38:50 2021 -0700 Add remote bitbang write buffer. Change 7dd323b26 reduced remote bitbang performance a lot. This change gets most of that performance back again, by reintroducing a write buffer. Performance numbers collected using DebugBreakpoint test from riscv-tests/debug against a single 64-bit spike (RISC-V simulator) instance. (Ubuntu 20.04.2, AMD Ryzen 5 3600) Before Windows support was added: 3.09s After Windows support was added: 12.67s After this change: 4.69s Signed-off-by: Tim Newsome <ti...@si...> Change-Id: I72ff4912cbbf316a30ef065e5b8f461a555f06cc Reviewed-on: http://openocd.zylin.com/6283 Tested-by: jenkins Reviewed-by: Jan Matyas <ma...@co...> Reviewed-by: Tarek BOCHKATI <tar...@gm...> Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/jtag/drivers/remote_bitbang.c b/src/jtag/drivers/remote_bitbang.c index f7b88303b..57f0c6e07 100644 --- a/src/jtag/drivers/remote_bitbang.c +++ b/src/jtag/drivers/remote_bitbang.c @@ -36,17 +36,19 @@ static char *remote_bitbang_host; static char *remote_bitbang_port; static int remote_bitbang_fd; +static uint8_t remote_bitbang_send_buf[512]; +static unsigned int remote_bitbang_send_buf_used; /* Circular buffer. When start == end, the buffer is empty. */ -static char remote_bitbang_buf[64]; -static unsigned remote_bitbang_start; -static unsigned remote_bitbang_end; +static char remote_bitbang_recv_buf[64]; +static unsigned int remote_bitbang_recv_buf_start; +static unsigned int remote_bitbang_recv_buf_end; -static int remote_bitbang_buf_full(void) +static bool remote_bitbang_buf_full(void) { - return remote_bitbang_end == - ((remote_bitbang_start + sizeof(remote_bitbang_buf) - 1) % - sizeof(remote_bitbang_buf)); + return remote_bitbang_recv_buf_end == + ((remote_bitbang_recv_buf_start + sizeof(remote_bitbang_recv_buf) - 1) % + sizeof(remote_bitbang_recv_buf)); } /* Read any incoming data, placing it into the buffer. */ @@ -54,23 +56,23 @@ static int remote_bitbang_fill_buf(void) { socket_nonblock(remote_bitbang_fd); while (!remote_bitbang_buf_full()) { - unsigned contiguous_available_space; - if (remote_bitbang_end >= remote_bitbang_start) { - contiguous_available_space = sizeof(remote_bitbang_buf) - - remote_bitbang_end; - if (remote_bitbang_start == 0) + unsigned int contiguous_available_space; + if (remote_bitbang_recv_buf_end >= remote_bitbang_recv_buf_start) { + contiguous_available_space = sizeof(remote_bitbang_recv_buf) - + remote_bitbang_recv_buf_end; + if (remote_bitbang_recv_buf_start == 0) contiguous_available_space -= 1; } else { - contiguous_available_space = remote_bitbang_start - - remote_bitbang_end - 1; + contiguous_available_space = remote_bitbang_recv_buf_start - + remote_bitbang_recv_buf_end - 1; } ssize_t count = read_socket(remote_bitbang_fd, - remote_bitbang_buf + remote_bitbang_end, + remote_bitbang_recv_buf + remote_bitbang_recv_buf_end, contiguous_available_space); if (count > 0) { - remote_bitbang_end += count; - if (remote_bitbang_end == sizeof(remote_bitbang_buf)) - remote_bitbang_end = 0; + remote_bitbang_recv_buf_end += count; + if (remote_bitbang_recv_buf_end == sizeof(remote_bitbang_recv_buf)) + remote_bitbang_recv_buf_end = 0; } else if (count == 0) { return ERROR_OK; } else if (count < 0) { @@ -90,20 +92,43 @@ static int remote_bitbang_fill_buf(void) return ERROR_OK; } -static int remote_bitbang_putc(int c) +static int remote_bitbang_flush(void) { - char buf = c; - ssize_t count = write_socket(remote_bitbang_fd, &buf, sizeof(buf)); - if (count < 0) { - log_socket_error("remote_bitbang_putc"); - return ERROR_FAIL; + if (remote_bitbang_send_buf_used <= 0) + return ERROR_OK; + + unsigned int offset = 0; + while (offset < remote_bitbang_send_buf_used) { + ssize_t written = write_socket(remote_bitbang_fd, remote_bitbang_send_buf + offset, + remote_bitbang_send_buf_used - offset); + if (written < 0) { + log_socket_error("remote_bitbang_putc"); + remote_bitbang_send_buf_used = 0; + return ERROR_FAIL; + } + offset += written; } + remote_bitbang_send_buf_used = 0; + return ERROR_OK; +} + +typedef enum { + NO_FLUSH, + FLUSH_SEND_BUF +} flush_bool_t; + +static int remote_bitbang_queue(int c, flush_bool_t flush) +{ + remote_bitbang_send_buf[remote_bitbang_send_buf_used++] = c; + if (flush == FLUSH_SEND_BUF || + remote_bitbang_send_buf_used >= ARRAY_SIZE(remote_bitbang_send_buf)) + return remote_bitbang_flush(); return ERROR_OK; } static int remote_bitbang_quit(void) { - if (remote_bitbang_putc('Q') == ERROR_FAIL) + if (remote_bitbang_queue('Q', FLUSH_SEND_BUF) == ERROR_FAIL) return ERROR_FAIL; if (close_socket(remote_bitbang_fd) != 0) { @@ -135,6 +160,9 @@ static bb_value_t char_to_int(int c) /* Get the next read response. */ static bb_value_t remote_bitbang_rread(void) { + if (remote_bitbang_flush() != ERROR_OK) + return ERROR_FAIL; + /* Enable blocking access. */ socket_block(remote_bitbang_fd); char c; @@ -154,15 +182,19 @@ static int remote_bitbang_sample(void) if (remote_bitbang_fill_buf() != ERROR_OK) return ERROR_FAIL; assert(!remote_bitbang_buf_full()); - return remote_bitbang_putc('R'); + return remote_bitbang_queue('R', NO_FLUSH); } static bb_value_t remote_bitbang_read_sample(void) { - if (remote_bitbang_start != remote_bitbang_end) { - int c = remote_bitbang_buf[remote_bitbang_start]; - remote_bitbang_start = - (remote_bitbang_start + 1) % sizeof(remote_bitbang_buf); + if (remote_bitbang_recv_buf_start == remote_bitbang_recv_buf_end) { + if (remote_bitbang_fill_buf() != ERROR_OK) + return ERROR_FAIL; + } + if (remote_bitbang_recv_buf_start != remote_bitbang_recv_buf_end) { + int c = remote_bitbang_recv_buf[remote_bitbang_recv_buf_start]; + remote_bitbang_recv_buf_start = + (remote_bitbang_recv_buf_start + 1) % sizeof(remote_bitbang_recv_buf); return char_to_int(c); } return remote_bitbang_rread(); @@ -171,23 +203,25 @@ static bb_value_t remote_bitbang_read_sample(void) static int remote_bitbang_write(int tck, int tms, int tdi) { char c = '0' + ((tck ? 0x4 : 0x0) | (tms ? 0x2 : 0x0) | (tdi ? 0x1 : 0x0)); - return remote_bitbang_putc(c); + return remote_bitbang_queue(c, NO_FLUSH); } static int remote_bitbang_reset(int trst, int srst) { char c = 'r' + ((trst ? 0x2 : 0x0) | (srst ? 0x1 : 0x0)); - return remote_bitbang_putc(c); + /* Always flush the send buffer on reset, because the reset call need not be + * followed by jtag_execute_queue(). */ + return remote_bitbang_queue(c, FLUSH_SEND_BUF); } static int remote_bitbang_blink(int on) { char c = on ? 'B' : 'b'; - return remote_bitbang_putc(c); + return remote_bitbang_queue(c, FLUSH_SEND_BUF); } static struct bitbang_interface remote_bitbang_bitbang = { - .buf_size = sizeof(remote_bitbang_buf) - 1, + .buf_size = sizeof(remote_bitbang_recv_buf) - 1, .sample = &remote_bitbang_sample, .read_sample = &remote_bitbang_read_sample, .write = &remote_bitbang_write, @@ -268,8 +302,8 @@ static int remote_bitbang_init(void) { bitbang_interface = &remote_bitbang_bitbang; - remote_bitbang_start = 0; - remote_bitbang_end = 0; + remote_bitbang_recv_buf_start = 0; + remote_bitbang_recv_buf_end = 0; LOG_INFO("Initializing remote_bitbang driver"); if (remote_bitbang_port == NULL) @@ -326,8 +360,23 @@ static const struct command_registration remote_bitbang_command_handlers[] = { COMMAND_REGISTRATION_DONE, }; +static int remote_bitbang_execute_queue(void) +{ + /* safety: the send buffer must be empty, no leftover characters from + * previous transactions */ + assert(remote_bitbang_send_buf_used == 0); + + /* process the JTAG command queue */ + int ret = bitbang_execute_queue(); + if (ret != ERROR_OK) + return ret; + + /* flush not-yet-sent characters, if any */ + return remote_bitbang_flush(); +} + static struct jtag_interface remote_bitbang_interface = { - .execute_queue = &bitbang_execute_queue, + .execute_queue = &remote_bitbang_execute_queue, }; struct adapter_driver remote_bitbang_adapter_driver = { ----------------------------------------------------------------------- Summary of changes: src/jtag/drivers/remote_bitbang.c | 123 ++++++++++++++++++++++++++------------ 1 file changed, 86 insertions(+), 37 deletions(-) hooks/post-receive -- Main OpenOCD repository |