diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mem/cache/cache.hh | 12 | ||||
-rw-r--r-- | src/mem/cache/cache_impl.hh | 91 |
2 files changed, 51 insertions, 52 deletions
diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index 0ee776e92..7971c6654 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -332,18 +332,6 @@ class Cache : public BaseCache bool invalidateVisitor(BlkType &blk); /** - * Flush a cache line due to an uncacheable memory access to the - * line. - * - * @note This shouldn't normally happen, but we need to handle it - * since some architecture models don't implement cache - * maintenance operations. We won't even try to get a decent - * timing here since the line should have been flushed earlier by - * a cache maintenance operation. - */ - void uncacheableFlush(PacketPtr pkt); - - /** * Squash all requests associated with specified thread. * intended for use by I-cache. * @param threadNum The thread to squash. diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index a21fa9f4e..b897a8467 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -311,7 +311,22 @@ Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk, DPRINTF(Cache, "%s for %s addr %#llx size %d\n", __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize()); if (pkt->req->isUncacheable()) { - uncacheableFlush(pkt); + DPRINTF(Cache, "%s%s addr %#llx uncacheable\n", pkt->cmdString(), + pkt->req->isInstFetch() ? " (ifetch)" : "", + pkt->getAddr()); + + if (pkt->req->isClearLL()) + tags->clearLocks(); + + // flush and invalidate any existing block + BlkType *old_blk(tags->findBlock(pkt->getAddr(), pkt->isSecure())); + if (old_blk && old_blk->isValid()) { + if (old_blk->isDirty()) + writebacks.push_back(writebackBlk(old_blk)); + tags->invalidate(old_blk); + old_blk->invalidate(); + } + blk = NULL; // lookupLatency is the latency in case the request is uncacheable. lat = lookupLatency; @@ -518,14 +533,32 @@ Cache<TagStore>::recvTimingReq(PacketPtr pkt) 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 +566,6 @@ Cache<TagStore>::recvTimingReq(PacketPtr pkt) // 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; @@ -743,15 +771,6 @@ Cache<TagStore>::recvTimingReq(PacketPtr pkt) 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; } @@ -870,8 +889,18 @@ Cache<TagStore>::recvAtomic(PacketPtr pkt) BlkType *blk = NULL; PacketList writebacks; + bool satisfied = 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 (!access(pkt, blk, lat, writebacks)) { + if (!satisfied) { // MISS PacketPtr bus_pkt = getBusPacket(pkt, blk, pkt->needsExclusive()); @@ -894,6 +923,7 @@ Cache<TagStore>::recvAtomic(PacketPtr pkt) 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", @@ -944,7 +974,7 @@ Cache<TagStore>::recvAtomic(PacketPtr pkt) // 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,25 +1426,6 @@ Cache<TagStore>::invalidateVisitor(BlkType &blk) } template<class TagStore> -void -Cache<TagStore>::uncacheableFlush(PacketPtr pkt) -{ - DPRINTF(Cache, "%s%s addr %#llx uncacheable\n", pkt->cmdString(), - pkt->req->isInstFetch() ? " (ifetch)" : "", - pkt->getAddr()); - - if (pkt->req->isClearLL()) - tags->clearLocks(); - - BlkType *blk(tags->findBlock(pkt->getAddr(), pkt->isSecure())); - if (blk) { - writebackVisitor(*blk); - invalidateVisitor(*blk); - } -} - - -template<class TagStore> typename Cache<TagStore>::BlkType* Cache<TagStore>::allocateBlock(Addr addr, bool is_secure, PacketList &writebacks) |