Improve debug performance.
authorTim Newsome <tim@sifive.com>
Wed, 22 Feb 2017 04:22:10 +0000 (20:22 -0800)
committerTim Newsome <tim@sifive.com>
Wed, 22 Feb 2017 04:22:10 +0000 (20:22 -0800)
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
riscv/jtag_dtm.h
riscv/remote_bitbang.cc
riscv/remote_bitbang.h

index 84182bbf02b7fcd361e5d1fd5329b2edc85456f1..bcc3720e6d576460b1e33ce660cd7a067d731196 100644 (file)
@@ -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;
index 97ce52172692ccd7a0f476708c21c0fc1f035d24..063e3f40b3416271255699b9fd2dfee0c781f507 100644 (file)
@@ -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();
index ff89e1516fe823643ae6831bffa274ed88995c83..9d0ca90a2b5584e38b5c14501a9e2de813d398aa 100644 (file)
@@ -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;
   }
 }
index 289fbb3e2f6f327a7720d6703bb24ebece51a1c7..1db4d550140ea8bad605663911579bbe8e857501 100644 (file)
@@ -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.