mem-cache: Create an address aware TempCacheBlk
authorDaniel R. Carvalho <odanrc@yahoo.com.br>
Mon, 16 Apr 2018 13:36:33 +0000 (15:36 +0200)
committerDaniel Carvalho <odanrc@yahoo.com.br>
Fri, 1 Jun 2018 11:21:46 +0000 (11:21 +0000)
tempBlock has its member variables  manually set in order to allow
it to be used in the block address regeneration function. This is
not necessary, and ti can be simply given the address, so  it does
not need to be aware of set and tag. This will simplify
implementation of sector and skewed caches.

Change-Id: Iaffb10c323509722cd5589fe1030b818d43336d6
Reviewed-on: https://gem5-review.googlesource.com/9961
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>

src/mem/cache/base.cc
src/mem/cache/base.hh
src/mem/cache/blk.cc
src/mem/cache/blk.hh
src/mem/cache/cache.cc

index 604aab6216cdf3e84c25ac118550bc80f3b085c5..efdb3be2ca8ae663abc8acad75a217aba60b0026 100644 (file)
@@ -113,7 +113,7 @@ BaseCache::BaseCache(const BaseCacheParams *p, unsigned blk_size)
     // forward snoops is overridden in init() once we can query
     // whether the connected master is actually snooping or not
 
-    tempBlock = new CacheBlk();
+    tempBlock = new TempCacheBlk();
     tempBlock->data = new uint8_t[blkSize];
 
     tags->setCache(this);
@@ -164,6 +164,16 @@ BaseCache::CacheSlavePort::processSendRetry()
     sendRetryReq();
 }
 
