mem-cache: Move cache bypass mechanism to the ports
authorNikos Nikoleris <nikos.nikoleris@arm.com>
Thu, 3 May 2018 14:51:41 +0000 (15:51 +0100)
committerNikos Nikoleris <nikos.nikoleris@arm.com>
Thu, 31 May 2018 15:12:49 +0000 (15:12 +0000)
Cache bypass is necessary for cpu models like the KvmCPU. Previously
the bypass would happen at the cache classes. With this change the
bypassing happens directly at the ports.

Change-Id: I34de9fc63383aee8590643e169501ea6060d2d62
Reviewed-on: https://gem5-review.googlesource.com/10432
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
src/mem/cache/base.cc
src/mem/cache/cache.cc

index d7d593ec0627bc979dc7048f889b7e1dd1d8227a..c50fcdb6e21103e662472cd18309b8e24f3de9da 100644 (file)
@@ -632,17 +632,6 @@ BaseCache::recvAtomic(PacketPtr pkt)
 void
 BaseCache::functionalAccess(PacketPtr pkt, bool from_cpu_side)
 {
-    if (system->bypassCaches()) {
-        // Packets from the memory side are snoop request and
-        // shouldn't happen in bypass mode.
-        assert(from_cpu_side);
-
-        // The cache should be flushed if we are in cache bypass mode,
-        // so we don't need to check if we need to update anything.
-        memSidePort.sendFunctional(pkt);
-        return;
-    }
-
     Addr blk_addr = pkt->getBlockAddr(blkSize);
     bool is_secure = pkt->isSecure();
     CacheBlk *blk = tags->findBlock(pkt->getAddr(), is_secure);
@@ -2147,6 +2136,11 @@ BaseCache::regStats()
 bool
 BaseCache::CpuSidePort::recvTimingSnoopResp(PacketPtr pkt)
 {
+    // Snoops shouldn't happen when bypassing caches
+    assert(!cache->system->bypassCaches());
+
+    assert(pkt->isResponse());
+
     // Express snoop responses from master to slave, e.g., from L1 to L2
     cache->recvTimingSnoopResp(pkt);
     return true;
@@ -2156,7 +2150,7 @@ BaseCache::CpuSidePort::recvTimingSnoopResp(PacketPtr pkt)
 bool
 BaseCache::CpuSidePort::tryTiming(PacketPtr pkt)
 {
-    if (pkt->isExpressSnoop()) {
+    if (cache->system->bypassCaches() || pkt->isExpressSnoop()) {
         // always let express snoop packets through even if blocked
         return true;
     } else if (blocked || mustSendRetry) {
@@ -2171,7 +2165,15 @@ BaseCache::CpuSidePort::tryTiming(PacketPtr pkt)
 bool
 BaseCache::CpuSidePort::recvTimingReq(PacketPtr pkt)
 {
-    if (tryTiming(pkt)) {
+    assert(pkt->isRequest());
+
+    if (cache->system->bypassCaches()) {
+        // Just forward the packet if caches are disabled.
+        // @todo This should really enqueue the packet rather
+        bool M5_VAR_USED success = cache->memSidePort.sendTimingReq(pkt);
+        assert(success);
+        return true;
+    } else if (tryTiming(pkt)) {
         cache->recvTimingReq(pkt);
         return true;
     }
@@ -2181,12 +2183,24 @@ BaseCache::CpuSidePort::recvTimingReq(PacketPtr pkt)
 Tick
 BaseCache::CpuSidePort::recvAtomic(PacketPtr pkt)
 {
-    return cache->recvAtomic(pkt);
+    if (cache->system->bypassCaches()) {
+        // Forward the request if the system is in cache bypass mode.
+        return cache->memSidePort.sendAtomic(pkt);
+    } else {
+        return cache->recvAtomic(pkt);
+    }
 }
 
 void
 BaseCache::CpuSidePort::recvFunctional(PacketPtr pkt)
 {
+    if (cache->system->bypassCaches()) {
+        // The cache should be flushed if we are in cache bypass mode,
+        // so we don't need to check if we need to update anything.
+        cache->memSidePort.sendFunctional(pkt);
+        return;
+    }
+
     // functional request
     cache->functionalAccess(pkt, true);
 }
@@ -2221,6 +2235,9 @@ BaseCache::MemSidePort::recvTimingResp(PacketPtr pkt)
 void
 BaseCache::MemSidePort::recvTimingSnoopReq(PacketPtr pkt)
 {
+    // Snoops shouldn't happen when bypassing caches
+    assert(!cache->system->bypassCaches());
+
     // handle snooping requests
     cache->recvTimingSnoopReq(pkt);
 }
@@ -2228,12 +2245,18 @@ BaseCache::MemSidePort::recvTimingSnoopReq(PacketPtr pkt)
 Tick
 BaseCache::MemSidePort::recvAtomicSnoop(PacketPtr pkt)
 {
+    // Snoops shouldn't happen when bypassing caches
+    assert(!cache->system->bypassCaches());
+
     return cache->recvAtomicSnoop(pkt);
 }
 
 void
 BaseCache::MemSidePort::recvFunctionalSnoop(PacketPtr pkt)
 {
+    // Snoops shouldn't happen when bypassing caches
+    assert(!cache->system->bypassCaches());
+
     // functional snoop (note that in contrast to atomic we don't have
     // a specific functionalSnoop method, as they have the same
     // behaviour regardless)
index f74afcb2bb8b002e5cf6289fe4e4fa957574aa34..5034ca521e41c6d091682a05784bffb194f9c52c 100644 (file)
@@ -271,9 +271,6 @@ Cache::recvTimingSnoopResp(PacketPtr pkt)
 {
     DPRINTF(Cache, "%s for %s\n", __func__, pkt->print());
 
-    assert(pkt->isResponse());
-    assert(!system->bypassCaches());
-
     // determine if the response is from a snoop request we created
     // (in which case it should be in the outstandingSnoop), or if we
     // merely forwarded someone else's snoop request
@@ -409,16 +406,6 @@ Cache::recvTimingReq(PacketPtr pkt)
 {
     DPRINTF(CacheTags, "%s tags:\n%s\n", __func__, tags->print());
 
-    assert(pkt->isRequest());
-
-    // Just forward the packet if caches are disabled.
-    if (system->bypassCaches()) {
-        // @todo This should really enqueue the packet rather
-        bool M5_VAR_USED success = memSidePort.sendTimingReq(pkt);
-        assert(success);
-        return;
-    }
-
     promoteWholeLineWrites(pkt);
 
     if (pkt->cacheResponding()) {
@@ -665,10 +652,6 @@ Cache::handleAtomicReqMiss(PacketPtr pkt, CacheBlk *blk,
 Tick
 Cache::recvAtomic(PacketPtr pkt)
 {
-    // Forward the request if the system is in cache bypass mode.
-    if (system->bypassCaches())
-        return ticksToCycles(memSidePort.sendAtomic(pkt));
-
     promoteWholeLineWrites(pkt);
 
     return BaseCache::recvAtomic(pkt);
@@ -1183,9 +1166,6 @@ Cache::recvTimingSnoopReq(PacketPtr pkt)
 {
     DPRINTF(CacheVerbose, "%s: for %s\n", __func__, pkt->print());
 
-    // Snoops shouldn't happen when bypassing caches
-    assert(!system->bypassCaches());
-
     // no need to snoop requests that are not in range
     if (!inRange(pkt->getAddr())) {
         return;
@@ -1309,9 +1289,6 @@ Cache::recvTimingSnoopReq(PacketPtr pkt)
 Tick
 Cache::recvAtomicSnoop(PacketPtr pkt)
 {
-    // Snoops shouldn't happen when bypassing caches
-    assert(!system->bypassCaches());
-
     // no need to snoop requests that are not in range.
     if (!inRange(pkt->getAddr())) {
         return 0;