New machine-mode timer facility
authorAndrew Waterman <waterman@cs.berkeley.edu>
Sun, 5 Jul 2015 23:47:20 +0000 (16:47 -0700)
committerAndrew Waterman <waterman@cs.berkeley.edu>
Sun, 5 Jul 2015 23:47:57 +0000 (16:47 -0700)
riscv/encoding.h
riscv/processor.cc
riscv/processor.h

index a95f4632fcdb008e282ba98542f1fba92c5ed63f..f9f4bfbd05b030b76cb06209d4c002eb65ca2436 100644 (file)
 #define CSR_SSTATUS 0x100
 #define CSR_STVEC 0x101
 #define CSR_SIE 0x104
-#define CSR_STIMECMP 0x121
 #define CSR_SSCRATCH 0x140
 #define CSR_SEPC 0x141
 #define CSR_SIP 0x144
 #define CSR_INSTRETHW 0x982
 #define CSR_STIMEH 0xd81
 #define CSR_STIMEHW 0xa81
+#define CSR_MTIMECMPH 0x361
 #define CSR_MTIMEH 0x741
 #define CAUSE_MISALIGNED_FETCH 0x0
 #define CAUSE_FAULT_FETCH 0x1
@@ -840,7 +840,6 @@ DECLARE_CSR(uarch15, CSR_UARCH15)
 DECLARE_CSR(sstatus, CSR_SSTATUS)
 DECLARE_CSR(stvec, CSR_STVEC)
 DECLARE_CSR(sie, CSR_SIE)
-DECLARE_CSR(stimecmp, CSR_STIMECMP)
 DECLARE_CSR(sscratch, CSR_SSCRATCH)
 DECLARE_CSR(sepc, CSR_SEPC)
 DECLARE_CSR(sip, CSR_SIP)
@@ -879,6 +878,7 @@ DECLARE_CSR(timehw, CSR_TIMEHW)
 DECLARE_CSR(instrethw, CSR_INSTRETHW)
 DECLARE_CSR(stimeh, CSR_STIMEH)
 DECLARE_CSR(stimehw, CSR_STIMEHW)
+DECLARE_CSR(mtimecmph, CSR_MTIMECMPH)
 DECLARE_CSR(mtimeh, CSR_MTIMEH)
 #endif
 #ifdef DECLARE_CAUSE
@@ -908,7 +908,6 @@ DECLARE_CAUSE("uarch15", CAUSE_UARCH15)
 DECLARE_CAUSE("sstatus", CAUSE_SSTATUS)
 DECLARE_CAUSE("stvec", CAUSE_STVEC)
 DECLARE_CAUSE("sie", CAUSE_SIE)
-DECLARE_CAUSE("stimecmp", CAUSE_STIMECMP)
 DECLARE_CAUSE("sscratch", CAUSE_SSCRATCH)
 DECLARE_CAUSE("sepc", CAUSE_SEPC)
 DECLARE_CAUSE("sip", CAUSE_SIP)
@@ -947,5 +946,6 @@ DECLARE_CAUSE("timehw", CAUSE_TIMEHW)
 DECLARE_CAUSE("instrethw", CAUSE_INSTRETHW)
 DECLARE_CAUSE("stimeh", CAUSE_STIMEH)
 DECLARE_CAUSE("stimehw", CAUSE_STIMEHW)
+DECLARE_CAUSE("mtimecmph", CAUSE_MTIMECMPH)
 DECLARE_CAUSE("mtimeh", CAUSE_MTIMEH)
 #endif
index cf6790a86f9eabbaa1ac92b3336aded873ccfc98..69a63f0fde3f16ae8f81472c6c03b2bfc0cb1442 100644 (file)
@@ -151,6 +151,9 @@ void processor_t::take_interrupt()
     if (interrupts & MIP_MSIP)
       raise_interrupt(IRQ_SOFT);
 
+    if (interrupts & MIP_MTIP)
+      raise_interrupt(IRQ_TIMER);
+
     if (state.fromhost != 0)
       raise_interrupt(IRQ_HOST);
   }
@@ -204,11 +207,8 @@ static reg_t execute_insn(processor_t* p, reg_t pc, insn_fetch_t fetch)
 
 void processor_t::check_timer()
 {
-  // this assumes the rtc doesn't change asynchronously during step(),
-  if (state.stimecmp >= (uint32_t)state.prev_rtc
-      && state.stimecmp < (uint32_t)sim->rtc)
-    state.mip |= MIP_STIP;
-  state.prev_rtc = sim->rtc;
+  if (sim->rtc >= state.mtimecmp)
+    state.mip |= MIP_MTIP;
 }
 
 void processor_t::step(size_t n)
@@ -427,12 +427,12 @@ void processor_t::set_csr(int which, reg_t val)
       break;
     }
     case CSR_MIP: {
-      reg_t mask = MIP_SSIP | MIP_MSIP;
+      reg_t mask = MIP_SSIP | MIP_MSIP | MIP_STIP;
       state.mip = (state.mip & ~mask) | (val & mask);
       break;
     }
     case CSR_MIE: {
-      reg_t mask = MIP_SSIP | MIP_MSIP | MIP_STIP;
+      reg_t mask = MIP_SSIP | MIP_MSIP | MIP_STIP | MIP_MTIP;
       state.mie = (state.mie & ~mask) | (val & mask);
       break;
     }
@@ -458,16 +458,16 @@ void processor_t::set_csr(int which, reg_t val)
     }
     case CSR_SEPC: state.sepc = val; break;
     case CSR_STVEC: state.stvec = val & ~3; break;
-    case CSR_STIMECMP:
-      state.mip &= ~MIP_STIP;
-      state.stimecmp = val;
-      break;
     case CSR_SPTBR: state.sptbr = zext_xlen(val & -PGSIZE); break;
     case CSR_SSCRATCH: state.sscratch = val; break;
     case CSR_MEPC: state.mepc = val; break;
     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_SEND_IPI: sim->send_ipi(val); break;
     case CSR_MTOHOST:
       if (state.tohost == 0)
@@ -541,7 +541,6 @@ reg_t processor_t::get_csr(int which)
     case CSR_SEPC: return state.sepc;
     case CSR_SBADADDR: return state.sbadaddr;
     case CSR_STVEC: return state.stvec;
-    case CSR_STIMECMP: return state.stimecmp;
     case CSR_SCAUSE:
       if (max_xlen > xlen)
         return state.scause | ((state.scause >> (max_xlen-1)) << (xlen-1));
@@ -556,6 +555,7 @@ 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_MCPUID: return cpuid;
     case CSR_MIMPID: return IMPL_ROCKET;
     case CSR_MHARTID: return id;
index 134c0a1696648a923a5bdce4c90d124bee79b554..6af78877f785785bc009aa9d6269ccf86e3a0c62 100644 (file)
@@ -43,6 +43,7 @@ struct state_t
   reg_t mstatus;
   reg_t mepc;
   reg_t mbadaddr;
+  reg_t mtimecmp;
   reg_t mscratch;
   reg_t mcause;
   reg_t minstret;
@@ -58,8 +59,6 @@ struct state_t
   reg_t suinstret_delta;
   reg_t tohost;
   reg_t fromhost;
-  reg_t prev_rtc;
-  uint32_t stimecmp;
   uint32_t fflags;
   uint32_t frm;
   bool serialized; // whether timer CSRs are in a well-defined state