diff options
Diffstat (limited to 'src/mem/bus.cc')
-rw-r--r-- | src/mem/bus.cc | 82 |
1 files changed, 56 insertions, 26 deletions
diff --git a/src/mem/bus.cc b/src/mem/bus.cc index cb359734b..42c4431bb 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -84,6 +84,7 @@ Bus::deletePortRefs(Port *p) if (funcPort == bp) return; interfaces.erase(bp->getId()); + clearBusCache(); delete bp; } @@ -176,7 +177,16 @@ Bus::recvTiming(PacketPtr pkt) DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n", src, pkt->getDest(), pkt->getAddr(), pkt->cmdString()); - BusPort *src_port = (src == defaultId) ? defaultPort : interfaces[src]; + BusPort *src_port; + if (src == defaultId) + src_port = defaultPort; + else { + src_port = checkBusCache(src); + if (src_port == NULL) { + src_port = interfaces[src]; + updateBusCache(src, src_port); + } + } // If the bus is busy, or other devices are in line ahead of the current // one, put this device on the retry list. @@ -201,25 +211,28 @@ Bus::recvTiming(PacketPtr pkt) dest_port_id = findPort(pkt->getAddr()); dest_port = (dest_port_id == defaultId) ? defaultPort : interfaces[dest_port_id]; - for (SnoopIter s_iter = snoopPorts.begin(); - s_iter != snoopPorts.end(); - s_iter++) { + SnoopIter s_end = snoopPorts.end(); + for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_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); + bool success M5_VAR_USED = p->sendTiming(pkt); assert(success); -#else - // avoid unused variable warning - p->sendTiming(pkt); -#endif } } } else { assert(dest >= 0 && dest < maxId); assert(dest != src); // catch infinite loops dest_port_id = dest; + if (dest_port_id == defaultId) + dest_port = defaultPort; + else { + dest_port = checkBusCache(dest); + if (dest_port == NULL) { + dest_port = interfaces[dest_port_id]; + // updateBusCache(dest_port_id, dest_port); + } + } dest_port = (dest_port_id == defaultId) ? defaultPort : interfaces[dest_port_id]; } @@ -291,15 +304,19 @@ Bus::findPort(Addr addr) /* An interval tree would be a better way to do this. --ali. */ int dest_id = -1; - PortIter i = portMap.find(RangeSize(addr,1)); - if (i != portMap.end()) - dest_id = i->second; + dest_id = checkPortCache(addr); + if (dest_id == -1) { + PortIter i = portMap.find(RangeSize(addr,1)); + if (i != portMap.end()) + dest_id = i->second; + updatePortCache(dest_id, i->first.start, i->first.end); + } // Check if this matches the default range if (dest_id == -1) { - for (AddrRangeIter iter = defaultRange.begin(); - iter != defaultRange.end(); iter++) { - if (*iter == addr) { + AddrRangeIter a_end = defaultRange.end(); + for (AddrRangeIter i = defaultRange.begin(); i != a_end; i++) { + if (*i == addr) { DPRINTF(Bus, " found addr %#llx on default\n", addr); return defaultId; } @@ -340,8 +357,16 @@ Bus::recvAtomic(PacketPtr pkt) int orig_src = pkt->getSrc(); int target_port_id = findPort(pkt->getAddr()); - Port *target_port = (target_port_id == defaultId) ? - defaultPort : interfaces[target_port_id]; + BusPort *target_port; + if (target_port_id == defaultId) + target_port = defaultPort; + else { + target_port = checkBusCache(target_port_id); + if (target_port == NULL) { + target_port = interfaces[target_port_id]; + updateBusCache(target_port_id, target_port); + } + } SnoopIter s_end = snoopPorts.end(); for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) { @@ -406,9 +431,8 @@ Bus::recvFunctional(PacketPtr pkt) assert(pkt->isRequest()); // hasn't already been satisfied - for (SnoopIter s_iter = snoopPorts.begin(); - s_iter != snoopPorts.end(); - s_iter++) { + SnoopIter s_end = snoopPorts.end(); + for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) { BusPort *p = *s_iter; if (p != port && p->getId() != src_id) { p->sendFunctional(pkt); @@ -433,11 +457,16 @@ Bus::recvStatusChange(Port::Status status, int id) bool snoops; AddrRangeIter iter; + if (inRecvStatusChange.count(id)) + return; + inRecvStatusChange.insert(id); + assert(status == Port::RangeChange && "The other statuses need to be implemented."); DPRINTF(BusAddrRanges, "received RangeChange from device id %d\n", id); + clearPortCache(); if (id == defaultId) { defaultRange.clear(); // Only try to update these ranges if the user set a default responder. @@ -499,6 +528,7 @@ Bus::recvStatusChange(Port::Status status, int id) if (id != defaultId && defaultPort) defaultPort->sendStatusChange(Port::RangeChange); + inRecvStatusChange.erase(id); } void @@ -557,14 +587,14 @@ Bus::findBlockSize(int id) int max_bs = -1; - for (PortIter portIter = portMap.begin(); - portIter != portMap.end(); portIter++) { - int tmp_bs = interfaces[portIter->second]->peerBlockSize(); + PortIter p_end = portMap.end(); + for (PortIter p_iter = portMap.begin(); p_iter != p_end; p_iter++) { + int tmp_bs = interfaces[p_iter->second]->peerBlockSize(); if (tmp_bs > max_bs) max_bs = tmp_bs; } - for (SnoopIter s_iter = snoopPorts.begin(); - s_iter != snoopPorts.end(); s_iter++) { + SnoopIter s_end = snoopPorts.end(); + for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) { int tmp_bs = (*s_iter)->peerBlockSize(); if (tmp_bs > max_bs) max_bs = tmp_bs; |