diff -r f17ffe53f7b1 -r 751a74a1ff5b src/mem/cache/cache.hh --- a/src/mem/cache/cache.hh Mon Mar 23 18:49:16 2015 +0000 +++ b/src/mem/cache/cache.hh Mon Mar 23 18:54:01 2015 +0000 @@ -341,7 +341,7 @@ * timing here since the line should have been flushed earlier by * a cache maintenance operation. */ - void uncacheableFlush(PacketPtr pkt); + void uncacheableFlush(PacketPtr pkt, PacketList &writebacks); /** * Squash all requests associated with specified thread. diff -r f17ffe53f7b1 -r 751a74a1ff5b src/mem/cache/cache_impl.hh --- a/src/mem/cache/cache_impl.hh Mon Mar 23 18:49:16 2015 +0000 +++ b/src/mem/cache/cache_impl.hh Mon Mar 23 18:54:01 2015 +0000 @@ -311,7 +311,7 @@ DPRINTF(Cache, "%s for %s addr %#llx size %d\n", __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize()); if (pkt->req->isUncacheable()) { - uncacheableFlush(pkt); + uncacheableFlush(pkt, writebacks); blk = NULL; // lookupLatency is the latency in case the request is uncacheable. lat = lookupLatency; @@ -518,14 +518,32 @@ return true; } + // anything that is merely forwarded pays for the forward latency and + // the delay provided by the crossbar + Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay; + // We use lookupLatency here because it is used to specify the latency // to access. Cycles lat = lookupLatency; BlkType *blk = NULL; - PacketList writebacks; - // Note that lat is passed by reference here. The function access() calls - // accessBlock() which can modify lat value. - bool satisfied = access(pkt, blk, lat, writebacks); + bool satisfied = false; + { + PacketList writebacks; + // Note that lat is passed by reference here. The function + // access() calls accessBlock() which can modify lat value. + satisfied = access(pkt, blk, lat, writebacks); + + // copy writebacks to write buffer here to ensure they logically + // proceed anything happening below + while (!writebacks.empty()) { + PacketPtr wbPkt = writebacks.front(); + // We use forwardLatency here because we are copying + // writebacks to write buffer. + allocateWriteBuffer(wbPkt, forward_time, true); + writebacks.pop_front(); + } + } + // Here we charge the headerDelay that takes into account the latencies // of the bus, if the packet comes from it. // The latency charged it is just lat that is the value of lookupLatency @@ -533,11 +551,6 @@ // In case of a hit we are neglecting response latency. // In case of a miss we are neglecting forward latency. Tick request_time = clockEdge(lat) + pkt->headerDelay; - // Here we condiser forward_time, paying for just forward latency and - // also charging the delay provided by the xbar. - // forward_time is used in allocateWriteBuffer() function, called - // in case of writeback. - Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay; // Here we reset the timing of the packet. pkt->headerDelay = pkt->payloadDelay = 0; @@ -741,15 +754,6 @@ if (next_pf_time != MaxTick) requestMemSideBus(Request_PF, std::max(clockEdge(forwardLatency), next_pf_time)); - // copy writebacks to write buffer - while (!writebacks.empty()) { - PacketPtr wbPkt = writebacks.front(); - // We use forwardLatency here because we are copying writebacks - // to write buffer. It specifies the latency to allocate an internal - // buffer and to schedule an event to the queued port. - allocateWriteBuffer(wbPkt, forward_time, true); - writebacks.pop_front(); - } return true; } @@ -869,8 +873,18 @@ BlkType *blk = NULL; PacketList writebacks; + bool satisfied = access(pkt, blk, lat, writebacks); - if (!access(pkt, blk, lat, writebacks)) { + // handle writebacks resulting from the access here to ensure they + // logically proceed anything happening below + while (!writebacks.empty()){ + PacketPtr wbPkt = writebacks.front(); + memSidePort->sendAtomic(wbPkt); + writebacks.pop_front(); + delete wbPkt; + } + + if (!satisfied) { // MISS PacketPtr bus_pkt = getBusPacket(pkt, blk, pkt->needsExclusive()); @@ -893,6 +907,7 @@ lat += ticksToCycles(memSidePort->sendAtomic(bus_pkt)); + // We are now dealing with the response handling DPRINTF(Cache, "Receive response: %s for addr %#llx (%s) in state %i\n", bus_pkt->cmdString(), bus_pkt->getAddr(), bus_pkt->isSecure() ? "s" : "ns", @@ -943,7 +958,7 @@ // immediately rather than calling requestMemSideBus() as we do // there). - // Handle writebacks if needed + // Handle writebacks (from the response handling) if needed while (!writebacks.empty()){ PacketPtr wbPkt = writebacks.front(); memSidePort->sendAtomic(wbPkt); @@ -1396,7 +1411,7 @@ template void -Cache::uncacheableFlush(PacketPtr pkt) +Cache::uncacheableFlush(PacketPtr pkt, PacketList &writebacks) { DPRINTF(Cache, "%s%s addr %#llx uncacheable\n", pkt->cmdString(), pkt->req->isInstFetch() ? " (ifetch)" : "", @@ -1406,9 +1421,11 @@ tags->clearLocks(); BlkType *blk(tags->findBlock(pkt->getAddr(), pkt->isSecure())); - if (blk) { - writebackVisitor(*blk); - invalidateVisitor(*blk); + if (blk && blk->isValid()) { + if (blk->isDirty()) + writebacks.push_back(writebackBlk(blk)); + tags->invalidate(blk); + blk->invalidate(); } }