* automatically generated. */
/* TODO */
#include "/media/sf_tnewsome/Synced/SiFive/debug-spec/core_registers.tex.h"
+#define DCSR_CAUSE_SWBP 1
+#define DCSR_CAUSE_HALT 5
+
+#define DEBUG_ROM_ENTRY 0x800
#endif
// fetch/decode/execute loop
void processor_t::step(size_t n)
{
- // TODO: We should really not call this function at all when halted, to avoid
- // burning CPU.
- if (single_step) {
- set_halted(false, HR_NONE);
- n = 1;
- }
-
- while (run && !halted && n > 0) {
+ while (n > 0) {
size_t instret = 0;
reg_t pc = state.pc;
mmu_t* _mmu = mmu;
state.minstret += instret;
n -= instret;
}
-
- if (single_step) {
- single_step = false;
- set_halted(true, HR_STEPPED);
- }
}
// gdb wants the core to be halted when it attaches.
processor_t *p = sim->get_core(0);
- p->set_halted(true, HR_ATTACHED);
+ // TODO p->set_halted(true, HR_ATTACHED);
}
}
// The remote disconnected.
client_fd = 0;
processor_t *p = sim->get_core(0);
- p->set_halted(false, HR_NONE);
+ // TODO p->set_halted(false, HR_NONE);
recv_buf.reset();
send_buf.reset();
} else {
return send_packet("E30");
}
- p->set_halted(false, HR_NONE);
+ // TODO p->set_halted(false, HR_NONE);
running = true;
}
return send_packet("E40");
}
- p->set_single_step(true);
+ // TODO: p->set_single_step(true);
running = true;
}
void gdbserver_t::handle_interrupt()
{
processor_t *p = sim->get_core(0);
- p->set_halted(true, HR_INTERRUPT);
+ // TODO p->set_halted(true, HR_INTERRUPT);
send_packet("S02"); // Pretend program received SIGINT.
running = false;
}
{
if (client_fd > 0) {
processor_t *p = sim->get_core(0);
+ /* TODO
if (running && p->halted) {
// The core was running, but now it's halted. Better tell gdb.
switch (p->halt_reason) {
// TODO: Actually include register values here
running = false;
}
+ */
this->read();
this->write();
processor_t::processor_t(const char* isa, sim_t* sim, uint32_t id)
: sim(sim), ext(NULL), disassembler(new disassembler_t),
- id(id), run(false), debug(false), halted(false), single_step(false)
+ id(id), run(false), debug(false)
{
parse_isa_string(isa);
ext->set_debug(value);
}
-void processor_t::set_halted(bool value, halt_reason_t reason)
-{
- halted = value;
- halt_reason = reason;
-}
-
-void processor_t::set_single_step(bool value)
-{
- single_step = value;
-}
-
void processor_t::set_histogram(bool value)
{
histogram_enabled = value;
state.prv = prv;
}
+void processor_t::enter_debug_mode(uint8_t cause)
+{
+ state.dcsr.cause = cause;
+ state.dpc = state.pc;
+ state.pc = DEBUG_ROM_ENTRY;
+}
+
void processor_t::take_trap(trap_t& t, reg_t epc)
{
if (debug)
if (t.cause() == CAUSE_BREAKPOINT &&
sim->gdbserver && sim->gdbserver->connected()) {
- set_halted(true, HR_SWBP);
+ enter_debug_mode(DCSR_CAUSE_SWBP);
return;
}
~processor_t();
void set_debug(bool value);
- void set_halted(bool value, halt_reason_t reason);
- void set_single_step(bool value);
void set_histogram(bool value);
void reset(bool value);
void step(size_t n); // run for n cycles
bool run; // !reset
// When true, display disassembly of each instruction that's executed.
bool debug;
- // TODO: Should this just be rolled into `run`?
- bool halted; // When true, no instructions are executed.
- halt_reason_t halt_reason; // Why is halted true?
- // When true, execute exactly one instruction (even if halted is true), then
- // set halted to true and single_step to false.
- bool single_step;
bool histogram_enabled;
std::vector<insn_desc_t> instructions;
void take_trap(trap_t& t, reg_t epc); // take an exception
void disasm(insn_t insn); // disassemble and print an instruction
+ void enter_debug_mode(uint8_t cause);
+
friend class sim_t;
friend class mmu_t;
friend class rtc_t;
for (size_t i = 0; i < procs.size(); i++) {
procs[i] = new processor_t(isa, this, i);
- procs[i]->set_halted(halted, HR_CMDLINE);
+ procs[i]->enter_debug_mode(DCSR_CAUSE_HALT);
}
rtc.reset(new rtc_t(procs));