aboutsummaryrefslogtreecommitdiff
path: root/riscv/remote_bitbang.h
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2017-02-03 11:29:54 -0800
committerTim Newsome <tim@sifive.com>2017-02-03 11:29:54 -0800
commitd1f2cf337e1a0be8eada2afadd745e1374b4a000 (patch)
tree0dd497bc9d49bd894e7cfd3afccea58a31646074 /riscv/remote_bitbang.h
parente9e30598e08e4f162b523f9ef07f1510f3cfe0a6 (diff)
downloadriscv-isa-sim-d1f2cf337e1a0be8eada2afadd745e1374b4a000.zip
riscv-isa-sim-d1f2cf337e1a0be8eada2afadd745e1374b4a000.tar.gz
riscv-isa-sim-d1f2cf337e1a0be8eada2afadd745e1374b4a000.tar.bz2
OpenOCD connects, and sends some data that we receive.
Diffstat (limited to 'riscv/remote_bitbang.h')
-rw-r--r--riscv/remote_bitbang.h70
1 files changed, 70 insertions, 0 deletions
diff --git a/riscv/remote_bitbang.h b/riscv/remote_bitbang.h
new file mode 100644
index 0000000..165cc40
--- /dev/null
+++ b/riscv/remote_bitbang.h
@@ -0,0 +1,70 @@
+#ifndef REMOTE_BITBANG_H
+#define REMOTE_BITBANG_H
+
+#include <stdint.h>
+
+class sim_t;
+
+template <typename T>
+class circular_buffer_t
+{
+public:
+ // The buffer can store capacity-1 data elements.
+ circular_buffer_t(unsigned int capacity) : data(new T[capacity]),
+ start(0), end(0), capacity(capacity) {}
+ circular_buffer_t() : start(0), end(0), capacity(0) {}
+ ~circular_buffer_t() { delete[] data; }
+
+ T *data;
+ unsigned int start; // Data start, inclusive.
+ unsigned int end; // Data end, exclusive.
+ unsigned int capacity; // Size of the buffer.
+ unsigned int size() const;
+ bool empty() const { return start == end; }
+ bool full() const { return ((end+1) % capacity) == start; }
+ T entry(unsigned index) { return data[(start + index) % capacity]; }
+
+ // Return size and address of the block of RAM where more data can be copied
+ // to be added to the buffer.
+ unsigned int contiguous_empty_size() const;
+ T *contiguous_empty() { return data + end; }
+ void data_added(unsigned int bytes);
+
+ unsigned int contiguous_data_size() const;
+ T *contiguous_data() { return data + start; }
+ // Tell the buffer that some bytes were consumed from the start of the
+ // buffer.
+ void consume(unsigned int bytes);
+
+ void reset();
+
+ T operator[](unsigned int i) const { return data[(start + i) % capacity]; }
+
+ void append(const T *src, unsigned int count);
+};
+
+class remote_bitbang_t
+{
+public:
+ // Create a new server, listening for connections from localhost on the given
+ // port.
+ remote_bitbang_t(uint16_t port, sim_t *sim);
+
+ // Do a bit of work.
+ void tick();
+
+private:
+ int socket_fd;
+ int client_fd;
+ circular_buffer_t<uint8_t> recv_buf;
+ circular_buffer_t<uint8_t> send_buf;
+
+ // Check for a client connecting, and accept if there is one.
+ void accept();
+ // Read as much into recv_buf as possible.
+ void read();
+ // Write as much of send_buf as possible.
+ void write();
+};
+
+#endif