summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);
}
}
};