fixes sc_core_adapter wrt refactored memory hierarchy

This commit is contained in:
Eyck Jentzsch 2025-03-16 12:29:03 +01:00
parent 54233b448d
commit 3b294d9da0
5 changed files with 50 additions and 52 deletions

View File

@ -365,6 +365,7 @@ template <typename BASE, typename LOGCAT = logging::disass> struct riscv_hart_co
csr_wr_cb[minstreth] = MK_CSR_WR_CB(write_instret); csr_wr_cb[minstreth] = MK_CSR_WR_CB(write_instret);
csr_rd_cb[mhartid] = MK_CSR_RD_CB(read_hartid); csr_rd_cb[mhartid] = MK_CSR_RD_CB(read_hartid);
}; };
~riscv_hart_common() { ~riscv_hart_common() {
if(io_buf.str().length()) { if(io_buf.str().length()) {
CPPLOG(INFO) << "tohost send '" << io_buf.str() << "'"; CPPLOG(INFO) << "tohost send '" << io_buf.str() << "'";
@ -427,14 +428,12 @@ template <typename BASE, typename LOGCAT = logging::disass> struct riscv_hart_co
#endif #endif
} }
} }
try { auto to_it = symbol_table.find("tohost");
tohost = symbol_table.at("tohost"); if(to_it!=std::end(symbol_table))
} catch(std::out_of_range& e) { tohost = to_it->second;
} auto from_it = symbol_table.find("tohost");
try { if(from_it!=std::end(symbol_table))
fromhost = symbol_table.at("fromhost"); tohost = from_it->second;
} catch(std::out_of_range& e) {
}
} }
return true; return true;
} }
@ -743,12 +742,12 @@ template <typename BASE, typename LOGCAT = logging::disass> struct riscv_hart_co
mem::memory_hierarchy memories; mem::memory_hierarchy memories;
virtual mem::memory_if get_mem_if() override { mem::memory_if get_mem_if() override {
assert(false || "This function should nevver be called"); assert(false || "This function should never be called");
return mem::memory_if{}; 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); } void set_irq_num(unsigned i) { mcause_max_irq = 1 << util::ilog2(i); }

View File

@ -22,15 +22,18 @@ void memory_hierarchy::append(memory_elem& e) {
void memory_hierarchy::insert_before(memory_elem&) {} void memory_hierarchy::insert_before(memory_elem&) {}
void memory_hierarchy::insert_after(memory_elem&) {} void memory_hierarchy::insert_after(memory_elem&) {}
void memory_hierarchy::replace_last(memory_elem& e) { 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<memory_elem> const& p) {return p.get()==old;});
hierarchy.pop_back(); hierarchy.pop_back();
if(it!=std::end(owned_elems))
owned_elems.erase(it);
hierarchy.push_back(&e); hierarchy.push_back(&e);
update_chain();
} }
void memory_hierarchy::update_chain() { void memory_hierarchy::update_chain() {
bool tail = false; bool tail = false;
for(size_t i = 0; i < hierarchy.size(); ++i) { for(size_t i = 1; i < hierarchy.size(); ++i) {
hierarchy[i]->register_csrs(); hierarchy[i - 1]->set_next(hierarchy[i]->get_mem_if());
if(i)
hierarchy[i - 1]->set_next(hierarchy[i]->get_mem_if());
} }
} }
@ -55,11 +58,7 @@ void memory_hierarchy::insert_after(std::unique_ptr<memory_elem>&& p) {
} }
void memory_hierarchy::replace_last(std::unique_ptr<memory_elem>&& p) { void memory_hierarchy::replace_last(std::unique_ptr<memory_elem>&& p) {
auto e = hierarchy.back();
replace_last(*p); replace_last(*p);
auto it = std::find_if(std::begin(owned_elems), std::end(owned_elems), [e](std::unique_ptr<memory_elem> const& p) {return p.get()==e;});
if(it!=std::end(owned_elems))
owned_elems.erase(it);
owned_elems.push_back(std::move(p)); owned_elems.push_back(std::move(p));
} }

View File

@ -58,7 +58,6 @@ struct memory_elem {
virtual ~memory_elem() = default; virtual ~memory_elem() = default;
virtual memory_if get_mem_if() = 0; virtual memory_if get_mem_if() = 0;
virtual void set_next(memory_if) = 0; virtual void set_next(memory_if) = 0;
virtual void register_csrs() {}
virtual std::tuple<uint64_t, uint64_t> get_range() { return {0, std::numeric_limits<uint64_t>::max()}; } virtual std::tuple<uint64_t, uint64_t> get_range() { return {0, std::numeric_limits<uint64_t>::max()}; }
}; };

