Narrow the interface used by the processors and memory to the top-level simulator...
authorPrashanth Mundkur <prashanth.mundkur@gmail.com>
Tue, 20 Feb 2018 23:16:53 +0000 (15:16 -0800)
committerAndrew Waterman <aswaterman@gmail.com>
Tue, 6 Mar 2018 18:07:03 +0000 (12:07 -0600)
This allows the implementation of an alternative top-level simulator class.

riscv/execute.cc
riscv/interactive.cc
riscv/mmu.cc
riscv/mmu.h
riscv/processor.cc
riscv/processor.h
riscv/sim.cc
riscv/sim.h

index c5cafc2ee5ead5df9b35f2156540f288167a3ec5..f8f122ad2a33a758b60cbe0c69bf0a7504f9d3c6 100644 (file)
@@ -2,7 +2,6 @@
 
 #include "processor.h"
 #include "mmu.h"
-#include "sim.h"
 #include <cassert>
 
 
index dbcd22455d5fe6fdb75388946df176d7227ca6df..b645c29e1c80a81b69a2bfea624deae41bd2eb40 100644 (file)
@@ -168,7 +168,7 @@ reg_t sim_t::get_pc(const std::vector<std::string>& args)
     throw trap_interactive();
 
   processor_t *p = get_core(args[0]);
-  return p->state.pc;
+  return p->get_state()->pc;
 }
 
 void sim_t::interactive_pc(const std::string& cmd, const std::vector<std::string>& args)
@@ -198,7 +198,7 @@ reg_t sim_t::get_reg(const std::vector<std::string>& args)
   if (r >= NXPR)
     throw trap_interactive();
 
-  return p->state.XPR[r];
+  return p->get_state()->XPR[r];
 }
 
 freg_t sim_t::get_freg(const std::vector<std::string>& args)
@@ -213,7 +213,7 @@ freg_t sim_t::get_freg(const std::vector<std::string>& args)
   if (r >= NFPR)
     throw trap_interactive();
 
-  return p->state.FPR[r];
+  return p->get_state()->FPR[r];
 }
 
 void sim_t::interactive_reg(const std::string& cmd, const std::vector<std::string>& args)
