Hack to the point where gdb reads a register.
[riscv-isa-sim.git] / riscv / gdbserver.h
1 #ifndef _RISCV_GDBSERVER_H
2 #define _RISCV_GDBSERVER_H
3
4 #include <stdint.h>
5
6 template <typename T>
7 class circular_buffer_t
8 {
9 public:
10 // The buffer can store capacity-1 data elements.
11 circular_buffer_t(unsigned int capacity) : data(new T[capacity]),
12 start(0), end(0), capacity(capacity) {}
13 circular_buffer_t() : start(0), end(0), capacity(0) {}
14 ~circular_buffer_t() { delete data; }
15
16 T *data;
17 unsigned int start; // Data start, inclusive.
18 unsigned int end; // Data end, exclusive.
19 unsigned int capacity; // Size of the buffer.
20 unsigned int size() const;
21 bool empty() const { return start == end; }
22 bool full() const { return ((end+1) % capacity) == start; }
23
24 // Return size and address of the block of RAM where more data can be copied
25 // to be added to the buffer.
26 unsigned int contiguous_empty_size() const;
27 T *contiguous_empty() { return data + end; }
28 void data_added(unsigned int bytes);
29
30 unsigned int contiguous_data_size() const;
31 T *contiguous_data() { return data + start; }
32 // Tell the buffer that some bytes were consumed from the start of the
33 // buffer.
34 void consume(unsigned int bytes);
35
36 void reset();
37
38 T operator[](unsigned int i) const { return data[(start + i) % capacity]; }
39
40 void append(const T *src, unsigned int count);
41 };
42
43 class gdbserver_t
44 {
45 public:
46 // Create a new server, listening for connections from localhost on the given
47 // port.
48 gdbserver_t(uint16_t port);
49
50 // Process all pending messages from a client.
51 void handle();
52
53 void handle_packet(const std::vector<uint8_t> &packet);
54 void handle_set_threadid(const std::vector<uint8_t> &packet);
55 void handle_halt_reason(const std::vector<uint8_t> &packet);
56
57 private:
58 int socket_fd;
59 int client_fd;
60 circular_buffer_t<uint8_t> recv_buf;
61 circular_buffer_t<uint8_t> send_buf;
62
63 bool expect_ack;
64
65 // Read pending data from the client.
66 void read();
67 void write();
68 // Accept a new client if there isn't one already connected.
69 void accept();
70 // Process all complete requests in recv_buf.
71 void process_requests();
72 // Add the given message to send_buf.
73 void send(const char* msg);
74 void send_packet(const char* data);
75 };
76
77 #endif