diff options
author | Andrew Waterman <andrew@sifive.com> | 2020-02-15 15:42:06 -0800 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2020-02-15 15:42:06 -0800 |
commit | f406783b136ee99db1b1f3da09176307818d14bd (patch) | |
tree | 034385e72f29c1b1a36c681d5fce60055d5eaf10 | |
parent | e5e64c0fa69993448d498735bfaef400aabd090b (diff) | |
parent | a8c83b8190f8ac72b04794c03e68cee873a28f3c (diff) | |
download | riscv-isa-sim-f406783b136ee99db1b1f3da09176307818d14bd.zip riscv-isa-sim-f406783b136ee99db1b1f3da09176307818d14bd.tar.gz riscv-isa-sim-f406783b136ee99db1b1f3da09176307818d14bd.tar.bz2 |
Merge branch 'avpatel-real_time_clint_v1'
-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..aee995b 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_hz, bool real_time) + : procs(procs), freq_hz(freq_hz), 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_hz / 1000000; + } 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..1bc9618 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_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; } @@ -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_hz; + 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..dd7b35d 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, 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( |