Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/20828 )

Change subject: x86: Use a std::function to handle MSI completion.
......................................................................

x86: Use a std::function to handle MSI completion.

This removes the recvResponse callback from the IntMasterPort, and
makes it easier to handle the default case where we just need to clean
up the Packet.

Change-Id: I8bcbfee0aaf68b12310d773f925c399fc87ea65d
---
M src/arch/x86/interrupts.cc
M src/arch/x86/interrupts.hh
M src/dev/x86/i82094aa.cc
M src/dev/x86/intdev.hh
4 files changed, 21 insertions(+), 20 deletions(-)



diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc
index c612908..d7f4d08 100644
--- a/src/arch/x86/interrupts.cc
+++ b/src/arch/x86/interrupts.cc
@@ -331,11 +331,9 @@
 }


-bool
-X86ISA::Interrupts::recvResponse(PacketPtr pkt)
+void
+X86ISA::Interrupts::completeIPI(PacketPtr pkt)
 {
-    assert(!pkt->isError());
-    assert(pkt->cmd == MemCmd::WriteResp);
     if (--pendingIPIs == 0) {
         InterruptCommandRegLow low = regs[APIC_INTERRUPT_COMMAND_LOW];
         // Record that the ICR is now idle.
@@ -343,7 +341,7 @@
         regs[APIC_INTERRUPT_COMMAND_LOW] = low;
     }
     DPRINTF(LocalApic, "ICR is now idle.\n");
-    return true;
+    delete pkt;
 }


@@ -548,7 +546,8 @@
             regs[APIC_INTERRUPT_COMMAND_LOW] = low;
             for (auto id: apics) {
                 PacketPtr pkt = buildIntTriggerPacket(id, message);
-                intMasterPort.sendMessage(pkt, sys->isTimingMode());
+                intMasterPort.sendMessage(pkt, sys->isTimingMode(),
+                        [this](PacketPtr pkt) { completeIPI(pkt); });
             }
             newVal = regs[APIC_INTERRUPT_COMMAND_LOW];
         }
diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh
index d9d3496..de5f1e7 100644
--- a/src/arch/x86/interrupts.hh
+++ b/src/arch/x86/interrupts.hh
@@ -206,7 +206,7 @@
     Tick read(PacketPtr pkt) override;
     Tick write(PacketPtr pkt) override;
     Tick recvMessage(PacketPtr pkt);
-    bool recvResponse(PacketPtr pkt);
+    void completeIPI(PacketPtr pkt);

     bool
     triggerTimerInterrupt()
diff --git a/src/dev/x86/i82094aa.cc b/src/dev/x86/i82094aa.cc
index 17ac65f..d6742a7 100644
--- a/src/dev/x86/i82094aa.cc
+++ b/src/dev/x86/i82094aa.cc
@@ -89,14 +89,6 @@
         return BasicPioDevice::getPort(if_name, idx);
 }

-bool
-X86ISA::I82094AA::recvResponse(PacketPtr pkt)
-{
-    // Packet instantiated calling sendMessage() in signalInterrupt()
-    delete pkt;
-    return true;
-}
-
 Tick
 X86ISA::I82094AA::read(PacketPtr pkt)
 {
diff --git a/src/dev/x86/intdev.hh b/src/dev/x86/intdev.hh
index 2e564a6..01ffb06 100644
--- a/src/dev/x86/intdev.hh
+++ b/src/dev/x86/intdev.hh
@@ -44,6 +44,7 @@
 #define __DEV_X86_INTDEV_HH__

 #include <cassert>
+#include <functional>
 #include <string>

 #include "mem/tport.hh"
@@ -96,12 +97,18 @@
 template <class Device>
 class IntMasterPort : public QueuedMasterPort
 {
+  private:
     ReqPacketQueue reqQueue;
     SnoopRespPacketQueue snoopRespQueue;

     Device* device;
     Tick latency;

+    typedef std::function<void(PacketPtr)> OnCompletionFunc;
+    OnCompletionFunc onCompletion = nullptr;
+    // If nothing extra needs to happen, just clean up the packet.
+    static void defaultOnCompletion(PacketPtr pkt) { delete pkt; }
+
   public:
     IntMasterPort(const std::string& _name, SimObject* _parent,
                   Device* dev, Tick _latency) :
@@ -114,23 +121,26 @@
     bool
     recvTimingResp(PacketPtr pkt) override
     {
-        return device->recvResponse(pkt);
+        assert(pkt->isResponse());
+        onCompletion(pkt);
+        onCompletion = nullptr;
+        return true;
     }

     // This is x86 focused, so if this class becomes generic, this would
     // need to be moved into a subclass.
     void
-    sendMessage(PacketPtr pkt, bool timing)
+    sendMessage(PacketPtr pkt, bool timing,
+            OnCompletionFunc func=defaultOnCompletion)
     {
         if (timing) {
+            onCompletion = func;
             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);
+            func(pkt);
         }
     }
 };

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/20828
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I8bcbfee0aaf68b12310d773f925c399fc87ea65d
Gerrit-Change-Number: 20828
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <gabebl...@google.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to