}
-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.
regs[APIC_INTERRUPT_COMMAND_LOW] = low;
}
DPRINTF(LocalApic, "ICR is now idle.\n");
- return true;
+ delete pkt;
}
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];
}
Tick read(PacketPtr pkt) override;
Tick write(PacketPtr pkt) override;
Tick recvMessage(PacketPtr pkt);
- bool recvResponse(PacketPtr pkt);
+ void completeIPI(PacketPtr pkt);
bool
triggerTimerInterrupt()
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)
{
#define __DEV_X86_INTDEV_HH__
#include <cassert>
+#include <functional>
#include <string>
#include "mem/tport.hh"
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) :
bool
recvTimingResp(PacketPtr pkt) override
{
- return device->recvResponse(pkt);
+ assert(pkt->isResponse());
+ onCompletion(pkt);
+ onCompletion = nullptr;
+ return true;
}
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);
}
}
};