diff --git a/src/iss/plugin/cycle_estimate.cpp b/src/iss/plugin/cycle_estimate.cpp index 705b976..f5bac69 100644 --- a/src/iss/plugin/cycle_estimate.cpp +++ b/src/iss/plugin/cycle_estimate.cpp @@ -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_idget_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; } } diff --git a/src/iss/plugin/cycle_estimate.h b/src/iss/plugin/cycle_estimate.h index 7fc1b46..07cdd61 100644 --- a/src/iss/plugin/cycle_estimate.h +++ b/src/iss/plugin/cycle_estimate.h @@ -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 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 delays; unsigned current_delay{0}; struct pair_hash { diff --git a/src/sysc/sc_core_adapter.h b/src/sysc/sc_core_adapter.h index bbd1465..4b937ac 100644 --- a/src/sysc/sc_core_adapter.h +++ b/src/sysc/sc_core_adapter.h @@ -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::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_ */