From a9c5b05eca6a46a0c8722b26b741fc7f1de22405 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 28 Apr 2016 15:01:09 -0700 Subject: [PATCH] Remove MTIME[CMP]; add RTC device --- riscv/devices.cc | 18 ------------------ riscv/devices.h | 16 ++++++++++++++++ riscv/encoding.h | 8 -------- riscv/processor.cc | 17 +---------------- riscv/processor.h | 2 +- riscv/riscv.mk.in | 2 ++ riscv/rom.cc | 19 +++++++++++++++++++ riscv/rtc.cc | 34 ++++++++++++++++++++++++++++++++++ riscv/sim.cc | 15 ++++++++++++--- riscv/sim.h | 3 ++- spike_main/disasm.cc | 1 - 11 files changed, 87 insertions(+), 48 deletions(-) create mode 100644 riscv/rom.cc create mode 100644 riscv/rtc.cc diff --git a/riscv/devices.cc b/riscv/devices.cc index 25e39e0..c7a63b0 100644 --- a/riscv/devices.cc +++ b/riscv/devices.cc @@ -20,21 +20,3 @@ bool bus_t::store(reg_t addr, size_t len, const uint8_t* bytes) return false; return it->second->store(addr - -it->first, len, bytes); } - -rom_device_t::rom_device_t(std::vector data) - : data(data) -{ -} - -bool rom_device_t::load(reg_t addr, size_t len, uint8_t* bytes) -{ - if (addr + len > data.size()) - return false; - memcpy(bytes, &data[addr], len); - return true; -} - -bool rom_device_t::store(reg_t addr, size_t len, const uint8_t* bytes) -{ - return false; -} diff --git a/riscv/devices.h b/riscv/devices.h index 558ecc7..cb3b6d9 100644 --- a/riscv/devices.h +++ b/riscv/devices.h @@ -5,6 +5,8 @@ #include #include +class processor_t; + class abstract_device_t { public: virtual bool load(reg_t addr, size_t len, uint8_t* bytes) = 0; @@ -27,8 +29,22 @@ class rom_device_t : public abstract_device_t { rom_device_t(std::vector data); bool load(reg_t addr, size_t len, uint8_t* bytes); bool store(reg_t addr, size_t len, const uint8_t* bytes); + const std::vector& contents() { return data; } private: std::vector data; }; +class rtc_t : public abstract_device_t { + public: + rtc_t(std::vector&); + 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 regs.size() * sizeof(regs[0]); } + void increment(reg_t inc); + private: + std::vector& procs; + std::vector regs; + uint64_t time() { return regs[0]; } +}; + #endif diff --git a/riscv/encoding.h b/riscv/encoding.h index 83ee482..b219309 100644 --- a/riscv/encoding.h +++ b/riscv/encoding.h @@ -653,7 +653,6 @@ #define CSR_MIDELEG 0x303 #define CSR_MIE 0x304 #define CSR_MTVEC 0x305 -#define CSR_MTIMECMP 0x321 #define CSR_MSCRATCH 0x340 #define CSR_MEPC 0x341 #define CSR_MCAUSE 0x342 @@ -669,7 +668,6 @@ #define CSR_MSTIME_DELTA 0x705 #define CSR_MSINSTRET_DELTA 0x706 #define CSR_MCYCLE 0xf00 -#define CSR_MTIME 0xf01 #define CSR_MINSTRET 0xf02 #define CSR_MISA 0xf10 #define CSR_MVENDORID 0xf11 @@ -683,7 +681,6 @@ #define CSR_CYCLEH 0xc80 #define CSR_TIMEH 0xc81 #define CSR_INSTRETH 0xc82 -#define CSR_MTIMECMPH 0x361 #define CSR_MUCYCLE_DELTAH 0x780 #define CSR_MUTIME_DELTAH 0x781 #define CSR_MUINSTRET_DELTAH 0x782 @@ -691,7 +688,6 @@ #define CSR_MSTIME_DELTAH 0x785 #define CSR_MSINSTRET_DELTAH 0x786 #define CSR_MCYCLEH 0xf80 -#define CSR_MTIMEH 0xf81 #define CSR_MINSTRETH 0xf82 #define CAUSE_MISALIGNED_FETCH 0x0 #define CAUSE_FAULT_FETCH 0x1 @@ -961,7 +957,6 @@ DECLARE_CSR(medeleg, CSR_MEDELEG) DECLARE_CSR(mideleg, CSR_MIDELEG) DECLARE_CSR(mie, CSR_MIE) DECLARE_CSR(mtvec, CSR_MTVEC) -DECLARE_CSR(mtimecmp, CSR_MTIMECMP) DECLARE_CSR(mscratch, CSR_MSCRATCH) DECLARE_CSR(mepc, CSR_MEPC) DECLARE_CSR(mcause, CSR_MCAUSE) @@ -977,7 +972,6 @@ DECLARE_CSR(mscycle_delta, CSR_MSCYCLE_DELTA) DECLARE_CSR(mstime_delta, CSR_MSTIME_DELTA) DECLARE_CSR(msinstret_delta, CSR_MSINSTRET_DELTA) DECLARE_CSR(mcycle, CSR_MCYCLE) -DECLARE_CSR(mtime, CSR_MTIME) DECLARE_CSR(minstret, CSR_MINSTRET) DECLARE_CSR(misa, CSR_MISA) DECLARE_CSR(mvendorid, CSR_MVENDORID) @@ -991,7 +985,6 @@ DECLARE_CSR(mreset, CSR_MRESET) DECLARE_CSR(cycleh, CSR_CYCLEH) DECLARE_CSR(timeh, CSR_TIMEH) DECLARE_CSR(instreth, CSR_INSTRETH) -DECLARE_CSR(mtimecmph, CSR_MTIMECMPH) DECLARE_CSR(mucycle_deltah, CSR_MUCYCLE_DELTAH) DECLARE_CSR(mutime_deltah, CSR_MUTIME_DELTAH) DECLARE_CSR(muinstret_deltah, CSR_MUINSTRET_DELTAH) @@ -999,7 +992,6 @@ DECLARE_CSR(mscycle_deltah, CSR_MSCYCLE_DELTAH) DECLARE_CSR(mstime_deltah, CSR_MSTIME_DELTAH) DECLARE_CSR(msinstret_deltah, CSR_MSINSTRET_DELTAH) DECLARE_CSR(mcycleh, CSR_MCYCLEH) -DECLARE_CSR(mtimeh, CSR_MTIMEH) DECLARE_CSR(minstreth, CSR_MINSTRETH) #endif #ifdef DECLARE_CAUSE diff --git a/riscv/processor.cc b/riscv/processor.cc index 1719b9a..b932034 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -165,8 +165,6 @@ static int ctz(reg_t val) void processor_t::take_interrupt() { - check_timer(); - reg_t pending_interrupts = state.mip & state.mie; reg_t mie = get_field(state.mstatus, MSTATUS_MIE); @@ -181,12 +179,6 @@ void processor_t::take_interrupt() raise_interrupt(ctz(enabled_interrupts)); } -void processor_t::check_timer() -{ - if (sim->rtc >= state.mtimecmp) - state.mip |= MIP_MTIP; -} - static bool validate_priv(reg_t priv) { return priv == PRV_U || priv == PRV_S || priv == PRV_M; @@ -355,10 +347,6 @@ void processor_t::set_csr(int which, reg_t val) case CSR_MSCRATCH: state.mscratch = val; break; case CSR_MCAUSE: state.mcause = val; break; case CSR_MBADADDR: state.mbadaddr = val; break; - case CSR_MTIMECMP: - state.mip &= ~MIP_MTIP; - state.mtimecmp = val; - break; case CSR_MTOHOST: if (state.tohost == 0) state.tohost = val; @@ -415,10 +403,8 @@ reg_t processor_t::get_csr(int which) case CSR_MSCYCLE_DELTAH: if (xlen > 32) break; else return 0; case CSR_MSTIME_DELTAH: if (xlen > 32) break; else return 0; case CSR_MSINSTRET_DELTAH: if (xlen > 32) break; else return 0; - case CSR_MTIME: return sim->rtc; case CSR_MCYCLE: return state.minstret; case CSR_MINSTRET: return state.minstret; - case CSR_MTIMEH: if (xlen > 32) break; else return sim->rtc >> 32; case CSR_MCYCLEH: if (xlen > 32) break; else return state.minstret >> 32; case CSR_MINSTRETH: if (xlen > 32) break; else return state.minstret >> 32; case CSR_SSTATUS: { @@ -450,7 +436,6 @@ reg_t processor_t::get_csr(int which) case CSR_MSCRATCH: return state.mscratch; case CSR_MCAUSE: return state.mcause; case CSR_MBADADDR: return state.mbadaddr; - case CSR_MTIMECMP: return state.mtimecmp; case CSR_MISA: return isa; case CSR_MARCHID: return 0; case CSR_MIMPID: return 0; @@ -465,7 +450,7 @@ reg_t processor_t::get_csr(int which) case CSR_MFROMHOST: sim->get_htif()->tick(); // not necessary, but faster return state.fromhost; - case CSR_MCFGADDR: return sim->memsz; + case CSR_MCFGADDR: return sim->config_string_addr; } throw trap_illegal_instruction(); } diff --git a/riscv/processor.h b/riscv/processor.h index e342ab0..5557e5a 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -45,7 +45,6 @@ struct state_t reg_t mstatus; reg_t mepc; reg_t mbadaddr; - reg_t mtimecmp; reg_t mscratch; reg_t mcause; reg_t minstret; @@ -136,6 +135,7 @@ private: friend class sim_t; friend class mmu_t; + friend class rtc_t; friend class extension_t; void parse_isa_string(const char* isa); diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in index 2dfe4ed..8ffff82 100644 --- a/riscv/riscv.mk.in +++ b/riscv/riscv.mk.in @@ -41,6 +41,8 @@ riscv_srcs = \ rocc.cc \ regnames.cc \ devices.cc \ + rom.cc \ + rtc.cc \ $(riscv_gen_srcs) \ riscv_test_srcs = diff --git a/riscv/rom.cc b/riscv/rom.cc new file mode 100644 index 0000000..b852862 --- /dev/null +++ b/riscv/rom.cc @@ -0,0 +1,19 @@ +#include "devices.h" + +rom_device_t::rom_device_t(std::vector data) + : data(data) +{ +} + +bool rom_device_t::load(reg_t addr, size_t len, uint8_t* bytes) +{ + if (addr + len > data.size()) + return false; + memcpy(bytes, &data[addr], len); + return true; +} + +bool rom_device_t::store(reg_t addr, size_t len, const uint8_t* bytes) +{ + return false; +} diff --git a/riscv/rtc.cc b/riscv/rtc.cc new file mode 100644 index 0000000..22f318c --- /dev/null +++ b/riscv/rtc.cc @@ -0,0 +1,34 @@ +#include "devices.h" +#include "processor.h" + +rtc_t::rtc_t(std::vector& procs) + : procs(procs), regs(1 + procs.size()) +{ +} + +bool rtc_t::load(reg_t addr, size_t len, uint8_t* bytes) +{ + if (addr + len > size()) + return false; + memcpy(bytes, (uint8_t*)®s[0] + addr, len); + return true; +} + +bool rtc_t::store(reg_t addr, size_t len, const uint8_t* bytes) +{ + if (addr + len > size() || addr < 8) + return false; + memcpy((uint8_t*)®s[0] + addr, bytes, len); + increment(0); + return true; +} + +void rtc_t::increment(reg_t inc) +{ + regs[0] += inc; + for (size_t i = 0; i < procs.size(); i++) { + procs[i]->state.mip &= ~MIP_MTIP; + if (regs[0] >= regs[1+i]) + procs[i]->state.mip |= MIP_MTIP; + } +} diff --git a/riscv/sim.cc b/riscv/sim.cc index f32de2b..b45c51e 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -22,7 +22,7 @@ static void handle_signal(int sig) sim_t::sim_t(const char* isa, size_t nprocs, size_t mem_mb, const std::vector& args) : htif(new htif_isasim_t(this, args)), procs(std::max(nprocs, size_t(1))), - rtc(0), current_step(0), current_proc(0), debug(false) + current_step(0), current_proc(0), debug(false) { signal(SIGINT, &handle_signal); // allocate target machine's memory, shrinking it as necessary @@ -45,6 +45,7 @@ sim_t::sim_t(const char* isa, size_t nprocs, size_t mem_mb, for (size_t i = 0; i < procs.size(); i++) procs[i] = new processor_t(isa, this, i); + rtc.reset(new rtc_t(procs)); make_config_string(); } @@ -94,7 +95,7 @@ void sim_t::step(size_t n) procs[current_proc]->yield_load_reservation(); if (++current_proc == procs.size()) { current_proc = 0; - rtc += INTERLEAVE / INSNS_PER_RTC_TICK; + rtc->increment(INTERLEAVE / INSNS_PER_RTC_TICK); } htif->tick(); @@ -161,12 +162,19 @@ void sim_t::make_config_string() size_t device_tree_addr = memsz; size_t cpu_addr = memsz + csr_size; + reg_t rtc_addr = memsz; + bus.add_device(rtc_addr, rtc.get()); + config_string_addr = rtc_addr + rtc->size(); + std::stringstream s; s << std::hex << "platform {\n" " vendor ucb;\n" " arch spike;\n" "};\n" + "rtc {\n" + " addr 0x" << rtc_addr << ";\n" + "};\n" "ram {\n" " 0 {\n" " addr 0;\n" @@ -180,6 +188,7 @@ void sim_t::make_config_string() " " << "0 {\n" << // hart 0 on core i " isa " << procs[i]->isa_string << ";\n" " addr 0x" << cpu_addr << ";\n" + " timecmp 0x" << (rtc_addr + 8*(1+i)) << ";\n" " };\n" " };\n"; bus.add_device(cpu_addr, procs[i]); @@ -192,5 +201,5 @@ void sim_t::make_config_string() vec.push_back(0); assert(vec.size() <= csr_size); config_string.reset(new rom_device_t(vec)); - bus.add_device(memsz, config_string.get()); + bus.add_device(config_string_addr, config_string.get()); } diff --git a/riscv/sim.h b/riscv/sim.h index 6745e75..89d3648 100644 --- a/riscv/sim.h +++ b/riscv/sim.h @@ -44,13 +44,14 @@ private: mmu_t* debug_mmu; // debug port into main memory std::vector procs; std::unique_ptr config_string; + std::unique_ptr rtc; + reg_t config_string_addr; bus_t bus; processor_t* get_core(const std::string& i); void step(size_t n); // step through simulation static const size_t INTERLEAVE = 5000; static const size_t INSNS_PER_RTC_TICK = 100; // 10 MHz clock for 1 BIPS core - reg_t rtc; size_t current_step; size_t current_proc; bool debug; diff --git a/spike_main/disasm.cc b/spike_main/disasm.cc index 0d239d7..9eea77e 100644 --- a/spike_main/disasm.cc +++ b/spike_main/disasm.cc @@ -7,7 +7,6 @@ #include #include - struct : public arg_t { std::string to_string(insn_t insn) const { return std::to_string((int)insn.i_imm()) + '(' + xpr_name[insn.rs1()] + ')'; -- 2.30.2