CPU: Add a setCPU function to the interrupt objects.
[gem5.git] / src / arch / alpha / interrupts.hh
index 0500714ad0d070572c5ddbc16b498c99861aadc9..f8e0ad4effcdc257d29a2870643d071962fa641b 100644 (file)
 #include "arch/alpha/faults.hh"
 #include "arch/alpha/isa_traits.hh"
 #include "base/compiler.hh"
+#include "base/trace.hh"
 #include "cpu/thread_context.hh"
+#include "params/AlphaInterrupts.hh"
+#include "sim/sim_object.hh"
 
-namespace AlphaISA
+namespace AlphaISA {
+
+class Interrupts : public SimObject
 {
-    class Interrupts
+  private:
+    bool newInfoSet;
+    int newIpl;
+    int newSummary;
+    BaseCPU * cpu;
+
+  protected:
+    uint64_t interrupts[NumInterruptLevels];
+    uint64_t intstatus;
+
+  public:
+    typedef AlphaInterruptsParams Params;
+
+    const Params *
+    params() const
     {
-      protected:
-        uint64_t interrupts[NumInterruptLevels];
-        uint64_t intstatus;
-
-      public:
-        Interrupts()
-        {
-            memset(interrupts, 0, sizeof(interrupts));
-            intstatus = 0;
-            newInfoSet = false;
-        }
+        return dynamic_cast<const Params *>(_params);
+    }
 
-        void post(int int_num, int index)
-        {
-            DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
+    Interrupts(Params * p) : SimObject(p), cpu(NULL)
+    {
+        memset(interrupts, 0, sizeof(interrupts));
+        intstatus = 0;
+        newInfoSet = false;
+    }
 
-            if (int_num < 0 || int_num >= NumInterruptLevels)
-                panic("int_num out of bounds\n");
+    void
+    setCPU(BaseCPU * _cpu)
+    {
+        cpu = _cpu;
+    }
 
-            if (index < 0 || index >= sizeof(uint64_t) * 8)
-                panic("int_num out of bounds\n");
+    void
+    post(int int_num, int index)
+    {
+        DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
 
-            interrupts[int_num] |= 1 << index;
-            intstatus |= (ULL(1) << int_num);
-        }
+        if (int_num < 0 || int_num >= NumInterruptLevels)
+            panic("int_num out of bounds\n");
 
-        void clear(int int_num, int index)
-        {
-            DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
+        if (index < 0 || index >= (int)sizeof(uint64_t) * 8)
+            panic("int_num out of bounds\n");
 
-            if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
-                panic("int_num out of bounds\n");
+        interrupts[int_num] |= 1 << index;
+        intstatus |= (ULL(1) << int_num);
+    }
 
-            if (index < 0 || index >= sizeof(uint64_t) * 8)
-                panic("int_num out of bounds\n");
+    void
+    clear(int int_num, int index)
+    {
+        DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
 
-            interrupts[int_num] &= ~(1 << index);
-            if (interrupts[int_num] == 0)
-                intstatus &= ~(ULL(1) << int_num);
-        }
+        if (int_num < 0 || int_num >= NumInterruptLevels)
+            panic("int_num out of bounds\n");
 
-        void clear_all()
-        {
-            DPRINTF(Interrupt, "Interrupts all cleared\n");
+        if (index < 0 || index >= (int)sizeof(uint64_t) * 8)
+            panic("int_num out of bounds\n");
 
-            memset(interrupts, 0, sizeof(interrupts));
-            intstatus = 0;
-        }
+        interrupts[int_num] &= ~(1 << index);
+        if (interrupts[int_num] == 0)
+            intstatus &= ~(ULL(1) << int_num);
+    }
 
-        void serialize(std::ostream &os)
-        {
-            SERIALIZE_ARRAY(interrupts, NumInterruptLevels);
-            SERIALIZE_SCALAR(intstatus);
-        }
+    void
+    clearAll()
+    {
+        DPRINTF(Interrupt, "Interrupts all cleared\n");
 
-        void unserialize(Checkpoint *cp, const std::string &section)
-        {
-            UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels);
-            UNSERIALIZE_SCALAR(intstatus);
-        }
+        memset(interrupts, 0, sizeof(interrupts));
+        intstatus = 0;
+    }
 
-        bool check_interrupts(ThreadContext * tc) const
-        {
-            return (intstatus != 0) && !(tc->readPC() & 0x3);
-        }
+    void
+    serialize(std::ostream &os)
+    {
+        SERIALIZE_ARRAY(interrupts, NumInterruptLevels);
+        SERIALIZE_SCALAR(intstatus);
+    }
 
-        Fault getInterrupt(ThreadContext * tc)
-        {
-            int ipl = 0;
-            int summary = 0;
-
-            if (tc->readMiscReg(IPR_ASTRR))
-                panic("asynchronous traps not implemented\n");
-
-            if (tc->readMiscReg(IPR_SIRR)) {
-                for (int i = INTLEVEL_SOFTWARE_MIN;
-                     i < INTLEVEL_SOFTWARE_MAX; i++) {
-                    if (tc->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
-                        // See table 4-19 of 21164 hardware reference
-                        ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
-                        summary |= (ULL(1) << i);
-                    }
-                }
-            }
+    void
+    unserialize(Checkpoint *cp, const std::string &section)
+    {
+        UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels);
+        UNSERIALIZE_SCALAR(intstatus);
+    }
+
+    bool
+    checkInterrupts(ThreadContext *tc) const
+    {
+        return (intstatus != 0) && !(tc->readPC() & 0x3);
+    }
 
-            uint64_t interrupts = intstatus;
-            if (interrupts) {
-                for (int i = INTLEVEL_EXTERNAL_MIN;
-                    i < INTLEVEL_EXTERNAL_MAX; i++) {
-                    if (interrupts & (ULL(1) << i)) {
-                        // See table 4-19 of 21164 hardware reference
-                        ipl = i;
-                        summary |= (ULL(1) << i);
-                    }
+    Fault
+    getInterrupt(ThreadContext *tc)
+    {
+        int ipl = 0;
+        int summary = 0;
+
+        if (tc->readMiscRegNoEffect(IPR_ASTRR))
+            panic("asynchronous traps not implemented\n");
+
+        if (tc->readMiscRegNoEffect(IPR_SIRR)) {
+            for (int i = INTLEVEL_SOFTWARE_MIN;
+                 i < INTLEVEL_SOFTWARE_MAX; i++) {
+                if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) {
+                    // See table 4-19 of 21164 hardware reference
+                    ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
+                    summary |= (ULL(1) << i);
                 }
             }
+        }
 
-            if (ipl && ipl > tc->readMiscReg(IPR_IPLR)) {
-                newIpl = ipl;
-                newSummary = summary;
-                newInfoSet = true;
-                DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
-                        tc->readMiscReg(IPR_IPLR), ipl, summary);
-
-                return new InterruptFault;
-            } else {
-                return NoFault;
+        uint64_t interrupts = intstatus;
+        if (interrupts) {
+            for (int i = INTLEVEL_EXTERNAL_MIN;
+                 i < INTLEVEL_EXTERNAL_MAX; i++) {
+                if (interrupts & (ULL(1) << i)) {
+                    // See table 4-19 of 21164 hardware reference
+                    ipl = i;
+                    summary |= (ULL(1) << i);
+                }
             }
         }
 
-        void updateIntrInfo(ThreadContext *tc)
-        {
-            assert(newInfoSet);
-            tc->setMiscReg(IPR_ISR, newSummary);
-            tc->setMiscReg(IPR_INTID, newIpl);
-            newInfoSet = false;
-        }
+        if (ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR)) {
+            newIpl = ipl;
+            newSummary = summary;
+            newInfoSet = true;
+            DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
+                    tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary);
 
-        uint64_t get_vec(int int_num)
-        {
-            panic("Shouldn't be called for Alpha\n");
-            M5_DUMMY_RETURN
+            return new InterruptFault;
+        } else {
+            return NoFault;
         }
+    }
+
+    void
+    updateIntrInfo(ThreadContext *tc)
+    {
+        assert(newInfoSet);
+        tc->setMiscRegNoEffect(IPR_ISR, newSummary);
+        tc->setMiscRegNoEffect(IPR_INTID, newIpl);
+        newInfoSet = false;
+    }
+};
 
-      private:
-        bool newInfoSet;
-        int newIpl;
-        int newSummary;
-    };
-}
+} // namespace AlphaISA
 
-#endif
+#endif // __ARCH_ALPHA_INTERRUPT_HH__