[sim,pk] added interrupt-pending field to cause reg
authorAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>
Sat, 5 Feb 2011 00:09:47 +0000 (16:09 -0800)
committerAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>
Sat, 5 Feb 2011 00:09:47 +0000 (16:09 -0800)
riscv/decode.h
riscv/insns/mtpcr.h
riscv/processor.cc
riscv/processor.h
riscv/trap.h

index 4c30e623e9684617b88d7b4dbaa7712de355ef56..40b8b5e668a1ea8d7387365dca0698178aeb5cb4 100644 (file)
@@ -44,6 +44,11 @@ const int JUMP_ALIGN_BITS = 1;
 #define SR_IM_SHIFT 8
 #define TIMER_IRQ 7
 
+#define CAUSE_EXCCODE 0x000000FF
+#define CAUSE_IP      0x0000FF00
+#define CAUSE_EXCCODE_SHIFT 0
+#define CAUSE_IP_SHIFT      8
+
 #define FP_RD_NE  0
 #define FP_RD_0   1
 #define FP_RD_DN  2
index 1a31a32151b08c789b29f29ee567b4836f680295..449f63d22d079b105a6e46c80d8edfec34cd3496 100644 (file)
@@ -15,7 +15,7 @@ switch(insn.rtype.rs2)
     count = RS1;
     break;
   case 5:
-    interrupts_pending &= ~(1 << TIMER_IRQ);
+    cause &= ~(1 << (TIMER_IRQ+CAUSE_IP_SHIFT));
     compare = RS1;
     break;
 
index 6f3665305751de22b14d0448ce9510b986657d19..f5b6de1b6123b6c5f19c4afc2c7db4a01d53b832 100644 (file)
@@ -25,7 +25,6 @@ processor_t::processor_t(sim_t* _sim, char* _mem, size_t _memsz)
   fromhost = 0;
   count = 0;
   compare = 0;
-  interrupts_pending = 0;
   set_sr(SR_S | SR_SX);  // SX ignored if 64b mode not supported
   set_fsr(0);
 
@@ -70,13 +69,10 @@ 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);
-      }
+      uint32_t interrupts = (cause & CAUSE_IP) >> CAUSE_IP_SHIFT;
+      interrupts &= (sr & SR_IM) >> SR_IM_SHIFT;
+      if(interrupts && (sr & SR_ET))
+        take_trap(trap_interrupt,noisy);
 
       insn_t insn = mmu.load_insn(pc);
   
@@ -91,7 +87,7 @@ void processor_t::step(size_t n, bool noisy)
       XPR[0] = 0;
 
       if(count++ == compare)
-        interrupts_pending |= 1 << TIMER_IRQ;
+        cause |= 1 << (TIMER_IRQ+CAUSE_IP_SHIFT);
     }
     return;
   }
@@ -112,7 +108,7 @@ void processor_t::take_trap(trap_t t, bool noisy)
            id, trap_name(t), (unsigned long long)pc);
 
   set_sr((((sr & ~SR_ET) | SR_S) & ~SR_PS) | ((sr & SR_S) ? SR_PS : 0));
-  cause = t;
+  cause = (cause & ~CAUSE_EXCCODE) | (t << CAUSE_EXCCODE_SHIFT);
   epc = pc;
   pc = evec;
   badvaddr = mmu.get_badvaddr();
index b54803844f01a32a784b9712ee401f05e66aba5c..c1c65ce2f1338d076abb0aa1fa6e85c42c63cc03 100644 (file)
@@ -36,7 +36,6 @@ private:
   uint32_t sr;
   uint32_t count;
   uint32_t compare;
-  uint32_t interrupts_pending;
 
   // unprivileged control registers
   uint32_t fsr;
index 5ba11839c42a33f5bc55e65a441932a1d2119fef..3af88407e902a5ba9af0d2f307a98843f30e3592 100644 (file)
@@ -8,7 +8,7 @@
   DECLARE_TRAP(privileged_instruction), \
   DECLARE_TRAP(fp_disabled), \
   DECLARE_TRAP(syscall), \
-  DECLARE_TRAP(breakpoint), \
+  DECLARE_TRAP(interrupt), \
   DECLARE_TRAP(data_address_misaligned), \
   DECLARE_TRAP(load_access_fault), \
   DECLARE_TRAP(store_access_fault), \