riscv: replace rtc device with a real clint implementation
authorWesley W. Terpstra <wesley@sifive.com>
Wed, 22 Mar 2017 20:57:56 +0000 (13:57 -0700)
committerWesley W. Terpstra <wesley@sifive.com>
Wed, 22 Mar 2017 21:21:54 +0000 (14:21 -0700)
riscv/clint.cc [new file with mode: 0644]
riscv/devices.h
riscv/encoding.h
riscv/processor.h
riscv/riscv.mk.in
riscv/rtc.cc [deleted file]
riscv/sim.cc
riscv/sim.h

diff --git a/riscv/clint.cc b/riscv/clint.cc
new file mode 100644 (file)
index 0000000..08508b4
--- /dev/null
@@ -0,0 +1,72 @@
+#include "devices.h"
+#include "processor.h"
+
+clint_t::clint_t(std::vector<processor_t*>& procs)
+  : procs(procs), mtimecmp(procs.size())
+{
+}
+
+/* 0000 msip hart 0
+ * 0004 msip hart 1
+ * 4000 mtimecmp hart 0 lo
+ * 4004 mtimecmp hart 0 hi
+ * 4008 mtimecmp hart 1 lo
+ * 400c mtimecmp hart 1 hi
+ * bff8 mtime lo
+ * bffc mtime hi
+ */
+
+#define MSIP_BASE      0x0
+#define MTIMECMP_BASE  0x4000
+#define MTIME_BASE     0xbff8
+
+bool clint_t::load(reg_t addr, size_t len, uint8_t* bytes)
+{
+  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)
+      msip[i] = !!(procs[i]->state.mip & MIP_MSIP);
+    memcpy(bytes, (uint8_t*)&msip[0] + addr - MSIP_BASE, len);
+  } else if (addr >= MTIMECMP_BASE && addr + len <= MTIMECMP_BASE + procs.size()*sizeof(mtimecmp_t)) {
+    memcpy(bytes, (uint8_t*)&mtimecmp[0] + addr - MTIMECMP_BASE, len);
+  } else if (addr >= MTIME_BASE && addr + len <= MTIME_BASE + sizeof(mtime_t)) {
+    memcpy(bytes, (uint8_t*)&mtime + addr - MTIME_BASE, len);
+  } else {
+    return false;
+  }
+  return true;
+}
+
+bool clint_t::store(reg_t addr, size_t len, const uint8_t* bytes)
+{
+  if (addr >= MSIP_BASE && addr + len <= MSIP_BASE + procs.size()*sizeof(msip_t)) {
+    std::vector<msip_t> msip(procs.size());
+    std::vector<msip_t> mask(procs.size(), 0);
+    memcpy((uint8_t*)&msip[0] + addr - MSIP_BASE, bytes, len);
+    memset((uint8_t*)&mask[0] + addr - MSIP_BASE, 0xff, len);
+    for (size_t i = 0; i < procs.size(); ++i) {
+      if (!(mask[i] & 0xFF)) continue;
+      procs[i]->state.mip &= ~MIP_MSIP;
+      if (!!(msip[i] & 1))
+        procs[i]->state.mip |= MIP_MSIP;
+    }
+  } else if (addr >= MTIMECMP_BASE && addr + len <= MTIMECMP_BASE + procs.size()*sizeof(mtimecmp_t)) {
+    memcpy((uint8_t*)&mtimecmp[0] + addr - MTIMECMP_BASE, bytes, len);
+  } else if (addr >= MTIME_BASE && addr + len <= MTIME_BASE + sizeof(mtime_t)) {
+    memcpy((uint8_t*)&mtime + addr - MTIME_BASE, bytes, len);
+  } else {
+    return false;
+  }
+  increment(0);
+  return true;
+}
+
+void clint_t::increment(reg_t inc)
+{
+  mtime += inc;
+  for (size_t i = 0; i < procs.size(); i++) {
+    procs[i]->state.mip &= ~MIP_MTIP;
+    if (mtime >= mtimecmp[i])
+      procs[i]->state.mip |= MIP_MTIP;
+  }
+}
index cb3b6d962cbe8c649c4e35560f1358c27839137f..f3ecb67a3c7f3ac46c5385aee18bb175ea93395c 100644 (file)
@@ -34,17 +34,20 @@ class rom_device_t : public abstract_device_t {
   std::vector<char> data;
 };
 
-class rtc_t : public abstract_device_t {
+class clint_t : public abstract_device_t {
  public:
-  rtc_t(std::vector<processor_t*>&);
+  clint_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]); }
+  size_t size() { return CLINT_SIZE; }
   void increment(reg_t inc);
  private:
+  typedef uint64_t mtime_t;
+  typedef uint64_t mtimecmp_t;
+  typedef uint32_t msip_t;
   std::vector<processor_t*>& procs;
-  std::vector<uint64_t> regs;
-  uint64_t time() { return regs[0]; }
+  mtime_t mtime;
+  std::vector<mtimecmp_t> mtimecmp;
 };
 
 #endif
