Make the bus is occupied for none broadcast packets as well.

--HG--
extra : convert_revision : aef3c625172e92be8f29c4c57077fefee43046bb
This commit is contained in:
Gabe Black 2006-10-10 23:28:33 -04:00
parent 59dd317cb5
commit 8353b1e21f
2 changed files with 53 additions and 45 deletions

View file

@ -80,52 +80,8 @@ const char * Bus::BusFreeEvent::description()
return "bus became available";
}
/** Function called by the port when the bus is receiving a Timing
* transaction.*/
bool
Bus::recvTiming(Packet *pkt)
void Bus::occupyBus(PacketPtr pkt)
{
Port *port;
DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n",
pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
BusPort *pktPort = interfaces[pkt->getSrc()];
// If the bus is busy, or other devices are in line ahead of the current
// one, put this device on the retry list.
if (tickNextIdle > curTick ||
(retryList.size() && (!inRetry || pktPort != retryList.front()))) {
addToRetryList(pktPort);
return false;
}
short dest = pkt->getDest();
if (dest == Packet::Broadcast) {
if (timingSnoop(pkt)) {
pkt->flags |= SNOOP_COMMIT;
bool success = timingSnoop(pkt);
assert(success);
if (pkt->flags & SATISFIED) {
//Cache-Cache transfer occuring
if (inRetry) {
retryList.front()->onRetryList(false);
retryList.pop_front();
inRetry = false;
}
return true;
}
port = findPort(pkt->getAddr(), pkt->getSrc());
} else {
//Snoop didn't succeed
addToRetryList(pktPort);
return false;
}
} else {
assert(dest >= 0 && dest < interfaces.size());
assert(dest != pkt->getSrc()); // catch infinite loops
port = interfaces[dest];
}
//Bring tickNextIdle up to the present tick
//There is some potential ambiguity where a cycle starts, which might make
//a difference when devices are acting right around a cycle boundary. Using
@ -177,6 +133,56 @@ Bus::recvTiming(Packet *pkt)
// The bus will become idle once the current packet is delivered.
pkt->finishTime = tickNextIdle;
}
/** Function called by the port when the bus is receiving a Timing
* transaction.*/
bool
Bus::recvTiming(Packet *pkt)
{
Port *port;
DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n",
pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
BusPort *pktPort = interfaces[pkt->getSrc()];
// If the bus is busy, or other devices are in line ahead of the current
// one, put this device on the retry list.
if (tickNextIdle > curTick ||
(retryList.size() && (!inRetry || pktPort != retryList.front()))) {
addToRetryList(pktPort);
return false;
}
short dest = pkt->getDest();
if (dest == Packet::Broadcast) {
if (timingSnoop(pkt)) {
pkt->flags |= SNOOP_COMMIT;
bool success = timingSnoop(pkt);
assert(success);
if (pkt->flags & SATISFIED) {
//Cache-Cache transfer occuring
if (inRetry) {
retryList.front()->onRetryList(false);
retryList.pop_front();
inRetry = false;
}
occupyBus(pkt);
return true;
}
port = findPort(pkt->getAddr(), pkt->getSrc());
} else {
//Snoop didn't succeed
addToRetryList(pktPort);
return false;
}
} else {
assert(dest >= 0 && dest < interfaces.size());
assert(dest != pkt->getSrc()); // catch infinite loops
port = interfaces[dest];
}
occupyBus(pkt);
if (port->sendTiming(pkt)) {
// Packet was successfully sent. Return true.

View file

@ -125,6 +125,8 @@ class Bus : public MemObject
*/
void addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id);
/** Occupy the bus with transmitting the packet pkt */
void occupyBus(PacketPtr pkt);
/** Declaration of the buses port type, one will be instantiated for each
of the interfaces connecting to the bus. */