From: Megan Wachs Date: Tue, 18 Apr 2017 21:34:51 +0000 (-0700) Subject: debug: move remote_bitbang into riscv X-Git-Url: https://git.libre-soc.org/?p=riscv-isa-sim.git;a=commitdiff_plain;h=089f0fa4cf1885b2333f4522140ae3747f2e367b debug: move remote_bitbang into riscv --- diff --git a/remote_bitbang.cc b/remote_bitbang.cc deleted file mode 100644 index 9d0ca90..0000000 --- a/remote_bitbang.cc +++ /dev/null @@ -1,174 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "remote_bitbang.h" - -#if 1 -# define D(x) x -#else -# define D(x) -#endif - -/////////// remote_bitbang_t - -remote_bitbang_t::remote_bitbang_t(uint16_t port, jtag_dtm_t *tap) : - tap(tap), - socket_fd(0), - client_fd(0), - recv_start(0), - recv_end(0) -{ - socket_fd = socket(AF_INET, SOCK_STREAM, 0); - if (socket_fd == -1) { - fprintf(stderr, "remote_bitbang failed to make socket: %s (%d)\n", - strerror(errno), errno); - abort(); - } - - fcntl(socket_fd, F_SETFL, O_NONBLOCK); - int reuseaddr = 1; - if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, - sizeof(int)) == -1) { - fprintf(stderr, "remote_bitbang failed setsockopt: %s (%d)\n", - strerror(errno), errno); - abort(); - } - - struct sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = htons(port); - - if (bind(socket_fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) { - fprintf(stderr, "remote_bitbang failed to bind socket: %s (%d)\n", - strerror(errno), errno); - abort(); - } - - if (listen(socket_fd, 1) == -1) { - fprintf(stderr, "remote_bitbang failed to listen on socket: %s (%d)\n", - strerror(errno), errno); - abort(); - } - - socklen_t addrlen = sizeof(addr); - if (getsockname(socket_fd, (struct sockaddr *) &addr, &addrlen) == -1) { - fprintf(stderr, "remote_bitbang getsockname failed: %s (%d)\n", - strerror(errno), errno); - abort(); - } - - printf("Listening for remote bitbang connection on port %d.\n", - ntohs(addr.sin_port)); - fflush(stdout); -} - -void remote_bitbang_t::accept() -{ - client_fd = ::accept(socket_fd, NULL, NULL); - if (client_fd == -1) { - if (errno == EAGAIN) { - // No client waiting to connect right now. - } else { - fprintf(stderr, "failed to accept on socket: %s (%d)\n", strerror(errno), - errno); - abort(); - } - } else { - fcntl(client_fd, F_SETFL, O_NONBLOCK); - } -} - -void remote_bitbang_t::tick() -{ - if (client_fd > 0) { - execute_commands(); - } else { - this->accept(); - } -} - -void remote_bitbang_t::execute_commands() -{ - static char send_buf[buf_size]; - unsigned total_processed = 0; - bool quit = false; - 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) { - 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; - } - } - - if (total_processed > buf_size || quit || entered_rti) { - // Don't go forever, because that could starve the main simulation. - break; - } - - 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; - } - } -} diff --git a/remote_bitbang.h b/remote_bitbang.h deleted file mode 100644 index 1db4d55..0000000 --- a/remote_bitbang.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef REMOTE_BITBANG_H -#define REMOTE_BITBANG_H - -#include - -#include "jtag_dtm.h" - -class remote_bitbang_t -{ -public: - // Create a new server, listening for connections from localhost on the given - // port. - remote_bitbang_t(uint16_t port, jtag_dtm_t *tap); - - // Do a bit of work. - void tick(); - -private: - jtag_dtm_t *tap; - - 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. - void execute_commands(); -}; - -#endif diff --git a/riscv/remote_bitbang.cc b/riscv/remote_bitbang.cc new file mode 100644 index 0000000..75aa8fe --- /dev/null +++ b/riscv/remote_bitbang.cc @@ -0,0 +1,180 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "remote_bitbang.h" + +#if 1 +# define D(x) x +#else +# define D(x) +#endif + +/////////// remote_bitbang_t + +remote_bitbang_t::remote_bitbang_t(uint16_t port, jtag_dtm_t *tap) : + tap(tap), + socket_fd(0), + client_fd(0), + recv_start(0), + recv_end(0) +{ + socket_fd = socket(AF_INET, SOCK_STREAM, 0); + if (socket_fd == -1) { + fprintf(stderr, "remote_bitbang failed to make socket: %s (%d)\n", + strerror(errno), errno); + abort(); + } + + fcntl(socket_fd, F_SETFL, O_NONBLOCK); + int reuseaddr = 1; + if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, + sizeof(int)) == -1) { + fprintf(stderr, "remote_bitbang failed setsockopt: %s (%d)\n", + strerror(errno), errno); + abort(); + } + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = htons(port); + + if (bind(socket_fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) { + fprintf(stderr, "remote_bitbang failed to bind socket: %s (%d)\n", + strerror(errno), errno); + abort(); + } + + if (listen(socket_fd, 1) == -1) { + fprintf(stderr, "remote_bitbang failed to listen on socket: %s (%d)\n", + strerror(errno), errno); + abort(); + } + + socklen_t addrlen = sizeof(addr); + if (getsockname(socket_fd, (struct sockaddr *) &addr, &addrlen) == -1) { + fprintf(stderr, "remote_bitbang getsockname failed: %s (%d)\n", + strerror(errno), errno); + abort(); + } + + printf("Listening for remote bitbang connection on port %d.\n", + ntohs(addr.sin_port)); + fflush(stdout); +} + +void remote_bitbang_t::accept() +{ + client_fd = ::accept(socket_fd, NULL, NULL); + if (client_fd == -1) { + if (errno == EAGAIN) { + // No client waiting to connect right now. + } else { + fprintf(stderr, "failed to accept on socket: %s (%d)\n", strerror(errno), + errno); + abort(); + } + } else { + fcntl(client_fd, F_SETFL, O_NONBLOCK); + } +} + +void remote_bitbang_t::tick() +{ + if (client_fd > 0) { + execute_commands(); + } else { + this->accept(); + } +} + +void remote_bitbang_t::execute_commands() +{ + static char send_buf[buf_size]; + unsigned total_processed = 0; + bool quit = false; + 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) { + 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; + } + } + + if (total_processed > buf_size || quit || entered_rti) { + // Don't go forever, because that could starve the main simulation. + break; + } + + 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 (quit) { + fprintf(stderr, "Remote Bitbang received 'Q'\n"); + } + + if (recv_end == 0 || quit) { + // The remote disconnected. + fprintf(stderr, "Received nothing. Quitting.\n"); + close(client_fd); + client_fd = 0; + break; + } + } +} diff --git a/riscv/remote_bitbang.h b/riscv/remote_bitbang.h new file mode 100644 index 0000000..1db4d55 --- /dev/null +++ b/riscv/remote_bitbang.h @@ -0,0 +1,34 @@ +#ifndef REMOTE_BITBANG_H +#define REMOTE_BITBANG_H + +#include + +#include "jtag_dtm.h" + +class remote_bitbang_t +{ +public: + // Create a new server, listening for connections from localhost on the given + // port. + remote_bitbang_t(uint16_t port, jtag_dtm_t *tap); + + // Do a bit of work. + void tick(); + +private: + jtag_dtm_t *tap; + + 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. + void execute_commands(); +}; + +#endif