Make Bus::findPort() a little more useful.

Move check for loops outside, since half the call sites
end up working around it anyway.  Return integer port ID
instead of port object pointer.

--HG--
extra : convert_revision : 4c31fe9930f4d1aa4919e764efb7c50d43792ea3
This commit is contained in:
Steve Reinhardt 2007-07-15 20:09:03 -07:00
parent 9172876dd7
commit f790f34fe3
2 changed files with 26 additions and 27 deletions

View file

@ -172,7 +172,7 @@ void Bus::occupyBus(PacketPtr pkt)
bool bool
Bus::recvTiming(PacketPtr pkt) Bus::recvTiming(PacketPtr pkt)
{ {
Port *port; int port_id;
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());
@ -196,8 +196,8 @@ Bus::recvTiming(PacketPtr pkt)
// Make sure to clear the snoop commit flag so it doesn't think an // Make sure to clear the snoop commit flag so it doesn't think an
// access has been handled twice. // access has been handled twice.
if (dest == Packet::Broadcast) { if (dest == Packet::Broadcast) {
port = findPort(pkt->getAddr(), pkt->getSrc()); port_id = findPort(pkt->getAddr());
timingSnoop(pkt, port ? port : interfaces[pkt->getSrc()]); timingSnoop(pkt, interfaces[port_id]);
if (pkt->memInhibitAsserted()) { if (pkt->memInhibitAsserted()) {
//Cache-Cache transfer occuring //Cache-Cache transfer occuring
@ -213,13 +213,13 @@ Bus::recvTiming(PacketPtr pkt)
} else { } else {
assert(dest >= 0 && dest < maxId); assert(dest >= 0 && dest < maxId);
assert(dest != pkt->getSrc()); // catch infinite loops assert(dest != pkt->getSrc()); // catch infinite loops
port = interfaces[dest]; port_id = dest;
} }
occupyBus(pkt); occupyBus(pkt);
if (port) { if (port_id != pkt->getSrc()) {
if (port->sendTiming(pkt)) { if (interfaces[port_id]->sendTiming(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) {
@ -279,8 +279,8 @@ Bus::recvRetry(int id)
} }
} }
Port * int
Bus::findPort(Addr addr, int id) Bus::findPort(Addr addr)
{ {
/* An interval tree would be a better way to do this. --ali. */ /* An interval tree would be a better way to do this. --ali. */
int dest_id = -1; int dest_id = -1;
@ -295,7 +295,7 @@ Bus::findPort(Addr addr, int id)
iter != defaultRange.end(); iter++) { iter != defaultRange.end(); iter++) {
if (*iter == addr) { if (*iter == addr) {
DPRINTF(Bus, " found addr %#llx on default\n", addr); DPRINTF(Bus, " found addr %#llx on default\n", addr);
return defaultPort; return defaultId;
} }
} }
@ -306,18 +306,11 @@ Bus::findPort(Addr addr, int id)
DPRINTF(Bus, "Unable to find destination for addr: %#llx, will use " DPRINTF(Bus, "Unable to find destination for addr: %#llx, will use "
"default port", addr); "default port", addr);
return defaultPort; return defaultId;
} }
} }
return dest_id;
// we shouldn't be sending this back to where it came from
// do the snoop access and then we should terminate
// the cyclical call.
if (dest_id == id)
return 0;
return interfaces[dest_id];
} }
void void
@ -380,7 +373,8 @@ Bus::recvAtomic(PacketPtr pkt)
Tick snoop_response_latency = 0; Tick snoop_response_latency = 0;
int orig_src = pkt->getSrc(); int orig_src = pkt->getSrc();
Port *target_port = findPort(pkt->getAddr(), pkt->getSrc()); int target_port_id = findPort(pkt->getAddr());
Port *target_port = interfaces[target_port_id];
SnoopIter s_end = snoopPorts.end(); SnoopIter s_end = snoopPorts.end();
for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) { for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) {
@ -406,7 +400,13 @@ Bus::recvAtomic(PacketPtr pkt)
} }
} }
Tick response_latency = target_port->sendAtomic(pkt); Tick response_latency = 0;
// we can get requests sent up from the memory side of the bus for
// snooping... don't send them back down!
if (target_port_id != pkt->getSrc()) {
response_latency = target_port->sendAtomic(pkt);
}
// if we got a response from a snooper, restore it here // if we got a response from a snooper, restore it here
if (snoop_response_cmd != MemCmd::InvalidCmd) { if (snoop_response_cmd != MemCmd::InvalidCmd) {
@ -431,11 +431,12 @@ Bus::recvFunctional(PacketPtr pkt)
pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString()); pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
assert(pkt->getDest() == Packet::Broadcast); assert(pkt->getDest() == Packet::Broadcast);
Port* port = findPort(pkt->getAddr(), pkt->getSrc()); int port_id = findPort(pkt->getAddr());
functionalSnoop(pkt, port ? port : interfaces[pkt->getSrc()]); Port *port = interfaces[port_id];
functionalSnoop(pkt, port);
// If the snooping hasn't found what we were looking for, keep going. // If the snooping hasn't found what we were looking for, keep going.
if (!pkt->isResponse() && port) { if (!pkt->isResponse() && port_id != pkt->getSrc()) {
port->sendFunctional(pkt); port->sendFunctional(pkt);
} }
} }

View file

@ -176,11 +176,9 @@ class Bus : public MemObject
/** Find which port connected to this bus (if any) should be given a packet /** Find which port connected to this bus (if any) should be given a packet
* with this address. * with this address.
* @param addr Address to find port for. * @param addr Address to find port for.
* @param id Id of the port this packet was received from (to prevent * @return id of port that the packet should be sent out of.
* loops)
* @return pointer to port that the packet should be sent out of.
*/ */
Port *findPort(Addr addr, int id); int findPort(Addr addr);
/** Snoop all relevant ports functionally. */ /** Snoop all relevant ports functionally. */
void functionalSnoop(PacketPtr pkt, Port *responder); void functionalSnoop(PacketPtr pkt, Port *responder);