fixes tohost behavior of SC wrapper and cycle-estimate plugin
This commit is contained in:
parent
b86d7a517d
commit
980c8031c3
|
@ -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) {
|
void iss::plugin::cycle_estimate::callback(instr_info_t instr_info) {
|
||||||
size_t instr_id = instr_info.instr_id;
|
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(instr_info.phase_id==PRE_SYNC) {
|
||||||
if(entry.f)
|
if(entry.f)
|
||||||
current_delay = entry.f(instr_if->get_instr_word());
|
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;
|
current_delay = instr_if->is_branch_taken()? entry.taken: entry.not_taken;
|
||||||
if(current_delay>1)
|
if(current_delay>1)
|
||||||
instr_if->update_last_instr_cycles(current_delay);
|
instr_if->update_last_instr_cycles(current_delay);
|
||||||
|
current_delay = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,10 +48,10 @@ namespace plugin {
|
||||||
|
|
||||||
class cycle_estimate: public vm_plugin {
|
class cycle_estimate: public vm_plugin {
|
||||||
struct instr_desc {
|
struct instr_desc {
|
||||||
size_t size;
|
size_t size{0};
|
||||||
bool is_branch;
|
bool is_branch{false};
|
||||||
unsigned not_taken;
|
unsigned not_taken{1};
|
||||||
unsigned taken;
|
unsigned taken{1};
|
||||||
std::function<unsigned(uint64_t)> f;
|
std::function<unsigned(uint64_t)> f;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ public:
|
||||||
private:
|
private:
|
||||||
iss::instrumentation_if *instr_if{nullptr};
|
iss::instrumentation_if *instr_if{nullptr};
|
||||||
uint32_t* reg_base_ptr {nullptr};
|
uint32_t* reg_base_ptr {nullptr};
|
||||||
|
instr_desc illegal_desc{};
|
||||||
std::vector<instr_desc> delays;
|
std::vector<instr_desc> delays;
|
||||||
unsigned current_delay{0};
|
unsigned current_delay{0};
|
||||||
struct pair_hash {
|
struct pair_hash {
|
||||||
|
|
|
@ -70,14 +70,43 @@ public:
|
||||||
if (addr.access && iss::access_type::DEBUG)
|
if (addr.access && iss::access_type::DEBUG)
|
||||||
return owner->write_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err;
|
return owner->write_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err;
|
||||||
else {
|
else {
|
||||||
auto res = owner->write_mem(addr.val, length, data) ? iss::Ok : iss::Err;
|
auto tohost_upper = (sizeof(reg_t) == 4 && addr.val == (this->tohost + 4)) ||
|
||||||
// clear MTIP on mtimecmp write
|
(sizeof(reg_t) == 8 && addr.val == this->tohost);
|
||||||
if (addr.val == 0x2004000) {
|
auto tohost_lower = (sizeof(reg_t) == 4 && addr.val == this->tohost) ||
|
||||||
reg_t val;
|
(sizeof(reg_t)== 64 && addr.val == this->tohost);
|
||||||
this->read_csr(iss::arch::mip, val);
|
if (tohost_lower || tohost_upper) {
|
||||||
if (val & (1ULL << 7)) this->write_csr(iss::arch::mip, val & ~(1ULL << 7));
|
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:
|
private:
|
||||||
sysc::tgfs::core_complex *const owner;
|
sysc::tgfs::core_complex *const owner;
|
||||||
sc_core::sc_event wfi_evt;
|
sc_core::sc_event wfi_evt;
|
||||||
|
uint64_t hostvar;
|
||||||
|
unsigned to_host_wr_cnt = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif /* _SYSC_SC_CORE_ADAPTER_H_ */
|
#endif /* _SYSC_SC_CORE_ADAPTER_H_ */
|
||||||
|
|
Loading…
Reference in New Issue