diff options
-rw-r--r-- | riscv/clint.cc | 23 | ||||
-rw-r--r-- | riscv/devices.h | 6 | ||||
-rw-r--r-- | riscv/sim.cc | 5 | ||||
-rw-r--r-- | riscv/sim.h | 3 | ||||
-rw-r--r-- | spike_main/spike.cc | 6 |
5 files changed, 35 insertions, 8 deletions
diff --git a/riscv/clint.cc b/riscv/clint.cc index 20a9fca..d68f4cc 100644 --- a/riscv/clint.cc +++ b/riscv/clint.cc @@ -1,9 +1,16 @@ +#include <sys/time.h> #include "devices.h" #include "processor.h" -clint_t::clint_t(std::vector<processor_t*>& procs) - : procs(procs), mtime(0), mtimecmp(procs.size()) +clint_t::clint_t(std::vector<processor_t*>& procs, uint64_t freq_mhz, bool real_time) + : procs(procs), freq_mhz(freq_mhz), real_time(real_time), mtime(0), mtimecmp(procs.size()) { + struct timeval base; + + gettimeofday(&base, NULL); + + real_time_ref_secs = base.tv_sec; + real_time_ref_usecs = base.tv_usec; } /* 0000 msip hart 0 @@ -22,6 +29,7 @@ clint_t::clint_t(std::vector<processor_t*>& procs) bool clint_t::load(reg_t addr, size_t len, uint8_t* bytes) { + increment(0); if (addr >= MSIP_BASE && addr + len <= MSIP_BASE + procs.size()*sizeof(msip_t)) { std::vector<msip_t> msip(procs.size()); for (size_t i = 0; i < procs.size(); ++i) @@ -63,7 +71,16 @@ bool clint_t::store(reg_t addr, size_t len, const uint8_t* bytes) void clint_t::increment(reg_t inc) { - mtime += inc; + if (real_time) { + struct timeval now; + uint64_t diff_usecs; + + gettimeofday(&now, NULL); + diff_usecs = ((now.tv_sec - real_time_ref_secs) * 1000000) + (now.tv_usec - real_time_ref_usecs); + mtime = diff_usecs * freq_mhz; + } else { + mtime += inc; + } for (size_t i = 0; i < procs.size(); i++) { procs[i]->state.mip &= ~MIP_MTIP; if (mtime >= mtimecmp[i]) diff --git a/riscv/devices.h b/riscv/devices.h index aa4c050..130be3c 100644 --- a/riscv/devices.h +++ b/riscv/devices.h @@ -63,7 +63,7 @@ class mem_t : public abstract_device_t { class clint_t : public abstract_device_t { public: - clint_t(std::vector<processor_t*>&); + clint_t(std::vector<processor_t*>&, uint64_t freq_mhz, 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; } @@ -73,6 +73,10 @@ class clint_t : public abstract_device_t { typedef uint64_t mtimecmp_t; typedef uint32_t msip_t; std::vector<processor_t*>& procs; + uint64_t freq_mhz; + bool real_time; + uint64_t real_time_ref_secs; + uint64_t real_time_ref_usecs; mtime_t mtime; std::vector<mtimecmp_t> mtimecmp; }; diff --git a/riscv/sim.cc b/riscv/sim.cc index 3d7cd88..96fd0b2 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -26,7 +26,8 @@ static void handle_signal(int sig) } sim_t::sim_t(const char* isa, const char* priv, const char* varch, - size_t nprocs, bool halted, reg_t initrd_start, reg_t initrd_end, + size_t nprocs, bool halted, bool real_time_clint, + reg_t initrd_start, reg_t initrd_end, reg_t start_pc, std::vector<std::pair<reg_t, mem_t*>> mems, std::vector<std::pair<reg_t, abstract_device_t*>> plugin_devices, const std::vector<std::string>& args, @@ -65,7 +66,7 @@ sim_t::sim_t(const char* isa, const char* priv, const char* varch, } } - clint.reset(new clint_t(procs)); + clint.reset(new clint_t(procs, CPU_HZ / INSNS_PER_RTC_TICK / 1000000, real_time_clint)); bus.add_device(CLINT_BASE, clint.get()); } diff --git a/riscv/sim.h b/riscv/sim.h index 44f2f92..a9d4923 100644 --- a/riscv/sim.h +++ b/riscv/sim.h @@ -22,7 +22,8 @@ class sim_t : public htif_t, public simif_t { public: sim_t(const char* isa, const char* priv, const char* varch, size_t _nprocs, - bool halted, reg_t initrd_start, reg_t initrd_end, + bool halted, bool real_time_clint, + reg_t initrd_start, reg_t initrd_end, reg_t start_pc, std::vector<std::pair<reg_t, mem_t*>> mems, std::vector<std::pair<reg_t, abstract_device_t*>> plugin_devices, const std::vector<std::string>& args, const std::vector<int> hartids, diff --git a/spike_main/spike.cc b/spike_main/spike.cc index f14ef87..1474a4c 100644 --- a/spike_main/spike.cc +++ b/spike_main/spike.cc @@ -51,6 +51,7 @@ static void help(int exit_code = 1) fprintf(stderr, " --dump-dts Print device tree string and exit\n"); fprintf(stderr, " --disable-dtb Don't write the device tree blob into memory\n"); fprintf(stderr, " --initrd=<path> Load kernel initrd into memory\n"); + fprintf(stderr, " --real-time-clint Increment clint time at real-time rate\n"); fprintf(stderr, " --dm-progsize=<words> Progsize for the debug module [default 2]\n"); fprintf(stderr, " --dm-sba=<bits> Debug bus master supports up to " "<bits> wide accesses [default 0]\n"); @@ -131,6 +132,7 @@ int main(int argc, char** argv) bool log = false; bool dump_dts = false; bool dtb_enabled = true; + bool real_time_clint = false; size_t nprocs = 1; size_t initrd_size; reg_t initrd_start = 0, initrd_end = 0; @@ -241,6 +243,7 @@ int main(int argc, char** argv) parser.option(0, "dump-dts", 0, [&](const char *s){dump_dts = true;}); parser.option(0, "disable-dtb", 0, [&](const char *s){dtb_enabled = false;}); parser.option(0, "initrd", 1, [&](const char* s){initrd = s;}); + parser.option(0, "real-time-clint", 0, [&](const char *s){real_time_clint = true;}); parser.option(0, "extlib", 1, [&](const char *s){ void *lib = dlopen(s, RTLD_NOW | RTLD_GLOBAL); if (lib == NULL) { @@ -286,7 +289,8 @@ int main(int argc, char** argv) } } - sim_t s(isa, priv, varch, nprocs, halted, initrd_start, initrd_end, start_pc, mems, plugin_devices, htif_args, + sim_t s(isa, priv, varch, nprocs, halted, real_time_clint, + initrd_start, initrd_end, start_pc, mems, plugin_devices, htif_args, std::move(hartids), dm_config); std::unique_ptr<remote_bitbang_t> remote_bitbang((remote_bitbang_t *) NULL); std::unique_ptr<jtag_dtm_t> jtag_dtm( |