summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2016-04-21 04:48:06 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2016-04-21 04:48:06 -0400
commit6c92ee49f1125559ffc7c20cfe96306b9c4de017 (patch)
tree2c74e0d43480d725ed436145a5c5ce93b105d824
parent53d735b17ee1a3bd27173138ed1937a45f20bc12 (diff)
downloadgem5-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.cc57
-rw-r--r--src/mem/cache/cache.hh10
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