}
}
-MasterPort&
-TableWalker::getMasterPort(const std::string &if_name, int idx)
+BaseMasterPort&
+TableWalker::getMasterPort(const std::string &if_name, PortID idx)
{
if (if_name == "port") {
return port;
void completeDrain();
virtual unsigned int drain(Event *de);
virtual void resume();
- virtual MasterPort& getMasterPort(const std::string &if_name,
- int idx = -1);
+ virtual BaseMasterPort& getMasterPort(const std::string &if_name,
+ PortID idx = InvalidPortID);
Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode,
TLB::Translation *_trans, bool timing, bool functional = false);
return fault;
}
-MasterPort*
+BaseMasterPort*
TLB::getMasterPort()
{
return &tableWalker->getMasterPort("port");
*
* @return A pointer to the walker master port
*/
- virtual MasterPort* getMasterPort();
+ virtual BaseMasterPort* getMasterPort();
// Caching misc register values here.
// Writing to misc registers needs to invalidate them.
AddrRangeList getAddrRanges() 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") {
return intMasterPort;
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") {
return intSlavePort;
return port.sendTimingReq(pkt);
}
-MasterPort &
-Walker::getMasterPort(const std::string &if_name, int idx)
+BaseMasterPort &
+Walker::getMasterPort(const std::string &if_name, PortID idx)
{
if (if_name == "port")
return port;
RequestPtr req, BaseTLB::Mode mode);
Fault startFunctional(ThreadContext * _tc, Addr &addr,
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:
// The TLB we're supposed to load.
{
}
-MasterPort *
+BaseMasterPort *
TLB::getMasterPort()
{
return &walker->getMasterPort("port");
*
* @return A pointer to the walker master port
*/
- virtual MasterPort *getMasterPort();
+ virtual BaseMasterPort *getMasterPort();
};
}
threadContexts[0]->regStats(name());
}
-MasterPort &
-BaseCPU::getMasterPort(const string &if_name, int idx)
+BaseMasterPort &
+BaseCPU::getMasterPort(const string &if_name, PortID idx)
{
// Get the right port based on name. This applies to all the
// subclasses of the base CPU and relies on their implementation
ThreadContext::compare(oldTC, newTC);
*/
- MasterPort *old_itb_port = oldTC->getITBPtr()->getMasterPort();
- MasterPort *old_dtb_port = oldTC->getDTBPtr()->getMasterPort();
- MasterPort *new_itb_port = newTC->getITBPtr()->getMasterPort();
- MasterPort *new_dtb_port = newTC->getDTBPtr()->getMasterPort();
+ BaseMasterPort *old_itb_port = oldTC->getITBPtr()->getMasterPort();
+ BaseMasterPort *old_dtb_port = oldTC->getDTBPtr()->getMasterPort();
+ BaseMasterPort *new_itb_port = newTC->getITBPtr()->getMasterPort();
+ BaseMasterPort *new_dtb_port = newTC->getDTBPtr()->getMasterPort();
// Move over any table walker ports if they exist
if (new_itb_port) {
assert(!new_itb_port->isConnected());
assert(old_itb_port);
assert(old_itb_port->isConnected());
- SlavePort &slavePort = old_itb_port->getSlavePort();
+ BaseSlavePort &slavePort = old_itb_port->getSlavePort();
old_itb_port->unbind();
new_itb_port->bind(slavePort);
}
assert(!new_dtb_port->isConnected());
assert(old_dtb_port);
assert(old_dtb_port->isConnected());
- SlavePort &slavePort = old_dtb_port->getSlavePort();
+ BaseSlavePort &slavePort = old_dtb_port->getSlavePort();
old_dtb_port->unbind();
new_dtb_port->bind(slavePort);
}
CheckerCPU *oldChecker = oldTC->getCheckerCpuPtr();
CheckerCPU *newChecker = newTC->getCheckerCpuPtr();
if (oldChecker && newChecker) {
- MasterPort *old_checker_itb_port =
+ BaseMasterPort *old_checker_itb_port =
oldChecker->getITBPtr()->getMasterPort();
- MasterPort *old_checker_dtb_port =
+ BaseMasterPort *old_checker_dtb_port =
oldChecker->getDTBPtr()->getMasterPort();
- MasterPort *new_checker_itb_port =
+ BaseMasterPort *new_checker_itb_port =
newChecker->getITBPtr()->getMasterPort();
- MasterPort *new_checker_dtb_port =
+ BaseMasterPort *new_checker_dtb_port =
newChecker->getDTBPtr()->getMasterPort();
// Move over any table walker ports if they exist for checker
assert(!new_checker_itb_port->isConnected());
assert(old_checker_itb_port);
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();
new_checker_itb_port->bind(slavePort);
}
assert(!new_checker_dtb_port->isConnected());
assert(old_checker_dtb_port);
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();
new_checker_dtb_port->bind(slavePort);
}
// we are switching to.
assert(!getInstPort().isConnected());
assert(oldCPU->getInstPort().isConnected());
- SlavePort &inst_peer_port = oldCPU->getInstPort().getSlavePort();
+ BaseSlavePort &inst_peer_port = oldCPU->getInstPort().getSlavePort();
oldCPU->getInstPort().unbind();
getInstPort().bind(inst_peer_port);
assert(!getDataPort().isConnected());
assert(oldCPU->getDataPort().isConnected());
- SlavePort &data_peer_port = oldCPU->getDataPort().getSlavePort();
+ BaseSlavePort &data_peer_port = oldCPU->getDataPort().getSlavePort();
oldCPU->getDataPort().unbind();
getDataPort().bind(data_peer_port);
}
*
* @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 workItemEnd() { numWorkItemsCompleted++; }
generator->setDirectedTester(this);
}
-MasterPort &
-RubyDirectedTester::getMasterPort(const std::string &if_name, int idx)
+BaseMasterPort &
+RubyDirectedTester::getMasterPort(const std::string &if_name, PortID idx)
{
if (if_name != "cpuPort") {
// pass it along to our super class
RubyDirectedTester(const Params *p);
~RubyDirectedTester();
- virtual MasterPort &getMasterPort(const std::string &if_name,
- int idx = -1);
+ virtual BaseMasterPort &getMasterPort(const std::string &if_name,
+ PortID idx = InvalidPortID);
MasterPort* getCpuPort(int idx);
dmaOutstanding = false;
}
-MasterPort &
-MemTest::getMasterPort(const std::string &if_name, int idx)
+BaseMasterPort &
+MemTest::getMasterPort(const std::string &if_name, PortID idx)
{
if (if_name == "functional")
return funcPort;
// main simulation loop (one cycle)
void tick();
- virtual MasterPort &getMasterPort(const std::string &if_name,
- int idx = -1);
+ virtual BaseMasterPort &getMasterPort(const std::string &if_name,
+ PortID idx = InvalidPortID);
/**
* Print state of address in memory system via PrintReq (for
name(), id);
}
-MasterPort &
-NetworkTest::getMasterPort(const std::string &if_name, int idx)
+BaseMasterPort &
+NetworkTest::getMasterPort(const std::string &if_name, PortID idx)
{
if (if_name == "test")
return cachePort;
// main simulation loop (one cycle)
void tick();
- virtual MasterPort &getMasterPort(const std::string &if_name,
- int idx = -1);
+ virtual BaseMasterPort &getMasterPort(const std::string &if_name,
+ PortID idx = InvalidPortID);
/**
* Print state of address in memory system via PrintReq (for
m_checkTable_ptr = new CheckTable(m_num_writers, m_num_readers, this);
}
-MasterPort &
-RubyTester::getMasterPort(const std::string &if_name, int idx)
+BaseMasterPort &
+RubyTester::getMasterPort(const std::string &if_name, PortID idx)
{
if (if_name != "cpuInstPort" && if_name != "cpuDataPort") {
// pass it along to our super class
// index
//
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",
idx);
}
RubyTester(const Params *p);
~RubyTester();
- virtual MasterPort &getMasterPort(const std::string &if_name,
- int idx = -1);
+ virtual BaseMasterPort &getMasterPort(const std::string &if_name,
+ PortID idx = InvalidPortID);
bool isInstReadableCpuPort(int idx);
return new TrafficGen(this);
}
-MasterPort&
-TrafficGen::getMasterPort(const string& if_name, int idx)
+BaseMasterPort&
+TrafficGen::getMasterPort(const string& if_name, PortID idx)
{
if (if_name == "port") {
return port;
~TrafficGen() {}
- virtual MasterPort& getMasterPort(const std::string &if_name,
- int idx = InvalidPortID);
+ virtual BaseMasterPort& getMasterPort(const std::string &if_name,
+ PortID idx = InvalidPortID);
void init();
delete [] copyBuffer;
}
-MasterPort &
-CopyEngine::getMasterPort(const std::string &if_name, int idx)
+BaseMasterPort &
+CopyEngine::getMasterPort(const std::string &if_name, PortID idx)
{
if (if_name != "dma") {
// pass it along to our super class
}
-MasterPort &
+BaseMasterPort &
CopyEngine::CopyEngineChannel::getMasterPort()
{
return cePort;
public:
CopyEngineChannel(CopyEngine *_ce, int cid);
virtual ~CopyEngineChannel();
- MasterPort &getMasterPort();
+ BaseMasterPort &getMasterPort();
std::string name() { assert(ce); return ce->name() + csprintf("-chan%d", channelId); }
virtual Tick read(PacketPtr pkt)
void regStats();
- virtual MasterPort &getMasterPort(const std::string &if_name,
- int idx = -1);
+ virtual BaseMasterPort &getMasterPort(const std::string &if_name,
+ PortID idx = InvalidPortID);
virtual Tick read(PacketPtr pkt);
virtual Tick write(PacketPtr pkt);
panic("Unknown memory mode.");
}
-MasterPort &
-DmaDevice::getMasterPort(const std::string &if_name, int idx)
+BaseMasterPort &
+DmaDevice::getMasterPort(const std::string &if_name, PortID idx)
{
if (if_name == "dma") {
return dmaPort;
unsigned cacheBlockSize() const { return dmaPort.cacheBlockSize(); }
- virtual MasterPort &getMasterPort(const std::string &if_name,
- int idx = -1);
+ virtual BaseMasterPort &getMasterPort(const std::string &if_name,
+ PortID idx = InvalidPortID);
friend class DmaPort;
};
pioPort.sendRangeChange();
}
-SlavePort &
-PioDevice::getSlavePort(const std::string &if_name, int idx)
+BaseSlavePort &
+PioDevice::getSlavePort(const std::string &if_name, PortID idx)
{
if (if_name == "pio") {
return pioPort;
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;
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") {
return configPort;
void writeReg(uint8_t offset, uint32_t value);
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")
return intMasterPort;
slavePort.peerBlockSize(), masterPort.peerBlockSize());
}
-MasterPort&
-AddrMapper::getMasterPort(const std::string& if_name, int idx)
+BaseMasterPort&
+AddrMapper::getMasterPort(const std::string& if_name, PortID idx)
{
if (if_name == "master") {
return masterPort;
}
}
-SlavePort&
-AddrMapper::getSlavePort(const std::string& if_name, int idx)
+BaseSlavePort&
+AddrMapper::getSlavePort(const std::string& if_name, PortID idx)
{
if (if_name == "slave") {
return slavePort;
bool
AddrMapper::isSnooping() const
{
- if (slavePort.getMasterPort().isSnooping())
+ if (slavePort.isSnooping())
fatal("AddrMapper doesn't support remapping of snooping requests\n");
return false;
}
RangeAddrMapper::getAddrRanges() const
{
AddrRangeList ranges;
- AddrRangeList actualRanges = masterPort.getSlavePort().getAddrRanges();
+ AddrRangeList actualRanges = masterPort.getAddrRanges();
for (AddrRangeIter r = actualRanges.begin(); r != actualRanges.end(); ++r) {
AddrRange range = *r;
virtual ~AddrMapper() { }
- virtual MasterPort& getMasterPort(const std::string& if_name,
- int idx = -1);
+ virtual BaseMasterPort& getMasterPort(const std::string& if_name,
+ 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();
{
}
-MasterPort&
-Bridge::getMasterPort(const std::string &if_name, int idx)
+BaseMasterPort&
+Bridge::getMasterPort(const std::string &if_name, PortID idx)
{
if (if_name == "master")
return masterPort;
return MemObject::getMasterPort(if_name, idx);
}
-SlavePort&
-Bridge::getSlavePort(const std::string &if_name, int idx)
+BaseSlavePort&
+Bridge::getSlavePort(const std::string &if_name, PortID idx)
{
if (if_name == "slave")
return slavePort;
public:
- virtual MasterPort& getMasterPort(const std::string& if_name,
- int idx = -1);
- virtual SlavePort& getSlavePort(const std::string& if_name, int idx = -1);
+ virtual BaseMasterPort& getMasterPort(const std::string& if_name,
+ PortID idx = InvalidPortID);
+ virtual BaseSlavePort& getSlavePort(const std::string& if_name,
+ PortID idx = InvalidPortID);
virtual void init();
warn_once("Block size is neither 16, 32, 64 or 128 bytes.\n");
}
-MasterPort &
-BaseBus::getMasterPort(const std::string &if_name, int idx)
+BaseMasterPort &
+BaseBus::getMasterPort(const std::string &if_name, PortID idx)
{
if (if_name == "master" && idx < masterPorts.size()) {
// the master port index translates directly to the vector position
}
}
-SlavePort &
-BaseBus::getSlavePort(const std::string &if_name, int idx)
+BaseSlavePort &
+BaseBus::getSlavePort(const std::string &if_name, PortID idx)
{
if (if_name == "slave" && idx < slavePorts.size()) {
// the slave port index translates directly to the vector position
virtual void init();
/** A function used to return the port associated with this bus object. */
- virtual MasterPort& getMasterPort(const std::string& if_name, int idx = -1);
- virtual SlavePort& getSlavePort(const std::string& if_name, int idx = -1);
+ BaseMasterPort& getMasterPort(const std::string& if_name,
+ PortID idx = InvalidPortID);
+ BaseSlavePort& getSlavePort(const std::string& if_name,
+ PortID idx = InvalidPortID);
virtual unsigned int drain(Event *de) = 0;
cpuSidePort->sendRangeChange();
}
-MasterPort &
-BaseCache::getMasterPort(const std::string &if_name, int idx)
+BaseMasterPort &
+BaseCache::getMasterPort(const std::string &if_name, PortID idx)
{
if (if_name == "mem_side") {
return *memSidePort;
}
}
-SlavePort &
-BaseCache::getSlavePort(const std::string &if_name, int idx)
+BaseSlavePort &
+BaseCache::getSlavePort(const std::string &if_name, PortID idx)
{
if (if_name == "cpu_side") {
return *cpuSidePort;
virtual void init();
- virtual MasterPort &getMasterPort(const std::string &if_name, int idx = -1);
- virtual SlavePort &getSlavePort(const std::string &if_name, int idx = -1);
+ virtual BaseMasterPort &getMasterPort(const std::string &if_name,
+ PortID idx = InvalidPortID);
+ virtual BaseSlavePort &getSlavePort(const std::string &if_name,
+ PortID idx = InvalidPortID);
/**
* Query block size of a cache.
fatal("Communication monitor is not connected on both sides.\n");
}
-MasterPort&
-CommMonitor::getMasterPort(const std::string& if_name, int idx)
+BaseMasterPort&
+CommMonitor::getMasterPort(const std::string& if_name, PortID idx)
{
if (if_name == "master") {
return masterPort;
}
}
-SlavePort&
-CommMonitor::getSlavePort(const std::string& if_name, int idx)
+BaseSlavePort&
+CommMonitor::getSlavePort(const std::string& if_name, PortID idx)
{
if (if_name == "slave") {
return slavePort;
/** Destructor */
~CommMonitor() { }
- virtual MasterPort& getMasterPort(const std::string& if_name,
- int idx = -1);
+ virtual BaseMasterPort& getMasterPort(const std::string& if_name,
+ 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();
{
}
-MasterPort&
-MemObject::getMasterPort(const std::string& if_name, int idx)
+BaseMasterPort&
+MemObject::getMasterPort(const std::string& if_name, PortID idx)
{
fatal("%s does not have any master port named %s\n", name(), if_name);
}
-SlavePort&
-MemObject::getSlavePort(const std::string& if_name, int idx)
+BaseSlavePort&
+MemObject::getSlavePort(const std::string& if_name, PortID idx)
{
fatal("%s does not have any slave port named %s\n", name(), if_name);
}
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 idx Index in the case of a VectorPort
*
* @return A reference to the given port
*/
- virtual MasterPort& getMasterPort(const std::string& if_name,
- int idx = -1);
+ virtual BaseMasterPort& getMasterPort(const std::string& if_name,
+ 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 idx Index in the case of a VectorPort
*
* @return A reference to the given port
*/
- virtual SlavePort& getSlavePort(const std::string& if_name,
- int idx = -1);
+ virtual BaseSlavePort& getSlavePort(const std::string& if_name,
+ PortID idx = InvalidPortID);
};
#endif //__MEM_MEM_OBJECT_HH__
{
}
-/**
- * Master port
- */
-MasterPort::MasterPort(const std::string& name, MemObject* owner, PortID _id)
- : Port(name, *owner, _id), _slavePort(NULL)
+BaseMasterPort::BaseMasterPort(const std::string& name, MemObject* owner,
+ PortID _id)
+ : Port(name, *owner, _id), _baseSlavePort(NULL)
{
}
-MasterPort::~MasterPort()
+BaseMasterPort::~BaseMasterPort()
{
}
-SlavePort&
-MasterPort::getSlavePort() const
+BaseSlavePort&
+BaseMasterPort::getSlavePort() const
{
- if(_slavePort == NULL)
+ if(_baseSlavePort == NULL)
panic("Cannot getSlavePort on master port %s that is not connected\n",
name());
- return *_slavePort;
+ return *_baseSlavePort;
}
-void
-MasterPort::unbind()
+bool
+BaseMasterPort::isConnected() const
{
- if (_slavePort == NULL)
- panic("Attempting to unbind master port %s that is not connected\n",
- name());
- _slavePort->unbind();
- _slavePort = NULL;
+ return _baseSlavePort != NULL;
}
-void
-MasterPort::bind(SlavePort& slave_port)
+BaseSlavePort::BaseSlavePort(const std::string& name, MemObject* owner,
+ PortID _id)
+ : Port(name, *owner, _id), _baseMasterPort(NULL)
{
- if (_slavePort != NULL)
- panic("Attempting to bind master port %s that is already connected\n",
- name());
+}
+
+BaseSlavePort::~BaseSlavePort()
+{
+}
- // master port keeps track of the slave port
- _slavePort = &slave_port;
+BaseMasterPort&
+BaseSlavePort::getMasterPort() const
+{
+ if(_baseMasterPort == NULL)
+ panic("Cannot getMasterPort on slave port %s that is not connected\n",
+ name());
- // slave port also keeps track of master port
- _slavePort->bind(*this);
+ return *_baseMasterPort;
}
bool
-MasterPort::isConnected() const
+BaseSlavePort::isConnected() const
+{
+ return _baseMasterPort != NULL;
+}
+
+/**
+ * Master port
+ */
+MasterPort::MasterPort(const std::string& name, MemObject* owner, PortID _id)
+ : BaseMasterPort(name, owner, _id), _slavePort(NULL)
{
- return _slavePort != NULL;
+}
+
+MasterPort::~MasterPort()
+{
+}
+
+void
+MasterPort::bind(BaseSlavePort& slave_port)
+{
+ // bind on the level of the base ports
+ _baseSlavePort = &slave_port;
+
+ // 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
+MasterPort::unbind()
+{
+ if (_slavePort == NULL)
+ panic("Attempting to unbind master port %s that is not connected\n",
+ name());
+ _slavePort->unbind();
+ _slavePort = NULL;
+ _baseSlavePort = NULL;
}
unsigned
* Slave port
*/
SlavePort::SlavePort(const std::string& name, MemObject* owner, PortID id)
- : Port(name, *owner, id), _masterPort(NULL)
+ : BaseSlavePort(name, owner, id), _masterPort(NULL)
{
}
void
SlavePort::unbind()
{
+ _baseMasterPort = NULL;
_masterPort = NULL;
}
void
SlavePort::bind(MasterPort& master_port)
{
+ _baseMasterPort = &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
SlavePort::peerBlockSize() const
{
return _masterPort->deviceBlockSize();
}
-bool
-SlavePort::isConnected() const
-{
- return _masterPort != NULL;
-}
-
Tick
SlavePort::sendAtomicSnoop(PacketPtr pkt)
{
};
+/** 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 */
class SlavePort;
/**
- * A MasterPort is a specialisation of a port. In addition to the
- * basic functionality of sending packets to its slave peer, it also
- * has functions specific to a master, e.g. to receive range changes
- * or determine if the port is snooping or not.
+ * A MasterPort is a specialisation of a BaseMasterPort, which
+ * implements the default protocol for the three different level of
+ * transport functions. In addition to the basic functionality of
+ * 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;
* Bind this master port to a slave port. This also does the
* 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.
*/
void unbind();
- SlavePort& getSlavePort() const;
- bool isConnected() const;
-
/**
* Send an atomic request packet, where the data is moved and the
* state is updated in zero time, without interleaving with other
* has functions specific to a slave, e.g. to send range changes
* and get the address ranges that the port responds to.
*/
-class SlavePort : public Port
+class SlavePort : public BaseSlavePort
{
friend class MasterPort;
PortID id = InvalidPortID);
virtual ~SlavePort();
- MasterPort& getMasterPort() const;
- bool isConnected() const;
-
/**
* Send an atomic snoop request packet, where the data is moved
* and the state is updated in zero time, without interleaving
m_mandatory_q_ptr = m_controller->getMandatoryQueue();
}
-MasterPort &
-RubyPort::getMasterPort(const std::string &if_name, int idx)
+BaseMasterPort &
+RubyPort::getMasterPort(const std::string &if_name, PortID idx)
{
if (if_name == "pio_port") {
return pio_port;
// pass it along to our super class
return MemObject::getMasterPort(if_name, idx);
} 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);
}
}
}
-SlavePort &
-RubyPort::getSlavePort(const std::string &if_name, int idx)
+BaseSlavePort &
+RubyPort::getSlavePort(const std::string &if_name, PortID idx)
{
// used by the CPUs to connect the caches to the interconnect, and
// for the x86 case also the interrupt master
// pass it along to our super class
return MemObject::getSlavePort(if_name, idx);
} 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);
}
void init();
- MasterPort &getMasterPort(const std::string &if_name, int idx);
- SlavePort &getSlavePort(const std::string &if_name, int idx);
+ BaseMasterPort &getMasterPort(const std::string &if_name,
+ PortID idx = InvalidPortID);
+ BaseSlavePort &getSlavePort(const std::string &if_name,
+ PortID idx = InvalidPortID);
virtual RequestStatus makeRequest(PacketPtr pkt) = 0;
virtual int outstandingCount() const = 0;
functionalAccess(pkt);
}
-SlavePort&
-SimpleDRAM::getSlavePort(const string &if_name, int idx)
+BaseSlavePort&
+SimpleDRAM::getSlavePort(const string &if_name, PortID idx)
{
if (if_name != "port") {
return MemObject::getSlavePort(if_name, idx);
unsigned int drain(Event* de);
- virtual SlavePort& getSlavePort(const std::string& if_name,
- int idx = InvalidPortID);
+ virtual BaseSlavePort& getSlavePort(const std::string& if_name,
+ PortID idx = InvalidPortID);
virtual void init();
virtual void startup();
}
}
-SlavePort &
-SimpleMemory::getSlavePort(const std::string &if_name, int idx)
+BaseSlavePort &
+SimpleMemory::getSlavePort(const std::string &if_name, PortID idx)
{
if (if_name != "port") {
return MemObject::getSlavePort(if_name, idx);
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();
protected:
}
// generic master/slave port connection
- MasterPort& masterPort = mo1->getMasterPort(name1, i1);
- SlavePort& slavePort = mo2->getSlavePort(name2, i2);
+ BaseMasterPort& masterPort = mo1->getMasterPort(name1, i1);
+ BaseSlavePort& slavePort = mo2->getSlavePort(name2, i2);
masterPort.bind(slavePort);
panic("System port on %s is not connected.\n", name());
}
-MasterPort&
-System::getMasterPort(const std::string &if_name, int idx)
+BaseMasterPort&
+System::getMasterPort(const std::string &if_name, PortID idx)
{
// no need to distinguish at the moment (besides checking)
return _systemPort;
/**
* 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];
#include "sim/sim_object.hh"
class ThreadContext;
-class MasterPort;
+class BaseMasterPort;
class BaseTLB : public SimObject
{
*
* @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
{