diff options
author | Andreas Hansson <andreas.hansson@arm.com> | 2016-04-21 04:48:06 -0400 |
---|---|---|
committer | Andreas Hansson <andreas.hansson@arm.com> | 2016-04-21 04:48:06 -0400 |
commit | 6c92ee49f1125559ffc7c20cfe96306b9c4de017 (patch) | |
tree | 2c74e0d43480d725ed436145a5c5ce93b105d824 | |
parent | 53d735b17ee1a3bd27173138ed1937a45f20bc12 (diff) | |
download | gem5-6c92ee49f1125559ffc7c20cfe96306b9c4de017.tar.xz |
mem: Align downstream cache packet creation in atomic and timing
This patch makes the control flow more uniform in atomic and timing,
ultimately making the code easier to understand.
-rw-r--r-- | src/mem/cache/cache.cc | 57 | ||||
-rw-r--r-- | src/mem/cache/cache.hh | 10 |
2 files changed, 34 insertions, 33 deletions
diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc index 5d5760ff3..0bdec65e7 100644 --- a/src/mem/cache/cache.cc +++ b/src/mem/cache/cache.cc @@ -903,30 +903,20 @@ Cache::recvTimingReq(PacketPtr pkt) return true; } - -// See comment in cache.hh. PacketPtr -Cache::getBusPacket(PacketPtr cpu_pkt, CacheBlk *blk, - bool needsWritable) const +Cache::createMissPacket(PacketPtr cpu_pkt, CacheBlk *blk, + bool needsWritable) const { - bool blkValid = blk && blk->isValid(); + // should never see evictions here + assert(!cpu_pkt->isEviction()); - if (cpu_pkt->req->isUncacheable()) { - // note that at the point we see the uncacheable request we - // flush any block, but there could be an outstanding MSHR, - // and the cache could have filled again before we actually - // send out the forwarded uncacheable request (blk could thus - // be non-null) - return NULL; - } + bool blkValid = blk && blk->isValid(); - if (!blkValid && - (cpu_pkt->isUpgrade() || - cpu_pkt->isEviction())) { - // Writebacks that weren't allocated in access() and upgrades - // from upper-level caches that missed completely just go - // through. - return NULL; + if (cpu_pkt->req->isUncacheable() || + (!blkValid && cpu_pkt->isUpgrade())) { + // uncacheable requests and upgrades from upper-level caches + // that missed completely just go through as is + return nullptr; } assert(cpu_pkt->needsResponse()); @@ -1032,7 +1022,16 @@ Cache::recvAtomic(PacketPtr pkt) if (!satisfied) { // MISS - PacketPtr bus_pkt = getBusPacket(pkt, blk, pkt->needsWritable()); + // deal with the packets that go through the write path of + // the cache, i.e. any evictions and uncacheable writes + if (pkt->isEviction() || + (pkt->req->isUncacheable() && pkt->isWrite())) { + lat += ticksToCycles(memSidePort->sendAtomic(pkt)); + return lat * clockPeriod(); + } + // only misses left + + PacketPtr bus_pkt = createMissPacket(pkt, blk, pkt->needsWritable()); bool is_forward = (bus_pkt == NULL); @@ -1052,6 +1051,8 @@ Cache::recvAtomic(PacketPtr pkt) lat += ticksToCycles(memSidePort->sendAtomic(bus_pkt)); + bool is_invalidate = bus_pkt->isInvalidate(); + // 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(), @@ -1068,12 +1069,6 @@ Cache::recvAtomic(PacketPtr pkt) if (bus_pkt->isError()) { pkt->makeAtomicResponse(); pkt->copyError(bus_pkt); - } else if (pkt->cmd == MemCmd::InvalidateReq) { - if (blk) { - // invalidate response to a cache that received - // an invalidate request - satisfyCpuSideRequest(pkt, blk); - } } else if (pkt->cmd == MemCmd::WriteLineReq) { // note the use of pkt, not bus_pkt here. @@ -1081,6 +1076,8 @@ Cache::recvAtomic(PacketPtr pkt) // the write to a whole line blk = handleFill(pkt, blk, writebacks, allocOnFill(pkt->cmd)); + assert(blk != NULL); + is_invalidate = false; satisfyCpuSideRequest(pkt, blk); } else if (bus_pkt->isRead() || bus_pkt->cmd == MemCmd::UpgradeResp) { @@ -1097,6 +1094,10 @@ Cache::recvAtomic(PacketPtr pkt) } delete bus_pkt; } + + if (is_invalidate && blk && blk->isValid()) { + invalidateBlock(blk); + } } // Note that we don't invoke the prefetcher at all in atomic mode. @@ -2445,7 +2446,7 @@ Cache::sendMSHRQueuePacket(MSHR* mshr) // either a prefetch that is not present upstream, or a normal // MSHR request, proceed to get the packet to send downstream - PacketPtr pkt = getBusPacket(tgt_pkt, blk, mshr->needsWritable()); + PacketPtr pkt = createMissPacket(tgt_pkt, blk, mshr->needsWritable()); mshr->isForward = (pkt == NULL); diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index f2288bd7c..d0bec127f 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -460,18 +460,18 @@ class Cache : public BaseCache bool invalidateVisitor(CacheBlk &blk); /** - * Generate an appropriate downstream bus request packet for the + * Create an appropriate downstream bus request packet for the * given parameters. - * @param cpu_pkt The upstream request that needs to be satisfied. + * @param cpu_pkt The miss that needs to be satisfied. * @param blk The block currently in the cache corresponding to * cpu_pkt (NULL if none). - * @param needsExclusive Indicates that an exclusive copy is required + * @param needsWritable Indicates that the block must be writable * even if the request in cpu_pkt doesn't indicate that. * @return A new Packet containing the request, or NULL if the * current request in cpu_pkt should just be forwarded on. */ - PacketPtr getBusPacket(PacketPtr cpu_pkt, CacheBlk *blk, - bool needsExclusive) const; + PacketPtr createMissPacket(PacketPtr cpu_pkt, CacheBlk *blk, + bool needsWritable) const; /** * Return the next queue entry to service, either a pending miss |