mem-cache: Optimize sector valid and secure check

Previously a loop was being done to check whether the
block was valid/secure or not. Variables have been
added to skip this loop and save and update sector
block state when sub-blocks are validated, invalidated
and secured.

Change-Id: Ie1734f7dfda9698c7bf22a1fcbfc47ffb9239cea
Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/14363
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Jason Lowe-Power <jason@lowepower.com>
diff --git a/src/mem/cache/tags/sector_blk.cc b/src/mem/cache/tags/sector_blk.cc
index de91536..93b1961 100644
--- a/src/mem/cache/tags/sector_blk.cc
+++ b/src/mem/cache/tags/sector_blk.cc
@@ -72,6 +72,27 @@
 }
 
 void
+SectorSubBlk::setValid()
+{
+    CacheBlk::setValid();
+    _sectorBlk->validateSubBlk();
+}
+
+void
+SectorSubBlk::setSecure()
+{
+    CacheBlk::setSecure();
+    _sectorBlk->setSecure();
+}
+
+void
+SectorSubBlk::invalidate()
+{
+    CacheBlk::invalidate();
+    _sectorBlk->invalidateSubBlk();
+}
+
+void
 SectorSubBlk::insert(const Addr tag, const bool is_secure,
                      const int src_master_ID, const uint32_t task_ID)
 {
@@ -94,28 +115,23 @@
                     getSectorOffset());
 }
 
+SectorBlk::SectorBlk()
+    : ReplaceableEntry(), _tag(MaxAddr), _validCounter(0), _secureBit(false)
+{
+}
+
 bool
 SectorBlk::isValid() const
 {
     // If any of the blocks in the sector is valid, so is the sector
-    for (const auto& blk : blks) {
-        if (blk->isValid()) {
-            return true;
-        }
-    }
-    return false;
+    return _validCounter > 0;
 }
 
 bool
 SectorBlk::isSecure() const
 {
     // If any of the valid blocks in the sector is secure, so is the sector
-    for (const auto& blk : blks) {
-        if (blk->isValid()) {
-            return blk->isSecure();
-        }
-    }
-    return false;
+    return _secureBit;
 }
 
 void
@@ -129,3 +145,25 @@
 {
     return _tag;
 }
+
+void
+SectorBlk::validateSubBlk()
+{
+    _validCounter++;
+}
+
+void
+SectorBlk::invalidateSubBlk()
+{
+    // If all sub-blocks have been invalidated, the sector becomes invalid,
+    // so clear secure bit
+    if (--_validCounter == 0) {
+        _secureBit = false;
+    }
+}
+
+void
+SectorBlk::setSecure()
+{
+    _secureBit = true;
+}
diff --git a/src/mem/cache/tags/sector_blk.hh b/src/mem/cache/tags/sector_blk.hh
index 12649fc..264836c 100644
--- a/src/mem/cache/tags/sector_blk.hh
+++ b/src/mem/cache/tags/sector_blk.hh
@@ -102,6 +102,21 @@
     Addr getTag() const;
 
     /**
+     * Set valid bit and inform sector block.
+     */
+    void setValid() override;
+
+    /**
+     * Set secure bit and inform sector block.
+     */
+    void setSecure() override;
+
+    /**
+     * Invalidate the block and inform sector block.
+     */
+    void invalidate() override;
+
+    /**
      * Set member variables when a block insertion occurs. Resets reference
      * count to 1 (the insertion counts as a reference), and touch block if
      * it hadn't been touched previously. Sets the insertion tick to the
@@ -135,8 +150,19 @@
      */
     Addr _tag;
 
+    /**
+     * Counter of the number of valid sub-blocks. The sector is valid if any
+     * of its sub-blocks is valid.
+     */
+    uint8_t _validCounter;
+
+    /**
+     * Whether sector blk is in secure-space or not.
+     */
+    bool _secureBit;
+
   public:
-    SectorBlk() : ReplaceableEntry(), _tag(MaxAddr) {}
+    SectorBlk();
     SectorBlk(const SectorBlk&) = delete;
     SectorBlk& operator=(const SectorBlk&) = delete;
     ~SectorBlk() {};
@@ -173,6 +199,21 @@
      * @return The tag value.
      */
     Addr getTag() const;
+
+    /**
+     * Increase the number of valid sub-blocks.
+     */
+    void validateSubBlk();
+
+    /**
+     * Decrease the number of valid sub-blocks.
+     */
+    void invalidateSubBlk();
+
+    /**
+     * Set secure bit.
+     */
+    void setSecure();
 };
 
 #endif //__MEM_CACHE_TAGS_SECTOR_BLK_HH__