mostly implemented SOFTINT relevant interrupt stuff.
authorLisa Hsu <hsul@eecs.umich.edu>
Fri, 8 Dec 2006 19:37:31 +0000 (14:37 -0500)
committerLisa Hsu <hsul@eecs.umich.edu>
Fri, 8 Dec 2006 19:37:31 +0000 (14:37 -0500)
src/arch/sparc/interrupts.hh:
    add in thread_context.hh to get access to tc.
    get rid of stubs that don't make sense right now.
    implement checking and get softint interrupts
src/arch/sparc/miscregfile.cc:
    softint should be OR-ed on a write.
src/arch/sparc/miscregfile.hh:
    add some enums for state fields for easy access to bitmasks of HPSTATE and PSTATE regs.
src/arch/sparc/ua2005.cc:
    implement writing SOFTINT, PSTATE, PIL, and HPSTATE properly, add helpful info to panic for bad reg write.

--HG--
extra : convert_revision : d12d1147b508121075ee9be4599693554d4b9eae

src/arch/sparc/interrupts.hh
src/arch/sparc/miscregfile.cc
src/arch/sparc/miscregfile.hh
src/arch/sparc/ua2005.cc

index 70838d1ce612d3a593a97c33c324c0e9b6cf1f9d..452164e46724d5d51d79df2571c4bf9fc14551c0 100644 (file)
 #define __ARCH_SPARC_INTERRUPT_HH__
 
 #include "arch/sparc/faults.hh"
+#include "cpu/thread_context.hh"
+
 
 namespace SparcISA
 {
     class Interrupts
     {
       protected:
-        Fault interrupts[NumInterruptLevels];
-        bool requested[NumInterruptLevels];
+
 
       public:
         Interrupts()
         {
-            for(int x = 0; x < NumInterruptLevels; x++)
-            {
-                interrupts[x] = new InterruptLevelN(x);
-                requested[x] = false;
-            }
+
         }
         void post(int int_num, int index)
         {
-            if(int_num < 0 || int_num >= NumInterruptLevels)
-                panic("int_num out of bounds\n");
 
-            requested[int_num] = true;
         }
 
         void clear(int int_num, int index)
         {
-            requested[int_num] = false;
+
         }
 
         void clear_all()
         {
-            for(int x = 0; x < NumInterruptLevels; x++)
-                requested[x] = false;
+
         }
 
         bool check_interrupts(ThreadContext * tc) const
         {
-            return true;
+            // so far only handle softint interrupts
+            int int_level = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT));
+            if (int_level)
+                return true;
+            else
+                return false;
         }
 
         Fault getInterrupt(ThreadContext * tc)
         {
-            return NoFault;
+            // conditioning the softint interrups
+            if (tc->readMiscReg(MISCREG_HPSTATE) & hpriv) {
+                // if running in privileged mode, then pend the interrupt
+                return NoFault;
+            } else {
+                int int_level = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT));
+                if ((int_level <= tc->readMiscReg(MISCREG_PIL)) ||
+                    !(tc->readMiscReg(MISCREG_PSTATE) & ie)) {
+                    // if PIL or no interrupt enabled, then pend the interrupt
+                    return NoFault;
+                } else {
+                    return new InterruptLevelN(int_level);
+                }
+            }
         }
 
         void updateIntrInfo(ThreadContext * tc)
index 47b4771d9380623a1c2e23072efd60f2e3f64ab0..0094f23535323936a25a16687acfbd0a4614b3c0 100644 (file)
@@ -369,7 +369,7 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val)
         gsr = val;
         break;
       case MISCREG_SOFTINT:
-        softint = val;
+        softint |= val;
         break;
       case MISCREG_TICK_CMPR:
         tick_cmpr = val;
index 3b8a977cc68bdbdb6276216109e985b08a8c1796..d09005795b7c9ec6b954566edd3093bcbe9a1241 100644 (file)
@@ -140,6 +140,24 @@ namespace SparcISA
         MISCREG_NUMMISCREGS
     };
 
+    enum HPStateFields {
+        id = 0x800,   // this impl. dependent (id) field must always be '1' for T1000
+        ibe = 0x400,
+        red = 0x20,
+        hpriv = 0x4,
+        tlz = 0x1
+    };
+
+    enum PStateFields {
+        cle = 0x200,
+        tle = 0x100,
+        mm = 0xC0,
+        pef = 0x10,
+        am = 0x8,
+        priv = 0x4,
+        ie = 0x2
+    };
+
     const int NumMiscArchRegs = MISCREG_NUMMISCREGS;
     const int NumMiscRegs = MISCREG_NUMMISCREGS;
 
index 32bc2a44bbb1b7e11ab0b7a07ef247f3012cab34..c5188f405bc120d260a80257fcf819407142590e 100644 (file)
@@ -41,18 +41,12 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
         ThreadContext *tc)
 {
     int64_t time;
-    int oldLevel, newLevel;
     switch (miscReg) {
         /* Full system only ASRs */
         case MISCREG_SOFTINT:
           // Check if we are going to interrupt because of something
-          oldLevel = InterruptLevel(softint);
-          newLevel = InterruptLevel(val);
           setReg(miscReg, val);
-          if (newLevel > oldLevel)
-              ; // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX
-              //tc->getCpuPtr()->checkInterrupts = true;
-          panic("SOFTINT not implemented\n");
+          tc->getCpuPtr()->checkInterrupts = true;
           break;
 
         case MISCREG_SOFTINT_CLR:
@@ -82,11 +76,17 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
               sTickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
           break;
 
+        case MISCREG_PSTATE:
+          if (val & ie && !(pstate & ie)) {
+              tc->getCpuPtr()->checkInterrupts = true;
+          }
+          setReg(miscReg, val);
+
         case MISCREG_PIL:
+          if (val < pil) {
+              tc->getCpuPtr()->checkInterrupts = true;
+          }
           setReg(miscReg, val);
-          //tc->getCpuPtr()->checkInterrupts;
-          // MUST DO SOMETHING HERE TO TELL CPU TO LOOK FOR INTERRUPTS XXX
-          panic("PIL not implemented\n");
           break;
 
         case MISCREG_HVER:
@@ -109,13 +109,16 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
           break;
 
         case MISCREG_HPSTATE:
+          // T1000 spec says impl. dependent val must always be 1
+          setReg(miscReg, val | id);
+
         case MISCREG_HTSTATE:
         case MISCREG_STRAND_STS_REG:
           setReg(miscReg, val);
           break;
 
         default:
-          panic("Invalid write to FS misc register\n");
+          panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg));
     }
 }