MATCH_SW;
}
+static uint32_t sd(unsigned int src, unsigned int base, uint16_t offset)
+{
+ return (bits(offset, 11, 5) << 25) |
+ (src << 20) |
+ (base << 15) |
+ (bits(offset, 4, 0) << 7) |
+ MATCH_SD;
+}
+
template <typename T>
unsigned int circular_buffer_t<T>::size() const
{
void gdbserver_t::halt()
{
- processor_t *p = sim->get_core(0);
+ // TODO: For now we just assume the target is 64-bit.
write_debug_ram(0, csrsi(DCSR_ADDRESS, DCSR_HALT_MASK));
write_debug_ram(1, csrr(S0, DPC_ADDRESS));
- write_debug_ram(2, sw(S0, 0, (uint16_t) DEBUG_RAM_START));
+ write_debug_ram(2, sd(S0, 0, (uint16_t) DEBUG_RAM_START));
write_debug_ram(3, csrr(S0, DCSR_ADDRESS));
- write_debug_ram(4, sw(S0, 0, (uint16_t) DEBUG_RAM_START + 8));
+ write_debug_ram(4, sd(S0, 0, (uint16_t) DEBUG_RAM_START + 8));
write_debug_ram(5, jal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*5))));
sim->debug_module.set_interrupt(0);
state = STATE_HALTING;
void die(const char* msg)
{
- fprintf(stderr, "%s\n", msg);
+ fprintf(stderr, "gdbserver code died: %s\n", msg);
abort();
}
send("$");
running_checksum = 0;
processor_t *p = sim->get_core(0);
- for (int r = 0; r < 32; r++) {
- die("handle_general_registers_read");
- // send(p->state.XPR[r]);
+
+ // x0 is always zero.
+ send((reg_t) 0);
+
+ write_debug_ram(0, sd(1, 0, (uint16_t) DEBUG_RAM_START + 16));
+ write_debug_ram(1, sd(2, 0, (uint16_t) DEBUG_RAM_START + 0));
+ write_debug_ram(2, jal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*2))));
+ sim->debug_module.set_interrupt(0);
+ state = STATE_CONT_GENERAL_REGISTERS;
+ state_argument = 1;
+}
+
+void gdbserver_t::continue_general_registers_read()
+{
+ send(((uint64_t) read_debug_ram(5) << 32) | read_debug_ram(4));
+ if (state_argument >= 31) {
+ send_running_checksum();
+ expect_ack = true;
+ state = STATE_HALTED;
+ } else {
+ send(((uint64_t) read_debug_ram(1) << 32) | read_debug_ram(0));
+
+ state_argument += 2;
+ // TODO properly read s0 and s1
+ write_debug_ram(0, sd(state_argument, 0, (uint16_t) DEBUG_RAM_START + 16));
+ write_debug_ram(1, sd(state_argument+1, 0, (uint16_t) DEBUG_RAM_START + 0));
+ write_debug_ram(2, jal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*2))));
+ sim->debug_module.set_interrupt(0);
+ state = STATE_CONT_GENERAL_REGISTERS;
}
- send_running_checksum();
- expect_ack = true;
}
// First byte is the most-significant one.
if (*iter != '#')
return send_packet("E01");
- processor_t *p = sim->get_core(0);
- send("$");
- running_checksum = 0;
+ state = STATE_CONT_REGISTER_READ;
+ state_argument = n;
- die("handle_register_read");
- /*
if (n >= REG_XPR0 && n <= REG_XPR31) {
- send(p->state.XPR[n - REG_XPR0]);
+ die("handle_register_read");
+ // send(p->state.XPR[n - REG_XPR0]);
} else if (n == REG_PC) {
- send(p->state.pc);
+ write_debug_ram(0, csrr(S0, DPC_ADDRESS));
+ write_debug_ram(1, sd(S0, 0, (uint16_t) DEBUG_RAM_START));
+ write_debug_ram(2, jal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*2))));
+ sim->debug_module.set_interrupt(0);
} else if (n >= REG_FPR0 && n <= REG_FPR31) {
- send(p->state.FPR[n - REG_FPR0]);
+ die("handle_register_read");
+ // send(p->state.FPR[n - REG_FPR0]);
} else if (n >= REG_CSR0 && n <= REG_CSR4095) {
try {
- send(p->get_csr(n - REG_CSR0));
+ die("handle_register_read");
+ // send(p->get_csr(n - REG_CSR0));
} catch(trap_t& t) {
// It would be nicer to return an error here, but if you do that then gdb
// exits out of 'info registers all' as soon as it encounters a register
send((reg_t) 0);
}
} else {
+ state = STATE_HALTED;
return send_packet("E02");
}
- */
+}
+
+void gdbserver_t::continue_register_read()
+{
+ send("$");
+ running_checksum = 0;
+
+ send(((uint64_t) read_debug_ram(1) << 32) | read_debug_ram(0));
send_running_checksum();
expect_ack = true;
+ state = STATE_HALTED;
}
void gdbserver_t::handle_register_write(const std::vector<uint8_t> &packet)
if (client_fd > 0) {
processor_t *p = sim->get_core(0);
- if (state == STATE_HALTING && sim->debug_module.get_interrupt(0) == 0) {
+ bool interrupt = sim->debug_module.get_interrupt(0);
+
+ if (state == STATE_HALTING && !interrupt) {
// gdb requested a halt and now it's done.
send_packet("T05");
fprintf(stderr, "DPC: 0x%x\n", read_debug_ram(0));
fprintf(stderr, "DCSR: 0x%x\n", read_debug_ram(2));
state = STATE_HALTED;
- p->debug = false;
+ }
+
+ if (!interrupt) {
+ switch (state) {
+ case STATE_CONT_GENERAL_REGISTERS:
+ continue_general_registers_read();
+ break;
+ case STATE_CONT_REGISTER_READ:
+ continue_register_read();
+ break;
+ default:
+ break;
+ }
}
/* TODO
}
*/
- this->read();
+ if (state == STATE_HALTED) {
+ this->read();
+ //p->debug = false;
+ } else {
+ //p->debug = true;
+ }
+
this->write();
} else {