x86: Templatize the IntMasterPort.

This makes the IntMasterPort usable with any class, making it possible
to avoid inheriting from IntDevice.

It also makes IntMasterPort inherit directly from QueuedMasterPort,
skipping over MessageMasterPort.

Change-Id: I9d218556c838ea567ced5f6fa4d57a3ec9d28d31
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20821
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc
index b7d0235..402b912 100644
--- a/src/arch/x86/interrupts.cc
+++ b/src/arch/x86/interrupts.cc
@@ -331,7 +331,7 @@
 }
 
 
-Tick
+bool
 X86ISA::Interrupts::recvResponse(PacketPtr pkt)
 {
     assert(!pkt->isError());
@@ -343,7 +343,7 @@
         regs[APIC_INTERRUPT_COMMAND_LOW] = low;
     }
     DPRINTF(LocalApic, "ICR is now idle.\n");
-    return 0;
+    return true;
 }
 
 
diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh
index 48e350c..e48fd4b 100644
--- a/src/arch/x86/interrupts.hh
+++ b/src/arch/x86/interrupts.hh
@@ -205,7 +205,7 @@
     Tick read(PacketPtr pkt) override;
     Tick write(PacketPtr pkt) override;
     Tick recvMessage(PacketPtr pkt);
-    Tick recvResponse(PacketPtr pkt) override;
+    bool recvResponse(PacketPtr pkt) override;
 
     bool
     triggerTimerInterrupt()
diff --git a/src/dev/x86/i82094aa.cc b/src/dev/x86/i82094aa.cc
index e73eec7..dfadbd9 100644
--- a/src/dev/x86/i82094aa.cc
+++ b/src/dev/x86/i82094aa.cc
@@ -85,12 +85,12 @@
         return BasicPioDevice::getPort(if_name, idx);
 }
 
-Tick
+bool
 X86ISA::I82094AA::recvResponse(PacketPtr pkt)
 {
     // Packet instantiated calling sendMessage() in signalInterrupt()
     delete pkt;
-    return 0;
+    return true;
 }
 
 Tick
diff --git a/src/dev/x86/i82094aa.hh b/src/dev/x86/i82094aa.hh
index 17a0da4..d9baf11 100644
--- a/src/dev/x86/i82094aa.hh
+++ b/src/dev/x86/i82094aa.hh
@@ -106,7 +106,7 @@
     Port &getPort(const std::string &if_name,
                   PortID idx=InvalidPortID) override;
 
-    Tick recvResponse(PacketPtr pkt) override;
+    bool recvResponse(PacketPtr pkt) override;
 
     void signalInterrupt(int line);
     void raiseInterruptPin(int number);
diff --git a/src/dev/x86/intdev.cc b/src/dev/x86/intdev.cc
index e6c068a..fbc2d51 100644
--- a/src/dev/x86/intdev.cc
+++ b/src/dev/x86/intdev.cc
@@ -43,27 +43,6 @@
 #include "dev/x86/intdev.hh"
 
 void
-X86ISA::IntDevice::IntMasterPort::sendMessage(ApicList apics,
-                                           TriggerIntMessage message,
-                                           bool timing)
-{
-    ApicList::iterator apicIt;
-    for (apicIt = apics.begin(); apicIt != apics.end(); apicIt++) {
-        PacketPtr pkt = buildIntRequest(*apicIt, message);
-        if (timing) {
-            schedTimingReq(pkt, curTick() + latency);
-            // The target handles cleaning up the packet in timing mode.
-        } else {
-            // ignore the latency involved in the atomic transaction
-            sendAtomic(pkt);
-            assert(pkt->isResponse());
-            // also ignore the latency in handling the response
-            recvResponse(pkt);
-        }
-    }
-}
-
-void
 X86ISA::IntDevice::init()
 {
     if (!intMasterPort.isConnected()) {
diff --git a/src/dev/x86/intdev.hh b/src/dev/x86/intdev.hh
index 1a198db..f71c9ff 100644
--- a/src/dev/x86/intdev.hh
+++ b/src/dev/x86/intdev.hh
@@ -49,10 +49,11 @@
 
 #include "arch/x86/intmessage.hh"
 #include "arch/x86/x86_traits.hh"
-#include "mem/mport.hh"
+#include "mem/tport.hh"
 #include "sim/sim_object.hh"
 
-namespace X86ISA {
+namespace X86ISA
+{
 
 template <class Device>
 class IntSlavePort : public SimpleTimingPort
@@ -85,33 +86,56 @@
 
 typedef std::list<int> ApicList;
 
+template <class Device>
+class IntMasterPort : public QueuedMasterPort
+{
+    ReqPacketQueue reqQueue;
+    SnoopRespPacketQueue snoopRespQueue;
+
+    Device* device;
+    Tick latency;
+
+  public:
+    IntMasterPort(const std::string& _name, SimObject* _parent,
+                  Device* dev, Tick _latency) :
+        QueuedMasterPort(_name, _parent, reqQueue, snoopRespQueue),
+        reqQueue(*_parent, *this), snoopRespQueue(*_parent, *this),
+        device(dev), latency(_latency)
+    {
+    }
+
+    bool
+    recvTimingResp(PacketPtr pkt) override
+    {
+        return device->recvResponse(pkt);
+    }
+
+    // This is x86 focused, so if this class becomes generic, this would
+    // need to be moved into a subclass.
+    void
+    sendMessage(X86ISA::ApicList apics, TriggerIntMessage message, bool timing)
+    {
+        for (auto id: apics) {
+            PacketPtr pkt = buildIntRequest(id, message);
+            if (timing) {
+                schedTimingReq(pkt, curTick() + latency);
+                // The target handles cleaning up the packet in timing mode.
+            } else {
+                // ignore the latency involved in the atomic transaction
+                sendAtomic(pkt);
+                assert(pkt->isResponse());
+                // also ignore the latency in handling the response
+                device->recvResponse(pkt);
+            }
+        }
+    }
+};
+
 class IntDevice
 {
   protected:
 
-    class IntMasterPort : public MessageMasterPort
-    {
-        IntDevice* device;
-        Tick latency;
-      public:
-        IntMasterPort(const std::string& _name, SimObject* _parent,
-                      IntDevice* dev, Tick _latency) :
-            MessageMasterPort(_name, _parent), device(dev), latency(_latency)
-        {
-        }
-
-        Tick recvResponse(PacketPtr pkt)
-        {
-            return device->recvResponse(pkt);
-        }
-
-        // This is x86 focused, so if this class becomes generic, this would
-        // need to be moved into a subclass.
-        void sendMessage(ApicList apics,
-                TriggerIntMessage message, bool timing);
-    };
-
-    IntMasterPort intMasterPort;
+    IntMasterPort<IntDevice> intMasterPort;
 
   public:
     IntDevice(SimObject * parent, Tick latency = 0) :
@@ -124,11 +148,10 @@
 
     virtual void init();
 
-    virtual Tick
+    virtual bool
     recvResponse(PacketPtr pkt)
     {
         panic("recvResponse not implemented.\n");
-        return 0;
     }
 };