arch: Make a base class for Interrupts.
authorGabe Black <gabeblack@google.com>
Tue, 3 Sep 2019 04:26:12 +0000 (21:26 -0700)
committerGabe Black <gabeblack@google.com>
Sat, 19 Oct 2019 01:45:48 +0000 (01:45 +0000)
That abstracts the ISA further from the CPU, getting us a small step
closer to being able to build in more than one ISA at a time.

Change-Id: Ibf7e26a3df411ffe994ac1e11d2a53b656863223
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20831
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>

31 files changed:
src/arch/alpha/AlphaInterrupts.py
src/arch/alpha/interrupts.hh
src/arch/alpha/isa/decoder.isa
src/arch/arm/ArmInterrupts.py
src/arch/arm/interrupts.hh
src/arch/arm/isa.cc
src/arch/arm/isa/includes.isa
src/arch/arm/isa/insts/misc.isa
src/arch/generic/BaseInterrupts.py [new file with mode: 0644]
src/arch/generic/SConscript
src/arch/generic/interrupts.hh [new file with mode: 0644]
src/arch/mips/MipsInterrupts.py
src/arch/mips/interrupts.cc
src/arch/mips/interrupts.hh
src/arch/power/PowerInterrupts.py
src/arch/power/interrupts.hh
src/arch/riscv/RiscvInterrupts.py
src/arch/riscv/interrupts.hh
src/arch/riscv/isa.cc
src/arch/sparc/SparcInterrupts.py
src/arch/sparc/interrupts.hh
src/arch/sparc/isa.cc
src/arch/x86/X86LocalApic.py
src/arch/x86/interrupts.cc
src/arch/x86/interrupts.hh
src/arch/x86/pagetable_walker.cc
src/cpu/BaseCPU.py
src/cpu/base.hh
src/cpu/kvm/base.hh
src/cpu/kvm/x86_cpu.cc
src/dev/x86/i82094aa.cc

index a75b11fc0442b01321c4f3107ed76284369464a5..7bab9b0ca2c337e5a95f94166b28768890a6fc45 100644 (file)
@@ -26,9 +26,9 @@
 #
 # Authors: Gabe Black
 
-from m5.SimObject import SimObject
+from m5.objects.BaseInterrupts import BaseInterrupts
 
-class AlphaInterrupts(SimObject):
+class AlphaInterrupts(BaseInterrupts):
     type = 'AlphaInterrupts'
     cxx_class = 'AlphaISA::Interrupts'
     cxx_header = "arch/alpha/interrupts.hh"
index 61ac6c9687c481c3efa557985fe83bdc971741df..e054b4389a8b312b8e0ca3f23be7b69bb50bab10 100644 (file)
 
 #include "arch/alpha/faults.hh"
 #include "arch/alpha/isa_traits.hh"
+#include "arch/generic/interrupts.hh"
 #include "base/compiler.hh"
 #include "base/trace.hh"
 #include "cpu/thread_context.hh"
 #include "debug/Flow.hh"
 #include "debug/Interrupt.hh"
 #include "params/AlphaInterrupts.hh"
