1 #ifndef _RISCV_GDBSERVER_H
2 #define _RISCV_GDBSERVER_H
12 class circular_buffer_t
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
; }
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
]; }
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
);
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
40 void consume(unsigned int bytes
);
44 T
operator[](unsigned int i
) const { return data
[(start
+ i
) % capacity
]; }
46 void append(const T
*src
, unsigned int count
);
49 // Class to track software breakpoints that we set.
50 class software_breakpoint_t
55 unsigned char instruction
[4];
58 class hardware_breakpoint_t
64 bool load
, store
, execute
;
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
;
80 operation_t(gdbserver_t
& gdbserver
) : gs(gdbserver
), current_step(0) {}
81 virtual ~operation_t() {}
84 bool result
= perform_step(current_step
);
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
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;
99 unsigned int current_step
;
104 * 0 inst/0 inst/0 inst/0
105 * 1 inst inst/0 inst/0
108 * 4 data0 data0 data0
109 * 5 data1 data0 data0
110 * 6 data2 data1 data0
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};
138 } gdb_breakpoint_type_t
;
143 // Create a new server, listening for connections from localhost on the given
145 gdbserver_t(uint16_t port
, sim_t
*sim
);
147 // Process all pending messages from a client.
150 void handle_packet(const std::vector
<uint8_t> &packet
);
151 void handle_interrupt();
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
);
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
);
173 bool connected() const { return client_fd
> 0; }
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
180 void send(uint64_t value
);
181 // Hex-encode a 32-bit value, and send it to gcc in target byte order (little
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.
190 // Send "#" and checksum.
191 void end_packet(const char* data
=NULL
);
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
);
206 uint64_t consume_hex_number_le(std::vector
<uint8_t>::const_iterator
&iter
,
207 std::vector
<uint8_t>::const_iterator end
);
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
);
213 void set_interrupt(uint32_t hartid
);
215 // Members that ought to be privated, but that we'd really like to access
216 // from operation classes.
224 bool fence_i_required
;
226 std::map
<reg_t
, reg_t
> pte_cache
;
228 reg_t
translate(reg_t vaddr
);
229 // Return the PRV_x that is used when the code under debug performs a memory
231 unsigned int privilege_mode();
232 // Return the VM_x that is used when the code under debug performs a memory
234 unsigned int virtual_memory();
238 std::set
<hardware_breakpoint_t
, hardware_breakpoint_compare_t
>
239 hardware_breakpoints
;
245 circular_buffer_t
<uint8_t> recv_buf
;
246 circular_buffer_t
<uint8_t> send_buf
;
250 // Used to track whether we think the target is running. If we think it is
251 // but it isn't, we need to tell gdb about it.
254 std::map
<reg_t
, software_breakpoint_t
> software_breakpoints
;
256 // Read pending data from the client.
259 // Accept a new client if there isn't one already connected.
261 // Process all complete requests in recv_buf.
262 void process_requests();
264 std::queue
<operation_t
*> operation_queue
;
265 void add_operation(operation_t
* operation
);