x86: Templatize the IntMasterPort.

This makes the IntMasterPort usable with any class, making it possible
to avoid inheriting from IntDevice.

It also makes IntMasterPort inherit directly from QueuedMasterPort,
skipping over MessageMasterPort.

Change-Id: I9d218556c838ea567ced5f6fa4d57a3ec9d28d31
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20821
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
This commit is contained in:
Gabe Black
2019-09-11 13:26:09 -07:00
parent cc03cf8270
commit e6c6f0601c
6 changed files with 56 additions and 54 deletions

View File

@@ -331,7 +331,7 @@ X86ISA::Interrupts::recvMessage(PacketPtr pkt)
}
Tick
bool
X86ISA::Interrupts::recvResponse(PacketPtr pkt)
{
assert(!pkt->isError());
@@ -343,7 +343,7 @@ X86ISA::Interrupts::recvResponse(PacketPtr pkt)
regs[APIC_INTERRUPT_COMMAND_LOW] = low;
}
DPRINTF(LocalApic, "ICR is now idle.\n");
return 0;
return true;
}

View File

@@ -205,7 +205,7 @@ class Interrupts : public PioDevice, IntDevice
Tick read(PacketPtr pkt) override;
Tick write(PacketPtr pkt) override;
Tick recvMessage(PacketPtr pkt);
Tick recvResponse(PacketPtr pkt) override;
bool recvResponse(PacketPtr pkt) override;
bool
triggerTimerInterrupt()

View File

@@ -85,12 +85,12 @@ X86ISA::I82094AA::getPort(const std::string &if_name, PortID idx)
return BasicPioDevice::getPort(if_name, idx);
}
Tick
bool
X86ISA::I82094AA::recvResponse(PacketPtr pkt)
{
// Packet instantiated calling sendMessage() in signalInterrupt()
delete pkt;
return 0;
return true;
}
Tick

View File

@@ -106,7 +106,7 @@ class I82094AA : public BasicPioDevice, public IntDevice
Port &getPort(const std::string &if_name,
PortID idx=InvalidPortID) override;
Tick recvResponse(PacketPtr pkt) override;
bool recvResponse(PacketPtr pkt) override;
void signalInterrupt(int line);
void raiseInterruptPin(int number);

View File

@@ -42,27 +42,6 @@
#include "dev/x86/intdev.hh"
void
X86ISA::IntDevice::IntMasterPort::sendMessage(ApicList apics,
TriggerIntMessage message,
bool timing)
{
ApicList::iterator apicIt;
for (apicIt = apics.begin(); apicIt != apics.end(); apicIt++) {
PacketPtr pkt = buildIntRequest(*apicIt, 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
recvResponse(pkt);
}
}
}
void
X86ISA::IntDevice::init()
{

View File

@@ -49,10 +49,11 @@
#include "arch/x86/intmessage.hh"
#include "arch/x86/x86_traits.hh"
#include "mem/mport.hh"
#include "mem/tport.hh"
#include "sim/sim_object.hh"
namespace X86ISA {
namespace X86ISA
{
template <class Device>
class IntSlavePort : public SimpleTimingPort
@@ -85,33 +86,56 @@ class IntSlavePort : public SimpleTimingPort
typedef std::list<int> ApicList;
template <class Device>
class IntMasterPort : public QueuedMasterPort
{
ReqPacketQueue reqQueue;
SnoopRespPacketQueue snoopRespQueue;
Device* device;
Tick latency;
public:
IntMasterPort(const std::string& _name, SimObject* _parent,
Device* dev, Tick _latency) :
QueuedMasterPort(_name, _parent, reqQueue, snoopRespQueue),
reqQueue(*_parent, *this), snoopRespQueue(*_parent, *this),
device(dev), latency(_latency)
{
}
bool
recvTimingResp(PacketPtr pkt) override
{
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)
{
for (auto id: apics) {
PacketPtr pkt = buildIntRequest(id, 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);
}
}
}
};
class IntDevice
{
protected:
class IntMasterPort : public MessageMasterPort
{
IntDevice* device;
Tick latency;
public:
IntMasterPort(const std::string& _name, SimObject* _parent,
IntDevice* dev, Tick _latency) :
MessageMasterPort(_name, _parent), device(dev), latency(_latency)
{
}
Tick recvResponse(PacketPtr pkt)
{
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(ApicList apics,
TriggerIntMessage message, bool timing);
};
IntMasterPort intMasterPort;
IntMasterPort<IntDevice> intMasterPort;
public:
IntDevice(SimObject * parent, Tick latency = 0) :
@@ -124,11 +148,10 @@ class IntDevice
virtual void init();
virtual Tick
virtual bool
recvResponse(PacketPtr pkt)
{
panic("recvResponse not implemented.\n");
return 0;
}
};