+Addr
+BaseCache::regenerateBlkAddr(CacheBlk* blk)
+{
+    if (blk != tempBlock) {
+        return tags->regenerateBlkAddr(blk);
+    } else {
+        return tempBlock->getAddr();
+    }
+}
+
 void
 BaseCache::init()
 {
@@ -1123,8 +1133,7 @@ BaseCache::handleFill(PacketPtr pkt, CacheBlk *blk, PacketList &writebacks,
             // current request and then get rid of it
             assert(!tempBlock->isValid());
             blk = tempBlock;
-            tempBlock->set = tags->extractSet(addr);
-            tempBlock->tag = tags->extractTag(addr);
+            tempBlock->insert(addr, is_secure);
             DPRINTF(Cache, "using temp block for %#llx (%s)\n", addr,
                     is_secure ? "s" : "ns");
         } else {
@@ -1207,7 +1216,7 @@ BaseCache::allocateBlock(Addr addr, bool is_secure, PacketList &writebacks)
         return nullptr;
 
     if (blk->isValid()) {
-        Addr repl_addr = tags->regenerateBlkAddr(blk);
+        Addr repl_addr = regenerateBlkAddr(blk);
         MSHR *repl_mshr = mshrQueue.findMatch(repl_addr, blk->isSecure());
         if (repl_mshr) {
             // must be an outstanding upgrade or clean request
@@ -1251,7 +1260,7 @@ BaseCache::writebackBlk(CacheBlk *blk)
 
     writebacks[Request::wbMasterId]++;
 
-    Request *req = new Request(tags->regenerateBlkAddr(blk), blkSize, 0,
+    Request *req = new Request(regenerateBlkAddr(blk), blkSize, 0,
                                Request::wbMasterId);
     if (blk->isSecure())
         req->setFlags(Request::SECURE);
@@ -1286,7 +1295,7 @@ BaseCache::writebackBlk(CacheBlk *blk)
 PacketPtr
 BaseCache::writecleanBlk(CacheBlk *blk, Request::Flags dest, PacketId id)
 {
-    Request *req = new Request(tags->regenerateBlkAddr(blk), blkSize, 0,
+    Request *req = new Request(regenerateBlkAddr(blk), blkSize, 0,
                                Request::wbMasterId);
     if (blk->isSecure()) {
         req->setFlags(Request::SECURE);
@@ -1346,7 +1355,7 @@ BaseCache::writebackVisitor(CacheBlk &blk)
     if (blk.isDirty()) {
         assert(blk.isValid());
 
-        Request request(tags->regenerateBlkAddr(&blk),
+        Request request(regenerateBlkAddr(&blk),
                         blkSize, 0, Request::funcMasterId);
         request.taskId(blk.task_id);
         if (blk.isSecure()) {
index 04225c12f67906d1daeef116685169f85df1b0e9..6600aeba6bfccdf8a8e67ee57fe02b979cbd55ff 100644 (file)
@@ -334,7 +334,7 @@ class BaseCache : public MemObject
      * is an outstanding request that accesses the victim block) or
      * when we want to avoid allocation (e.g., exclusive caches)
      */
-    CacheBlk *tempBlock;
+    TempCacheBlk *tempBlock;
 
     /**
      * Upstream caches need this packet until true is returned, so
@@ -389,6 +389,16 @@ class BaseCache : public MemObject
             cmd.isLLSC();
     }
 
+    /**
+     * Regenerate block address using tags.
+     * Block address regeneration depends on whether we're using a temporary
+     * block or not.
+     *
+     * @param blk The block to regenerate address.
+     * @return The block's address.
+     */
+    Addr regenerateBlkAddr(CacheBlk* blk);
+
     /**
      * Does all the processing necessary to perform the provided request.
      * @param pkt The memory request to perform.
index ad0c20a6fac9acd00600da86768a96960a007d5f..45bd9bfd43a2869d8efdc9874579b797c9c72879 100644 (file)
@@ -43,7 +43,7 @@
 #include "base/cprintf.hh"
 
 void
-CacheBlk::insert(const Addr tag, const State is_secure,
+CacheBlk::insert(const Addr tag, const bool is_secure,
                  const int src_master_ID, const uint32_t task_ID)
 {
     // Set block tag
index c94c3ba7d2055d9e01c27816607f571be8f891ee..c4ec12ff381223c9cc4ba1bedaac5f04f676f750 100644 (file)
@@ -166,7 +166,6 @@ class CacheBlk : public ReplaceableEntry
     std::list<Lock> lockList;
 
   public:
-
     CacheBlk()
     {
         invalidate();
@@ -261,7 +260,7 @@ class CacheBlk : public ReplaceableEntry
      * @param src_master_ID The source requestor ID.
      * @param task_ID The new task ID.
      */
-    void insert(const Addr tag, const State is_secure, const int src_master_ID,
+    void insert(const Addr tag, const bool is_secure, const int src_master_ID,
                 const uint32_t task_ID);
 
     /**
@@ -393,6 +392,66 @@ class CacheBlk : public ReplaceableEntry
     }
 };
 
+/**
+ * Special instance of CacheBlk for use with tempBlk that deals with its
+ * block address regeneration.
+ * @sa Cache
+ */
+class TempCacheBlk final : public CacheBlk
+{
+  private:
+    /**
+     * Copy of the block's address, used to regenerate tempBlock's address.
+     */
+    Addr _addr;
+
+  public:
+    TempCacheBlk() : CacheBlk() {}
+    TempCacheBlk(const TempCacheBlk&) = delete;
+    TempCacheBlk& operator=(const TempCacheBlk&) = delete;
+    ~TempCacheBlk() {};
+
+    /**
+     * Invalidate the block and clear all state.
+     */
+    void invalidate() override {
+        CacheBlk::invalidate();
+
+        _addr = MaxAddr;
+    }
+
+    /**
+     * Set member variables when a block insertion occurs. A TempCacheBlk does
+     * not have all the information required to regenerate the block's address,
+     * so it is provided the address itself for easy regeneration.
+     *
+     * @param addr Block address.
+     * @param is_secure Whether the block is in secure space or not.
+     */
+    void insert(const Addr addr, const bool is_secure)
+    {
+        // Set block address
+        _addr = addr;
+
+        // Set secure state
+        if (is_secure) {
+            status = BlkSecure;
+        } else {
+            status = 0;
+        }
+    }
+
+    /**
+     * Get block's address.
+     *
+     * @return addr Address value.
+     */
+    Addr getAddr() const
+    {
+        return _addr;
+    }
+};
+
 /**
  * Simple class to provide virtual print() method on cache blocks
  * without allocating a vtable pointer for every single cache block.
index 9177ebea8036056497088916f5c16a84b1d9a36f..34f3dc5b913fcf4a0e6f3586295e12dc328a251a 100644 (file)
@@ -873,7 +873,7 @@ Cache::cleanEvictBlk(CacheBlk *blk)
     assert(blk && blk->isValid() && !blk->isDirty());
     // Creating a zero sized write, a message to the snoop filter
     Request *req =
-        new Request(tags->regenerateBlkAddr(blk), blkSize, 0,
+        new Request(regenerateBlkAddr(blk), blkSize, 0,
                     Request::wbMasterId);
     if (blk->isSecure())
         req->setFlags(Request::SECURE);