summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2019-09-11 15:17:38 -0700
committerGabe Black <gabeblack@google.com>2019-10-15 00:47:23 +0000
commit3b58400b27629779a386ffb21e62473044d88680 (patch)
treed570553edb34ad2e1db78a9476e0f6fbb022b7a5
parent6518171f8204511d9c2ac26c8c203baba9276cd2 (diff)
downloadgem5-3b58400b27629779a386ffb21e62473044d88680.tar.xz
x86: De-x86ify the IntMasterPort.
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>
-rw-r--r--src/arch/x86/interrupts.cc8
-rw-r--r--src/arch/x86/intmessage.hh14
-rw-r--r--src/dev/x86/i82094aa.cc11
-rw-r--r--src/dev/x86/intdev.hh40
4 files changed, 40 insertions, 33 deletions
diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc
index d4ee9f6a6..1b21835c5 100644
--- a/src/arch/x86/interrupts.cc
+++ b/src/arch/x86/interrupts.cc
@@ -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;
diff --git a/src/arch/x86/intmessage.hh b/src/arch/x86/intmessage.hh
index d2a5dfa1c..bf1e5c44a 100644
--- a/src/arch/x86/intmessage.hh
+++ b/src/arch/x86/intmessage.hh
@@ -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);
}
}
diff --git a/src/dev/x86/i82094aa.cc b/src/dev/x86/i82094aa.cc
index 5daebe7b6..17ac65f96 100644
--- a/src/dev/x86/i82094aa.cc
+++ b/src/dev/x86/i82094aa.cc
@@ -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());
+ }
}
}
diff --git a/src/dev/x86/intdev.hh b/src/dev/x86/intdev.hh
index 052928043..48d32d771 100644
--- a/src/dev/x86/intdev.hh
+++ b/src/dev/x86/intdev.hh
@@ -44,10 +44,8 @@
#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);
}
}
};