Looks like single step works.
[riscv-isa-sim.git] / riscv / gdbserver.h
1 #ifndef _RISCV_GDBSERVER_H
2 #define _RISCV_GDBSERVER_H
3
4 #include <stdint.h>
5
6 class sim_t;
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
26 // Return size and address of the block of RAM where more data can be copied
27 // to be added to the buffer.
28 unsigned int contiguous_empty_size() const;
29 T *contiguous_empty() { return data + end; }
30 void data_added(unsigned int bytes);
31
32 unsigned int contiguous_data_size() const;
33 T *contiguous_data() { return data + start; }
34 // Tell the buffer that some bytes were consumed from the start of the
35 // buffer.
36 void consume(unsigned int bytes);
37
38 void reset();
39
40 T operator[](unsigned int i) const { return data[(start + i) % capacity]; }
41
42 void append(const T *src, unsigned int count);
43 };
44
45 class gdbserver_t
46 {
47 public:
48 // Create a new server, listening for connections from localhost on the given
49 // port.
50 gdbserver_t(uint16_t port, sim_t *sim);
51
52 // Process all pending messages from a client.
53 void handle();
54
55 void handle_packet(const std::vector<uint8_t> &packet);
56 void handle_interrupt();
57
58 void handle_continue(const std::vector<uint8_t> &packet);
59 void handle_extended(const std::vector<uint8_t> &packet);
60 void handle_general_registers_read(const std::vector<uint8_t> &packet);
61 void handle_halt_reason(const std::vector<uint8_t> &packet);
62 void handle_kill(const std::vector<uint8_t> &packet);
63 void handle_memory_binary_write(const std::vector<uint8_t> &packet);
64 void handle_memory_read(const std::vector<uint8_t> &packet);
65 void handle_register_read(const std::vector<uint8_t> &packet);
66 void handle_step(const std::vector<uint8_t> &packet);
67
68 private:
69 sim_t *sim;
70 int socket_fd;
71 int client_fd;
72 circular_buffer_t<uint8_t> recv_buf;
73 circular_buffer_t<uint8_t> send_buf;
74
75 bool expect_ack;
76 bool extended_mode;
77 // Used to track whether we think the target is running. If we think it is
78 // but it isn't, we need to tell gdb about it.
79 bool running;
80
81 // Read pending data from the client.
82 void read();
83 void write();
84 // Accept a new client if there isn't one already connected.
85 void accept();
86 // Process all complete requests in recv_buf.
87 void process_requests();
88 // Add the given message to send_buf.
89 void send(const char* msg);
90 // Hex-encode a 64-bit value, and send it to gcc in target byte order (little
91 // endian).
92 void send(uint64_t value);
93 // Hex-encode a 32-bit value, and send it to gcc in target byte order (little
94 // endian).
95 void send(uint32_t value);
96 void send_packet(const char* data);
97 uint8_t running_checksum;
98 void send_running_checksum();
99 };
100
101 #endif