Fix bus in FS mode.

src/mem/bus.cc:
    Add debugging statement
src/mem/bus.hh:
    Fix implementation of bus for subsequent recvTimings while handling a retry request.
src/mem/tport.cc:
    Rework timing port to retry properly

--HG--
extra : convert_revision : fbfb5e8b4a625e49c6cd764da1df46a4f336b1b2
This commit is contained in:
Ron Dreslinski 2006-10-11 19:25:48 -04:00
parent 567afbf6ce
commit 3c7e0ec752
3 changed files with 34 additions and 21 deletions

View file

@ -173,6 +173,7 @@ Bus::recvTiming(Packet *pkt)
port = findPort(pkt->getAddr(), pkt->getSrc()); port = findPort(pkt->getAddr(), pkt->getSrc());
} else { } else {
//Snoop didn't succeed //Snoop didn't succeed
DPRINTF(Bus, "Adding a retry to RETRY list %i\n", pktPort);
addToRetryList(pktPort); addToRetryList(pktPort);
return false; return false;
} }

View file

@ -224,13 +224,15 @@ class Bus : public MemObject
port->onRetryList(true); 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 if (port->onRetryList()) {
// it at the head of the retry list. // The device was retrying a packet. It didn't work, so we'll leave
inRetry = false; // it at the head of the retry list.
assert(port == retryList.front());
/* // We shouldn't be receiving a packet from one port when a different inRetry = false;
// one is retrying. }
assert(port == retryingPort);*/ else {
retryList.push_back(port);
}
} }
} }

View file

@ -58,15 +58,17 @@ SimpleTimingPort::recvTiming(Packet *pkt)
void void
SimpleTimingPort::recvRetry() SimpleTimingPort::recvRetry()
{ {
bool result = true; assert(outTiming > 0);
assert(!transmitList.empty());
assert(transmitList.size()); if (sendTiming(transmitList.front())) {
while (result && transmitList.size()) { transmitList.pop_front();
result = sendTiming(transmitList.front()); outTiming--;
if (result) DPRINTF(Bus, "No Longer waiting on retry\n");
transmitList.pop_front(); if (!transmitList.empty())
sendTimingLater(transmitList.front(), 1);
} }
if (transmitList.size() == 0 && drainEvent) {
if (transmitList.empty() && drainEvent) {
drainEvent->process(); drainEvent->process();
drainEvent = NULL; drainEvent = NULL;
} }
@ -75,20 +77,28 @@ SimpleTimingPort::recvRetry()
void void
SimpleTimingPort::SendEvent::process() SimpleTimingPort::SendEvent::process()
{ {
port->outTiming--; assert(port->outTiming > 0);
assert(port->outTiming >= 0); if (!port->transmitList.empty() && port->transmitList.front() != packet) {
if (port->transmitList.size()) { //We are not the head of the list
port->transmitList.push_back(packet); port->transmitList.push_back(packet);
} else if (port->sendTiming(packet)) { } else if (port->sendTiming(packet)) {
// send successful // send successful
if (port->transmitList.size() == 0 && port->drainEvent) { if (port->transmitList.size()) {
port->transmitList.pop_front();
port->outTiming--;
if (!port->transmitList.empty())
port->sendTimingLater(port->transmitList.front(), 1);
}
if (port->transmitList.empty() && port->drainEvent) {
port->drainEvent->process(); port->drainEvent->process();
port->drainEvent = NULL; port->drainEvent = NULL;
} }
} else { } else {
// send unsuccessful (due to flow control). Will get retry // send unsuccessful (due to flow control). Will get retry
// callback later; save for then. // callback later; save for then if not already
port->transmitList.push_back(packet); DPRINTF(Bus, "Waiting on retry\n");
if (!(port->transmitList.front() == packet))
port->transmitList.push_back(packet);
} }
} }