mem-cache: add option to send pf on hit on pf

From the point of view of the prefetchers, a hit on a prefetched block
should be considered the same as a miss: a new prefetch should be
generated.

Change-Id: If865324502b81cfd3ae8c009666d3f498092b90f
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/47201
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Maintainer: Daniel Carvalho <odanrc@yahoo.com.br>
diff --git a/src/mem/cache/Cache.py b/src/mem/cache/Cache.py
index b4df2a0..72665e1 100644
--- a/src/mem/cache/Cache.py
+++ b/src/mem/cache/Cache.py
@@ -99,6 +99,8 @@
     prefetcher = Param.BasePrefetcher(NULL,"Prefetcher attached to cache")
     prefetch_on_access = Param.Bool(False,
          "Notify the hardware prefetcher on every access (not just misses)")
+    prefetch_on_pf_hit = Param.Bool(False,
+        "Notify the hardware prefetcher on hit on prefetched lines")
 
     tags = Param.BaseTags(BaseSetAssoc(), "Tag store")
     replacement_policy = Param.BaseReplacementPolicy(LRURP(),
diff --git a/src/mem/cache/prefetch/Prefetcher.py b/src/mem/cache/prefetch/Prefetcher.py
index fbae086..5346937 100644
--- a/src/mem/cache/prefetch/Prefetcher.py
+++ b/src/mem/cache/prefetch/Prefetcher.py
@@ -77,6 +77,8 @@
     on_inst  = Param.Bool(True, "Notify prefetcher on instruction accesses")
     prefetch_on_access = Param.Bool(Parent.prefetch_on_access,
         "Notify the hardware prefetcher on every access (not just misses)")
+    prefetch_on_pf_hit = Param.Bool(Parent.prefetch_on_pf_hit,
+        "Notify the hardware prefetcher on hit on prefetched lines")
     use_virtual_addresses = Param.Bool(False,
         "Use virtual addresses for prefetching")
 
diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc
index 4c97588..2746908 100644
--- a/src/mem/cache/prefetch/base.cc
+++ b/src/mem/cache/prefetch/base.cc
@@ -100,6 +100,7 @@
       requestorId(p.sys->getRequestorId(this)),
       pageBytes(p.sys->getPageBytes()),
       prefetchOnAccess(p.prefetch_on_access),
+      prefetchOnPfHit(p.prefetch_on_pf_hit),
       useVirtualAddresses(p.use_virtual_addresses),
       prefetchStats(this), issuedPrefetches(0),
       usefulPrefetches(0), tlb(nullptr)
@@ -153,7 +154,12 @@
     bool read = pkt->isRead();
     bool inv = pkt->isInvalidate();
 
-    if (!miss && !prefetchOnAccess) return false;
+    if (!miss) {
+        if (prefetchOnPfHit)
+            return hasBeenPrefetched(pkt->getAddr(), pkt->isSecure());
+        if (!prefetchOnAccess)
+            return false;
+    }
     if (pkt->req->isUncacheable()) return false;
     if (fetch && !onInst) return false;
     if (!fetch && !onData) return false;
diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh
index 0b19e01..20a2d70 100644
--- a/src/mem/cache/prefetch/base.hh
+++ b/src/mem/cache/prefetch/base.hh
@@ -295,6 +295,9 @@
     /** Prefetch on every access, not just misses */
     const bool prefetchOnAccess;
 
+    /** Prefetch on hit on prefetched lines */
+    const bool prefetchOnPfHit;
+
     /** Use Virtual Addresses for prefetching */
     const bool useVirtualAddresses;