Port: Add protocol-agnostic ports in the port hierarchy

This patch adds an additional level of ports in the inheritance
hierarchy, separating out the protocol-specific and protocl-agnostic
parts. All the functionality related to the binding of ports is now
confined to use BaseMaster/BaseSlavePorts, and all the
protocol-specific parts stay in the Master/SlavePort. In the future it
will be possible to add other protocol-specific implementations.

The functions used in the binding of ports, i.e. getMaster/SlavePort
now use the base classes, and the index parameter is updated to use
the PortID typedef with the symbolic InvalidPortID as the default.
This commit is contained in:
Andreas Hansson 2012-10-15 08:12:35 -04:00
parent 9baa35ba80
commit 2a740aa096
53 changed files with 290 additions and 192 deletions

View file

@ -110,8 +110,8 @@ TableWalker::resume()
} }
} }
MasterPort& BaseMasterPort&
TableWalker::getMasterPort(const std::string &if_name, int idx) TableWalker::getMasterPort(const std::string &if_name, PortID idx)
{ {
if (if_name == "port") { if (if_name == "port") {
return port; return port;

View file

@ -399,8 +399,8 @@ class TableWalker : public MemObject
void completeDrain(); void completeDrain();
virtual unsigned int drain(Event *de); virtual unsigned int drain(Event *de);
virtual void resume(); virtual void resume();
virtual MasterPort& getMasterPort(const std::string &if_name, virtual BaseMasterPort& getMasterPort(const std::string &if_name,
int idx = -1); PortID idx = InvalidPortID);
Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode, Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode,
TLB::Translation *_trans, bool timing, bool functional = false); TLB::Translation *_trans, bool timing, bool functional = false);

View file

@ -722,7 +722,7 @@ TLB::translateTiming(RequestPtr req, ThreadContext *tc,
return fault; return fault;
} }
MasterPort* BaseMasterPort*
TLB::getMasterPort() TLB::getMasterPort()
{ {
return &tableWalker->getMasterPort("port"); return &tableWalker->getMasterPort("port");

View file

@ -224,7 +224,7 @@ class TLB : public BaseTLB
* *
* @return A pointer to the walker master port * @return A pointer to the walker master port
*/ */
virtual MasterPort* getMasterPort(); virtual BaseMasterPort* getMasterPort();
// Caching misc register values here. // Caching misc register values here.
// Writing to misc registers needs to invalidate them. // Writing to misc registers needs to invalidate them.

View file

@ -238,7 +238,8 @@ class Interrupts : public BasicPioDevice, IntDev
AddrRangeList getAddrRanges() const; AddrRangeList getAddrRanges() const;
AddrRangeList getIntAddrRange() const; AddrRangeList getIntAddrRange() const;
MasterPort &getMasterPort(const std::string &if_name, int idx = -1) BaseMasterPort &getMasterPort(const std::string &if_name,
PortID idx = InvalidPortID)
{ {
if (if_name == "int_master") { if (if_name == "int_master") {
return intMasterPort; return intMasterPort;
@ -246,7 +247,8 @@ class Interrupts : public BasicPioDevice, IntDev
return BasicPioDevice::getMasterPort(if_name, idx); return BasicPioDevice::getMasterPort(if_name, idx);
} }
SlavePort &getSlavePort(const std::string &if_name, int idx = -1) BaseSlavePort &getSlavePort(const std::string &if_name,
PortID idx = InvalidPortID)
{ {
if (if_name == "int_slave") { if (if_name == "int_slave") {
return intSlavePort; return intSlavePort;

View file

@ -173,8 +173,8 @@ bool Walker::sendTiming(WalkerState* sendingState, PacketPtr pkt)
return port.sendTimingReq(pkt); return port.sendTimingReq(pkt);
} }
MasterPort & BaseMasterPort &
Walker::getMasterPort(const std::string &if_name, int idx) Walker::getMasterPort(const std::string &if_name, PortID idx)
{ {
if (if_name == "port") if (if_name == "port")
return port; return port;

View file

@ -169,7 +169,8 @@ namespace X86ISA
RequestPtr req, BaseTLB::Mode mode); RequestPtr req, BaseTLB::Mode mode);
Fault startFunctional(ThreadContext * _tc, Addr &addr, Fault startFunctional(ThreadContext * _tc, Addr &addr,
unsigned &logBytes, BaseTLB::Mode mode); unsigned &logBytes, BaseTLB::Mode mode);
MasterPort &getMasterPort(const std::string &if_name, int idx = -1); BaseMasterPort &getMasterPort(const std::string &if_name,
PortID idx = InvalidPortID);
protected: protected:
// The TLB we're supposed to load. // The TLB we're supposed to load.

View file

@ -435,7 +435,7 @@ TLB::unserialize(Checkpoint *cp, const std::string &section)
{ {
} }
MasterPort * BaseMasterPort *
TLB::getMasterPort() TLB::getMasterPort()
{ {
return &walker->getMasterPort("port"); return &walker->getMasterPort("port");

View file

@ -147,7 +147,7 @@ namespace X86ISA
* *
* @return A pointer to the walker master port * @return A pointer to the walker master port
*/ */
virtual MasterPort *getMasterPort(); virtual BaseMasterPort *getMasterPort();
}; };
} }

View file

@ -296,8 +296,8 @@ BaseCPU::regStats()
threadContexts[0]->regStats(name()); threadContexts[0]->regStats(name());
} }
MasterPort & BaseMasterPort &
BaseCPU::getMasterPort(const string &if_name, int idx) BaseCPU::getMasterPort(const string &if_name, PortID idx)
{ {
// Get the right port based on name. This applies to all the // Get the right port based on name. This applies to all the
// subclasses of the base CPU and relies on their implementation // subclasses of the base CPU and relies on their implementation
@ -380,17 +380,17 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
ThreadContext::compare(oldTC, newTC); ThreadContext::compare(oldTC, newTC);
*/ */
MasterPort *old_itb_port = oldTC->getITBPtr()->getMasterPort(); BaseMasterPort *old_itb_port = oldTC->getITBPtr()->getMasterPort();
MasterPort *old_dtb_port = oldTC->getDTBPtr()->getMasterPort(); BaseMasterPort *old_dtb_port = oldTC->getDTBPtr()->getMasterPort();
MasterPort *new_itb_port = newTC->getITBPtr()->getMasterPort(); BaseMasterPort *new_itb_port = newTC->getITBPtr()->getMasterPort();
MasterPort *new_dtb_port = newTC->getDTBPtr()->getMasterPort(); BaseMasterPort *new_dtb_port = newTC->getDTBPtr()->getMasterPort();
// Move over any table walker ports if they exist // Move over any table walker ports if they exist
if (new_itb_port) { if (new_itb_port) {
assert(!new_itb_port->isConnected()); assert(!new_itb_port->isConnected());
assert(old_itb_port); assert(old_itb_port);
assert(old_itb_port->isConnected()); assert(old_itb_port->isConnected());
SlavePort &slavePort = old_itb_port->getSlavePort(); BaseSlavePort &slavePort = old_itb_port->getSlavePort();
old_itb_port->unbind(); old_itb_port->unbind();
new_itb_port->bind(slavePort); new_itb_port->bind(slavePort);
} }
@ -398,7 +398,7 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
assert(!new_dtb_port->isConnected()); assert(!new_dtb_port->isConnected());
assert(old_dtb_port); assert(old_dtb_port);
assert(old_dtb_port->isConnected()); assert(old_dtb_port->isConnected());
SlavePort &slavePort = old_dtb_port->getSlavePort(); BaseSlavePort &slavePort = old_dtb_port->getSlavePort();
old_dtb_port->unbind(); old_dtb_port->unbind();
new_dtb_port->bind(slavePort); new_dtb_port->bind(slavePort);
} }
@ -408,13 +408,13 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
CheckerCPU *oldChecker = oldTC->getCheckerCpuPtr(); CheckerCPU *oldChecker = oldTC->getCheckerCpuPtr();
CheckerCPU *newChecker = newTC->getCheckerCpuPtr(); CheckerCPU *newChecker = newTC->getCheckerCpuPtr();
if (oldChecker && newChecker) { if (oldChecker && newChecker) {
MasterPort *old_checker_itb_port = BaseMasterPort *old_checker_itb_port =
oldChecker->getITBPtr()->getMasterPort(); oldChecker->getITBPtr()->getMasterPort();
MasterPort *old_checker_dtb_port = BaseMasterPort *old_checker_dtb_port =
oldChecker->getDTBPtr()->getMasterPort(); oldChecker->getDTBPtr()->getMasterPort();
MasterPort *new_checker_itb_port = BaseMasterPort *new_checker_itb_port =
newChecker->getITBPtr()->getMasterPort(); newChecker->getITBPtr()->getMasterPort();
MasterPort *new_checker_dtb_port = BaseMasterPort *new_checker_dtb_port =
newChecker->getDTBPtr()->getMasterPort(); newChecker->getDTBPtr()->getMasterPort();
// Move over any table walker ports if they exist for checker // Move over any table walker ports if they exist for checker
@ -422,7 +422,8 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
assert(!new_checker_itb_port->isConnected()); assert(!new_checker_itb_port->isConnected());
assert(old_checker_itb_port); assert(old_checker_itb_port);
assert(old_checker_itb_port->isConnected()); assert(old_checker_itb_port->isConnected());
SlavePort &slavePort = old_checker_itb_port->getSlavePort(); BaseSlavePort &slavePort =
old_checker_itb_port->getSlavePort();
old_checker_itb_port->unbind(); old_checker_itb_port->unbind();
new_checker_itb_port->bind(slavePort); new_checker_itb_port->bind(slavePort);
} }
@ -430,7 +431,8 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
assert(!new_checker_dtb_port->isConnected()); assert(!new_checker_dtb_port->isConnected());
assert(old_checker_dtb_port); assert(old_checker_dtb_port);
assert(old_checker_dtb_port->isConnected()); assert(old_checker_dtb_port->isConnected());
SlavePort &slavePort = old_checker_dtb_port->getSlavePort(); BaseSlavePort &slavePort =
old_checker_dtb_port->getSlavePort();
old_checker_dtb_port->unbind(); old_checker_dtb_port->unbind();
new_checker_dtb_port->bind(slavePort); new_checker_dtb_port->bind(slavePort);
} }
@ -455,13 +457,13 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
// we are switching to. // we are switching to.
assert(!getInstPort().isConnected()); assert(!getInstPort().isConnected());
assert(oldCPU->getInstPort().isConnected()); assert(oldCPU->getInstPort().isConnected());
SlavePort &inst_peer_port = oldCPU->getInstPort().getSlavePort(); BaseSlavePort &inst_peer_port = oldCPU->getInstPort().getSlavePort();
oldCPU->getInstPort().unbind(); oldCPU->getInstPort().unbind();
getInstPort().bind(inst_peer_port); getInstPort().bind(inst_peer_port);
assert(!getDataPort().isConnected()); assert(!getDataPort().isConnected());
assert(oldCPU->getDataPort().isConnected()); assert(oldCPU->getDataPort().isConnected());
SlavePort &data_peer_port = oldCPU->getDataPort().getSlavePort(); BaseSlavePort &data_peer_port = oldCPU->getDataPort().getSlavePort();
oldCPU->getDataPort().unbind(); oldCPU->getDataPort().unbind();
getDataPort().bind(data_peer_port); getDataPort().bind(data_peer_port);
} }