View File

@ -419,7 +419,7 @@ template <unsigned int BUSWIDTH> bool core_complex<BUSWIDTH>::read_mem(uint64_t
gp.set_extension(preExt); gp.set_extension(preExt);
} }
auto pre_delay = delay; auto pre_delay = delay;
dbus->b_transport(gp, delay); sckt->b_transport(gp, delay);
if(pre_delay > delay) { if(pre_delay > delay) {
quantum_keeper.reset(); quantum_keeper.reset();
} else { } else {

View File

@ -14,15 +14,21 @@
#include <iss/vm_types.h> #include <iss/vm_types.h>
#include <scc/report.h> #include <scc/report.h>
#include <util/ities.h> #include <util/ities.h>
#include <iss/mem/memory_if.h>
namespace sysc { namespace sysc {
template <typename PLAT> class sc_core_adapter : public PLAT, public sc_core_adapter_if { template <typename PLAT> class sc_core_adapter : public PLAT, public sc_core_adapter_if {
public: public:
using this_class = sc_core_adapter<PLAT>;
using reg_t = typename iss::arch::traits<typename PLAT::core>::reg_t; using reg_t = typename iss::arch::traits<typename PLAT::core>::reg_t;
using phys_addr_t = typename iss::arch::traits<typename PLAT::core>::phys_addr_t; using phys_addr_t = typename iss::arch::traits<typename PLAT::core>::phys_addr_t;
using heart_state_t = typename PLAT::hart_state_type;
sc_core_adapter(sysc::tgfs::core_complex_if* owner) 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; } 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 { iss::mem::memory_if get_mem_if() override {
if(addr.access && iss::access_type::DEBUG) return iss::mem::memory_if{
return owner->read_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err; .rd_mem{util::delegate<iss::mem::rd_mem_func_sig>::from<this_class, &this_class::read_mem>(this)},
.wr_mem{util::delegate<iss::mem::wr_mem_func_sig>::from<this_class, &this_class::write_mem>(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 { 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 { iss::status write_mem(iss::access_type access, uint64_t addr, unsigned length, uint8_t const* data) {
if(addr.access && iss::access_type::DEBUG) if(access && iss::access_type::DEBUG)
return owner->write_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err; return owner->write_mem_dbg(addr, length, data) ? iss::Ok : iss::Err;
if(addr.val == this->tohost) { if(addr == this->tohost) {
reg_t cur_data = *reinterpret_cast<const reg_t*>(data); reg_t cur_data = *reinterpret_cast<const reg_t*>(data);
// Extract Device (bits 63:56) // Extract Device (bits 63:56)
uint8_t device = sizeof(reg_t) == 4 ? 0 : (cur_data >> 56) & 0xFF; uint8_t device = sizeof(reg_t) == 4 ? 0 : (cur_data >> 56) & 0xFF;
@ -117,31 +129,20 @@ public:
this->interrupt_sim = payload_addr; this->interrupt_sim = payload_addr;
return iss::Ok; return iss::Ok;
} }
auto res = owner->write_mem(addr.val, length, data) ? iss::Ok : iss::Err; auto res = owner->write_mem(addr, 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;
} }
iss::status read_csr(unsigned addr, reg_t& val) override { iss::status read_time(unsigned addr, reg_t& val) {
if((addr == iss::arch::time || addr == iss::arch::timeh)) { uint64_t time_val = owner->mtime_i.get_interface() ? owner->mtime_i.read() : 0;
uint64_t time_val = owner->mtime_i.get_interface() ? owner->mtime_i.read() : 0; if(addr == iss::arch::time) {
if(addr == iss::arch::time) { val = static_cast<reg_t>(time_val);
val = static_cast<reg_t>(time_val); } else if(addr == iss::arch::timeh) {
} else if(addr == iss::arch::timeh) { if(sizeof(reg_t) != 4)
if(sizeof(reg_t) != 4) return iss::Err;
return iss::Err; val = static_cast<reg_t>(time_val >> 32);
val = static_cast<reg_t>(time_val >> 32);
}
return iss::Ok;
} else {
return PLAT::read_csr(addr, val);
} }
return iss::Ok;
} }
void wait_until(uint64_t flags) override { void wait_until(uint64_t flags) override {