memset(halted, 0, sizeof(halted));
memset(debug_rom_flags, 0, sizeof(debug_rom_flags));
memset(resumeack, 0, sizeof(resumeack));
+ memset(havereset, 0, sizeof(havereset));
memset(program_buffer, 0, program_buffer_bytes);
program_buffer[4*progbufsize] = ebreak();
program_buffer[4*progbufsize+1] = ebreak() >> 8;
result = set_field(result, DMI_DMSTATUS_IMPEBREAK,
dmstatus.impebreak);
+ result = set_field(result, DMI_DMSTATUS_ALLHAVERESET,
+ havereset[dmcontrol.hartsel]);
+ result = set_field(result, DMI_DMSTATUS_ANYHAVERESET,
+ havereset[dmcontrol.hartsel]);
result = set_field(result, DMI_DMSTATUS_ALLNONEXISTENT, dmstatus.allnonexistant);
result = set_field(result, DMI_DMSTATUS_ALLUNAVAIL, dmstatus.allunavail);
result = set_field(result, DMI_DMSTATUS_ALLRUNNING, dmstatus.allrunning);
dmcontrol.ndmreset = get_field(value, DMI_DMCONTROL_NDMRESET);
dmcontrol.hartsel = get_field(value, ((1L<<hartsellen)-1) <<
DMI_DMCONTROL_HARTSEL_OFFSET);
+ if (get_field(value, DMI_DMCONTROL_ACKHAVERESET)) {
+ havereset[dmcontrol.hartsel] = false;
+ }
}
processor_t *proc = current_proc();
if (proc) {
}
return false;
}
+
+void debug_module_t::proc_reset(unsigned id)
+{
+ havereset[id] = true;
+ halted[id] = false;
+}
typedef struct {
bool impebreak;
+ bool allhavereset;
+ bool anyhavereset;
bool allnonexistant;
bool anynonexistant;
bool allunavail;
bool dmi_read(unsigned address, uint32_t *value);
bool dmi_write(unsigned address, uint32_t value);
+ // Called when one of the attached harts was reset.
+ void proc_reset(unsigned id);
+
private:
static const unsigned datasize = 2;
// Size of program_buffer in 32-bit words, as exposed to the rest of the
uint8_t debug_abstract[debug_abstract_size * 4];
uint8_t *program_buffer;
uint8_t dmdata[datasize * 4];
-
+
bool halted[1024];
bool resumeack[1024];
+ bool havereset[1024];
uint8_t debug_rom_flags[1024];
void write32(uint8_t *rom, unsigned int index, uint32_t value);
// used for MMIO addresses
virtual bool mmio_load(reg_t addr, size_t len, uint8_t* bytes) = 0;
virtual bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes) = 0;
+ // Callback for processors to let the simulation know they were reset.
+ virtual void proc_reset(unsigned id) = 0;
};
// this class encapsulates the processors and memory in a RISC-V machine.
processor_t* get_core(size_t i) { return procs.at(i); }
unsigned nprocs() const { return procs.size(); }
+ // Callback for processors to let the simulation know they were reset.
+ void proc_reset(unsigned id);
+
private:
std::vector<std::pair<reg_t, mem_t*>> mems;
mmu_t* debug_mmu; // debug port into main memory