diff options
Diffstat (limited to 'riscv/clint.cc')
-rw-r--r-- | riscv/clint.cc | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/riscv/clint.cc b/riscv/clint.cc index 25e45fb..908ccb6 100644 --- a/riscv/clint.cc +++ b/riscv/clint.cc @@ -1,7 +1,10 @@ #include <sys/time.h> +#include <sstream> #include "devices.h" #include "processor.h" #include "simif.h" +#include "sim.h" +#include "dts.h" clint_t::clint_t(const simif_t* sim, uint64_t freq_hz, bool real_time) : sim(sim), freq_hz(freq_hz), real_time(real_time), mtime(0) @@ -112,3 +115,31 @@ void clint_t::tick(reg_t rtc_ticks) hart->state.mip->backdoor_write_with_mask(MIP_MTIP, mtime >= mtimecmp[hart_id] ? MIP_MTIP : 0); } } + +clint_t* clint_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base) { + if (fdt_parse_clint(fdt, base, "riscv,clint0") == 0) + return new clint_t(sim, + sim->CPU_HZ / sim->INSNS_PER_RTC_TICK, + sim->get_cfg().real_time_clint()); + else + return nullptr; +} + +std::string clint_generate_dts(const sim_t* sim) { + std::stringstream s; + s << std::hex + << " clint@" << CLINT_BASE << " {\n" + " compatible = \"riscv,clint0\";\n" + " interrupts-extended = <" << std::dec; + for (size_t i = 0; i < sim->get_cfg().nprocs(); i++) + s << "&CPU" << i << "_intc 3 &CPU" << i << "_intc 7 "; + reg_t clintbs = CLINT_BASE; + reg_t clintsz = CLINT_SIZE; + s << std::hex << ">;\n" + " reg = <0x" << (clintbs >> 32) << " 0x" << (clintbs & (uint32_t)-1) << + " 0x" << (clintsz >> 32) << " 0x" << (clintsz & (uint32_t)-1) << ">;\n" + " };\n"; + return s.str(); +} + +REGISTER_DEVICE(clint, clint_parse_from_fdt, clint_generate_dts) |