x86: De-x86ify the IntMasterPort.
authorGabe Black <gabeblack@google.com>
Wed, 11 Sep 2019 22:17:38 +0000 (15:17 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 15 Oct 2019 00:47:23 +0000 (00:47 +0000)
The devices which host an IntMasterPort are very specific to x86 at the
moment, but the ports don't have to be. This change moves
responsibilities around so that the x86 specific aspects are handled
in the device, and the ports themselves are ISA agnostic.

Change-Id: I50141b66895be7d8f6303605505002ef424af7fd
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20827
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/x86/interrupts.cc
src/arch/x86/intmessage.hh
src/dev/x86/i82094aa.cc
src/dev/x86/intdev.hh

index d4ee9f6a6241c632072e5710dce22954c257de8f..1b21835c5b4c152a5aee56fb19f1dd322ce22ca4 100644 (file)
@@ -51,6 +51,7 @@
 
 #include "arch/x86/interrupts.hh"
 
+#include <list>
 #include <memory>
 
 #include "arch/x86/intmessage.hh"
@@ -484,7 +485,7 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
             message.destMode = low.destMode;
             message.level = low.level;
             message.trigger = low.trigger;
-            ApicList apics;
+            std::list<int> apics;
             int numContexts = sys->numContexts();
             switch (low.destShorthand) {
               case 0:
@@ -545,7 +546,10 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
                 pendingIPIs += apics.size();
             }
             regs[APIC_INTERRUPT_COMMAND_LOW] = low;
-            intMasterPort.sendMessage(apics, message, sys->isTimingMode());
+            for (auto id: apics) {
+                PacketPtr pkt = buildIntTriggerPacket(id, message);
+                intMasterPort.sendMessage(pkt, sys->isTimingMode());
+            }
             newVal = regs[APIC_INTERRUPT_COMMAND_LOW];
         }
         break;
index d2a5dfa1c7c5506a718ea43be6cc9a78f213d03a..bf1e5c44aea9b0b76b8aab32f1423e0252050d3d 100644 (file)
@@ -34,6 +34,7 @@
 #include "arch/x86/x86_traits.hh"
 #include "base/bitunion.hh"
 #include "base/types.hh"
+#include "dev/x86/intdev.hh"
 #include "mem/packet.hh"
 #include "mem/packet_access.hh"
 #include "mem/request.hh"
@@ -76,16 +77,11 @@ namespace X86ISA
 
     static const Addr TriggerIntOffset = 0;
 
-    template<class T>
-    PacketPtr
-    buildIntPacket(Addr addr, T payload)
+    static inline PacketPtr
+    buildIntTriggerPacket(int id, TriggerIntMessage message)
     {
-        RequestPtr req = std::make_shared<Request>(
-            addr, sizeof(T), Request::UNCACHEABLE, Request::intMasterId);
-        PacketPtr pkt = new Packet(req, MemCmd::WriteReq);
-        pkt->allocate();
-        pkt->setRaw<T>(payload);
-        return pkt;
+        Addr addr = x86InterruptAddress(id, TriggerIntOffset);
+        return buildIntPacket(addr, message);
     }
 }
 
index 5daebe7b654040b4e152184d8bb9709f65f79483..17ac65f96ad69afdef71e7abd30e491fcdafb7bc 100644 (file)
@@ -30,6 +30,8 @@
 
 #include "dev/x86/i82094aa.hh"
 
+#include <list>
+
 #include "arch/x86/interrupts.hh"
 #include "arch/x86/intmessage.hh"
 #include "cpu/base.hh"
@@ -205,7 +207,7 @@ X86ISA::I82094AA::signalInterrupt(int line)
         message.destMode = entry.destMode;
         message.level = entry.polarity;
         message.trigger = entry.trigger;
-        ApicList apics;
+        std::list<int> apics;
         int numContexts = sys->numContexts();
         if (message.destMode == 0) {
             if (message.deliveryMode == DeliveryMode::LowestPriority) {
@@ -237,7 +239,7 @@ X86ISA::I82094AA::signalInterrupt(int line)
                 // through the set of APICs selected above.
                 uint64_t modOffset = lowestPriorityOffset % apics.size();
                 lowestPriorityOffset++;
-                ApicList::iterator apicIt = apics.begin();
+                auto apicIt = apics.begin();
                 while (modOffset--) {
                     apicIt++;
                     assert(apicIt != apics.end());
@@ -247,7 +249,10 @@ X86ISA::I82094AA::signalInterrupt(int line)
                 apics.push_back(selected);
             }
         }
-        intMasterPort.sendMessage(apics, message, sys->isTimingMode());
+        for (auto id: apics) {
+            PacketPtr pkt = buildIntTriggerPacket(id, message);
+            intMasterPort.sendMessage(pkt, sys->isTimingMode());
+        }
     }
 }
 
index 052928043f4f116a7da9094c8190813a92a42420..48d32d7715faca5a4d91ba296707a874629028c7 100644 (file)
 #define __DEV_X86_INTDEV_HH__
 
 #include <cassert>
-#include <list>
 #include <string>
 
-#include "arch/x86/intmessage.hh"
 #include "mem/tport.hh"
 #include "sim/sim_object.hh"
 
@@ -83,7 +81,17 @@ class IntSlavePort : public SimpleTimingPort
     }
 };
 
-typedef std::list<int> ApicList;
+template<class T>
+PacketPtr
+buildIntPacket(Addr addr, T payload)
+{
+    RequestPtr req = std::make_shared<Request>(
+        addr, sizeof(T), Request::UNCACHEABLE, Request::intMasterId);
+    PacketPtr pkt = new Packet(req, MemCmd::WriteReq);
+    pkt->allocate();
+    pkt->setRaw<T>(payload);
+    return pkt;
+}
 
 template <class Device>
 class IntMasterPort : public QueuedMasterPort
@@ -109,24 +117,18 @@ class IntMasterPort : public QueuedMasterPort
         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)
+    sendMessage(PacketPtr pkt, bool timing)
     {
-        for (auto id: apics) {
-            Addr addr = x86InterruptAddress(id, TriggerIntOffset);
-            PacketPtr pkt = buildIntPacket(addr, 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);
-            }
+        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);
         }
     }
 };