mem-cache: Add multiple eviction stats
[gem5.git] / src / arch / arm / interrupts.hh
index 8e6c2b26129c6fd97372ba34fe9e704605a83f02..1f8e321cd18f6337e6f6b5566ca6245c047a42ff 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012-2013 ARM Limited
+ * Copyright (c) 2010, 2012-2013, 2016 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
 #include "arch/arm/miscregs.hh"
 #include "arch/arm/registers.hh"
 #include "arch/arm/utility.hh"
+#include "arch/generic/interrupts.hh"
 #include "cpu/thread_context.hh"
 #include "debug/Interrupt.hh"
 #include "params/ArmInterrupts.hh"
-#include "sim/sim_object.hh"
 
 namespace ArmISA
 {
 
-class Interrupts : public SimObject
+class Interrupts : public BaseInterrupts
 {
   private:
     BaseCPU * cpu;
@@ -80,7 +80,7 @@ class Interrupts : public SimObject
         return dynamic_cast<const Params *>(_params);
     }
 
-    Interrupts(Params * p) : SimObject(p), cpu(NULL)
+    Interrupts(Params * p) : BaseInterrupts(p), cpu(NULL)
     {
         clearAll();
     }
@@ -141,14 +141,17 @@ class Interrupts : public SimObject
             return false;
 
         CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
-        SCR  scr  = tc->readMiscReg(MISCREG_SCR);
 
-        bool isHypMode   = cpsr.mode == MODE_HYP;
-        bool isSecure    = inSecureState(scr, cpsr);
+        bool isHypMode   = currEL(tc) == EL2;
+        bool isSecure    = inSecureState(tc);
         bool allowVIrq   = !cpsr.i && hcr.imo && !isSecure && !isHypMode;
         bool allowVFiq   = !cpsr.f && hcr.fmo && !isSecure && !isHypMode;
         bool allowVAbort = !cpsr.a && hcr.amo && !isSecure && !isHypMode;
 
+        if ( !(intStatus || (hcr.vi && allowVIrq) || (hcr.vf && allowVFiq) ||
+               (hcr.va && allowVAbort)) )
+            return false;
+
         bool take_irq = takeInt(tc, INT_IRQ);
         bool take_fiq = takeInt(tc, INT_FIQ);
         bool take_ea =  takeInt(tc, INT_ABT);
@@ -221,45 +224,42 @@ class Interrupts : public SimObject
     Fault
     getInterrupt(ThreadContext *tc)
     {
+        assert(checkInterrupts(tc));
+
         HCR  hcr  = tc->readMiscReg(MISCREG_HCR);
         CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
-        SCR  scr  = tc->readMiscReg(MISCREG_SCR);
 
         // Calculate a few temp vars so we can work out if there's a pending
         // virtual interrupt, and if its allowed to happen
         // ARM ARM Issue C section B1.9.9, B1.9.11, and B1.9.13
-        bool isHypMode   = cpsr.mode == MODE_HYP;
-        bool isSecure    = inSecureState(scr, cpsr);
+        bool isHypMode   = currEL(tc) == EL2;
+        bool isSecure    = inSecureState(tc);
         bool allowVIrq   = !cpsr.i && hcr.imo && !isSecure && !isHypMode;
         bool allowVFiq   = !cpsr.f && hcr.fmo && !isSecure && !isHypMode;
         bool allowVAbort = !cpsr.a && hcr.amo && !isSecure && !isHypMode;
 
-        if ( !(intStatus || (hcr.vi && allowVIrq) || (hcr.vf && allowVFiq) ||
-               (hcr.va && allowVAbort)) )
-            return NoFault;
-
         bool take_irq = takeInt(tc, INT_IRQ);
         bool take_fiq = takeInt(tc, INT_FIQ);
         bool take_ea =  takeInt(tc, INT_ABT);
 
-
         if (interrupts[INT_IRQ] && take_irq)
-            return new Interrupt;
+            return std::make_shared<Interrupt>();
         if ((interrupts[INT_VIRT_IRQ] || hcr.vi) && allowVIrq)
-            return new VirtualInterrupt;
+            return std::make_shared<VirtualInterrupt>();
         if (interrupts[INT_FIQ] && take_fiq)
-            return new FastInterrupt;
+            return std::make_shared<FastInterrupt>();
         if ((interrupts[INT_VIRT_FIQ] || hcr.vf) && allowVFiq)
-            return new VirtualFastInterrupt;
+            return std::make_shared<VirtualFastInterrupt>();
         if (interrupts[INT_ABT] && take_ea)
-            return new SystemError;
+            return std::make_shared<SystemError>();
         if (hcr.va && allowVAbort)
-            return new VirtualDataAbort(0, TlbEntry::DomainType::NoAccess, false,
-                                 ArmFault::AsynchronousExternalAbort);
+            return std::make_shared<VirtualDataAbort>(
+                0, TlbEntry::DomainType::NoAccess, false,
+                ArmFault::AsynchronousExternalAbort);
         if (interrupts[INT_RST])
-            return new Reset;
+            return std::make_shared<Reset>();
         if (interrupts[INT_SEV])
-            return new ArmSev;
+            return std::make_shared<ArmSev>();
 
         panic("intStatus and interrupts not in sync\n");
     }
@@ -271,14 +271,14 @@ class Interrupts : public SimObject
     }
 
     void
-    serialize(std::ostream &os)
+    serialize(CheckpointOut &cp) const
     {
         SERIALIZE_ARRAY(interrupts, NumInterruptTypes);
         SERIALIZE_SCALAR(intStatus);
     }
 
     void
-    unserialize(Checkpoint *cp, const std::string &section)
+    unserialize(CheckpointIn &cp)
     {
         UNSERIALIZE_ARRAY(interrupts, NumInterruptTypes);
         UNSERIALIZE_SCALAR(intStatus);