Add option to set start pc
[riscv-isa-sim.git] / riscv / gdbserver.h
1 #ifndef _RISCV_GDBSERVER_H
2 #define _RISCV_GDBSERVER_H
3
4 #include <map>
5 #include <queue>
6
7 #include <stdint.h>
8
9 class sim_t;
10
11 template <typename T>
12 class circular_buffer_t
13 {
14 public:
15 // The buffer can store capacity-1 data elements.
16 circular_buffer_t(unsigned int capacity) : data(new T[capacity]),
17 start(0), end(0), capacity(capacity) {}
18 circular_buffer_t() : start(0), end(0), capacity(0) {}
19 ~circular_buffer_t() { delete[] data; }
20
21 T *data;
22 unsigned int start; // Data start, inclusive.
23 unsigned int end; // Data end, exclusive.
24 unsigned int capacity; // Size of the buffer.
25 unsigned int size() const;
26 bool empty() const { return start == end; }
27 bool full() const { return ((end+1) % capacity) == start; }
28 T entry(unsigned index) { return data[(start + index) % capacity]; }
29
30 // Return size and address of the block of RAM where more data can be copied
31 // to be added to the buffer.
32 unsigned int contiguous_empty_size() const;
33 T *contiguous_empty() { return data + end; }
34 void data_added(unsigned int bytes);
35
36 unsigned int contiguous_data_size() const;
37 T *contiguous_data() { return data + start; }
38 // Tell the buffer that some bytes were consumed from the start of the
39 // buffer.
40 void consume(unsigned int bytes);
41
42 void reset();
43
44 T operator[](unsigned int i) const { return data[(start + i) % capacity]; }
45
46 void append(const T *src, unsigned int count);
47 };
48
49 // Class to track software breakpoints that we set.
50 class software_breakpoint_t
51 {
52 public:
53 reg_t vaddr;
54 unsigned int size;
55 unsigned char instruction[4];
56 };
57
58 class hardware_breakpoint_t
59 {
60 public:
61 reg_t vaddr;
62 unsigned int size;
63 unsigned int index;
64 bool load, store, execute;
65 };
66
67 struct hardware_breakpoint_compare_t {
68 bool operator()(const hardware_breakpoint_t& a, const hardware_breakpoint_t& b) const {
69 if (a.vaddr != b.vaddr)
70 return a.vaddr < b.vaddr;
71 return a.size < b.size;
72 }
73 };
74
75 class gdbserver_t;
76
77 class operation_t
78 {
79 public:
80 operation_t(gdbserver_t& gdbserver) : gs(gdbserver), current_step(0) {}
81 virtual ~operation_t() {}
82
83 bool step() {
84 bool result = perform_step(current_step);
85 current_step++;
86 return result;
87 }
88
89 // Perform the next step of this operation (which is probably to write to
90 // Debug RAM and assert the debug interrupt).
91 // Return true if this operation is complete. In that case the object will
92 // be deleted.
93 // Return false if more steps are required the next time the debug
94 // interrupt is clear.
95 virtual bool perform_step(unsigned int step) = 0;
96
97 protected:
98 gdbserver_t& gs;
99 unsigned int current_step;
100 };
101
102 /*
103 * word 32 64 128
104 * 0 inst/0 inst/0 inst/0
105 * 1 inst inst/0 inst/0
106 * 2 inst inst inst/0
107 * 3 inst inst inst/0
108 * 4 data0 data0 data0
109 * 5 data1 data0 data0
110 * 6 data2 data1 data0
111 * 7 data1 data0
112 * 8 data2 data1
113 * 9 data2 data1
114 * 10 data1
115 * 11 data1
116 * 12 data2
117 * 13 data2
118 * 14 data2
119 * 15 data2
120 */
121 enum slot {
122 SLOT_INST0,
123 SLOT_DATA0,
124 SLOT_DATA1,
125 SLOT_DATA_LAST,
126 };
127
128 static const unsigned int slot_offset32[] = {0, 4, 5, DEBUG_RAM_SIZE/4 - 1};
129 static const unsigned int slot_offset64[] = {0, 4, 6, DEBUG_RAM_SIZE/4 - 2};
130 static const unsigned int slot_offset128[] = {0, 4, 8, DEBUG_RAM_SIZE/4 - 4};
131
132 typedef enum {
133 GB_SOFTWARE = 0,
134 GB_HARDWARE = 1,
135 GB_WRITE = 2,
136 GB_READ = 3,
137 GB_ACCESS = 4,
138 } gdb_breakpoint_type_t;
139
140 class gdbserver_t
141 {
142 public:
143 // Create a new server, listening for connections from localhost on the given
144 // port.
145 gdbserver_t(uint16_t port, sim_t *sim);
146
147 // Process all pending messages from a client.
148 void handle();
149
150 void handle_packet(const std::vector<uint8_t> &packet);
151 void handle_interrupt();
152
153 void software_breakpoint_remove(reg_t vaddr, unsigned int size);
154 void software_breakpoint_insert(reg_t vaddr, unsigned int size);
155 void hardware_breakpoint_remove(const hardware_breakpoint_t &bp);
156 void hardware_breakpoint_insert(const hardware_breakpoint_t &bp);
157
158 void handle_breakpoint(const std::vector<uint8_t> &packet);
159 void handle_continue(const std::vector<uint8_t> &packet);
160 void handle_extended(const std::vector<uint8_t> &packet);
161 void handle_general_registers_read(const std::vector<uint8_t> &packet);
162 void continue_general_registers_read();
163 void handle_halt_reason(const std::vector<uint8_t> &packet);
164 void handle_kill(const std::vector<uint8_t> &packet);
165 void handle_memory_binary_write(const std::vector<uint8_t> &packet);
166 void handle_memory_read(const std::vector<uint8_t> &packet);
167 void handle_query(const std::vector<uint8_t> &packet);
168 void handle_register_read(const std::vector<uint8_t> &packet);
169 void continue_register_read();
170 void handle_register_write(const std::vector<uint8_t> &packet);
171 void handle_step(const std::vector<uint8_t> &packet);
172
173 bool connected() const { return client_fd > 0; }
174
175 // TODO: Move this into its own packet sending class?
176 // Add the given message to send_buf.
177 void send(const char* msg);
178 // Hex-encode a 64-bit value, and send it to gcc in target byte order (little
179 // endian).
180 void send(uint64_t value);
181 // Hex-encode a 32-bit value, and send it to gcc in target byte order (little
182 // endian).
183 void send(uint32_t value);
184 // Hex-encode an 8-bit value, and send it to gcc.
185 void send(uint8_t value);
186 void send_packet(const char* data);
187 uint8_t running_checksum;
188 // Send "$" and clear running checksum.
189 void start_packet();
190 // Send "#" and checksum.
191 void end_packet(const char* data=NULL);
192
193 // Write value to the index'th word in Debug RAM.
194 void dr_write32(unsigned int index, uint32_t value);
195 void dr_write64(unsigned int index, uint64_t value);
196 void dr_write(enum slot slot, uint64_t value);
197 // Write jump-to-resume instruction to the index'th word in Debug RAM.
198 void dr_write_jump(unsigned int index);
199 // Write an xlen-bit store instruction.
200 void dr_write_store(unsigned int index, unsigned int reg, enum slot);
201 void dr_write_load(unsigned int index, unsigned int reg, enum slot);
202 uint32_t dr_read32(unsigned int index);
203 uint64_t dr_read64(unsigned int index);
204 uint64_t dr_read(enum slot slot);
205
206 uint64_t consume_hex_number_le(std::vector<uint8_t>::const_iterator &iter,
207 std::vector<uint8_t>::const_iterator end);
208
209 // Return access size to use when writing length bytes to address, so that
210 // every write will be aligned.
211 unsigned int find_access_size(reg_t address, int length);
212
213 void set_interrupt(uint32_t hartid);
214
215 // Members that ought to be privated, but that we'd really like to access
216 // from operation classes.
217 reg_t dpc;
218 reg_t dcsr;
219 reg_t mstatus;
220 bool mstatus_dirty;
221 reg_t sptbr;
222 bool sptbr_valid;
223 reg_t tselect;
224 bool tselect_valid;
225 bool fence_i_required;
226
227 std::map<reg_t, reg_t> pte_cache;
228
229 reg_t translate(reg_t vaddr);
230 // Return the PRV_x that is used when the code under debug performs a memory
231 // access.
232 unsigned int privilege_mode();
233
234 unsigned int xlen;
235
236 std::set<hardware_breakpoint_t, hardware_breakpoint_compare_t>
237 hardware_breakpoints;
238
239 private:
240 sim_t *sim;
241 int socket_fd;
242 int client_fd;
243 circular_buffer_t<uint8_t> recv_buf;
244 circular_buffer_t<uint8_t> send_buf;
245
246 bool expect_ack;
247 bool extended_mode;
248 // Used to track whether we think the target is running. If we think it is
249 // but it isn't, we need to tell gdb about it.
250 bool running;
251
252 std::map<reg_t, software_breakpoint_t> software_breakpoints;
253
254 // Read pending data from the client.
255 void read();
256 void write();
257 // Accept a new client if there isn't one already connected.
258 void accept();
259 // Process all complete requests in recv_buf.
260 void process_requests();
261
262 std::queue<operation_t*> operation_queue;
263 void add_operation(operation_t* operation);
264 };
265
266 #endif