Refactor remote bitbang code.
[riscv-isa-sim.git] / riscv / remote_bitbang.h
1 #ifndef REMOTE_BITBANG_H
2 #define REMOTE_BITBANG_H
3
4 #include <stdint.h>
5
6 #include "jtag_dtm.h"
7
8 template <typename T>
9 class circular_buffer_t
10 {
11 public:
12 // The buffer can store capacity-1 data elements.
13 circular_buffer_t(unsigned int capacity) : data(new T[capacity]),
14 start(0), end(0), capacity(capacity) {}
15 circular_buffer_t() : start(0), end(0), capacity(0) {}
16 ~circular_buffer_t() { delete[] data; }
17
18 T *data;
19 unsigned int start; // Data start, inclusive.
20 unsigned int end; // Data end, exclusive.
21 unsigned int capacity; // Size of the buffer.
22 unsigned int size() const;
23 bool empty() const { return start == end; }
24 bool full() const { return ((end+1) % capacity) == start; }
25 T entry(unsigned index) { return data[(start + index) % capacity]; }
26
27 // Return size and address of the block of RAM where more data can be copied
28 // to be added to the buffer.
29 unsigned int contiguous_empty_size() const;
30 T *contiguous_empty() { return data + end; }
31 void data_added(unsigned int bytes);
32
33 unsigned int contiguous_data_size() const;
34 T *contiguous_data() { return data + start; }
35 // Tell the buffer that some bytes were consumed from the start of the
36 // buffer.
37 void consume(unsigned int bytes);
38
39 void reset();
40
41 T operator[](unsigned int i) const { return data[(start + i) % capacity]; }
42
43 void append(const T *src, unsigned int count);
44 void append(T value);
45 };
46
47 class remote_bitbang_t
48 {
49 public:
50 // Create a new server, listening for connections from localhost on the given
51 // port.
52 remote_bitbang_t(uint16_t port, jtag_dtm_t *tap);
53
54 // Do a bit of work.
55 void tick();
56
57 private:
58 jtag_dtm_t *tap;
59
60 int socket_fd;
61 int client_fd;
62 circular_buffer_t<uint8_t> recv_buf;
63 circular_buffer_t<uint8_t> send_buf;
64
65 // Check for a client connecting, and accept if there is one.
66 void accept();
67 // Read as much into recv_buf as possible.
68 void read();
69 // Write as much of send_buf as possible.
70 void write();
71
72 // Process the input buffer.
73 void process_input();
74 };
75
76 #endif