fixes tohost behavior of SC wrapper and cycle-estimate plugin

This commit is contained in:
Eyck Jentzsch 2023-10-25 20:37:10 +02:00
parent b86d7a517d
commit 980c8031c3
3 changed files with 45 additions and 12 deletions

View File

@ -101,7 +101,7 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if&
void iss::plugin::cycle_estimate::callback(instr_info_t instr_info) {
size_t instr_id = instr_info.instr_id;
auto entry = delays[instr_id];
auto& entry = instr_id<delays.size()?delays[instr_id]:illegal_desc;
if(instr_info.phase_id==PRE_SYNC) {
if(entry.f)
current_delay = entry.f(instr_if->get_instr_word());
@ -110,5 +110,6 @@ void iss::plugin::cycle_estimate::callback(instr_info_t instr_info) {
current_delay = instr_if->is_branch_taken()? entry.taken: entry.not_taken;
if(current_delay>1)
instr_if->update_last_instr_cycles(current_delay);
current_delay = 1;
}
}

View File

@ -48,10 +48,10 @@ namespace plugin {
class cycle_estimate: public vm_plugin {
struct instr_desc {
size_t size;
bool is_branch;
unsigned not_taken;
unsigned taken;
size_t size{0};
bool is_branch{false};
unsigned not_taken{1};
unsigned taken{1};
std::function<unsigned(uint64_t)> f;
};
@ -79,6 +79,7 @@ public:
private:
iss::instrumentation_if *instr_if{nullptr};
uint32_t* reg_base_ptr {nullptr};
instr_desc illegal_desc{};
std::vector<instr_desc> delays;
unsigned current_delay{0};
struct pair_hash {

View File

@ -70,14 +70,43 @@ public:
if (addr.access && iss::access_type::DEBUG)
return owner->write_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err;
else {
auto res = owner->write_mem(addr.val, length, data) ? iss::Ok : iss::Err;
// clear MTIP on mtimecmp write
if (addr.val == 0x2004000) {
reg_t val;
this->read_csr(iss::arch::mip, val);
if (val & (1ULL << 7)) this->write_csr(iss::arch::mip, val & ~(1ULL << 7));
auto tohost_upper = (sizeof(reg_t) == 4 && addr.val == (this->tohost + 4)) ||
(sizeof(reg_t) == 8 && addr.val == this->tohost);
auto tohost_lower = (sizeof(reg_t) == 4 && addr.val == this->tohost) ||
(sizeof(reg_t)== 64 && addr.val == this->tohost);
if (tohost_lower || tohost_upper) {
if (tohost_upper || (tohost_lower && to_host_wr_cnt > 0)) {
switch (hostvar >> 48) {
case 0:
if (hostvar != 0x1) {
SCCINFO(owner->name()) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
<< "), stopping simulation";
} else {
SCCINFO(owner->name()) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
<< "), stopping simulation";
}
this->reg.trap_state=std::numeric_limits<uint32_t>::max();
this->interrupt_sim=hostvar;
#ifndef WITH_TCC
throw(iss::simulation_stopped(hostvar));
#endif
break;
default:
break;
}
} else if (tohost_lower)
to_host_wr_cnt++;
return iss::Ok;
} else {
auto res = owner->write_mem(addr.val, length, data) ? iss::Ok : iss::Err;
// clear MTIP on mtimecmp write
if (addr.val == 0x2004000) {
reg_t val;
this->read_csr(iss::arch::mip, val);
if (val & (1ULL << 7)) this->write_csr(iss::arch::mip, val & ~(1ULL << 7));
}
return res;
}
return res;
}
}
@ -146,6 +175,8 @@ public:
private:
sysc::tgfs::core_complex *const owner;
sc_core::sc_event wfi_evt;
uint64_t hostvar;
unsigned to_host_wr_cnt = 0;
};
}
#endif /* _SYSC_SC_CORE_ADAPTER_H_ */