diff --git a/src/iss/arch/riscv_hart_common.h b/src/iss/arch/riscv_hart_common.h index a4035d2..30b8c3c 100644 --- a/src/iss/arch/riscv_hart_common.h +++ b/src/iss/arch/riscv_hart_common.h @@ -365,6 +365,7 @@ template struct riscv_hart_co csr_wr_cb[minstreth] = MK_CSR_WR_CB(write_instret); csr_rd_cb[mhartid] = MK_CSR_RD_CB(read_hartid); }; + ~riscv_hart_common() { if(io_buf.str().length()) { CPPLOG(INFO) << "tohost send '" << io_buf.str() << "'"; @@ -427,14 +428,12 @@ template struct riscv_hart_co #endif } } - try { - tohost = symbol_table.at("tohost"); - } catch(std::out_of_range& e) { - } - try { - fromhost = symbol_table.at("fromhost"); - } catch(std::out_of_range& e) { - } + auto to_it = symbol_table.find("tohost"); + if(to_it!=std::end(symbol_table)) + tohost = to_it->second; + auto from_it = symbol_table.find("tohost"); + if(from_it!=std::end(symbol_table)) + tohost = from_it->second; } return true; } @@ -743,12 +742,12 @@ template struct riscv_hart_co mem::memory_hierarchy memories; - virtual mem::memory_if get_mem_if() override { - assert(false || "This function should nevver be called"); + mem::memory_if get_mem_if() override { + assert(false || "This function should never be called"); return mem::memory_if{}; } - virtual void set_next(mem::memory_if mem_if) { memory = mem_if; }; + void set_next(mem::memory_if mem_if) override { memory = mem_if; }; void set_irq_num(unsigned i) { mcause_max_irq = 1 << util::ilog2(i); } diff --git a/src/iss/mem/memory_if.cpp b/src/iss/mem/memory_if.cpp index 2beedf8..76f5bd2 100644 --- a/src/iss/mem/memory_if.cpp +++ b/src/iss/mem/memory_if.cpp @@ -22,15 +22,18 @@ void memory_hierarchy::append(memory_elem& e) { void memory_hierarchy::insert_before(memory_elem&) {} void memory_hierarchy::insert_after(memory_elem&) {} void memory_hierarchy::replace_last(memory_elem& e) { + auto old = hierarchy.back(); + auto it = std::find_if(std::begin(owned_elems), std::end(owned_elems), [old](std::unique_ptr const& p) {return p.get()==old;}); hierarchy.pop_back(); + if(it!=std::end(owned_elems)) + owned_elems.erase(it); hierarchy.push_back(&e); + update_chain(); } void memory_hierarchy::update_chain() { bool tail = false; - for(size_t i = 0; i < hierarchy.size(); ++i) { - hierarchy[i]->register_csrs(); - if(i) - hierarchy[i - 1]->set_next(hierarchy[i]->get_mem_if()); + for(size_t i = 1; i < hierarchy.size(); ++i) { + hierarchy[i - 1]->set_next(hierarchy[i]->get_mem_if()); } } @@ -55,11 +58,7 @@ void memory_hierarchy::insert_after(std::unique_ptr&& p) { } void memory_hierarchy::replace_last(std::unique_ptr&& p) { - auto e = hierarchy.back(); replace_last(*p); - auto it = std::find_if(std::begin(owned_elems), std::end(owned_elems), [e](std::unique_ptr const& p) {return p.get()==e;}); - if(it!=std::end(owned_elems)) - owned_elems.erase(it); owned_elems.push_back(std::move(p)); } diff --git a/src/iss/mem/memory_if.h b/src/iss/mem/memory_if.h index 14e042c..2b5d946 100644 --- a/src/iss/mem/memory_if.h +++ b/src/iss/mem/memory_if.h @@ -58,7 +58,6 @@ struct memory_elem { virtual ~memory_elem() = default; virtual memory_if get_mem_if() = 0; virtual void set_next(memory_if) = 0; - virtual void register_csrs() {} virtual std::tuple get_range() { return {0, std::numeric_limits::max()}; } }; diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index dfe61ef..f738aa4 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -419,7 +419,7 @@ template bool core_complex::read_mem(uint64_t gp.set_extension(preExt); } auto pre_delay = delay; - dbus->b_transport(gp, delay); + sckt->b_transport(gp, delay); if(pre_delay > delay) { quantum_keeper.reset(); } else { diff --git a/src/sysc/sc_core_adapter.h b/src/sysc/sc_core_adapter.h index d654800..384e008 100644 --- a/src/sysc/sc_core_adapter.h +++ b/src/sysc/sc_core_adapter.h @@ -14,15 +14,21 @@ #include #include #include +#include namespace sysc { template class sc_core_adapter : public PLAT, public sc_core_adapter_if { public: + using this_class = sc_core_adapter; using reg_t = typename iss::arch::traits::reg_t; using phys_addr_t = typename iss::arch::traits::phys_addr_t; - using heart_state_t = typename PLAT::hart_state_type; sc_core_adapter(sysc::tgfs::core_complex_if* owner) - : owner(owner) {} + : owner(owner) { + this->csr_rd_cb[iss::arch::time] = MK_CSR_RD_CB(read_time); + if(sizeof(reg_t) == 4) + this->csr_rd_cb[iss::arch::timeh] = MK_CSR_RD_CB(read_time); + this->memories.replace_last(*this); + } iss::arch_if* get_arch_if() override { return this; } @@ -60,18 +66,24 @@ public: } }; - iss::status read_mem(phys_addr_t addr, unsigned length, uint8_t* const data) override { - if(addr.access && iss::access_type::DEBUG) - return owner->read_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err; + iss::mem::memory_if get_mem_if() override { + return iss::mem::memory_if{ + .rd_mem{util::delegate::from(this)}, + .wr_mem{util::delegate::from(this)}}; + } + + iss::status read_mem(iss::access_type access, uint64_t addr, unsigned length, uint8_t* data) { + if(access && iss::access_type::DEBUG) + return owner->read_mem_dbg(addr, length, data) ? iss::Ok : iss::Err; else { - return owner->read_mem(addr.val, length, data, is_fetch(addr.access)) ? iss::Ok : iss::Err; + return owner->read_mem(addr, length, data, is_fetch(access)) ? iss::Ok : iss::Err; } } - iss::status write_mem(phys_addr_t addr, unsigned length, const uint8_t* const data) override { - if(addr.access && iss::access_type::DEBUG) - return owner->write_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err; - if(addr.val == this->tohost) { + iss::status write_mem(iss::access_type access, uint64_t addr, unsigned length, uint8_t const* data) { + if(access && iss::access_type::DEBUG) + return owner->write_mem_dbg(addr, length, data) ? iss::Ok : iss::Err; + if(addr == this->tohost) { reg_t cur_data = *reinterpret_cast(data); // Extract Device (bits 63:56) uint8_t device = sizeof(reg_t) == 4 ? 0 : (cur_data >> 56) & 0xFF; @@ -117,31 +129,20 @@ public: this->interrupt_sim = payload_addr; return iss::Ok; } - 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 res = owner->write_mem(addr, length, data) ? iss::Ok : iss::Err; return res; } - iss::status read_csr(unsigned addr, reg_t& val) override { - if((addr == iss::arch::time || addr == iss::arch::timeh)) { - uint64_t time_val = owner->mtime_i.get_interface() ? owner->mtime_i.read() : 0; - if(addr == iss::arch::time) { - val = static_cast(time_val); - } else if(addr == iss::arch::timeh) { - if(sizeof(reg_t) != 4) - return iss::Err; - val = static_cast(time_val >> 32); - } - return iss::Ok; - } else { - return PLAT::read_csr(addr, val); + iss::status read_time(unsigned addr, reg_t& val) { + uint64_t time_val = owner->mtime_i.get_interface() ? owner->mtime_i.read() : 0; + if(addr == iss::arch::time) { + val = static_cast(time_val); + } else if(addr == iss::arch::timeh) { + if(sizeof(reg_t) != 4) + return iss::Err; + val = static_cast(time_val >> 32); } + return iss::Ok; } void wait_until(uint64_t flags) override {