Remove MTIME[CMP]; add RTC device
authorAndrew Waterman <waterman@cs.berkeley.edu>
Thu, 28 Apr 2016 22:01:09 +0000 (15:01 -0700)
committerAndrew Waterman <waterman@cs.berkeley.edu>
Thu, 28 Apr 2016 22:17:06 +0000 (15:17 -0700)
riscv/devices.cc
riscv/devices.h
riscv/encoding.h
riscv/processor.cc
riscv/processor.h
riscv/riscv.mk.in
riscv/rom.cc [new file with mode: 0644]
riscv/rtc.cc [new file with mode: 0644]
riscv/sim.cc
riscv/sim.h
spike_main/disasm.cc

index 25e39e0dc866326d31ae4a6329ea7e1207bd05be..c7a63b0044b87e5a9a5dbd3df2958abd95699cd5 100644 (file)
@@ -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<char> 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;
-}
index 558ecc7f59e0ddaf9890b5cdf096baa5fddfaa32..cb3b6d962cbe8c649c4e35560f1358c27839137f 100644 (file)
@@ -5,6 +5,8 @@
 #include <map>
 #include <vector>
 
+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<char> 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<char>& contents() { return data; }
  private:
   std::vector<char> data;
 };
 
+class rtc_t : public abstract_device_t {
+ public:
+  rtc_t(std::vector<processor_t*>&);
+  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<processor_t*>& procs;
+  std::vector<uint64_t> regs;
+  uint64_t time() { return regs[0]; }
+};
+
 #endif
index 83ee482d87dce3d971a950bd5b25b9ffedfcbccb..b219309f26707f618159ecfd68821f071a8ab3c3 100644 (file)
 #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
 #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
 #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
 #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
index 1719b9a0cf52faafd06dad870eef436450efbb7f..b932034e9a6415ba8079490565a78ccff2c9be1d 100644 (file)
@@ -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();
 }
index e342ab07170d4c09398180c9af174ba9b8e67104..5557e5afad3bceede99d44735142e9bd6793df6b 100644 (file)
@@ -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);
index 2dfe4ed8ac8d88c07919cbf1f0c9d8b6a3007153..8ffff82f9650f34f640f716614a1ae1031f9966e 100644 (file)
@@ -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 (file)
index 0000000..b852862
--- /dev/null
@@ -0,0 +1,19 @@
+#include "devices.h"
+
+rom_device_t::rom_device_t(std::vector<char> 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 (file)
index 0000000..22f318c
--- /dev/null
@@ -0,0 +1,34 @@
+#include "devices.h"
+#include "processor.h"
+
+rtc_t::rtc_t(std::vector<processor_t*>& 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*)&regs[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*)&regs[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;
+  }
+}
index f32de2bcc870acdbf19b75419dd664a41df47c8d..b45c51ee8f43d16af0955b1d46b322413bb2a6ce 100644 (file)
@@ -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<std::string>& 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());
 }
index 6745e75f8e9694db330a990d032ca4ff9151e7b9..89d3648ee4aa91651d5628d960ccd56ecfa66291 100644 (file)
@@ -44,13 +44,14 @@ private:
   mmu_t* debug_mmu;  // debug port into main memory
   std::vector<processor_t*> procs;
   std::unique_ptr<rom_device_t> config_string;
+  std::unique_ptr<rtc_t> 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;
index 0d239d74df6dbda9f48fa7c58c15257e0d0d061a..9eea77ed9715aa4b6079669ec0234437496de89d 100644 (file)
@@ -7,7 +7,6 @@
 #include <sstream>
 #include <stdlib.h>
 
-
 struct : public arg_t {
   std::string to_string(insn_t insn) const {
     return std::to_string((int)insn.i_imm()) + '(' + xpr_name[insn.rs1()] + ')';