@@ -223,7 +223,7 @@ void sim_t::interactive_reg(const std::string& cmd, const std::vector<std::strin
     processor_t *p = get_core(args[0]);
 
     for (int r = 0; r < NXPR; ++r) {
-      fprintf(stderr, "%-4s: 0x%016" PRIx64 "  ", xpr_name[r], p->state.XPR[r]);
+      fprintf(stderr, "%-4s: 0x%016" PRIx64 "  ", xpr_name[r], p->get_state()->XPR[r]);
       if ((r + 1) % 4 == 0)
         fprintf(stderr, "\n");
     }
index 5f054db64239214a3bd14b7ea238dc229accc839..eca8a8339968ef6880cba51dd08272b85a2e72a0 100644 (file)
@@ -4,7 +4,7 @@
 #include "sim.h"
 #include "processor.h"
 
-mmu_t::mmu_t(sim_t* sim, processor_t* proc)
+mmu_t::mmu_t(simif_t* sim, processor_t* proc)
  : sim(sim), proc(proc),
   check_triggers_fetch(false),
   check_triggers_load(false),
index d275ab2baa2e412319c0a6ada72f41b932058e14..f0bc19d1f546b47a999e63b61d46654da97d86a8 100644 (file)
@@ -53,7 +53,7 @@ class trigger_matched_t
 class mmu_t
 {
 public:
-  mmu_t(sim_t* sim, processor_t* proc);
+  mmu_t(simif_t* sim, processor_t* proc);
   ~mmu_t();
 
   inline reg_t misaligned_load(reg_t addr, size_t size)
@@ -240,7 +240,7 @@ public:
   void register_memtracer(memtracer_t*);
 
 private:
-  sim_t* sim;
+  simif_t* sim;
   processor_t* proc;
   memtracer_list_t tracer;
   uint16_t fetch_temp;
index 943951b322def34cc8bd079d2ec74e704a419b13..ce040443977a61faecf7d243dcbedf685574f71c 100644 (file)
@@ -19,7 +19,7 @@
 #undef STATE
 #define STATE state
 
-processor_t::processor_t(const char* isa, sim_t* sim, uint32_t id,
+processor_t::processor_t(const char* isa, simif_t* sim, uint32_t id,
         bool halt_on_reset)
   : debug(false), halt_request(false), sim(sim), ext(NULL), id(id),
   halt_on_reset(halt_on_reset), last_pc(1), executions(1)
index 3998ce5a49fa34af20f6963c2192d11db4f62794..51fe8d2c8eb81a19be09c4674327c9df48d55e80 100644 (file)
@@ -14,7 +14,7 @@
 class processor_t;
 class mmu_t;
 typedef reg_t (*insn_func_t)(processor_t*, insn_t, reg_t);
-class sim_t;
+class simif_t;
 class trap_t;
 class extension_t;
 class disassembler_t;
@@ -163,7 +163,7 @@ static int cto(reg_t val)
 class processor_t : public abstract_device_t
 {
 public:
-  processor_t(const char* isa, sim_t* sim, uint32_t id, bool halt_on_reset=false);
+  processor_t(const char* isa, simif_t* sim, uint32_t id, bool halt_on_reset=false);
   ~processor_t();
 
   void set_debug(bool value);
@@ -175,6 +175,8 @@ public:
   mmu_t* get_mmu() { return mmu; }
   state_t* get_state() { return &state; }
   unsigned get_xlen() { return xlen; }
+  unsigned get_max_xlen() { return max_xlen; }
+  std::string get_isa_string() { return isa_string; }
   unsigned get_flen() {
     return supports_extension('Q') ? 128 :
            supports_extension('D') ? 64 :
@@ -292,7 +294,7 @@ public:
   void trigger_updated();
 
 private:
-  sim_t* sim;
+  simif_t* sim;
   mmu_t* mmu; // main memory is always accessed via the mmu
   extension_t* ext;
   disassembler_t* disassembler;
@@ -320,7 +322,6 @@ private:
 
   void enter_debug_mode(uint8_t cause);
 
-  friend class sim_t;
   friend class mmu_t;
   friend class clint_t;
   friend class extension_t;
index 009bb98845d3d9723132abe9a4e839169ae107cf..10c1898d993152b2ac7661f25cd010610ddc9eef 100644 (file)
@@ -247,7 +247,7 @@ void sim_t::make_dtb()
     0x297,                                      // auipc  t0,0x0
     0x28593 + (reset_vec_size * 4 << 20),       // addi   a1, t0, &dtb
     0xf1402573,                                 // csrr   a0, mhartid
-    get_core(0)->xlen == 32 ?
+    get_core(0)->get_xlen() == 32 ?
       0x0182a283u :                             // lw     t0,24(t0)
       0x0182b283u,                              // ld     t0,24(t0)
     0x28067,                                    // jr     t0
@@ -277,8 +277,8 @@ void sim_t::make_dtb()
          "      reg = <" << i << ">;\n"
          "      status = \"okay\";\n"
          "      compatible = \"riscv\";\n"
-         "      riscv,isa = \"" << procs[i]->isa_string << "\";\n"
-         "      mmu-type = \"riscv," << (procs[i]->max_xlen <= 32 ? "sv32" : "sv48") << "\";\n"
+         "      riscv,isa = \"" << procs[i]->get_isa_string() << "\";\n"
+         "      mmu-type = \"riscv," << (procs[i]->get_max_xlen() <= 32 ? "sv32" : "sv48") << "\";\n"
          "      clock-frequency = <" << CPU_HZ << ">;\n"
          "      CPU" << i << "_intc: interrupt-controller {\n"
          "        #interrupt-cells = <1>;\n"
index 47f3a452077e650fa2ea868b23800b1a9ba568cf..638206e11b329249e04f6b8c37ba0dee1280229b 100644 (file)
 class mmu_t;
 class remote_bitbang_t;
 
+// this is the interface to the simulator used by the processors and memory
+class simif_t
+{
+public:
+  // should return NULL for MMIO addresses
+  virtual char* addr_to_mem(reg_t addr) = 0;
+  // used for MMIO addresses
+  virtual bool mmio_load(reg_t addr, size_t len, uint8_t* bytes) = 0;
+  virtual bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes) = 0;
+};
+
 // this class encapsulates the processors and memory in a RISC-V machine.
-class sim_t : public htif_t
+class sim_t : public htif_t, public simif_t
 {
 public:
   sim_t(const char* isa, size_t _nprocs,  bool halted, reg_t start_pc,