Browse Source

gdb can now read spike memory.

The endianness is wrong, but I think it might be that gdb doesn't have
it right. Need to investigate what architecture gdb thinks it's
debugging.
pull/39/head
Tim Newsome 11 years ago
parent
commit
d1ba8b5593
  1. 106
      riscv/gdbserver.cc
  2. 10
      riscv/gdbserver.h
  3. 1
      riscv/processor.h
  4. 1
      riscv/sim.h
  5. 2
      spike_main/spike.cc

106
riscv/gdbserver.cc

@ -12,6 +12,8 @@
#include <cstdio>
#include <vector>
#include "disasm.h"
#include "sim.h"
#include "gdbserver.h"
template <typename T>
@ -82,7 +84,8 @@ void circular_buffer_t<T>::append(const T *src, unsigned int count)
// Code inspired by/copied from OpenOCD server/server.c.
gdbserver_t::gdbserver_t(uint16_t port) :
gdbserver_t::gdbserver_t(uint16_t port, sim_t *sim) :
sim(sim),
client_fd(0),
recv_buf(64 * 1024), send_buf(64 * 1024)
{
@ -222,7 +225,7 @@ uint8_t character_hex_value(uint8_t character)
return 10 + character - 'a';
if (character >= 'A' && character <= 'F')
return 10 + character - 'A';
return 0;
return 0xff;
}
uint8_t extract_checksum(const std::vector<uint8_t> &packet)
@ -274,19 +277,78 @@ void gdbserver_t::process_requests()
}
}
void gdbserver_t::handle_set_threadid(const std::vector<uint8_t> &packet)
void gdbserver_t::handle_halt_reason(const std::vector<uint8_t> &packet)
{
if (packet[2] == 'g' && packet[3] == '0') {
// Use thread 0 for all operations.
send("OK");
} else {
send("$#00");
send_packet("S00");
}
void gdbserver_t::handle_read_general_registers(const std::vector<uint8_t> &packet)
{
// Register order that gdb expects is:
// "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
// "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
// "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
// "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31",
// "pc",
// "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
// "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
// "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
// "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
send("$");
running_checksum = 0;
char buffer[17];
processor_t *p = sim->get_core(0);
for (int r = 0; r < 32; r++) {
sprintf(buffer, "%08lx", p->state.XPR[r]);
send(buffer);
}
send_running_checksum();
expect_ack = true;
}
void gdbserver_t::handle_halt_reason(const std::vector<uint8_t> &packet)
uint64_t consume_hex_number(std::vector<uint8_t>::const_iterator &iter,
std::vector<uint8_t>::const_iterator end)
{
send_packet("S00");
uint64_t value = 0;
while (iter != end) {
uint8_t c = *iter;
uint64_t c_value = character_hex_value(c);
if (c_value > 15)
break;
iter++;
value <<= 4;
value += c_value;
}
return value;
}
void gdbserver_t::handle_read_memory(const std::vector<uint8_t> &packet)
{
// m addr,length
std::vector<uint8_t>::const_iterator iter = packet.begin() + 2;
reg_t address = consume_hex_number(iter, packet.end());
printf("address=%lx %c\n", address, *iter);
if (*iter != ',')
return send_packet("E16"); // EINVAL
iter++;
reg_t length = consume_hex_number(iter, packet.end());
printf("length=%lx %c\n", length, *iter);
if (*iter != '#')
return send_packet("E16"); // EINVAL
send("$");
running_checksum = 0;
char buffer[3];
processor_t *p = sim->get_core(0);
mmu_t* mmu = sim->debug_mmu;
for (reg_t i = 0; i < length; i++) {
sprintf(buffer, "%02x", mmu->load_uint8(address + i));
send(buffer);
}
send_running_checksum();
}
void gdbserver_t::handle_packet(const std::vector<uint8_t> &packet)
@ -304,10 +366,12 @@ void gdbserver_t::handle_packet(const std::vector<uint8_t> &packet)
send("+");
switch (packet[1]) {
case 'H':
return handle_set_threadid(packet);
case '?':
return handle_halt_reason(packet);
case 'g':
return handle_read_general_registers(packet);
case 'm':
return handle_read_memory(packet);
}
// Not supported.
@ -330,21 +394,23 @@ void gdbserver_t::handle()
void gdbserver_t::send(const char* msg)
{
unsigned int length = strlen(msg);
for (const char *c = msg; *c; c++)
running_checksum += *c;
send_buf.append((const uint8_t *) msg, length);
}
void gdbserver_t::send_packet(const char* data)
{
send("$");
running_checksum = 0;
send(data);
send("#");
send_running_checksum();
expect_ack = true;
}
uint8_t checksum = 0;
for ( ; *data; data++) {
checksum += *data;
}
char checksum_string[3];
sprintf(checksum_string, "%02x", checksum);
void gdbserver_t::send_running_checksum()
{
char checksum_string[4];
sprintf(checksum_string, "#%02x", running_checksum);
send(checksum_string);
expect_ack = true;
}

10
riscv/gdbserver.h

@ -3,6 +3,8 @@
#include <stdint.h>
class sim_t;
template <typename T>
class circular_buffer_t
{
@ -45,16 +47,18 @@ class gdbserver_t
public:
// Create a new server, listening for connections from localhost on the given
// port.
gdbserver_t(uint16_t port);
gdbserver_t(uint16_t port, sim_t *sim);
// Process all pending messages from a client.
void handle();
void handle_packet(const std::vector<uint8_t> &packet);
void handle_set_threadid(const std::vector<uint8_t> &packet);
void handle_halt_reason(const std::vector<uint8_t> &packet);
void handle_read_general_registers(const std::vector<uint8_t> &packet);
void handle_read_memory(const std::vector<uint8_t> &packet);
private:
sim_t *sim;
int socket_fd;
int client_fd;
circular_buffer_t<uint8_t> recv_buf;
@ -72,6 +76,8 @@ private:
// Add the given message to send_buf.
void send(const char* msg);
void send_packet(const char* data);
uint8_t running_checksum;
void send_running_checksum();
};
#endif

1
riscv/processor.h

@ -136,6 +136,7 @@ private:
friend class mmu_t;
friend class rtc_t;
friend class extension_t;
friend class gdbserver_t;
void parse_isa_string(const char* isa);
void build_opcode_map();

1
riscv/sim.h

@ -92,6 +92,7 @@ private:
friend class htif_isasim_t;
friend class processor_t;
friend class mmu_t;
friend class gdbserver_t;
};
extern volatile bool ctrlc_pressed;

2
spike_main/spike.cc

@ -74,7 +74,7 @@ int main(int argc, char** argv)
auto argv1 = parser.parse(argv);
std::vector<std::string> htif_args(argv1, (const char*const*)argv + argc);
sim_t s(isa, nprocs, mem_mb, htif_args);
gdbserver_t gdbserver(9824);
gdbserver_t gdbserver(9824, &s);
s.set_gdbserver(&gdbserver);
if (dump_config_string) {

Loading…
Cancel
Save