Port: Move retry from port base class to Master/SlavePort
This patch is the last part of moving all protocol-related functionality out of the Port base class. All the send/recv functions are already moved, and the retry (which still governs all the timing transport functions) is the only part that remained in the base class. The only point where this currently causes a bit of inconvenience is in the bus where the retry list is global and holds Port pointers (not Master/SlavePort). This is about to change with the split into a request/response bus and will soon be removed anyway. The patch has no impact on any regressions.
This commit is contained in:
parent
ff5718f042
commit
17f9270dad
5 changed files with 48 additions and 30 deletions
|
@ -170,7 +170,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
|
||||||
void schedule(PacketPtr _pkt, Tick t);
|
void schedule(PacketPtr _pkt, Tick t);
|
||||||
};
|
};
|
||||||
|
|
||||||
EventWrapper<Port, &Port::sendRetry> retryEvent;
|
EventWrapper<MasterPort, &MasterPort::sendRetry> retryEvent;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IcachePort : public TimingCPUPort
|
class IcachePort : public TimingCPUPort
|
||||||
|
|
|
@ -218,7 +218,10 @@ BaseBus::retryWaiting()
|
||||||
// note that we might have blocked on the receiving port being
|
// note that we might have blocked on the receiving port being
|
||||||
// busy (rather than the bus itself) and now call retry before the
|
// busy (rather than the bus itself) and now call retry before the
|
||||||
// destination called retry on the bus
|
// destination called retry on the bus
|
||||||
retryList.front()->sendRetry();
|
if (dynamic_cast<SlavePort*>(retryList.front()) != NULL)
|
||||||
|
(dynamic_cast<SlavePort*>(retryList.front()))->sendRetry();
|
||||||
|
else
|
||||||
|
(dynamic_cast<MasterPort*>(retryList.front()))->sendRetry();
|
||||||
|
|
||||||
// If inRetry is still true, sendTiming wasn't called in zero time
|
// If inRetry is still true, sendTiming wasn't called in zero time
|
||||||
// (e.g. the cache does this)
|
// (e.g. the cache does this)
|
||||||
|
|
2
src/mem/cache/base.hh
vendored
2
src/mem/cache/base.hh
vendored
|
@ -204,7 +204,7 @@ class BaseCache : public MemObject
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
EventWrapper<Port, &Port::sendRetry> sendRetryEvent;
|
EventWrapper<SlavePort, &SlavePort::sendRetry> sendRetryEvent;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
#include "mem/port.hh"
|
#include "mem/port.hh"
|
||||||
|
|
||||||
Port::Port(const std::string &_name, MemObject& _owner, PortID _id)
|
Port::Port(const std::string &_name, MemObject& _owner, PortID _id)
|
||||||
: portName(_name), id(_id), peer(NULL), owner(_owner)
|
: portName(_name), id(_id), owner(_owner)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,6 @@ MasterPort::bind(SlavePort& slave_port)
|
||||||
{
|
{
|
||||||
// master port keeps track of the slave port
|
// master port keeps track of the slave port
|
||||||
_slavePort = &slave_port;
|
_slavePort = &slave_port;
|
||||||
peer = &slave_port;
|
|
||||||
|
|
||||||
// slave port also keeps track of master port
|
// slave port also keeps track of master port
|
||||||
_slavePort->bind(*this);
|
_slavePort->bind(*this);
|
||||||
|
@ -132,6 +131,12 @@ MasterPort::sendTimingSnoopResp(PacketPtr pkt)
|
||||||
return _slavePort->recvTimingSnoopResp(pkt);
|
return _slavePort->recvTimingSnoopResp(pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MasterPort::sendRetry()
|
||||||
|
{
|
||||||
|
_slavePort->recvRetry();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MasterPort::printAddr(Addr a)
|
MasterPort::printAddr(Addr a)
|
||||||
{
|
{
|
||||||
|
@ -159,7 +164,6 @@ void
|
||||||
SlavePort::bind(MasterPort& master_port)
|
SlavePort::bind(MasterPort& master_port)
|
||||||
{
|
{
|
||||||
_masterPort = &master_port;
|
_masterPort = &master_port;
|
||||||
peer = &master_port;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MasterPort&
|
MasterPort&
|
||||||
|
@ -211,3 +215,9 @@ SlavePort::sendTimingSnoopReq(PacketPtr pkt)
|
||||||
assert(pkt->isRequest());
|
assert(pkt->isRequest());
|
||||||
_masterPort->recvTimingSnoopReq(pkt);
|
_masterPort->recvTimingSnoopReq(pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SlavePort::sendRetry()
|
||||||
|
{
|
||||||
|
_masterPort->recvRetry();
|
||||||
|
}
|
||||||
|
|
|
@ -70,10 +70,7 @@ class MemObject;
|
||||||
/**
|
/**
|
||||||
* Ports are used to interface memory objects to each other. A port is
|
* Ports are used to interface memory objects to each other. A port is
|
||||||
* either a master or a slave and the connected peer is always of the
|
* either a master or a slave and the connected peer is always of the
|
||||||
* opposite role.
|
* opposite role. Each port has a name, an owner, and an identifier.
|
||||||
*
|
|
||||||
* Each port has a name and an owner, and enables three basic types of
|
|
||||||
* accesses to the peer port: functional, atomic and timing.
|
|
||||||
*/
|
*/
|
||||||
class Port
|
class Port
|
||||||
{
|
{
|
||||||
|
@ -91,9 +88,6 @@ class Port
|
||||||
*/
|
*/
|
||||||
const PortID id;
|
const PortID id;
|
||||||
|
|
||||||
/** A pointer to the peer port. */
|
|
||||||
Port* peer;
|
|
||||||
|
|
||||||
/** A reference to the MemObject that owns this port. */
|
/** A reference to the MemObject that owns this port. */
|
||||||
MemObject& owner;
|
MemObject& owner;
|
||||||
|
|
||||||
|
@ -119,23 +113,6 @@ class Port
|
||||||
/** Get the port id. */
|
/** Get the port id. */
|
||||||
PortID getId() const { return id; }
|
PortID getId() const { return id; }
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called by a peer port if sendTimingReq, sendTimingResp or
|
|
||||||
* sendTimingSnoopResp was unsuccesful, and had to wait.
|
|
||||||
*/
|
|
||||||
virtual void recvRetry() = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a retry to a peer port that previously attempted a
|
|
||||||
* sendTimingReq, sendTimingResp or sendTimingSnoopResp which was
|
|
||||||
* unsuccessful.
|
|
||||||
*/
|
|
||||||
void sendRetry() { return peer->recvRetry(); }
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Forward declaration */
|
/** Forward declaration */
|
||||||
|
@ -210,6 +187,12 @@ class MasterPort : public Port
|
||||||
*/
|
*/
|
||||||
bool sendTimingSnoopResp(PacketPtr pkt);
|
bool sendTimingSnoopResp(PacketPtr pkt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a retry to the slave port that previously attempted a
|
||||||
|
* sendTimingResp to this master port and failed.
|
||||||
|
*/
|
||||||
|
void sendRetry();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if this master port is snooping or not. The default
|
* Determine if this master port is snooping or not. The default
|
||||||
* implementation returns false and thus tells the neighbour we
|
* implementation returns false and thus tells the neighbour we
|
||||||
|
@ -269,6 +252,14 @@ class MasterPort : public Port
|
||||||
panic("%s was not expecting a timing snoop request\n", name());
|
panic("%s was not expecting a timing snoop request\n", name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by the slave port if sendTimingReq or
|
||||||
|
* sendTimingSnoopResp was called on this master port (causing
|
||||||
|
* recvTimingReq and recvTimingSnoopResp to be called on the
|
||||||
|
* slave port) and was unsuccesful.
|
||||||
|
*/
|
||||||
|
virtual void recvRetry() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to receive an address range change from the peer slave
|
* Called to receive an address range change from the peer slave
|
||||||
* port. the default implementation ignored the change and does
|
* port. the default implementation ignored the change and does
|
||||||
|
@ -346,6 +337,13 @@ class SlavePort : public Port
|
||||||
*/
|
*/
|
||||||
void sendTimingSnoopReq(PacketPtr pkt);
|
void sendTimingSnoopReq(PacketPtr pkt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a retry to the master port that previously attempted a
|
||||||
|
* sendTimingReq or sendTimingSnoopResp to this slave port and
|
||||||
|
* failed.
|
||||||
|
*/
|
||||||
|
void sendRetry();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by a peer port in order to determine the block size of
|
* Called by a peer port in order to determine the block size of
|
||||||
* the owner of this port.
|
* the owner of this port.
|
||||||
|
@ -396,6 +394,13 @@ class SlavePort : public Port
|
||||||
panic("%s was not expecting a timing snoop response\n", name());
|
panic("%s was not expecting a timing snoop response\n", name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by the master port if sendTimingResp was called on this
|
||||||
|
* slave port (causing recvTimingResp to be called on the master
|
||||||
|
* port) and was unsuccesful.
|
||||||
|
*/
|
||||||
|
virtual void recvRetry() = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__MEM_PORT_HH__
|
#endif //__MEM_PORT_HH__
|
||||||
|
|
Loading…
Reference in a new issue