aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscv/clint.cc23
-rw-r--r--riscv/devices.h6
-rw-r--r--riscv/sim.cc5
-rw-r--r--riscv/sim.h3
-rw-r--r--spike_main/spike.cc6
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(