diff options
author | Andrew Waterman <andrew@sifive.com> | 2023-02-05 16:02:30 -0800 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2023-02-05 16:02:30 -0800 |
commit | 456c9e19d811ddc5da99974a40ee79a6f535a597 (patch) | |
tree | 3bd813365ea097bdee34d25871f4e1bf6e76ac48 | |
parent | e85f86695092f1377a515c94de5c706bcff1f2bd (diff) | |
download | riscv-isa-sim-456c9e19d811ddc5da99974a40ee79a6f535a597.zip riscv-isa-sim-456c9e19d811ddc5da99974a40ee79a6f535a597.tar.gz riscv-isa-sim-456c9e19d811ddc5da99974a40ee79a6f535a597.tar.bz2 |
Make clint tolerant of discontiguous hart IDsplic-clint-endian
-rw-r--r-- | riscv/clint.cc | 37 | ||||
-rw-r--r-- | riscv/devices.h | 6 | ||||
-rw-r--r-- | riscv/sim.cc | 2 |
3 files changed, 26 insertions, 19 deletions
diff --git a/riscv/clint.cc b/riscv/clint.cc index 056aa00..338e7a3 100644 --- a/riscv/clint.cc +++ b/riscv/clint.cc @@ -1,9 +1,10 @@ #include <sys/time.h> #include "devices.h" #include "processor.h" +#include "sim.h" -clint_t::clint_t(std::vector<processor_t*>& procs, uint64_t freq_hz, bool real_time) - : procs(procs), freq_hz(freq_hz), real_time(real_time), mtime(0), mtimecmp(procs.size()) +clint_t::clint_t(sim_t* sim, uint64_t freq_hz, bool real_time) + : sim(sim), freq_hz(freq_hz), real_time(real_time), mtime(0) { struct timeval base; @@ -11,6 +12,8 @@ clint_t::clint_t(std::vector<processor_t*>& procs, uint64_t freq_hz, bool real_t real_time_ref_secs = base.tv_sec; real_time_ref_usecs = base.tv_usec; + + increment(0); // initializes mtimecmp as a side effect } /* 0000 msip hart 0 @@ -53,19 +56,21 @@ bool clint_t::load(reg_t addr, size_t len, uint8_t* bytes) increment(0); const auto msip_hart_id = (addr - MSIP_BASE) / sizeof(msip_t); + const auto msip_hart_iter = sim->get_harts().find(msip_hart_id); const auto mtimecmp_hart_id = (addr - MTIMECMP_BASE) / sizeof(mtimecmp_t); + const auto mtimecmp_iter = mtimecmp.find(mtimecmp_hart_id); - if (addr >= MSIP_BASE && msip_hart_id < procs.size()) { + if (addr >= MSIP_BASE && msip_hart_iter != sim->get_harts().end()) { if (len == 8) { // Implement double-word loads as a pair of word loads return load(addr, 4, bytes) && load(addr + 4, 4, bytes + 4); } - msip_t res = !!(procs[msip_hart_id]->state.mip->read() & MIP_MSIP); + msip_t res = !!(msip_hart_iter->second->state.mip->read() & MIP_MSIP); partial_read(res, addr, len, bytes); return true; - } else if (addr >= MTIMECMP_BASE && mtimecmp_hart_id < procs.size()) { - partial_read(mtimecmp[mtimecmp_hart_id], addr, len, bytes); + } else if (addr >= MTIMECMP_BASE && mtimecmp_iter != mtimecmp.end()) { + partial_read(mtimecmp_iter->second, addr, len, bytes); } else if (addr >= MTIME_BASE && addr < MTIME_BASE + sizeof(mtime_t)) { partial_read(mtime, addr, len, bytes); } else if (addr + len <= CLINT_SIZE) { @@ -82,18 +87,20 @@ bool clint_t::store(reg_t addr, size_t len, const uint8_t* bytes) return false; const auto msip_hart_id = (addr - MSIP_BASE) / sizeof(msip_t); + const auto msip_hart_iter = sim->get_harts().find(msip_hart_id); const auto mtimecmp_hart_id = (addr - MTIMECMP_BASE) / sizeof(mtimecmp_t); + const auto mtimecmp_iter = mtimecmp.find(mtimecmp_hart_id); - if (addr >= MSIP_BASE && msip_hart_id < procs.size()) { + if (addr >= MSIP_BASE && msip_hart_iter != sim->get_harts().end()) { if (len == 8) { // Implement double-word stores as a pair of word stores return store(addr, 4, bytes) && store(addr + 4, 4, bytes + 4); } if (addr % sizeof(msip_t) == 0) - procs[msip_hart_id]->state.mip->backdoor_write_with_mask(MIP_MSIP, bytes[0] & 1 ? MIP_MSIP : 0); - } else if (addr >= MTIMECMP_BASE && mtimecmp_hart_id < procs.size()) { - partial_write(&mtimecmp[mtimecmp_hart_id], addr, len, bytes); + msip_hart_iter->second->state.mip->backdoor_write_with_mask(MIP_MSIP, bytes[0] & 1 ? MIP_MSIP : 0); + } else if (addr >= MTIMECMP_BASE && mtimecmp_iter != mtimecmp.end()) { + partial_write(&mtimecmp_iter->second, addr, len, bytes); } else if (addr >= MTIME_BASE && addr < MTIME_BASE + sizeof(mtime_t)) { partial_write(&mtime, addr, len, bytes); } else if (addr + len <= CLINT_SIZE) { @@ -117,10 +124,10 @@ void clint_t::increment(reg_t inc) } else { mtime += inc; } - for (size_t i = 0; i < procs.size(); i++) { - procs[i]->state.time->sync(mtime); - procs[i]->state.mip->backdoor_write_with_mask(MIP_MTIP, 0); - if (mtime >= mtimecmp[i]) - procs[i]->state.mip->backdoor_write_with_mask(MIP_MTIP, MIP_MTIP); + for (const auto& [hart_id, hart] : sim->get_harts()) { + hart->state.time->sync(mtime); + hart->state.mip->backdoor_write_with_mask(MIP_MTIP, 0); + if (mtime >= mtimecmp[hart_id]) + hart->state.mip->backdoor_write_with_mask(MIP_MTIP, MIP_MTIP); } } diff --git a/riscv/devices.h b/riscv/devices.h index 6facaa3..eaa2f7a 100644 --- a/riscv/devices.h +++ b/riscv/devices.h @@ -57,7 +57,7 @@ class mem_t : public abstract_device_t { class clint_t : public abstract_device_t { public: - clint_t(std::vector<processor_t*>&, uint64_t freq_hz, bool real_time); + clint_t(sim_t* sim, uint64_t freq_hz, bool real_time); bool load(reg_t addr, size_t len, uint8_t* bytes); bool store(reg_t addr, size_t len, const uint8_t* bytes); size_t size() { return CLINT_SIZE; } @@ -68,13 +68,13 @@ class clint_t : public abstract_device_t { typedef uint64_t mtime_t; typedef uint64_t mtimecmp_t; typedef uint32_t msip_t; - std::vector<processor_t*>& procs; + sim_t* sim; uint64_t freq_hz; bool real_time; uint64_t real_time_ref_secs; uint64_t real_time_ref_usecs; mtime_t mtime; - std::vector<mtimecmp_t> mtimecmp; + std::map<size_t, mtimecmp_t> mtimecmp; }; #define PLIC_MAX_DEVICES 1024 diff --git a/riscv/sim.cc b/riscv/sim.cc index 4e5e9a7..114151a 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -116,7 +116,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted, // setting the dtb_file argument has one. reg_t clint_base; if (fdt_parse_clint(fdt, &clint_base, "riscv,clint0") == 0) { - clint.reset(new clint_t(procs, CPU_HZ / INSNS_PER_RTC_TICK, cfg->real_time_clint())); + clint.reset(new clint_t(this, CPU_HZ / INSNS_PER_RTC_TICK, cfg->real_time_clint())); bus.add_device(clint_base, clint.get()); } |