# define D(x)
#endif // DEBUG
-const int debug_gdbserver = 0;
-
void die(const char* msg)
{
fprintf(stderr, "gdbserver code died: %s\n", msg);
REG_FPR31 = 64,
REG_CSR0 = 65,
REG_CSR4095 = 4160,
- REG_END = 4161
+ REG_PRIV = 4161
};
//////////////////////////////////////// Functions to generate RISC-V opcodes.
// If we hit an exception reading the CSR, we'll end up returning ~0 as
// the register's value, which is what we want. (Right?)
gs.dr_write(SLOT_DATA0, ~(uint64_t) 0);
+ } else if (reg == REG_PRIV) {
+ gs.start_packet();
+ gs.send((uint8_t) get_field(gs.dcsr, DCSR_PRV));
+ gs.end_packet();
+ return true;
} else {
gs.send_packet("E02");
return true;
gs.sptbr = value;
gs.sptbr_valid = true;
}
+ } else if (reg == REG_PRIV) {
+ gs.dcsr = set_field(gs.dcsr, DCSR_PRV, value);
+ return true;
} else {
gs.send_packet("E02");
return true;
}
value >>= 8;
}
- if (data && debug_gdbserver) {
+ if (data) {
D(fprintf(stderr, "\n"));
}
length -= access_size;
}
}
+void gdbserver_t::send(uint8_t value)
+{
+ char buffer[3];
+ sprintf(buffer, "%02x", (int) value);
+ send(buffer);
+}
+
void gdbserver_t::send_packet(const char* data)
{
start_packet();
// Hex-encode a 32-bit value, and send it to gcc in target byte order (little
// endian).
void send(uint32_t value);
+ // Hex-encode an 8-bit value, and send it to gcc.
+ void send(uint8_t value);
void send_packet(const char* data);
uint8_t running_checksum;
// Send "$" and clear running checksum.
require_privilege(PRV_M);
set_pc_and_serialize(STATE.dpc);
-p->set_privilege(STATE.dcsr.prv);
+/* The debug spec says we can't crash when prv is set to an invalid value. */
+if (p->validate_priv(STATE.dcsr.prv)) {
+ p->set_privilege(STATE.dcsr.prv);
+}
/* We're not in Debug Mode anymore. */
STATE.dcsr.cause = 0;
raise_interrupt(ctz(enabled_interrupts));
}
-static bool validate_priv(reg_t priv)
+bool processor_t::validate_priv(reg_t priv)
{
return priv == PRV_U || priv == PRV_S || priv == PRV_M;
}
if (ext >= 'a' && ext <= 'z') ext += 'A' - 'a';
return ext >= 'A' && ext <= 'Z' && ((isa >> (ext - 'A')) & 1);
}
+ bool validate_priv(reg_t priv);
void set_privilege(reg_t);
void yield_load_reservation() { state.load_reservation = (reg_t)-1; }
void update_histogram(reg_t pc);