From 21fb735d62ec9d22e5ac10180716db0d9b5b4217 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Tue, 21 Feb 2017 20:22:10 -0800 Subject: [PATCH] Improve debug performance. It's still pitiful, but less so. (5KB/s download speed.) The tweaks involve switching to the other context as soon as it might be helpful. The two contexts are executing code, and handling JTAG TAP input. --- riscv/jtag_dtm.cc | 14 +++-- riscv/jtag_dtm.h | 4 +- riscv/remote_bitbang.cc | 114 ++++++++++++++++++++++------------------ riscv/remote_bitbang.h | 4 ++ 4 files changed, 76 insertions(+), 60 deletions(-) diff --git a/riscv/jtag_dtm.cc b/riscv/jtag_dtm.cc index 84182bb..bcc3720 100644 --- a/riscv/jtag_dtm.cc +++ b/riscv/jtag_dtm.cc @@ -42,12 +42,12 @@ jtag_dtm_t::jtag_dtm_t(debug_module_t *dm) : _tck(false), _tms(false), _tdi(false), _tdo(false), dtmcontrol((abits << DTM_DTMCONTROL_ABITS_OFFSET) | 1), dmi(DMI_OP_STATUS_FAILED << DTM_DMI_OP_OFFSET), - state(TEST_LOGIC_RESET) + _state(TEST_LOGIC_RESET) { } void jtag_dtm_t::reset() { - state = TEST_LOGIC_RESET; + _state = TEST_LOGIC_RESET; } void jtag_dtm_t::set_pins(bool tck, bool tms, bool tdi) { @@ -73,7 +73,7 @@ void jtag_dtm_t::set_pins(bool tck, bool tms, bool tdi) { if (!_tck && tck) { // Positive clock edge. - switch (state) { + switch (_state) { case SHIFT_DR: dr >>= 1; dr |= (uint64_t) _tdi << (dr_length-1); @@ -85,8 +85,8 @@ void jtag_dtm_t::set_pins(bool tck, bool tms, bool tdi) { default: break; } - state = next[state][_tms]; - switch (state) { + _state = next[_state][_tms]; + switch (_state) { case TEST_LOGIC_RESET: ir = IR_IDCODE; break; @@ -111,11 +111,9 @@ void jtag_dtm_t::set_pins(bool tck, bool tms, bool tdi) { } } - /* D(fprintf(stderr, "state=%2d, tdi=%d, tdo=%d, tms=%d, tck=%d, ir=0x%02x, " "dr=0x%lx\n", - state, _tdi, _tdo, _tms, _tck, ir, dr)); - */ + _state, _tdi, _tdo, _tms, _tck, ir, dr)); _tck = tck; _tms = tms; diff --git a/riscv/jtag_dtm.h b/riscv/jtag_dtm.h index 97ce521..063e3f4 100644 --- a/riscv/jtag_dtm.h +++ b/riscv/jtag_dtm.h @@ -36,6 +36,8 @@ class jtag_dtm_t bool tdo() const { return _tdo; } + jtag_state_t state() const { return _state; } + private: debug_module_t *dm; bool _tck, _tms, _tdi, _tdo; @@ -50,7 +52,7 @@ class jtag_dtm_t uint32_t dtmcontrol; uint64_t dmi; - jtag_state_t state; + jtag_state_t _state; void capture_dr(); void update_dr(); diff --git a/riscv/remote_bitbang.cc b/riscv/remote_bitbang.cc index ff89e15..9d0ca90 100644 --- a/riscv/remote_bitbang.cc +++ b/riscv/remote_bitbang.cc @@ -22,7 +22,9 @@ remote_bitbang_t::remote_bitbang_t(uint16_t port, jtag_dtm_t *tap) : tap(tap), socket_fd(0), - client_fd(0) + client_fd(0), + recv_start(0), + recv_end(0) { socket_fd = socket(AF_INET, SOCK_STREAM, 0); if (socket_fd == -1) { @@ -97,66 +99,76 @@ void remote_bitbang_t::tick() void remote_bitbang_t::execute_commands() { - const unsigned buf_size = 64 * 1024; - static char recv_buf[buf_size]; static char send_buf[buf_size]; - unsigned total_received = 0; - ssize_t bytes = read(client_fd, recv_buf, buf_size); + unsigned total_processed = 0; bool quit = false; - while (bytes > 0) { - total_received += bytes; - unsigned send_offset = 0; - for (unsigned i = 0; i < bytes; i++) { - uint8_t command = recv_buf[i]; - - switch (command) { - case 'B': /* fprintf(stderr, "*BLINK*\n"); */ break; - case 'b': /* fprintf(stderr, "_______\n"); */ break; - case 'r': tap->reset(); break; - case '0': tap->set_pins(0, 0, 0); break; - case '1': tap->set_pins(0, 0, 1); break; - case '2': tap->set_pins(0, 1, 0); break; - case '3': tap->set_pins(0, 1, 1); break; - case '4': tap->set_pins(1, 0, 0); break; - case '5': tap->set_pins(1, 0, 1); break; - case '6': tap->set_pins(1, 1, 0); break; - case '7': tap->set_pins(1, 1, 1); break; - case 'R': send_buf[send_offset++] = tap->tdo() ? '1' : '0'; break; - case 'Q': quit = true; break; - default: - fprintf(stderr, "remote_bitbang got unsupported command '%c'\n", - command); + bool in_rti = tap->state() == RUN_TEST_IDLE; + bool entered_rti = false; + while (1) { + if (recv_start < recv_end) { + unsigned send_offset = 0; + while (recv_start < recv_end) { + uint8_t command = recv_buf[recv_start]; + + switch (command) { + case 'B': /* fprintf(stderr, "*BLINK*\n"); */ break; + case 'b': /* fprintf(stderr, "_______\n"); */ break; + case 'r': tap->reset(); break; + case '0': tap->set_pins(0, 0, 0); break; + case '1': tap->set_pins(0, 0, 1); break; + case '2': tap->set_pins(0, 1, 0); break; + case '3': tap->set_pins(0, 1, 1); break; + case '4': tap->set_pins(1, 0, 0); break; + case '5': tap->set_pins(1, 0, 1); break; + case '6': tap->set_pins(1, 1, 0); break; + case '7': tap->set_pins(1, 1, 1); break; + case 'R': send_buf[send_offset++] = tap->tdo() ? '1' : '0'; break; + case 'Q': quit = true; break; + default: + fprintf(stderr, "remote_bitbang got unsupported command '%c'\n", + command); + } + recv_start++; + total_processed++; + if (!in_rti && tap->state() == RUN_TEST_IDLE) { + entered_rti = true; + break; + } + in_rti = false; } - } - unsigned sent = 0; - while (sent < send_offset) { - bytes = write(client_fd, send_buf + sent, send_offset); - if (bytes == -1) { - fprintf(stderr, "failed to write to socket: %s (%d)\n", strerror(errno), errno); - abort(); + unsigned sent = 0; + while (sent < send_offset) { + ssize_t bytes = write(client_fd, send_buf + sent, send_offset); + if (bytes == -1) { + fprintf(stderr, "failed to write to socket: %s (%d)\n", strerror(errno), errno); + abort(); + } + sent += bytes; } - sent += bytes; } - if (total_received > buf_size || quit) { + if (total_processed > buf_size || quit || entered_rti) { // Don't go forever, because that could starve the main simulation. break; } - bytes = read(client_fd, recv_buf, buf_size); - } - if (bytes == -1) { - if (errno == EAGAIN) { - // We'll try again the next call. - } else { - fprintf(stderr, "remote_bitbang failed to read on socket: %s (%d)\n", - strerror(errno), errno); - abort(); + recv_start = 0; + recv_end = read(client_fd, recv_buf, buf_size); + + if (recv_end == -1) { + if (errno == EAGAIN) { + // We'll try again the next call. + } else { + fprintf(stderr, "remote_bitbang failed to read on socket: %s (%d)\n", + strerror(errno), errno); + abort(); + } + } + if (recv_end == 0 || quit) { + // The remote disconnected. + close(client_fd); + client_fd = 0; + break; } - } - if (bytes == 0 || quit) { - // The remote disconnected. - close(client_fd); - client_fd = 0; } } diff --git a/riscv/remote_bitbang.h b/riscv/remote_bitbang.h index 289fbb3..1db4d55 100644 --- a/riscv/remote_bitbang.h +++ b/riscv/remote_bitbang.h @@ -21,6 +21,10 @@ private: int socket_fd; int client_fd; + static const ssize_t buf_size = 64 * 1024; + char recv_buf[buf_size]; + ssize_t recv_start, recv_end; + // Check for a client connecting, and accept if there is one. void accept(); // Execute any commands the client has for us. -- 2.30.2