-#include "sim/sim_object.hh"
 
 namespace AlphaISA {
 
-class Interrupts : public SimObject
+class Interrupts : public BaseInterrupts
 {
   private:
     bool newInfoSet;
@@ -67,7 +67,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)
     {
         memset(interrupts, 0, sizeof(interrupts));
         intstatus = 0;
index 8732d70ba2922aff973d60a1baab3839912b7972..020e43359f02cad5069d2624828bd06e253b71b2 100644 (file)
@@ -982,7 +982,7 @@ decode OPCODE default Unknown::unknown() {
             }}, IsNonSpeculative);
             0x01: quiesce({{
                 // Don't sleep if (unmasked) interrupts are pending
-                Interrupts* interrupts =
+                BaseInterrupts* interrupts =
                     xc->tcBase()->getCpuPtr()->getInterruptController(0);
                 if (interrupts->checkInterrupts(xc->tcBase())) {
                     PseudoInst::quiesceSkip(xc->tcBase());
index 68a58958d7db5c5e70139d0af6871f4269329f39..9a6b546a51e022271753ab72c20d9f28a2d08313 100644 (file)
@@ -26,9 +26,9 @@
 #
 # Authors: Ali Saidi
 
-from m5.SimObject import SimObject
+from m5.objects.BaseInterrupts import BaseInterrupts
 
-class ArmInterrupts(SimObject):
+class ArmInterrupts(BaseInterrupts):
     type = 'ArmInterrupts'
     cxx_class = 'ArmISA::Interrupts'
     cxx_header = "arch/arm/interrupts.hh"
index 8d0cb49ea7eab7b9d594fdb0b34ebd73b743bbb9..1f8e321cd18f6337e6f6b5566ca6245c047a42ff 100644 (file)
 #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();
     }
index 6e65102b6f0d674c213b6c51409fefb9a97ca8d7..712b430406c4a9dd07263a1b7edb0210bce77c4f 100644 (file)
@@ -39,6 +39,9 @@
  */
 
 #include "arch/arm/isa.hh"
+
+#include "arch/arm/faults.hh"
+#include "arch/arm/interrupts.hh"
 #include "arch/arm/pmu.hh"
 #include "arch/arm/system.hh"
 #include "arch/arm/tlb.hh"
@@ -672,15 +675,23 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
       case MISCREG_DBGDSCRint:
         return 0;
       case MISCREG_ISR:
-        return tc->getCpuPtr()->getInterruptController(tc->threadId())->getISR(
-            readMiscRegNoEffect(MISCREG_HCR),
-            readMiscRegNoEffect(MISCREG_CPSR),
-            readMiscRegNoEffect(MISCREG_SCR));
+        {
+            auto ic = dynamic_cast<ArmISA::Interrupts *>(
+                    tc->getCpuPtr()->getInterruptController(tc->threadId()));
+            return ic->getISR(
+                readMiscRegNoEffect(MISCREG_HCR),
+                readMiscRegNoEffect(MISCREG_CPSR),
+                readMiscRegNoEffect(MISCREG_SCR));
+        }
       case MISCREG_ISR_EL1:
-        return tc->getCpuPtr()->getInterruptController(tc->threadId())->getISR(
-            readMiscRegNoEffect(MISCREG_HCR_EL2),
-            readMiscRegNoEffect(MISCREG_CPSR),
-            readMiscRegNoEffect(MISCREG_SCR_EL3));
+        {
+            auto ic = dynamic_cast<ArmISA::Interrupts *>(
+                    tc->getCpuPtr()->getInterruptController(tc->threadId()));
+            return ic->getISR(
+                readMiscRegNoEffect(MISCREG_HCR_EL2),
+                readMiscRegNoEffect(MISCREG_CPSR),
+                readMiscRegNoEffect(MISCREG_SCR_EL3));
+        }
       case MISCREG_DCZID_EL0:
         return 0x04;  // DC ZVA clear 64-byte chunks
       case MISCREG_HCPTR:
index f054bc862f9514652abecf2efa99719117ebd2b0..d584d8225862d2ab951d22165e2bb92754f7cc2e 100644 (file)
@@ -96,6 +96,7 @@ output exec {{
 #include <cmath>
 
 #include "arch/arm/faults.hh"
+#include "arch/arm/interrupts.hh"
 #include "arch/arm/isa.hh"
 #include "arch/arm/isa_traits.hh"
 #include "arch/arm/utility.hh"
index ecf09aab5dd451b6d7e8294bd832095f3af566d0..b2dc2f6d87d4fb308f8f2e0605e486f405d43f90 100644 (file)
@@ -756,8 +756,9 @@ let {{
 
     // WFI doesn't sleep if interrupts are pending (masked or not)
     ThreadContext *tc = xc->tcBase();
-    if (tc->getCpuPtr()->getInterruptController(
-                tc->threadId())->checkWfiWake(hcr, cpsr, scr)) {
+    auto *ic = dynamic_cast<ArmISA::Interrupts *>(
+            tc->getCpuPtr()->getInterruptController(tc->threadId()));
+    if (ic->checkWfiWake(hcr, cpsr, scr)) {
         PseudoInst::quiesceSkip(tc);
     } else {
         fault = trapWFx(tc, cpsr, scr, false);
diff --git a/src/arch/generic/BaseInterrupts.py b/src/arch/generic/BaseInterrupts.py
new file mode 100644 (file)
index 0000000..b373d80
--- /dev/null
@@ -0,0 +1,34 @@
+# Copyright 2019 Google, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Gabe Black
+
+from m5.params import *
+from m5.SimObject import SimObject
+
+class BaseInterrupts(SimObject):
+    type = 'BaseInterrupts'
+    abstract = True
+    cxx_header = "arch/generic/interrupts.hh"
index 0fc5e7402e0c0079c5b365bfb27a60c41a4490ba..61034bfe911249269f373581d81140f885876208 100644 (file)
@@ -46,6 +46,7 @@ if env['TARGET_ISA'] == 'null':
 Source('decode_cache.cc')
 Source('mmapped_ipr.cc')
 
+SimObject('BaseInterrupts.py')
 SimObject('BaseTLB.py')
 SimObject('ISACommon.py')
 
diff --git a/src/arch/generic/interrupts.hh b/src/arch/generic/interrupts.hh
new file mode 100644 (file)
index 0000000..cae2d09
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2019 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_GENERIC_INTERRUPTS_HH__
+#define __ARCH_GENERIC_INTERRUPTS_HH__
+
+#include "params/BaseInterrupts.hh"
+#include "sim/sim_object.hh"
+
+class ThreadContext;
+class BaseCPU;
+
+class BaseInterrupts : public SimObject
+{
+  protected:
+    BaseCPU *cpu;
+
+  public:
+    typedef BaseInterruptsParams Params;
+
+    BaseInterrupts(Params *p) : SimObject(p) {}
+
+    virtual void setCPU(BaseCPU * newCPU) = 0;
+
+    const Params *
+    params() const
+    {
+        return dynamic_cast<const Params *>(_params);
+    }
+
+    /*
+     * Functions for retrieving interrupts for the CPU to handle.
+     */
+
+    /*
+     * Return whether there are any interrupts waiting to be recognized.
+     */
+    virtual bool checkInterrupts(ThreadContext *tc) const = 0;
+    /*
+     * Return an interrupt to process. This should return an interrupt exactly
+     * when checkInterrupts returns true.
+     */
+    virtual Fault getInterrupt(ThreadContext *tc) = 0;
+    /*
+     * Update interrupt related state after an interrupt has been processed.
+     */
+    virtual void updateIntrInfo(ThreadContext *tc) = 0;
+
+    /*
+     * Old functions needed for compatability but which will be phased out
+     * eventually.
+     */
+    virtual void
+    post(int int_num, int index)
+    {
+        panic("Interrupts::post unimplemented!\n");
+    }
+
+    virtual void
+    clear(int int_num, int index)
+    {
+        panic("Interrupts::clear unimplemented!\n");
+    }
+
+    virtual void
+    clearAll()
+    {
+        panic("Interrupts::clearAll unimplemented!\n");
+    }
+};
+
+#endif // __ARCH_GENERIC_INTERRUPTS_HH__
index 9cde5daef6c3dfda8eff2c1840527dce57faacfd..1065701710f8f1b5bd66aa17fbffeff02efaa42c 100644 (file)
@@ -26,9 +26,9 @@
 #
 # Authors: Gabe Black
 
-from m5.SimObject import SimObject
+from m5.objects.BaseInterrupts import BaseInterrupts
 
-class MipsInterrupts(SimObject):
+class MipsInterrupts(BaseInterrupts):
     type = 'MipsInterrupts'
     cxx_class = 'MipsISA::Interrupts'
     cxx_header = 'arch/mips/interrupts.hh'
index a8c94169d33b876c45dbffe86f317f22b53585c5..94d0535ca6afd0e03117b3b57ae235287e54a5c7 100644 (file)
@@ -153,7 +153,7 @@ Interrupts::onCpuTimerInterrupt(ThreadContext * tc) const
 }
 
 void
-Interrupts::updateIntrInfo(ThreadContext *tc) const
+Interrupts::updateIntrInfo(ThreadContext *tc)
 {
     //Nothing needs to be done.
 }
index ce9e0e4a3dc874a644e3734466276fcc992ce061..02927ef2aea615c92ee983484defa7fd56aa9858 100644 (file)
 
 #include <string>
 
+#include "arch/generic/interrupts.hh"
 #include "arch/mips/faults.hh"
 #include "base/compiler.hh"
 #include "base/logging.hh"
 #include "params/MipsInterrupts.hh"
 #include "sim/serialize.hh"
-#include "sim/sim_object.hh"
 
 class BaseCPU;
 class Checkpoint;
@@ -46,7 +46,7 @@ class Checkpoint;
 namespace MipsISA
 {
 
-class Interrupts : public SimObject
+class Interrupts : public BaseInterrupts
 {
   public:
     typedef MipsInterruptsParams Params;
@@ -57,7 +57,7 @@ class Interrupts : public SimObject
         return dynamic_cast<const Params *>(_params);
     }
 
-    Interrupts(Params * p) : SimObject(p)
+    Interrupts(Params * p) : BaseInterrupts(p)
     {
     }
 
@@ -104,7 +104,7 @@ class Interrupts : public SimObject
     //  MIPS cause register with the instatus variable. instatus
     //  is essentially a copy of the MIPS cause[IP7:IP0]
     //
-    void updateIntrInfo(ThreadContext *tc) const;
+    void updateIntrInfo(ThreadContext *tc);
     bool interruptsPending(ThreadContext *tc) const;
     bool onCpuTimerInterrupt(ThreadContext *tc) const;
     bool checkInterrupts(ThreadContext *tc) const;
index 2c6a5c2c3a05625aeef75c5d2655ab54c20c1c53..f7e7e57bbd35fffde7c2fae6523346ddfafe934b 100644 (file)
@@ -26,9 +26,9 @@
 #
 # Authors: Gabe Black
 
-from m5.SimObject import SimObject
+from m5.objects.BaseInterrupts import BaseInterrupts
 
-class PowerInterrupts(SimObject):
+class PowerInterrupts(BaseInterrupts):
     type = 'PowerInterrupts'
     cxx_class = 'PowerISA::Interrupts'
     cxx_header = 'arch/power/interrupts.hh'
index f8995986373d1ef36edbb104f86eb6d571514eeb..b68cf8742ab3be8a98f075d1aa55eb4d7f248cab 100644 (file)
 #ifndef __ARCH_POWER_INTERRUPT_HH__
 #define __ARCH_POWER_INTERRUPT_HH__
 
+#include "arch/generic/interrupts.hh"
 #include "base/logging.hh"
 #include "params/PowerInterrupts.hh"
-#include "sim/sim_object.hh"
 
 class BaseCPU;
 class ThreadContext;
 
 namespace PowerISA {
 
-class Interrupts : public SimObject
+class Interrupts : public BaseInterrupts
 {
   private:
     BaseCPU * cpu;
@@ -54,7 +54,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)
     {}
 
     void
index 57b29b4cabb5f0a2c57a13e133102539cf8d5efa..7e63dedeaee561b8cd925a5df4ee6a5cad9b9e63 100644 (file)
@@ -31,9 +31,9 @@
 #          Sven Karlsson
 #          Alec Roelke
 
-from m5.SimObject import SimObject
+from m5.objects.BaseInterrupts import BaseInterrupts
 
-class RiscvInterrupts(SimObject):
+class RiscvInterrupts(BaseInterrupts):
     type = 'RiscvInterrupts'
     cxx_class = 'RiscvISA::Interrupts'
     cxx_header = 'arch/riscv/interrupts.hh'
index ed946879b3391120ae1a6ec9fbcb93b7ed697a70..509b483918db448cb4116972ac194ef9640c2162 100644 (file)
@@ -34,6 +34,7 @@
 #include <bitset>
 #include <memory>
 
+#include "arch/generic/interrupts.hh"
 #include "arch/riscv/faults.hh"
 #include "arch/riscv/registers.hh"
 #include "base/logging.hh"
@@ -51,7 +52,7 @@ namespace RiscvISA {
  * This is based on version 1.10 of the RISC-V privileged ISA reference,
  * chapter 3.1.14.
  */
-class Interrupts : public SimObject
+class Interrupts : public BaseInterrupts
 {
   private:
     BaseCPU * cpu;
@@ -67,7 +68,7 @@ class Interrupts : public SimObject
         return dynamic_cast<const Params *>(_params);
     }
 
-    Interrupts(Params * p) : SimObject(p), cpu(nullptr), ip(0), ie(0) {}
+    Interrupts(Params * p) : BaseInterrupts(p), cpu(nullptr), ip(0), ie(0) {}
 
     void setCPU(BaseCPU * _cpu) { cpu = _cpu; }
 
@@ -92,7 +93,7 @@ class Interrupts : public SimObject
     }
 
     Fault
-    getInterrupt(ThreadContext *tc) const
+    getInterrupt(ThreadContext *tc)
     {
         assert(checkInterrupts(tc));
         std::bitset<NumInterruptTypes> mask = globalMask(tc);
index cc86752ab4e6eaf068314cac8bea3be91be6f1d2..0fa730533c35c0bd2886bd548a95605ec00230e0 100644 (file)
@@ -34,6 +34,7 @@
 #include <set>
 #include <sstream>
 
+#include "arch/riscv/interrupts.hh"
 #include "arch/riscv/registers.hh"
 #include "base/bitfield.hh"
 #include "cpu/base.hh"
@@ -142,11 +143,17 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
             return 0;
         }
       case MISCREG_IP:
-        return tc->getCpuPtr()->getInterruptController(tc->threadId())
-                              ->readIP();
+        {
+            auto ic = dynamic_cast<RiscvISA::Interrupts *>(
+                    tc->getCpuPtr()->getInterruptController(tc->threadId()));
+            return ic->readIP();
+        }
       case MISCREG_IE:
-        return tc->getCpuPtr()->getInterruptController(tc->threadId())
-                              ->readIE();
+        {
+            auto ic = dynamic_cast<RiscvISA::Interrupts *>(
+                    tc->getCpuPtr()->getInterruptController(tc->threadId()));
+            return ic->readIE();
+        }
       default:
         // Try reading HPM counters
         // As a placeholder, all HPM counters are just cycle counters
@@ -185,11 +192,19 @@ ISA::setMiscReg(int misc_reg, RegVal val, ThreadContext *tc)
     } else {
         switch (misc_reg) {
           case MISCREG_IP:
-            return tc->getCpuPtr()->getInterruptController(tc->threadId())
-                                  ->setIP(val);
+            {
+                auto ic = dynamic_cast<RiscvISA::Interrupts *>(
+                    tc->getCpuPtr()->getInterruptController(tc->threadId()));
+                ic->setIP(val);
+            }
+            break;
           case MISCREG_IE:
-            return tc->getCpuPtr()->getInterruptController(tc->threadId())
-                                  ->setIE(val);
+            {
+                auto ic = dynamic_cast<RiscvISA::Interrupts *>(
+                    tc->getCpuPtr()->getInterruptController(tc->threadId()));
+                ic->setIE(val);
+            }
+            break;
           default:
             setMiscRegNoEffect(misc_reg, val);
         }
index c11176164abff3f42e3d084d5054e2d001e45f70..04979ad099ce5b743b70741dd6b6012ba88d8759 100644 (file)
@@ -26,9 +26,9 @@
 #
 # Authors: Gabe Black
 
-from m5.SimObject import SimObject
+from m5.objects.BaseInterrupts import BaseInterrupts
 
-class SparcInterrupts(SimObject):
+class SparcInterrupts(BaseInterrupts):
     type = 'SparcInterrupts'
     cxx_class = 'SparcISA::Interrupts'
     cxx_header = 'arch/sparc/interrupts.hh'
index abc899efbeb74bb107f1418e13b2d0eba84cbab9..58c7014774ef43889062e5562372f673b877074b 100644 (file)
@@ -32,6 +32,7 @@
 #ifndef __ARCH_SPARC_INTERRUPT_HH__
 #define __ARCH_SPARC_INTERRUPT_HH__
 
+#include "arch/generic/interrupts.hh"
 #include "arch/sparc/faults.hh"
 #include "arch/sparc/isa_traits.hh"
 #include "arch/sparc/registers.hh"
@@ -55,7 +56,7 @@ enum InterruptTypes
     NumInterruptTypes
 };
 
-class Interrupts : public SimObject
+class Interrupts : public BaseInterrupts
 {
   private:
     BaseCPU * cpu;
@@ -79,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();
     }
index f75d006451f1c3bbb09500481df14cf5c2c55179..b89f46550d4aa64b663d2e299f9def83ef4ef010 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "arch/sparc/asi.hh"
 #include "arch/sparc/decoder.hh"
+#include "arch/sparc/interrupts.hh"
 #include "base/bitfield.hh"
 #include "base/trace.hh"
 #include "cpu/base.hh"
index 914f29766c3bcc1d4fdf53bb8df0c31d768c6745..b7ab7bc6dc38bd3410f4c219902ed58779c4de79 100644 (file)
@@ -42,10 +42,11 @@ from m5.defines import buildEnv
 from m5.params import *
 from m5.proxy import *
 
+from m5.objects.BaseInterrupts import BaseInterrupts
 from m5.objects.ClockDomain import DerivedClockDomain
 from m5.SimObject import SimObject
 
-class X86LocalApic(SimObject):
+class X86LocalApic(BaseInterrupts):
     type = 'X86LocalApic'
     cxx_class = 'X86ISA::Interrupts'
     cxx_header = 'arch/x86/interrupts.hh'
index d237366ab1a27cfc4eec3e1ca37cf8895e68a2d1..80d2650ef40c3826251b0e9d88578af93b7efdeb 100644 (file)
@@ -596,7 +596,7 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
 
 
 X86ISA::Interrupts::Interrupts(Params * p)
-    : SimObject(p), sys(p->system), clockDomain(*p->clk_domain),
+    : BaseInterrupts(p), sys(p->system), clockDomain(*p->clk_domain),
       apicTimerEvent([this]{ processApicTimerEvent(); }, name()),
       pendingSmi(false), smiVector(0),
       pendingNmi(false), nmiVector(0),
index 519d9f10ec98c715f72915330f2148c8aa3d795d..3c383ab9204a878b6734a93af9076eba63114679 100644 (file)
 #ifndef __ARCH_X86_INTERRUPTS_HH__
 #define __ARCH_X86_INTERRUPTS_HH__
 
-#include "arch/x86/regs/apic.hh"
+#include "arch/generic/interrupts.hh"
 #include "arch/x86/faults.hh"
 #include "arch/x86/intmessage.hh"
+#include "arch/x86/regs/apic.hh"
 #include "base/bitfield.hh"
 #include "cpu/thread_context.hh"
-#include "dev/x86/intdev.hh"
 #include "dev/io_device.hh"
+#include "dev/x86/intdev.hh"
 #include "params/X86LocalApic.hh"
 #include "sim/eventq.hh"
 
@@ -72,7 +73,7 @@ namespace X86ISA {
 
 ApicRegIndex decodeAddr(Addr paddr);
 
-class Interrupts : public SimObject
+class Interrupts : public BaseInterrupts
 {
   protected:
     System *sys;
index 86f140fdc67b1066629c07ee8e6914975b94a954..aab0a711892e0090b35f8609a3b2e863be840f26 100644 (file)
@@ -53,6 +53,7 @@
 
 #include <memory>
 
+#include "arch/x86/faults.hh"
 #include "arch/x86/pagetable.hh"
 #include "arch/x86/tlb.hh"
 #include "arch/x86/vtophys.hh"
index 143ee922434afbffb1b3ae0178734ec4dd0dfee9..e17e26a11bc265c7d004db6f4635f44b1972d21d 100644 (file)
@@ -66,44 +66,37 @@ if buildEnv['TARGET_ISA'] == 'alpha':
     from m5.objects.AlphaTLB import AlphaDTB as ArchDTB, AlphaITB as ArchITB
     from m5.objects.AlphaInterrupts import AlphaInterrupts as ArchInterrupts
     from m5.objects.AlphaISA import AlphaISA as ArchISA
-    ArchInterruptsParam = VectorParam.AlphaInterrupts
     ArchISAsParam = VectorParam.AlphaISA
 elif buildEnv['TARGET_ISA'] == 'sparc':
     from m5.objects.SparcTLB import SparcTLB as ArchDTB, SparcTLB as ArchITB
     from m5.objects.SparcInterrupts import SparcInterrupts as ArchInterrupts
     from m5.objects.SparcISA import SparcISA as ArchISA
-    ArchInterruptsParam = VectorParam.SparcInterrupts
     ArchISAsParam = VectorParam.SparcISA
 elif buildEnv['TARGET_ISA'] == 'x86':
     from m5.objects.X86TLB import X86TLB as ArchDTB, X86TLB as ArchITB
     from m5.objects.X86LocalApic import X86LocalApic as ArchInterrupts
     from m5.objects.X86ISA import X86ISA as ArchISA
-    ArchInterruptsParam = VectorParam.X86LocalApic
     ArchISAsParam = VectorParam.X86ISA
 elif buildEnv['TARGET_ISA'] == 'mips':
     from m5.objects.MipsTLB import MipsTLB as ArchDTB, MipsTLB as ArchITB
     from m5.objects.MipsInterrupts import MipsInterrupts as ArchInterrupts
     from m5.objects.MipsISA import MipsISA as ArchISA
-    ArchInterruptsParam = VectorParam.MipsInterrupts
     ArchISAsParam = VectorParam.MipsISA
 elif buildEnv['TARGET_ISA'] == 'arm':
     from m5.objects.ArmTLB import ArmTLB as ArchDTB, ArmTLB as ArchITB
     from m5.objects.ArmTLB import ArmStage2IMMU, ArmStage2DMMU
     from m5.objects.ArmInterrupts import ArmInterrupts as ArchInterrupts
     from m5.objects.ArmISA import ArmISA as ArchISA
-    ArchInterruptsParam = VectorParam.ArmInterrupts
     ArchISAsParam = VectorParam.ArmISA
 elif buildEnv['TARGET_ISA'] == 'power':
     from m5.objects.PowerTLB import PowerTLB as ArchDTB, PowerTLB as ArchITB
     from m5.objects.PowerInterrupts import PowerInterrupts as ArchInterrupts
     from m5.objects.PowerISA import PowerISA as ArchISA
-    ArchInterruptsParam = VectorParam.PowerInterrupts
     ArchISAsParam = VectorParam.PowerISA
 elif buildEnv['TARGET_ISA'] == 'riscv':
     from m5.objects.RiscvTLB import RiscvTLB as ArchDTB, RiscvTLB as ArchITB
     from m5.objects.RiscvInterrupts import RiscvInterrupts as ArchInterrupts
     from m5.objects.RiscvISA import RiscvISA as ArchISA
-    ArchInterruptsParam = VectorParam.RiscvInterrupts
     ArchISAsParam = VectorParam.RiscvISA
 else:
     print("Don't know what object types to use for ISA %s" %
@@ -186,7 +179,7 @@ class BaseCPU(ClockedObject):
         dstage2_mmu = ArmStage2DMMU()
     elif buildEnv['TARGET_ISA'] == 'power':
         UnifiedTLB = Param.Bool(True, "Is this a Unified TLB?")
-    interrupts = ArchInterruptsParam([], "Interrupt Controller")
+    interrupts = VectorParam.BaseInterrupts([], "Interrupt Controller")
     isa = ArchISAsParam([], "ISA instance")
 
     max_insts_all_threads = Param.Counter(0,
index 383ae818528d26f6aad05c30fe8417f26e473d80..cb23cb1ba72cf2a00d57a1c7e67bcebb7ef81c68 100644 (file)
@@ -54,7 +54,7 @@
 #if THE_ISA == NULL_ISA
 #include "arch/null/cpu_dummy.hh"
 #else
-#include "arch/interrupts.hh"
+#include "arch/generic/interrupts.hh"
 #include "arch/isa_traits.hh"
 #include "arch/microcode_rom.hh"
 #include "base/statistics.hh"
@@ -219,10 +219,10 @@ class BaseCPU : public ClockedObject
     TheISA::MicrocodeRom microcodeRom;
 
   protected:
-    std::vector<TheISA::Interrupts*> interrupts;
+    std::vector<BaseInterrupts*> interrupts;
 
   public:
-    TheISA::Interrupts *
+    BaseInterrupts *
     getInterruptController(ThreadID tid)
     {
         if (interrupts.empty())
index 7bf518f04dd94bf73ab1e487368b28472a02649f..8d1258b4c8c49576a011d8651e743371de9e803f 100644 (file)
@@ -52,6 +52,7 @@
 #include "cpu/kvm/vm.hh"
 #include "cpu/base.hh"
 #include "cpu/simple_thread.hh"
+#include "sim/faults.hh"
 
 /** Signal to use to trigger exits from KVM */
 #define KVM_KICK_SIGNAL SIGRTMIN
index 681e142006db9efba18b9cbdd66f2dd8fb4b46c2..5d2250dae3cab91307a4c5d4d21357019b64eef5 100644 (file)
@@ -38,6 +38,8 @@
 
 #include "arch/registers.hh"
 #include "arch/x86/cpuid.hh"
+#include "arch/x86/faults.hh"
+#include "arch/x86/interrupts.hh"
 #include "arch/x86/regs/msr.hh"
 #include "arch/x86/utility.hh"
 #include "cpu/kvm/base.hh"
@@ -1185,8 +1187,10 @@ X86KvmCPU::kvmRun(Tick ticks)
 {
     struct kvm_run &kvm_run(*getKvmRunState());
 
-    if (interrupts[0]->checkInterruptsRaw()) {
-        if (interrupts[0]->hasPendingUnmaskable()) {
+    auto *lapic = dynamic_cast<X86ISA::Interrupts *>(interrupts[0]);
+
+    if (lapic->checkInterruptsRaw()) {
+        if (lapic->hasPendingUnmaskable()) {
             DPRINTF(KvmInt,
                     "Delivering unmaskable interrupt.\n");
             syncThreadContext();
@@ -1198,7 +1202,7 @@ X86KvmCPU::kvmRun(Tick ticks)
             // the thread context and check if there are /really/
             // interrupts that should be delivered now.
             syncThreadContext();
-            if (interrupts[0]->checkInterrupts(tc)) {
+            if (lapic->checkInterrupts(tc)) {
                 DPRINTF(KvmInt,
                         "M5 has pending interrupts, delivering interrupt.\n");
 
index d6742a780334168bc1bd78d9cb2ed4e063242904..ba50ad57f9381caf92a93ccdb8c1af67196bcafa 100644 (file)
@@ -216,8 +216,9 @@ X86ISA::I82094AA::signalInterrupt(int line)
             }
         } else {
             for (int i = 0; i < numContexts; i++) {
-                Interrupts *localApic = sys->getThreadContext(i)->
+                BaseInterrupts *base_int = sys->getThreadContext(i)->
                     getCpuPtr()->getInterruptController(0);
+                auto *localApic = dynamic_cast<Interrupts *>(base_int);
                 if ((localApic->readReg(APIC_LOGICAL_DESTINATION) >> 24) &
                         message.destination) {
                     apics.push_back(localApic->getInitialApicId());