View file

@ -171,7 +171,8 @@ class BaseCPU : public MemObject
* *
* @return a reference to the port with the given name * @return a reference to the port with the given name
*/ */
MasterPort &getMasterPort(const std::string &if_name, int idx = -1); BaseMasterPort &getMasterPort(const std::string &if_name,
PortID idx = InvalidPortID);
inline void workItemBegin() { numWorkItemsStarted++; } inline void workItemBegin() { numWorkItemsStarted++; }
inline void workItemEnd() { numWorkItemsCompleted++; } inline void workItemEnd() { numWorkItemsCompleted++; }

View file

@ -74,8 +74,8 @@ RubyDirectedTester::init()
generator->setDirectedTester(this); generator->setDirectedTester(this);
} }
MasterPort & BaseMasterPort &
RubyDirectedTester::getMasterPort(const std::string &if_name, int idx) RubyDirectedTester::getMasterPort(const std::string &if_name, PortID idx)
{ {
if (if_name != "cpuPort") { if (if_name != "cpuPort") {
// pass it along to our super class // pass it along to our super class

View file

@ -68,8 +68,8 @@ class RubyDirectedTester : public MemObject
RubyDirectedTester(const Params *p); RubyDirectedTester(const Params *p);
~RubyDirectedTester(); ~RubyDirectedTester();
virtual MasterPort &getMasterPort(const std::string &if_name, virtual BaseMasterPort &getMasterPort(const std::string &if_name,
int idx = -1); PortID idx = InvalidPortID);
MasterPort* getCpuPort(int idx); MasterPort* getCpuPort(int idx);

View file

@ -131,8 +131,8 @@ MemTest::MemTest(const Params *p)
dmaOutstanding = false; dmaOutstanding = false;
} }
MasterPort & BaseMasterPort &
MemTest::getMasterPort(const std::string &if_name, int idx) MemTest::getMasterPort(const std::string &if_name, PortID idx)
{ {
if (if_name == "functional") if (if_name == "functional")
return funcPort; return funcPort;

View file

@ -59,8 +59,8 @@ class MemTest : public MemObject
// main simulation loop (one cycle) // main simulation loop (one cycle)
void tick(); void tick();
virtual MasterPort &getMasterPort(const std::string &if_name, virtual BaseMasterPort &getMasterPort(const std::string &if_name,
int idx = -1); PortID idx = InvalidPortID);
/** /**
* Print state of address in memory system via PrintReq (for * Print state of address in memory system via PrintReq (for

View file

@ -97,8 +97,8 @@ NetworkTest::NetworkTest(const Params *p)
name(), id); name(), id);
} }
MasterPort & BaseMasterPort &
NetworkTest::getMasterPort(const std::string &if_name, int idx) NetworkTest::getMasterPort(const std::string &if_name, PortID idx)
{ {
if (if_name == "test") if (if_name == "test")
return cachePort; return cachePort;

View file

@ -54,8 +54,8 @@ class NetworkTest : public MemObject
// main simulation loop (one cycle) // main simulation loop (one cycle)
void tick(); void tick();
virtual MasterPort &getMasterPort(const std::string &if_name, virtual BaseMasterPort &getMasterPort(const std::string &if_name,
int idx = -1); PortID idx = InvalidPortID);
/** /**
* Print state of address in memory system via PrintReq (for * Print state of address in memory system via PrintReq (for

View file

@ -111,8 +111,8 @@ RubyTester::init()
m_checkTable_ptr = new CheckTable(m_num_writers, m_num_readers, this); m_checkTable_ptr = new CheckTable(m_num_writers, m_num_readers, this);
} }
MasterPort & BaseMasterPort &
RubyTester::getMasterPort(const std::string &if_name, int idx) RubyTester::getMasterPort(const std::string &if_name, PortID idx)
{ {
if (if_name != "cpuInstPort" && if_name != "cpuDataPort") { if (if_name != "cpuInstPort" && if_name != "cpuDataPort") {
// pass it along to our super class // pass it along to our super class
@ -134,7 +134,7 @@ RubyTester::getMasterPort(const std::string &if_name, int idx)
// index // index
// //
int read_idx = idx + m_num_inst_ports; int read_idx = idx + m_num_inst_ports;
if (read_idx >= static_cast<int>(readPorts.size())) { if (read_idx >= static_cast<PortID>(readPorts.size())) {
panic("RubyTester::getMasterPort: unknown data port idx %d\n", panic("RubyTester::getMasterPort: unknown data port idx %d\n",
idx); idx);
} }

View file

@ -89,8 +89,8 @@ class RubyTester : public MemObject
RubyTester(const Params *p); RubyTester(const Params *p);
~RubyTester(); ~RubyTester();
virtual MasterPort &getMasterPort(const std::string &if_name, virtual BaseMasterPort &getMasterPort(const std::string &if_name,
int idx = -1); PortID idx = InvalidPortID);
bool isInstReadableCpuPort(int idx); bool isInstReadableCpuPort(int idx);

View file

@ -66,8 +66,8 @@ TrafficGenParams::create()
return new TrafficGen(this); return new TrafficGen(this);
} }
MasterPort& BaseMasterPort&
TrafficGen::getMasterPort(const string& if_name, int idx) TrafficGen::getMasterPort(const string& if_name, PortID idx)
{ {
if (if_name == "port") { if (if_name == "port") {
return port; return port;

View file

@ -597,8 +597,8 @@ class TrafficGen : public MemObject
~TrafficGen() {} ~TrafficGen() {}
virtual MasterPort& getMasterPort(const std::string &if_name, virtual BaseMasterPort& getMasterPort(const std::string &if_name,
int idx = InvalidPortID); PortID idx = InvalidPortID);
void init(); void init();

View file

@ -110,8 +110,8 @@ CopyEngine::CopyEngineChannel::~CopyEngineChannel()
delete [] copyBuffer; delete [] copyBuffer;
} }
MasterPort & BaseMasterPort &
CopyEngine::getMasterPort(const std::string &if_name, int idx) CopyEngine::getMasterPort(const std::string &if_name, PortID idx)
{ {
if (if_name != "dma") { if (if_name != "dma") {
// pass it along to our super class // pass it along to our super class
@ -126,7 +126,7 @@ CopyEngine::getMasterPort(const std::string &if_name, int idx)
} }
MasterPort & BaseMasterPort &
CopyEngine::CopyEngineChannel::getMasterPort() CopyEngine::CopyEngineChannel::getMasterPort()
{ {
return cePort; return cePort;

View file

@ -94,7 +94,7 @@ class CopyEngine : public PciDev
public: public:
CopyEngineChannel(CopyEngine *_ce, int cid); CopyEngineChannel(CopyEngine *_ce, int cid);
virtual ~CopyEngineChannel(); virtual ~CopyEngineChannel();
MasterPort &getMasterPort(); BaseMasterPort &getMasterPort();
std::string name() { assert(ce); return ce->name() + csprintf("-chan%d", channelId); } std::string name() { assert(ce); return ce->name() + csprintf("-chan%d", channelId); }
virtual Tick read(PacketPtr pkt) virtual Tick read(PacketPtr pkt)
@ -196,8 +196,8 @@ class CopyEngine : public PciDev
void regStats(); void regStats();
virtual MasterPort &getMasterPort(const std::string &if_name, virtual BaseMasterPort &getMasterPort(const std::string &if_name,
int idx = -1); PortID idx = InvalidPortID);
virtual Tick read(PacketPtr pkt); virtual Tick read(PacketPtr pkt);
virtual Tick write(PacketPtr pkt); virtual Tick write(PacketPtr pkt);

View file

@ -254,8 +254,8 @@ DmaPort::sendDma()
panic("Unknown memory mode."); panic("Unknown memory mode.");
} }
MasterPort & BaseMasterPort &
DmaDevice::getMasterPort(const std::string &if_name, int idx) DmaDevice::getMasterPort(const std::string &if_name, PortID idx)
{ {
if (if_name == "dma") { if (if_name == "dma") {
return dmaPort; return dmaPort;

View file

@ -156,8 +156,8 @@ class DmaDevice : public PioDevice
unsigned cacheBlockSize() const { return dmaPort.cacheBlockSize(); } unsigned cacheBlockSize() const { return dmaPort.cacheBlockSize(); }
virtual MasterPort &getMasterPort(const std::string &if_name, virtual BaseMasterPort &getMasterPort(const std::string &if_name,
int idx = -1); PortID idx = InvalidPortID);
friend class DmaPort; friend class DmaPort;
}; };

View file

@ -79,8 +79,8 @@ PioDevice::init()
pioPort.sendRangeChange(); pioPort.sendRangeChange();
} }
SlavePort & BaseSlavePort &
PioDevice::getSlavePort(const std::string &if_name, int idx) PioDevice::getSlavePort(const std::string &if_name, PortID idx)
{ {
if (if_name == "pio") { if (if_name == "pio") {
return pioPort; return pioPort;

View file

@ -127,7 +127,8 @@ class PioDevice : public MemObject
virtual unsigned int drain(Event *de); virtual unsigned int drain(Event *de);
virtual SlavePort &getSlavePort(const std::string &if_name, int idx = -1); virtual BaseSlavePort &getSlavePort(const std::string &if_name,
PortID idx = InvalidPortID);
friend class PioPort; friend class PioPort;

View file

@ -218,7 +218,8 @@ class PciDev : public DmaDevice
virtual unsigned int drain(Event *de); virtual unsigned int drain(Event *de);
virtual SlavePort &getSlavePort(const std::string &if_name, int idx = -1) virtual BaseSlavePort &getSlavePort(const std::string &if_name,
PortID idx = InvalidPortID)
{ {
if (if_name == "config") { if (if_name == "config") {
return configPort; return configPort;

View file

@ -120,7 +120,8 @@ class I82094AA : public PioDevice, public IntDev
void writeReg(uint8_t offset, uint32_t value); void writeReg(uint8_t offset, uint32_t value);
uint32_t readReg(uint8_t offset); uint32_t readReg(uint8_t offset);
MasterPort &getMasterPort(const std::string &if_name, int idx = -1) BaseMasterPort &getMasterPort(const std::string &if_name,
PortID idx = InvalidPortID)
{ {
if (if_name == "int_master") if (if_name == "int_master")
return intMasterPort; return intMasterPort;

View file

@ -59,8 +59,8 @@ AddrMapper::init()
slavePort.peerBlockSize(), masterPort.peerBlockSize()); slavePort.peerBlockSize(), masterPort.peerBlockSize());
} }
MasterPort& BaseMasterPort&
AddrMapper::getMasterPort(const std::string& if_name, int idx) AddrMapper::getMasterPort(const std::string& if_name, PortID idx)
{ {
if (if_name == "master") { if (if_name == "master") {
return masterPort; return masterPort;
@ -69,8 +69,8 @@ AddrMapper::getMasterPort(const std::string& if_name, int idx)
} }
} }
SlavePort& BaseSlavePort&
AddrMapper::getSlavePort(const std::string& if_name, int idx) AddrMapper::getSlavePort(const std::string& if_name, PortID idx)
{ {
if (if_name == "slave") { if (if_name == "slave") {
return slavePort; return slavePort;
@ -192,7 +192,7 @@ AddrMapper::recvTimingSnoopResp(PacketPtr pkt)
bool bool
AddrMapper::isSnooping() const AddrMapper::isSnooping() const
{ {
if (slavePort.getMasterPort().isSnooping()) if (slavePort.isSnooping())
fatal("AddrMapper doesn't support remapping of snooping requests\n"); fatal("AddrMapper doesn't support remapping of snooping requests\n");
return false; return false;
} }
@ -266,7 +266,7 @@ AddrRangeList
RangeAddrMapper::getAddrRanges() const RangeAddrMapper::getAddrRanges() const
{ {
AddrRangeList ranges; AddrRangeList ranges;
AddrRangeList actualRanges = masterPort.getSlavePort().getAddrRanges(); AddrRangeList actualRanges = masterPort.getAddrRanges();
for (AddrRangeIter r = actualRanges.begin(); r != actualRanges.end(); ++r) { for (AddrRangeIter r = actualRanges.begin(); r != actualRanges.end(); ++r) {
AddrRange range = *r; AddrRange range = *r;

View file

@ -62,11 +62,11 @@ class AddrMapper : public MemObject
virtual ~AddrMapper() { } virtual ~AddrMapper() { }
virtual MasterPort& getMasterPort(const std::string& if_name, virtual BaseMasterPort& getMasterPort(const std::string& if_name,
int idx = -1); PortID idx = InvalidPortID);
virtual SlavePort& getSlavePort(const std::string& if_name, virtual BaseSlavePort& getSlavePort(const std::string& if_name,
int idx = -1); PortID idx = InvalidPortID);
virtual void init(); virtual void init();

View file

@ -83,8 +83,8 @@ Bridge::Bridge(Params *p)
{ {
} }
MasterPort& BaseMasterPort&
Bridge::getMasterPort(const std::string &if_name, int idx) Bridge::getMasterPort(const std::string &if_name, PortID idx)
{ {
if (if_name == "master") if (if_name == "master")
return masterPort; return masterPort;
@ -93,8 +93,8 @@ Bridge::getMasterPort(const std::string &if_name, int idx)
return MemObject::getMasterPort(if_name, idx); return MemObject::getMasterPort(if_name, idx);
} }
SlavePort& BaseSlavePort&
Bridge::getSlavePort(const std::string &if_name, int idx) Bridge::getSlavePort(const std::string &if_name, PortID idx)
{ {
if (if_name == "slave") if (if_name == "slave")
return slavePort; return slavePort;

View file

@ -338,9 +338,10 @@ class Bridge : public MemObject
public: public:
virtual MasterPort& getMasterPort(const std::string& if_name, virtual BaseMasterPort& getMasterPort(const std::string& if_name,
int idx = -1); PortID idx = InvalidPortID);
virtual SlavePort& getSlavePort(const std::string& if_name, int idx = -1); virtual BaseSlavePort& getSlavePort(const std::string& if_name,
PortID idx = InvalidPortID);
virtual void init(); virtual void init();

View file

@ -105,8 +105,8 @@ BaseBus::init()
warn_once("Block size is neither 16, 32, 64 or 128 bytes.\n"); warn_once("Block size is neither 16, 32, 64 or 128 bytes.\n");
} }
MasterPort & BaseMasterPort &
BaseBus::getMasterPort(const std::string &if_name, int idx) BaseBus::getMasterPort(const std::string &if_name, PortID idx)
{ {
if (if_name == "master" && idx < masterPorts.size()) { if (if_name == "master" && idx < masterPorts.size()) {
// the master port index translates directly to the vector position // the master port index translates directly to the vector position
@ -118,8 +118,8 @@ BaseBus::getMasterPort(const std::string &if_name, int idx)
} }
} }
SlavePort & BaseSlavePort &
BaseBus::getSlavePort(const std::string &if_name, int idx) BaseBus::getSlavePort(const std::string &if_name, PortID idx)
{ {
if (if_name == "slave" && idx < slavePorts.size()) { if (if_name == "slave" && idx < slavePorts.size()) {
// the slave port index translates directly to the vector position // the slave port index translates directly to the vector position

View file

@ -361,8 +361,10 @@ class BaseBus : public MemObject
virtual void init(); virtual void init();
/** A function used to return the port associated with this bus object. */ /** A function used to return the port associated with this bus object. */
virtual MasterPort& getMasterPort(const std::string& if_name, int idx = -1); BaseMasterPort& getMasterPort(const std::string& if_name,
virtual SlavePort& getSlavePort(const std::string& if_name, int idx = -1); PortID idx = InvalidPortID);
BaseSlavePort& getSlavePort(const std::string& if_name,
PortID idx = InvalidPortID);
virtual unsigned int drain(Event *de) = 0; virtual unsigned int drain(Event *de) = 0;

View file

@ -118,8 +118,8 @@ BaseCache::init()
cpuSidePort->sendRangeChange(); cpuSidePort->sendRangeChange();
} }
MasterPort & BaseMasterPort &
BaseCache::getMasterPort(const std::string &if_name, int idx) BaseCache::getMasterPort(const std::string &if_name, PortID idx)
{ {
if (if_name == "mem_side") { if (if_name == "mem_side") {
return *memSidePort; return *memSidePort;
@ -128,8 +128,8 @@ BaseCache::getMasterPort(const std::string &if_name, int idx)
} }
} }
SlavePort & BaseSlavePort &
BaseCache::getSlavePort(const std::string &if_name, int idx) BaseCache::getSlavePort(const std::string &if_name, PortID idx)
{ {
if (if_name == "cpu_side") { if (if_name == "cpu_side") {
return *cpuSidePort; return *cpuSidePort;

View file

@ -430,8 +430,10 @@ class BaseCache : public MemObject
virtual void init(); virtual void init();
virtual MasterPort &getMasterPort(const std::string &if_name, int idx = -1); virtual BaseMasterPort &getMasterPort(const std::string &if_name,
virtual SlavePort &getSlavePort(const std::string &if_name, int idx = -1); PortID idx = InvalidPortID);
virtual BaseSlavePort &getSlavePort(const std::string &if_name,
PortID idx = InvalidPortID);
/** /**
* Query block size of a cache. * Query block size of a cache.

View file

@ -74,8 +74,8 @@ CommMonitor::init()
fatal("Communication monitor is not connected on both sides.\n"); fatal("Communication monitor is not connected on both sides.\n");
} }
MasterPort& BaseMasterPort&
CommMonitor::getMasterPort(const std::string& if_name, int idx) CommMonitor::getMasterPort(const std::string& if_name, PortID idx)
{ {
if (if_name == "master") { if (if_name == "master") {
return masterPort; return masterPort;
@ -84,8 +84,8 @@ CommMonitor::getMasterPort(const std::string& if_name, int idx)
} }
} }
SlavePort& BaseSlavePort&
CommMonitor::getSlavePort(const std::string& if_name, int idx) CommMonitor::getSlavePort(const std::string& if_name, PortID idx)
{ {
if (if_name == "slave") { if (if_name == "slave") {
return slavePort; return slavePort;

View file

@ -77,11 +77,11 @@ class CommMonitor : public MemObject
/** Destructor */ /** Destructor */
~CommMonitor() { } ~CommMonitor() { }
virtual MasterPort& getMasterPort(const std::string& if_name, virtual BaseMasterPort& getMasterPort(const std::string& if_name,
int idx = -1); PortID idx = InvalidPortID);
virtual SlavePort& getSlavePort(const std::string& if_name, virtual BaseSlavePort& getSlavePort(const std::string& if_name,
int idx = -1); PortID idx = InvalidPortID);
virtual void init(); virtual void init();

View file

@ -48,14 +48,14 @@ MemObject::MemObject(const Params *params)
{ {
} }
MasterPort& BaseMasterPort&
MemObject::getMasterPort(const std::string& if_name, int idx) MemObject::getMasterPort(const std::string& if_name, PortID idx)
{ {
fatal("%s does not have any master port named %s\n", name(), if_name); fatal("%s does not have any master port named %s\n", name(), if_name);
} }
SlavePort& BaseSlavePort&
MemObject::getSlavePort(const std::string& if_name, int idx) MemObject::getSlavePort(const std::string& if_name, PortID idx)
{ {
fatal("%s does not have any slave port named %s\n", name(), if_name); fatal("%s does not have any slave port named %s\n", name(), if_name);
} }

View file

@ -67,26 +67,30 @@ class MemObject : public ClockedObject
MemObject(const Params *params); MemObject(const Params *params);
/** /**
* Get a master port with a given name and index. * Get a master port with a given name and index. This is used at
* binding time and returns a reference to a protocol-agnostic
* base master port.
* *
* @param if_name Port name * @param if_name Port name
* @param idx Index in the case of a VectorPort * @param idx Index in the case of a VectorPort
* *
* @return A reference to the given port * @return A reference to the given port
*/ */
virtual MasterPort& getMasterPort(const std::string& if_name, virtual BaseMasterPort& getMasterPort(const std::string& if_name,
int idx = -1); PortID idx = InvalidPortID);
/** /**
* Get a slave port with a given name and index. * Get a slave port with a given name and index. This is used at
* binding time and returns a reference to a protocol-agnostic
* base master port.
* *
* @param if_name Port name * @param if_name Port name
* @param idx Index in the case of a VectorPort * @param idx Index in the case of a VectorPort
* *
* @return A reference to the given port * @return A reference to the given port
*/ */
virtual SlavePort& getSlavePort(const std::string& if_name, virtual BaseSlavePort& getSlavePort(const std::string& if_name,
int idx = -1); PortID idx = InvalidPortID);
}; };
#endif //__MEM_MEM_OBJECT_HH__ #endif //__MEM_MEM_OBJECT_HH__

View file

@ -59,11 +59,63 @@ Port::~Port()
{ {
} }
BaseMasterPort::BaseMasterPort(const std::string& name, MemObject* owner,
PortID _id)
: Port(name, *owner, _id), _baseSlavePort(NULL)
{
}
BaseMasterPort::~BaseMasterPort()
{
}
BaseSlavePort&
BaseMasterPort::getSlavePort() const
{
if(_baseSlavePort == NULL)
panic("Cannot getSlavePort on master port %s that is not connected\n",
name());
return *_baseSlavePort;
}
bool
BaseMasterPort::isConnected() const
{
return _baseSlavePort != NULL;
}
BaseSlavePort::BaseSlavePort(const std::string& name, MemObject* owner,
PortID _id)
: Port(name, *owner, _id), _baseMasterPort(NULL)
{
}
BaseSlavePort::~BaseSlavePort()
{
}
BaseMasterPort&
BaseSlavePort::getMasterPort() const
{
if(_baseMasterPort == NULL)
panic("Cannot getMasterPort on slave port %s that is not connected\n",
name());
return *_baseMasterPort;
}
bool
BaseSlavePort::isConnected() const
{
return _baseMasterPort != NULL;
}
/** /**
* Master port * Master port
*/ */
MasterPort::MasterPort(const std::string& name, MemObject* owner, PortID _id) MasterPort::MasterPort(const std::string& name, MemObject* owner, PortID _id)
: Port(name, *owner, _id), _slavePort(NULL) : BaseMasterPort(name, owner, _id), _slavePort(NULL)
{ {
} }
@ -71,14 +123,25 @@ MasterPort::~MasterPort()
{ {
} }
SlavePort& void
MasterPort::getSlavePort() const MasterPort::bind(BaseSlavePort& slave_port)
{ {
if(_slavePort == NULL) // bind on the level of the base ports
panic("Cannot getSlavePort on master port %s that is not connected\n", _baseSlavePort = &slave_port;
name());
return *_slavePort; // also attempt to base the slave to the appropriate type
SlavePort* cast_slave_port = dynamic_cast<SlavePort*>(&slave_port);
// if this port is compatible, then proceed with the binding
if (cast_slave_port != NULL) {
// master port keeps track of the slave port
_slavePort = cast_slave_port;
// slave port also keeps track of master port
_slavePort->bind(*this);
} else {
fatal("Master port %s cannot bind to %s\n", name(),
slave_port.name());
}
} }
void void
@ -89,26 +152,7 @@ MasterPort::unbind()
name()); name());
_slavePort->unbind(); _slavePort->unbind();
_slavePort = NULL; _slavePort = NULL;
} _baseSlavePort = NULL;
void
MasterPort::bind(SlavePort& slave_port)
{
if (_slavePort != NULL)
panic("Attempting to bind master port %s that is already connected\n",
name());
// master port keeps track of the slave port
_slavePort = &slave_port;
// slave port also keeps track of master port
_slavePort->bind(*this);
}
bool
MasterPort::isConnected() const
{
return _slavePort != NULL;
} }
unsigned unsigned
@ -172,7 +216,7 @@ MasterPort::printAddr(Addr a)
* Slave port * Slave port
*/ */
SlavePort::SlavePort(const std::string& name, MemObject* owner, PortID id) SlavePort::SlavePort(const std::string& name, MemObject* owner, PortID id)
: Port(name, *owner, id), _masterPort(NULL) : BaseSlavePort(name, owner, id), _masterPort(NULL)
{ {
} }
@ -183,37 +227,23 @@ SlavePort::~SlavePort()
void void
SlavePort::unbind() SlavePort::unbind()
{ {
_baseMasterPort = NULL;
_masterPort = NULL; _masterPort = NULL;
} }
void void
SlavePort::bind(MasterPort& master_port) SlavePort::bind(MasterPort& master_port)
{ {
_baseMasterPort = &master_port;
_masterPort = &master_port; _masterPort = &master_port;
} }
MasterPort&
SlavePort::getMasterPort() const
{
if (_masterPort == NULL)
panic("Cannot getMasterPort on slave port %s that is not connected\n",
name());
return *_masterPort;
}
unsigned unsigned
SlavePort::peerBlockSize() const SlavePort::peerBlockSize() const
{ {
return _masterPort->deviceBlockSize(); return _masterPort->deviceBlockSize();
} }
bool
SlavePort::isConnected() const
{
return _masterPort != NULL;
}
Tick Tick
SlavePort::sendAtomicSnoop(PacketPtr pkt) SlavePort::sendAtomicSnoop(PacketPtr pkt)
{ {

View file

@ -116,16 +116,68 @@ class Port
}; };
/** Forward declaration */
class BaseSlavePort;
/**
* A BaseMasterPort is a protocol-agnostic master port, responsible
* only for the structural connection to a slave port. The final
* master port that inherits from the base class must override the
* bind member function for the specific slave port class.
*/
class BaseMasterPort : public Port
{
protected:
BaseSlavePort* _baseSlavePort;
BaseMasterPort(const std::string& name, MemObject* owner,
PortID id = InvalidPortID);
virtual ~BaseMasterPort();
public:
virtual void bind(BaseSlavePort& slave_port) = 0;
virtual void unbind() = 0;
BaseSlavePort& getSlavePort() const;
bool isConnected() const;
};
/**
* A BaseSlavePort is a protocol-agnostic slave port, responsible
* only for the structural connection to a master port.
*/
class BaseSlavePort : public Port
{
protected:
BaseMasterPort* _baseMasterPort;
BaseSlavePort(const std::string& name, MemObject* owner,
PortID id = InvalidPortID);
virtual ~BaseSlavePort();
public:
BaseMasterPort& getMasterPort() const;
bool isConnected() const;
};
/** Forward declaration */ /** Forward declaration */
class SlavePort; class SlavePort;
/** /**
* A MasterPort is a specialisation of a port. In addition to the * A MasterPort is a specialisation of a BaseMasterPort, which
* basic functionality of sending packets to its slave peer, it also * implements the default protocol for the three different level of
* has functions specific to a master, e.g. to receive range changes * transport functions. In addition to the basic functionality of
* or determine if the port is snooping or not. * sending packets, it also has functions to receive range changes or
* determine if the port is snooping or not.
*/ */
class MasterPort : public Port class MasterPort : public BaseMasterPort
{ {
friend class SlavePort; friend class SlavePort;
@ -144,16 +196,13 @@ class MasterPort : public Port
* Bind this master port to a slave port. This also does the * Bind this master port to a slave port. This also does the
* mirror action and binds the slave port to the master port. * mirror action and binds the slave port to the master port.
*/ */
void bind(SlavePort& slave_port); void bind(BaseSlavePort& slave_port);
/** /**
* Unbind this master port and the associated slave port. * Unbind this master port and the associated slave port.
*/ */
void unbind(); void unbind();
SlavePort& getSlavePort() const;
bool isConnected() const;
/** /**
* Send an atomic request packet, where the data is moved and the * Send an atomic request packet, where the data is moved and the
* state is updated in zero time, without interleaving with other * state is updated in zero time, without interleaving with other
@ -292,7 +341,7 @@ class MasterPort : public Port
* has functions specific to a slave, e.g. to send range changes * has functions specific to a slave, e.g. to send range changes
* and get the address ranges that the port responds to. * and get the address ranges that the port responds to.
*/ */
class SlavePort : public Port class SlavePort : public BaseSlavePort
{ {
friend class MasterPort; friend class MasterPort;
@ -307,9 +356,6 @@ class SlavePort : public Port
PortID id = InvalidPortID); PortID id = InvalidPortID);
virtual ~SlavePort(); virtual ~SlavePort();
MasterPort& getMasterPort() const;
bool isConnected() const;
/** /**
* Send an atomic snoop request packet, where the data is moved * Send an atomic snoop request packet, where the data is moved
* and the state is updated in zero time, without interleaving * and the state is updated in zero time, without interleaving

View file

@ -78,8 +78,8 @@ RubyPort::init()
m_mandatory_q_ptr = m_controller->getMandatoryQueue(); m_mandatory_q_ptr = m_controller->getMandatoryQueue();
} }
MasterPort & BaseMasterPort &
RubyPort::getMasterPort(const std::string &if_name, int idx) RubyPort::getMasterPort(const std::string &if_name, PortID idx)
{ {
if (if_name == "pio_port") { if (if_name == "pio_port") {
return pio_port; return pio_port;
@ -91,7 +91,7 @@ RubyPort::getMasterPort(const std::string &if_name, int idx)
// pass it along to our super class // pass it along to our super class
return MemObject::getMasterPort(if_name, idx); return MemObject::getMasterPort(if_name, idx);
} else { } else {
if (idx >= static_cast<int>(master_ports.size())) { if (idx >= static_cast<PortID>(master_ports.size())) {
panic("RubyPort::getMasterPort: unknown index %d\n", idx); panic("RubyPort::getMasterPort: unknown index %d\n", idx);
} }
@ -99,8 +99,8 @@ RubyPort::getMasterPort(const std::string &if_name, int idx)
} }
} }
SlavePort & BaseSlavePort &
RubyPort::getSlavePort(const std::string &if_name, int idx) RubyPort::getSlavePort(const std::string &if_name, PortID idx)
{ {
// used by the CPUs to connect the caches to the interconnect, and // used by the CPUs to connect the caches to the interconnect, and
// for the x86 case also the interrupt master // for the x86 case also the interrupt master
@ -108,7 +108,7 @@ RubyPort::getSlavePort(const std::string &if_name, int idx)
// pass it along to our super class // pass it along to our super class
return MemObject::getSlavePort(if_name, idx); return MemObject::getSlavePort(if_name, idx);
} else { } else {
if (idx >= static_cast<int>(slave_ports.size())) { if (idx >= static_cast<PortID>(slave_ports.size())) {
panic("RubyPort::getSlavePort: unknown index %d\n", idx); panic("RubyPort::getSlavePort: unknown index %d\n", idx);
} }

View file

@ -126,8 +126,10 @@ class RubyPort : public MemObject
void init(); void init();
MasterPort &getMasterPort(const std::string &if_name, int idx); BaseMasterPort &getMasterPort(const std::string &if_name,
SlavePort &getSlavePort(const std::string &if_name, int idx); PortID idx = InvalidPortID);
BaseSlavePort &getSlavePort(const std::string &if_name,
PortID idx = InvalidPortID);
virtual RequestStatus makeRequest(PacketPtr pkt) = 0; virtual RequestStatus makeRequest(PacketPtr pkt) = 0;
virtual int outstandingCount() const = 0; virtual int outstandingCount() const = 0;

View file

@ -1186,8 +1186,8 @@ SimpleDRAM::recvFunctional(PacketPtr pkt)
functionalAccess(pkt); functionalAccess(pkt);
} }
SlavePort& BaseSlavePort&
SimpleDRAM::getSlavePort(const string &if_name, int idx) SimpleDRAM::getSlavePort(const string &if_name, PortID idx)
{ {
if (if_name != "port") { if (if_name != "port") {
return MemObject::getSlavePort(if_name, idx); return MemObject::getSlavePort(if_name, idx);

View file

@ -461,8 +461,8 @@ class SimpleDRAM : public AbstractMemory
unsigned int drain(Event* de); unsigned int drain(Event* de);
virtual SlavePort& getSlavePort(const std::string& if_name, virtual BaseSlavePort& getSlavePort(const std::string& if_name,
int idx = InvalidPortID); PortID idx = InvalidPortID);
virtual void init(); virtual void init();
virtual void startup(); virtual void startup();

View file

@ -165,8 +165,8 @@ SimpleMemory::release()
} }
} }
SlavePort & BaseSlavePort &
SimpleMemory::getSlavePort(const std::string &if_name, int idx) SimpleMemory::getSlavePort(const std::string &if_name, PortID idx)
{ {
if (if_name != "port") { if (if_name != "port") {
return MemObject::getSlavePort(if_name, idx); return MemObject::getSlavePort(if_name, idx);

View file

@ -125,7 +125,8 @@ class SimpleMemory : public AbstractMemory
unsigned int drain(Event* de); unsigned int drain(Event* de);
virtual SlavePort& getSlavePort(const std::string& if_name, int idx = -1); virtual BaseSlavePort& getSlavePort(const std::string& if_name,
PortID idx = InvalidPortID);
virtual void init(); virtual void init();
protected: protected:

View file

@ -102,8 +102,8 @@ connectPorts(SimObject *o1, const std::string &name1, int i1,
} }
// generic master/slave port connection // generic master/slave port connection
MasterPort& masterPort = mo1->getMasterPort(name1, i1); BaseMasterPort& masterPort = mo1->getMasterPort(name1, i1);
SlavePort& slavePort = mo2->getSlavePort(name2, i2); BaseSlavePort& slavePort = mo2->getSlavePort(name2, i2);
masterPort.bind(slavePort); masterPort.bind(slavePort);

View file

@ -171,8 +171,8 @@ System::init()
panic("System port on %s is not connected.\n", name()); panic("System port on %s is not connected.\n", name());
} }
MasterPort& BaseMasterPort&
System::getMasterPort(const std::string &if_name, int idx) System::getMasterPort(const std::string &if_name, PortID idx)
{ {
// no need to distinguish at the moment (besides checking) // no need to distinguish at the moment (besides checking)
return _systemPort; return _systemPort;

View file

@ -117,7 +117,8 @@ class System : public MemObject
/** /**
* Additional function to return the Port of a memory object. * Additional function to return the Port of a memory object.
*/ */
MasterPort& getMasterPort(const std::string &if_name, int idx = -1); BaseMasterPort& getMasterPort(const std::string &if_name,
PortID idx = InvalidPortID);
static const char *MemoryModeStrings[3]; static const char *MemoryModeStrings[3];

View file

@ -49,7 +49,7 @@
#include "sim/sim_object.hh" #include "sim/sim_object.hh"
class ThreadContext; class ThreadContext;
class MasterPort; class BaseMasterPort;
class BaseTLB : public SimObject class BaseTLB : public SimObject
{ {
@ -73,7 +73,7 @@ class BaseTLB : public SimObject
* *
* @return A pointer to the walker master port or NULL if not present * @return A pointer to the walker master port or NULL if not present
*/ */
virtual MasterPort* getMasterPort() { return NULL; } virtual BaseMasterPort* getMasterPort() { return NULL; }
class Translation class Translation
{ {