Add --disable-dtb option to suppress writing the DTB to memory
[riscv-isa-sim.git] / riscv / processor.cc
index 52f69c1d460778519bf34f8020c4c6b73b9dd3cb..4a7d0ec6147a8c58be756faf914b4b4ab6732fbe 100644 (file)
@@ -24,12 +24,16 @@ processor_t::processor_t(const char* isa, simif_t* sim, uint32_t id,
   : debug(false), halt_request(false), sim(sim), ext(NULL), id(id),
   halt_on_reset(halt_on_reset), last_pc(1), executions(1)
 {
-  disassembler = new disassembler_t(max_xlen);
   parse_isa_string(isa);
   register_base_instructions();
 
   mmu = new mmu_t(sim, this);
 
+  disassembler = new disassembler_t(max_xlen);
+  if (ext)
+    for (auto disasm_insn : ext->get_disasms())
+      disassembler->add_insn(disasm_insn);
+
   reset();
 }
 
@@ -326,7 +330,8 @@ int processor_t::paddr_bits()
 void processor_t::set_csr(int which, reg_t val)
 {
   val = zext_xlen(val);
-  reg_t delegable_ints = MIP_SSIP | MIP_STIP | MIP_SEIP | (1 << IRQ_COP);
+  reg_t delegable_ints = MIP_SSIP | MIP_STIP | MIP_SEIP
+                       | ((ext != NULL) << IRQ_COP);
   reg_t all_ints = delegable_ints | MIP_MSIP | MIP_MTIP;
   switch (which)
   {
@@ -403,10 +408,16 @@ void processor_t::set_csr(int which, reg_t val)
         state.minstret = (state.minstret >> 32 << 32) | (val & 0xffffffffU);
       else
         state.minstret = val;
+      // The ISA mandates that if an instruction writes instret, the write
+      // takes precedence over the increment to instret.  However, Spike
+      // unconditionally increments instret after executing an instruction.
+      // Correct for this artifact by decrementing instret here.
+      state.minstret--;
       break;
     case CSR_MINSTRETH:
     case CSR_MCYCLEH:
       state.minstret = (val << 32) | (state.minstret << 32 >> 32);
+      state.minstret--; // See comment above.
       break;
     case CSR_SCOUNTEREN:
       state.scounteren = val;
@@ -584,7 +595,7 @@ reg_t processor_t::get_csr(int which)
     case CSR_MCOUNTEREN: return state.mcounteren;
     case CSR_SSTATUS: {
       reg_t mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_SPP | SSTATUS_FS
-                 | SSTATUS_XS | SSTATUS_SUM | SSTATUS_UXL;
+                 | SSTATUS_XS | SSTATUS_SUM | SSTATUS_MXR | SSTATUS_UXL;
       reg_t sstatus = state.mstatus & mask;
       if ((sstatus & SSTATUS_FS) == SSTATUS_FS ||
           (sstatus & SSTATUS_XS) == SSTATUS_XS)