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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user