index ef68c2ffe20d37760d1d1da89dd4cbcfdc52db04..3923bffa818e08ddae19d3a89d73215587940be4 100644 (file)
 #define IRQ_HOST     13
 
 #define DEFAULT_RSTVEC     0x00001000
+#define CLINT_BASE         0x02000000
+#define CLINT_SIZE         0x000c0000
 #define EXT_IO_BASE        0x40000000
 #define DRAM_BASE          0x80000000
 
index c294e5794853d7f69c4a60b1af139252205a65c5..7e9e932f7b13a8c5cd4cb3275c3a697913c6f0f1 100644 (file)
@@ -306,7 +306,7 @@ private:
 
   friend class sim_t;
   friend class mmu_t;
-  friend class rtc_t;
+  friend class clint_t;
   friend class extension_t;
 
   void parse_isa_string(const char* isa);
index 17479dce558847a06d7e9fdb8cdc60ea21b55965..e9544162f756250c0c5b61493c3709c2a43eec2c 100644 (file)
@@ -44,7 +44,7 @@ riscv_srcs = \
        regnames.cc \
        devices.cc \
        rom.cc \
-       rtc.cc \
+       clint.cc \
        gdbserver.cc \
        debug_module.cc \
        $(riscv_gen_srcs) \
diff --git a/riscv/rtc.cc b/riscv/rtc.cc
deleted file mode 100644 (file)
index 22f318c..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#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 bdf55e275bfec0e937c9804fe49e92610b982cc8..e1a85408042284f20dbbdd9d8b273fe0544fdf43 100644 (file)
@@ -52,7 +52,9 @@ sim_t::sim_t(const char* isa, size_t nprocs, size_t mem_mb, bool halted,
     procs[i] = new processor_t(isa, this, i, halted);
   }
 
-  rtc.reset(new rtc_t(procs));
+  clint.reset(new clint_t(procs));
+  bus.add_device(CLINT_BASE, clint.get());
+
   make_dtb();
 }
 
@@ -107,7 +109,7 @@ void sim_t::step(size_t n)
       procs[current_proc]->yield_load_reservation();
       if (++current_proc == procs.size()) {
         current_proc = 0;
-        rtc->increment(INTERLEAVE / INSNS_PER_RTC_TICK);
+        clint->increment(INTERLEAVE / INSNS_PER_RTC_TICK);
       }
 
       host->switch_to();
@@ -236,13 +238,6 @@ static std::string dts_compile(const std::string& dts)
 
 void sim_t::make_dtb()
 {
-  reg_t rtc_addr = EXT_IO_BASE;
-  bus.add_device(rtc_addr, rtc.get());
-
-  const int align = 0x1000;
-  reg_t cpu_addr = rtc_addr + ((rtc->size() - 1) / align + 1) * align;
-  reg_t cpu_size = align;
-
   uint32_t reset_vec[] = {
     0x297 + DRAM_BASE - DEFAULT_RSTVEC, // auipc t0, DRAM_BASE
     0x597,                              // auipc a1, 0
@@ -293,14 +288,16 @@ void sim_t::make_dtb()
          "    #size-cells = <2>;\n"
          "    compatible = \"ucbbar,spike-bare-soc\";\n"
          "    ranges;\n"
-         "    clint@" << rtc_addr << " {\n"
+         "    clint@" << CLINT_BASE << " {\n"
          "      compatible = \"riscv,clint0\";\n"
          "      interrupts-extended = <" << std::dec;
   for (size_t i = 0; i < procs.size(); i++)
     s << "&CPU" << i << " 3 &CPU" << i << " 7 ";
+  reg_t clintbs = CLINT_BASE;
+  reg_t clintsz = CLINT_SIZE;
   s << std::hex << ">;\n"
-         "      reg = <0x" << (rtc_addr >> 32) << " 0x" << (rtc_addr & (uint32_t)-1) <<
-                     " 0x0 0x10000>;\n"
+         "      reg = <0x" << (clintbs >> 32) << " 0x" << (clintbs & (uint32_t)-1) <<
+                     " 0x" << (clintsz >> 32) << " 0x" << (clintsz & (uint32_t)-1) << ">;\n"
          "    };\n"
          "  };\n"
          "};\n";
@@ -309,7 +306,8 @@ void sim_t::make_dtb()
   std::string dtb = dts_compile(dts);
 
   rom.insert(rom.end(), dtb.begin(), dtb.end());
-  rom.resize((rom.size() / align + 1) * align);
+  const int align = 0x1000;
+  rom.resize((rom.size() + align - 1) / align * align);
 
   boot_rom.reset(new rom_device_t(rom));
   bus.add_device(DEFAULT_RSTVEC, boot_rom.get());
index 4111caf52083700f53d08d7aecd84aa51e470352..57bdf8ce8113275a20e78b786da8fa8758c59759 100644 (file)
@@ -40,7 +40,7 @@ private:
   std::vector<processor_t*> procs;
   std::string dts;
   std::unique_ptr<rom_device_t> boot_rom;
-  std::unique_ptr<rtc_t> rtc;
+  std::unique_ptr<clint_t> clint;
   bus_t bus;
   debug_module_t debug_module;