Put in an accounting mechanism and an assert to make sure something doesn't try to send another packet while it's still waiting for the bus.
--HG-- extra : convert_revision : 4a2b83111e49f71ca27e05c98b55bc3bac8d9f53
This commit is contained in:
parent
404b2a951d
commit
59dd317cb5
2 changed files with 18 additions and 6 deletions
|
@ -61,7 +61,7 @@ Bus::getPort(const std::string &if_name, int idx)
|
||||||
void
|
void
|
||||||
Bus::init()
|
Bus::init()
|
||||||
{
|
{
|
||||||
std::vector<Port*>::iterator intIter;
|
std::vector<BusPort*>::iterator intIter;
|
||||||
|
|
||||||
for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
|
for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
|
||||||
(*intIter)->sendStatusChange(Port::RangeChange);
|
(*intIter)->sendStatusChange(Port::RangeChange);
|
||||||
|
@ -89,7 +89,7 @@ Bus::recvTiming(Packet *pkt)
|
||||||
DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n",
|
DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n",
|
||||||
pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
|
pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
|
||||||
|
|
||||||
Port *pktPort = interfaces[pkt->getSrc()];
|
BusPort *pktPort = interfaces[pkt->getSrc()];
|
||||||
|
|
||||||
// If the bus is busy, or other devices are in line ahead of the current
|
// If the bus is busy, or other devices are in line ahead of the current
|
||||||
// one, put this device on the retry list.
|
// one, put this device on the retry list.
|
||||||
|
@ -108,6 +108,7 @@ Bus::recvTiming(Packet *pkt)
|
||||||
if (pkt->flags & SATISFIED) {
|
if (pkt->flags & SATISFIED) {
|
||||||
//Cache-Cache transfer occuring
|
//Cache-Cache transfer occuring
|
||||||
if (inRetry) {
|
if (inRetry) {
|
||||||
|
retryList.front()->onRetryList(false);
|
||||||
retryList.pop_front();
|
retryList.pop_front();
|
||||||
inRetry = false;
|
inRetry = false;
|
||||||
}
|
}
|
||||||
|
@ -181,6 +182,7 @@ Bus::recvTiming(Packet *pkt)
|
||||||
// Packet was successfully sent. Return true.
|
// Packet was successfully sent. Return true.
|
||||||
// Also take care of retries
|
// Also take care of retries
|
||||||
if (inRetry) {
|
if (inRetry) {
|
||||||
|
retryList.front()->onRetryList(false);
|
||||||
retryList.pop_front();
|
retryList.pop_front();
|
||||||
inRetry = false;
|
inRetry = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,6 +130,8 @@ class Bus : public MemObject
|
||||||
of the interfaces connecting to the bus. */
|
of the interfaces connecting to the bus. */
|
||||||
class BusPort : public Port
|
class BusPort : public Port
|
||||||
{
|
{
|
||||||
|
bool _onRetryList;
|
||||||
|
|
||||||
/** A pointer to the bus to which this port belongs. */
|
/** A pointer to the bus to which this port belongs. */
|
||||||
Bus *bus;
|
Bus *bus;
|
||||||
|
|
||||||
|
@ -140,9 +142,15 @@ class Bus : public MemObject
|
||||||
|
|
||||||
/** Constructor for the BusPort.*/
|
/** Constructor for the BusPort.*/
|
||||||
BusPort(const std::string &_name, Bus *_bus, int _id)
|
BusPort(const std::string &_name, Bus *_bus, int _id)
|
||||||
: Port(_name), bus(_bus), id(_id)
|
: Port(_name), _onRetryList(false), bus(_bus), id(_id)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
bool onRetryList()
|
||||||
|
{ return _onRetryList; }
|
||||||
|
|
||||||
|
void onRetryList(bool newVal)
|
||||||
|
{ _onRetryList = newVal; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** When reciving a timing request from the peer port (at id),
|
/** When reciving a timing request from the peer port (at id),
|
||||||
|
@ -199,17 +207,19 @@ class Bus : public MemObject
|
||||||
|
|
||||||
/** An array of pointers to the peer port interfaces
|
/** An array of pointers to the peer port interfaces
|
||||||
connected to this bus.*/
|
connected to this bus.*/
|
||||||
std::vector<Port*> interfaces;
|
std::vector<BusPort*> interfaces;
|
||||||
|
|
||||||
/** An array of pointers to ports that retry should be called on because the
|
/** An array of pointers to ports that retry should be called on because the
|
||||||
* original send failed for whatever reason.*/
|
* original send failed for whatever reason.*/
|
||||||
std::list<Port*> retryList;
|
std::list<BusPort*> retryList;
|
||||||
|
|
||||||
void addToRetryList(Port * port)
|
void addToRetryList(BusPort * port)
|
||||||
{
|
{
|
||||||
if (!inRetry) {
|
if (!inRetry) {
|
||||||
// The device wasn't retrying a packet, or wasn't at an appropriate
|
// The device wasn't retrying a packet, or wasn't at an appropriate
|
||||||
// time.
|
// time.
|
||||||
|
assert(!port->onRetryList());
|
||||||
|
port->onRetryList(true);
|
||||||
retryList.push_back(port);
|
retryList.push_back(port);
|
||||||
} else {
|
} else {
|
||||||
// The device was retrying a packet. It didn't work, so we'll leave
|
// The device was retrying a packet. It didn't work, so we'll leave
|
||||||
|
|
Loading…
Reference in a new issue