From de52eebd3bbdeebadd5d7e7ce5f16dd68efb8301 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Tue, 24 Jul 2007 22:37:41 -0700 Subject: Integrate snoop loop functions into their respective call sites. Also some additional cleanup of Bus::recvTiming(). --HG-- extra : convert_revision : 156814119f75d04c2e954aec2d7ed6fdc186c26f --- src/mem/bus.cc | 156 +++++++++++++++++++++++++-------------------------------- 1 file changed, 67 insertions(+), 89 deletions(-) (limited to 'src/mem/bus.cc') diff --git a/src/mem/bus.cc b/src/mem/bus.cc index da8df06ea..8243d40f1 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -172,78 +172,79 @@ void Bus::occupyBus(PacketPtr pkt) bool Bus::recvTiming(PacketPtr pkt) { - int port_id; + short src = pkt->getSrc(); DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n", - pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString()); + src, pkt->getDest(), pkt->getAddr(), pkt->cmdString()); - BusPort *pktPort; - if (pkt->getSrc() == defaultId) - pktPort = defaultPort; - else pktPort = interfaces[pkt->getSrc()]; + BusPort *src_port = (src == defaultId) ? defaultPort : interfaces[src]; // If the bus is busy, or other devices are in line ahead of the current // one, put this device on the retry list. if (!(pkt->isResponse() || pkt->isExpressSnoop()) && (tickNextIdle > curTick || - (retryList.size() && (!inRetry || pktPort != retryList.front())))) + (retryList.size() && (!inRetry || src_port != retryList.front())))) { - addToRetryList(pktPort); + addToRetryList(src_port); DPRINTF(Bus, "recvTiming: Bus is busy, returning false\n"); return false; } + occupyBus(pkt); + short dest = pkt->getDest(); + int dest_port_id; + Port *dest_port; if (dest == Packet::Broadcast) { - port_id = findPort(pkt->getAddr()); - timingSnoop(pkt, interfaces[port_id]); - - if (pkt->memInhibitAsserted()) { - //Cache-Cache transfer occuring - if (inRetry) { - retryList.front()->onRetryList(false); - retryList.pop_front(); - inRetry = false; + dest_port_id = findPort(pkt->getAddr()); + dest_port = interfaces[dest_port_id]; + for (SnoopIter s_iter = snoopPorts.begin(); + s_iter != snoopPorts.end(); + s_iter++) { + BusPort *p = *s_iter; + if (p != dest_port && p != src_port) { +#ifndef NDEBUG + // cache is not allowed to refuse snoop + bool success = p->sendTiming(pkt); + assert(success); +#else + // avoid unused variable warning + p->sendTiming(pkt); +#endif } - occupyBus(pkt); - DPRINTF(Bus, "recvTiming: Packet sucessfully sent\n"); - return true; } } else { assert(dest >= 0 && dest < maxId); - assert(dest != pkt->getSrc()); // catch infinite loops - port_id = dest; + assert(dest != src); // catch infinite loops + dest_port_id = dest; + dest_port = interfaces[dest_port_id]; } - occupyBus(pkt); - - if (port_id != pkt->getSrc()) { - if (interfaces[port_id]->sendTiming(pkt)) { - // Packet was successfully sent. Return true. - // Also take care of retries - if (inRetry) { - DPRINTF(Bus, "Remove retry from list %d\n", - retryList.front()->getId()); - retryList.front()->onRetryList(false); - retryList.pop_front(); - inRetry = false; - } - return true; + if (dest_port_id == src) { + // Must be forwarded snoop up from below... + assert(dest == Packet::Broadcast); + } else { + // send to actual target + if (!dest_port->sendTiming(pkt)) { + // Packet not successfully sent. Leave or put it on the retry list. + // illegal to block responses... can lead to deadlock + assert(!pkt->isResponse()); + DPRINTF(Bus, "Adding2 a retry to RETRY list %d\n", src); + addToRetryList(src_port); + return false; } - - // Packet not successfully sent. Leave or put it on the retry list. - // illegal to block responses... can lead to deadlock - assert(!pkt->isResponse()); - DPRINTF(Bus, "Adding2 a retry to RETRY list %d\n", - pktPort->getId()); - addToRetryList(pktPort); - return false; + // send OK, fall through } - else { - //Forwarding up from responder, just return true; - DPRINTF(Bus, "recvTiming: can we be here?\n"); - return true; + + // Packet was successfully sent. + // Also take care of retries + if (inRetry) { + DPRINTF(Bus, "Remove retry from list %d\n", src); + retryList.front()->onRetryList(false); + retryList.pop_front(); + inRetry = false; } + return true; } void @@ -314,46 +315,6 @@ Bus::findPort(Addr addr) return dest_id; } -void -Bus::functionalSnoop(PacketPtr pkt, Port *responder) -{ - // The packet may be changed by another bus on snoops, restore the - // id after each - int src_id = pkt->getSrc(); - - assert(pkt->isRequest()); // hasn't already been satisfied - - for (SnoopIter s_iter = snoopPorts.begin(); - s_iter != snoopPorts.end(); - s_iter++) { - BusPort *p = *s_iter; - if (p != responder && p->getId() != src_id) { - p->sendFunctional(pkt); - } - if (pkt->isResponse()) { - break; - } - pkt->setSrc(src_id); - } -} - -bool -Bus::timingSnoop(PacketPtr pkt, Port* responder) -{ - for (SnoopIter s_iter = snoopPorts.begin(); - s_iter != snoopPorts.end(); - s_iter++) { - BusPort *p = *s_iter; - if (p != responder && p->getId() != pkt->getSrc()) { - bool success = p->sendTiming(pkt); - if (!success) - return false; - } - } - - return true; -} - /** Function called by the port when the bus is receiving a Atomic * transaction.*/ @@ -434,7 +395,24 @@ Bus::recvFunctional(PacketPtr pkt) int port_id = findPort(pkt->getAddr()); Port *port = interfaces[port_id]; - functionalSnoop(pkt, port); + // The packet may be changed by another bus on snoops, restore the + // id after each + int src_id = pkt->getSrc(); + + assert(pkt->isRequest()); // hasn't already been satisfied + + for (SnoopIter s_iter = snoopPorts.begin(); + s_iter != snoopPorts.end(); + s_iter++) { + BusPort *p = *s_iter; + if (p != port && p->getId() != src_id) { + p->sendFunctional(pkt); + } + if (pkt->isResponse()) { + break; + } + pkt->setSrc(src_id); + } // If the snooping hasn't found what we were looking for, keep going. if (!pkt->isResponse() && port_id != pkt->getSrc()) { -- cgit v1.2.3