[pk, sim] added interrupt support to sim; added timer interrupt
authorAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>
Thu, 9 Sep 2010 22:39:40 +0000 (15:39 -0700)
committerAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>
Thu, 9 Sep 2010 22:39:40 +0000 (15:39 -0700)
riscv/decode.h
riscv/insns/mfcr.h
riscv/insns/mfpcr.h
riscv/insns/mtcr.h
riscv/insns/mtpcr.h
riscv/processor.cc
riscv/processor.h

index dffb9bef50541afbc3403f3f4d8f5b3c1331167e..a5ea4bc9e963b63f42710a77c7e760ade85287c8 100644 (file)
@@ -36,9 +36,11 @@ const int JUMP_ALIGN_BITS = 1;
 #define SR_S     0x0000000000000008ULL
 #define SR_EF    0x0000000000000010ULL
 #define SR_UX    0x0000000000000020ULL
-#define SR_KX    0x0000000000000040ULL
+#define SR_SX    0x0000000000000040ULL
 #define SR_IM    0x000000000000FF00ULL
-#define SR_ZERO  ~(SR_ET | SR_PS | SR_S | SR_EF | SR_UX | SR_KX | SR_IM)
+#define SR_ZERO  ~(SR_ET | SR_PS | SR_S | SR_EF | SR_UX | SR_SX | SR_IM)
+#define SR_IM_SHIFT 8
+#define TIMER_IRQ 7
 
 #define FP_RD_NE  0
 #define FP_RD_0   1
index 7ce1d9ee79a195a20a9a0ac63eae50f5dd87a91b..088480cba7e4f18c96b5998a98284084df67cf25 100644 (file)
@@ -2,6 +2,10 @@ reg_t val;
 
 switch(insn.rtype.rb)
 {
+  case 0:
+    val = fsr;
+    break;
+
   case 1:
     val = 32; // synci_step
     break;
index d9bfc223f20d1a0de02c02d3ac7b559dde8f94d8..d6fd4248d55f8b27ff32dfb33a8b406a8fe9bebd 100644 (file)
@@ -16,6 +16,12 @@ switch(insn.rtype.rb)
   case 3:
     val = ebase;
     break;
+  case 4:
+    val = count;
+    break;
+  case 5:
+    val = compare;
+    break;
 
   case 8:
     val = MEMSIZE >> 12;
index 5f85a51abcd3853cc12c5b3178b4d119d3634856..d7b2b17eb2b1c9d6c689528ad0357da562f46bb9 100644 (file)
@@ -1,8 +1,10 @@
-reg_t val = gprlen == 64 ? RA : sext32(RA);
-
 switch(insn.rtype.rb)
 {
+  case 0:
+    set_fsr(RA);
+    break;
+
   case 29:
-    tid = val;
+    tid = RA;
     break;
 }
index cbb580b52d152bc969aa299eeb9aca46f531680b..d9b47f02fd8ea0b6a06c79cc38fa8464ded09691 100644 (file)
@@ -1,27 +1,32 @@
 require_supervisor;
 
-reg_t val = gprlen == 64 ? RA : sext32(RA);
-
 switch(insn.rtype.rb)
 {
   case 0:
-    set_sr(val);
+    set_sr(RA);
     break;
   case 1:
-    epc = val;
+    epc = RA;
     break;
   case 3:
-    ebase = val & ~0xFFF;
+    ebase = RA & ~0xFFF;
+    break;
+  case 4:
+    count = RA;
+    break;
+  case 5:
+    interrupts_pending &= ~(1 << TIMER_IRQ);
+    compare = RA;
     break;
 
   case 16:
-    sim->set_tohost(val);
+    sim->set_tohost(RA);
     break;
 
   case 24:
-    pcr_k0 = val;
+    pcr_k0 = RA;
     break;
   case 25:
-    pcr_k1 = val;
+    pcr_k1 = RA;
     break;
 }
index fb32f96dc56a89cf8882a53007ad9dff0a3662d1..e04f4985d74ceea9633b9f0f29335ecad78e70f6 100644 (file)
@@ -21,7 +21,10 @@ processor_t::processor_t(sim_t* _sim, char* _mem, size_t _memsz)
   tid = 0;
   pcr_k0 = 0;
   pcr_k1 = 0;
-  set_sr(SR_S | (support_64bit ? SR_KX : 0));
+  count = 0;
+  compare = 0;
+  interrupts_pending = 0;
+  set_sr(SR_S | (support_64bit ? SR_SX : 0));
   set_fsr(0);
 
   memset(counters,0,sizeof(counters));
@@ -44,14 +47,15 @@ void processor_t::set_sr(uint32_t val)
 {
   sr = val & ~SR_ZERO;
   if(!support_64bit)
-    sr &= ~(SR_KX | SR_UX);
+    sr &= ~(SR_SX | SR_UX);
 
-  gprlen = ((sr & SR_S) ? (sr & SR_KX) : (sr & SR_UX)) ? 64 : 32;
+  gprlen = ((sr & SR_S) ? (sr & SR_SX) : (sr & SR_UX)) ? 64 : 32;
 }
 
 void processor_t::set_fsr(uint32_t val)
 {
   fsr = val & ~FSR_ZERO;
+  softfloat_roundingMode = (fsr & FSR_RD) >> FSR_RD_SHIFT;
 }
 
 void processor_t::step(size_t n, bool noisy)
@@ -61,6 +65,14 @@ void processor_t::step(size_t n, bool noisy)
   {
     for( ; i < n; i++)
     {
+      uint32_t interrupts = interrupts_pending & ((sr & SR_IM) >> SR_IM_SHIFT);
+      if((sr & SR_ET) && interrupts)
+      {
+        for(int i = 0; interrupts; i++, interrupts >>= 1)
+          if(interrupts & 1)
+            throw trap_t(16+i);
+      }
+
       insn_t insn = mmu.load_insn(pc);
   
       reg_t npc = pc+sizeof(insn);
@@ -73,7 +85,8 @@ void processor_t::step(size_t n, bool noisy)
       pc = npc;
       R[0] = 0;
 
-      counters[0]++;
+      if(count++ == compare)
+        interrupts_pending |= 1 << TIMER_IRQ;
     }
     return;
   }
index 26e49f39e3c150a98da4bad8c1be5e433ec10cb3..8e9e6f0b404e69f374266137b05debfbc1468b41 100644 (file)
@@ -31,6 +31,9 @@ private:
   reg_t pcr_k1;
   uint32_t id;
   uint32_t sr;
+  uint32_t count;
+  uint32_t compare;
+  uint32_t interrupts_pending;
 
   // unprivileged control registers
   uint32_t tid;