From: Daniel R. Carvalho Date: Tue, 6 Oct 2020 10:25:06 +0000 (+0200) Subject: mem-cache: Create a tagged entry class X-Git-Tag: develop-gem5-snapshot~670 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e3edf5e78f7ceeb7af9a0181497944433e301ce6;p=gem5.git mem-cache: Create a tagged entry class The TaggedEntry class inherits from the ReplaceableEntry class. Its purpose is to define a replaceable entry with tagging attributes. It has been created as a separate class because both the replacement policies and the AbstractCacheEntry use ReplaceableEntry, and do not need the tagging information to perform their operations. Change-Id: I24e87c865fc21c79dea7e488507a8cafc5223b39 Signed-off-by: Daniel R. Carvalho Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35698 Reviewed-by: Nikos Nikoleris Maintainer: Nikos Nikoleris Tested-by: kokoro --- diff --git a/src/mem/cache/cache_blk.cc b/src/mem/cache/cache_blk.cc index 01b71c5b7..b747f3905 100644 --- a/src/mem/cache/cache_blk.cc +++ b/src/mem/cache/cache_blk.cc @@ -43,12 +43,6 @@ #include "base/cprintf.hh" -bool -CacheBlk::matchTag(Addr tag, bool is_secure) const -{ - return isValid() && (getTag() == tag) && (isSecure() == is_secure); -} - void CacheBlk::insert(const Addr tag, const bool is_secure, const int src_requestor_ID, const uint32_t task_ID) @@ -56,8 +50,7 @@ CacheBlk::insert(const Addr tag, const bool is_secure, // Make sure that the block has been properly invalidated assert(status == 0); - // Set block tag - setTag(tag); + insert(tag, is_secure); // Set source requestor ID setSrcRequestorId(src_requestor_ID); @@ -70,14 +63,6 @@ CacheBlk::insert(const Addr tag, const bool is_secure, // Insertion counts as a reference to the block increaseRefCount(); - - // Set secure state - if (is_secure) { - setSecure(); - } - - // Validate block - setValid(); } void diff --git a/src/mem/cache/cache_blk.hh b/src/mem/cache/cache_blk.hh index 0ad355c37..b0d45af55 100644 --- a/src/mem/cache/cache_blk.hh +++ b/src/mem/cache/cache_blk.hh @@ -54,7 +54,7 @@ #include "base/printable.hh" #include "base/types.hh" -#include "mem/cache/replacement_policies/base.hh" +#include "mem/cache/tags/tagged_entry.hh" #include "mem/packet.hh" #include "mem/request.hh" #include "sim/core.hh" @@ -63,8 +63,6 @@ * Cache block status bit assignments */ enum CacheBlkStatusBits : unsigned { - /** valid, readable */ - BlkValid = 0x01, /** write permission */ BlkWritable = 0x02, /** read permission (yes, block can be valid but not readable) */ @@ -73,17 +71,16 @@ enum CacheBlkStatusBits : unsigned { BlkDirty = 0x08, /** block was a hardware prefetch yet unaccessed*/ BlkHWPrefetched = 0x20, - /** block holds data from the secure memory space */ - BlkSecure = 0x40, /** block holds compressed data */ BlkCompressed = 0x80 }; /** * A Basic Cache block. - * Contains the tag, status, and a pointer to data. + * Contains information regarding its coherence, prefetching and compression + * status, as well as a pointer to its data. */ -class CacheBlk : public ReplaceableEntry +class CacheBlk : public TaggedEntry { public: /** @@ -150,7 +147,7 @@ class CacheBlk : public ReplaceableEntry std::list lockList; public: - CacheBlk() : data(nullptr), _tickInserted(0) + CacheBlk() : TaggedEntry(), data(nullptr), _tickInserted(0) { invalidate(); } @@ -163,11 +160,7 @@ class CacheBlk : public ReplaceableEntry * Checks the write permissions of this block. * @return True if the block is writable. */ - bool isWritable() const - { - const State needed_bits = BlkWritable | BlkValid; - return (status & needed_bits) == needed_bits; - } + bool isWritable() const { return isValid() && (status & BlkWritable); } /** * Checks the read permissions of this block. Note that a block @@ -175,27 +168,14 @@ class CacheBlk : public ReplaceableEntry * upgrade miss. * @return True if the block is readable. */ - bool isReadable() const - { - const State needed_bits = BlkReadable | BlkValid; - return (status & needed_bits) == needed_bits; - } - - /** - * Checks that a block is valid. - * @return True if the block is valid. - */ - bool isValid() const - { - return (status & BlkValid) != 0; - } + bool isReadable() const { return isValid() && (status & BlkReadable); } /** * Invalidate the block and clear all state. */ virtual void invalidate() { - setTag(MaxAddr); + TaggedEntry::invalidate(); setTaskId(ContextSwitchTaskId::Unknown); status = 0; whenReady = MaxTick; @@ -223,46 +203,6 @@ class CacheBlk : public ReplaceableEntry return (status & BlkHWPrefetched) != 0; } - /** - * Get tag associated to this block. - * - * @return The tag value. - */ - virtual Addr getTag() const { return _tag; } - - /** - * Set tag associated to this block. - * - * @param The tag value. - */ - virtual void setTag(Addr tag) { _tag = tag; } - - /** - * Check if this block holds data from the secure memory space. - * @return True if the block holds data from the secure memory space. - */ - bool isSecure() const - { - return (status & BlkSecure) != 0; - } - - /** - * Set valid bit. - */ - virtual void setValid() - { - assert(!isValid()); - status |= BlkValid; - } - - /** - * Set secure bit. - */ - virtual void setSecure() - { - status |= BlkSecure; - } - /** * Get tick at which block's data will be available for access. * @@ -311,14 +251,6 @@ class CacheBlk : public ReplaceableEntry return curTick() - _tickInserted; } - /** - * Checks if the given information corresponds to this block's. - * - * @param tag The tag value to compare to. - * @param is_secure Whether secure bit is set. - */ - virtual bool matchTag(Addr tag, bool is_secure) const; - /** * Set member variables when a block insertion occurs. Resets reference * count to 1 (the insertion counts as a reference), and touch block if @@ -330,8 +262,9 @@ class CacheBlk : public ReplaceableEntry * @param src_requestor_ID The source requestor ID. * @param task_ID The new task ID. */ - virtual void insert(const Addr tag, const bool is_secure, - const int src_requestor_ID, const uint32_t task_ID); + void insert(const Addr tag, const bool is_secure, + const int src_requestor_ID, const uint32_t task_ID); + using TaggedEntry::insert; /** * Track the fact that a local locked was issued to the @@ -410,9 +343,9 @@ class CacheBlk : public ReplaceableEntry case 0b000: s = 'I'; break; default: s = 'T'; break; // @TODO add other types } - return csprintf("state: %x (%c) valid: %d writable: %d readable: %d " - "dirty: %d | tag: %#x %s", status, s, isValid(), isWritable(), - isReadable(), isDirty(), getTag(), ReplaceableEntry::print()); + return csprintf("state: %x (%c) writable: %d readable: %d " + "dirty: %d | %s", status, s, isWritable(), isReadable(), + isDirty(), TaggedEntry::print()); } /** @@ -476,9 +409,6 @@ class CacheBlk : public ReplaceableEntry void setTickInserted() { _tickInserted = curTick(); } private: - /** Data block tag value. */ - Addr _tag; - /** Task Id associated with this block */ uint32_t _taskId; @@ -530,23 +460,11 @@ class TempCacheBlk final : public CacheBlk _addr = MaxAddr; } - void insert(const Addr addr, const bool is_secure, - const int src_requestor_ID=0, const uint32_t task_ID=0) - override + void + insert(const Addr addr, const bool is_secure) override { - // Make sure that the block has been properly invalidated - assert(status == 0); - - // Set block address + CacheBlk::insert(addr, is_secure); _addr = addr; - - // Set secure state - if (is_secure) { - setSecure(); - } - - // Validate block - setValid(); } /** diff --git a/src/mem/cache/prefetch/associative_set.hh b/src/mem/cache/prefetch/associative_set.hh index adfc29a37..32bfb8373 100644 --- a/src/mem/cache/prefetch/associative_set.hh +++ b/src/mem/cache/prefetch/associative_set.hh @@ -30,83 +30,8 @@ #define __CACHE_PREFETCH_ASSOCIATIVE_SET_HH__ #include "mem/cache/replacement_policies/base.hh" -#include "mem/cache/replacement_policies/replaceable_entry.hh" #include "mem/cache/tags/indexing_policies/base.hh" - -/** - * Entry used for set-associative tables, usable with replacement policies - */ -class TaggedEntry : public ReplaceableEntry { - /** Tag for the entry */ - Addr tag; - /** Valid bit */ - bool valid; - /** Whether this entry refers to a memory area in the secure space */ - bool secure; - public: - TaggedEntry() : tag(0), valid(false), secure(false) {} - virtual ~TaggedEntry() {} - - /** - * Consult the valid bit - * @return True if the entry is valid - */ - bool isValid() const - { - return valid; - } - - /** - * Sets the entry to valid - */ - void setValid() - { - valid = true; - } - - /** Invalidates the entry. */ - virtual void - invalidate() - { - valid = false; - } - - /** - * Obtain the entry tag - * @return the tag value - */ - Addr getTag() const - { - return tag; - } - - /** - * Sets the tag of the entry - * @param t the tag value - */ - void setTag(Addr t) - { - tag = t; - } - - /** - * Consult if this entry refers to a memory in the secure area - * @return True if this entry refers to secure memory area - */ - bool isSecure() const - { - return secure; - } - - /** - * Sets the secure value bit - * @param s secure bit value - */ - void setSecure(bool s) - { - secure = s; - } -}; +#include "mem/cache/tags/tagged_entry.hh" /** * Associative container based on the previosuly defined Entry type diff --git a/src/mem/cache/prefetch/associative_set_impl.hh b/src/mem/cache/prefetch/associative_set_impl.hh index 77f783b06..f8316add2 100644 --- a/src/mem/cache/prefetch/associative_set_impl.hh +++ b/src/mem/cache/prefetch/associative_set_impl.hh @@ -109,9 +109,7 @@ template void AssociativeSet::insertEntry(Addr addr, bool is_secure, Entry* entry) { - entry->setValid(); - entry->setTag(indexingPolicy->extractTag(addr)); - entry->setSecure(is_secure); + entry->insert(indexingPolicy->extractTag(addr), is_secure); replacementPolicy->reset(entry->replacementData); } diff --git a/src/mem/cache/tags/sector_blk.cc b/src/mem/cache/tags/sector_blk.cc index 81c9de2a3..57bfb4d16 100644 --- a/src/mem/cache/tags/sector_blk.cc +++ b/src/mem/cache/tags/sector_blk.cc @@ -72,17 +72,6 @@ SectorSubBlk::getTag() const return tag; } -void -SectorSubBlk::setTag(Addr tag) -{ - CacheBlk::setTag(tag); - - // The sector block handles its own tag's invalidation - if (tag != MaxAddr) { - _sectorBlk->setTag(tag); - } -} - void SectorSubBlk::setValid() { @@ -91,10 +80,18 @@ SectorSubBlk::setValid() } void -SectorSubBlk::setSecure() +SectorSubBlk::insert(const Addr tag, const bool is_secure) { - CacheBlk::setSecure(); - _sectorBlk->setSecure(); + // Make sure it is not overwriting another sector + panic_if(_sectorBlk && _sectorBlk->isValid() && + !_sectorBlk->matchTag(tag, is_secure), "Overwriting valid sector!"); + + // If the sector is not valid, insert the new tag. The sector block + // handles its own tag's invalidation, so do not attempt to insert MaxAddr. + if ((_sectorBlk && !_sectorBlk->isValid()) && (tag != MaxAddr)) { + _sectorBlk->insert(tag, is_secure); + } + CacheBlk::insert(tag, is_secure); } void @@ -104,17 +101,6 @@ SectorSubBlk::invalidate() _sectorBlk->invalidateSubBlk(); } -void -SectorSubBlk::insert(const Addr tag, const bool is_secure, - const int src_requestor_ID, const uint32_t task_ID) -{ - // Make sure it is not overwriting another sector - panic_if(_sectorBlk && _sectorBlk->isValid() && - !_sectorBlk->matchTag(tag, is_secure), "Overwriting valid sector!"); - - CacheBlk::insert(tag, is_secure, src_requestor_ID, task_ID); -} - std::string SectorSubBlk::print() const { @@ -123,7 +109,7 @@ SectorSubBlk::print() const } SectorBlk::SectorBlk() - : ReplaceableEntry(), _validCounter(0), _tag(MaxAddr), _secureBit(false) + : TaggedEntry(), _validCounter(0) { } @@ -140,25 +126,6 @@ SectorBlk::getNumValid() const return _validCounter; } -bool -SectorBlk::isSecure() const -{ - // If any of the valid blocks in the sector is secure, so is the sector - return _secureBit; -} - -void -SectorBlk::setTag(const Addr tag) -{ - _tag = tag; -} - -Addr -SectorBlk::getTag() const -{ - return _tag; -} - void SectorBlk::validateSubBlk() { @@ -171,17 +138,10 @@ SectorBlk::invalidateSubBlk() // If all sub-blocks have been invalidated, the sector becomes invalid, // so clear secure bit if (--_validCounter == 0) { - _secureBit = false; - setTag(MaxAddr); + invalidate(); } } -void -SectorBlk::setSecure() -{ - _secureBit = true; -} - void SectorBlk::setPosition(const uint32_t set, const uint32_t way) { @@ -190,9 +150,3 @@ SectorBlk::setPosition(const uint32_t set, const uint32_t way) blk->setPosition(set, way); } } - -bool -SectorBlk::matchTag(Addr tag, bool is_secure) const -{ - return isValid() && (getTag() == tag) && (isSecure() == is_secure); -} diff --git a/src/mem/cache/tags/sector_blk.hh b/src/mem/cache/tags/sector_blk.hh index c5c4fc8ca..ea3c79aa9 100644 --- a/src/mem/cache/tags/sector_blk.hh +++ b/src/mem/cache/tags/sector_blk.hh @@ -93,37 +93,19 @@ class SectorSubBlk : public CacheBlk int getSectorOffset() const; Addr getTag() const override; - void setTag(Addr tag) override; /** * Set valid bit and inform sector block. */ void setValid() override; - /** - * Set secure bit and inform sector block. - */ - void setSecure() override; + void insert(const Addr tag, const bool is_secure) 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 - * current tick. Marks the block valid. - * - * @param tag Block address tag. - * @param is_secure Whether the block is in secure space or not. - * @param src_requestor_ID The source requestor ID. - * @param task_ID The new task ID. - */ - void insert(const Addr tag, const bool is_secure, const int - src_requestor_ID, const uint32_t task_ID) override; - /** * Pretty-print sector offset and other CacheBlk information. * @@ -136,7 +118,7 @@ class SectorSubBlk : public CacheBlk * A Basic Sector block. * Contains the tag and a list of blocks associated to this sector. */ -class SectorBlk : public ReplaceableEntry +class SectorBlk : public TaggedEntry { private: /** @@ -145,17 +127,6 @@ class SectorBlk : public ReplaceableEntry */ uint8_t _validCounter; - protected: - /** - * Sector tag value. A sector's tag is the tag of all its sub-blocks. - */ - Addr _tag; - - /** - * Whether sector blk is in secure-space or not. - */ - bool _secureBit; - public: SectorBlk(); SectorBlk(const SectorBlk&) = delete; @@ -170,7 +141,7 @@ class SectorBlk : public ReplaceableEntry * * @return True if any of the blocks in the sector is valid. */ - bool isValid() const; + bool isValid() const override; /** * Get the number of sub-blocks that have been validated. @@ -179,29 +150,6 @@ class SectorBlk : public ReplaceableEntry */ uint8_t getNumValid() const; - /** - * Checks that a sector block is secure. A single secure block suffices - * to imply that the whole sector is secure, as the insertion proccess - * asserts that different secure spaces can't coexist in the same sector. - * - * @return True if any of the blocks in the sector is secure. - */ - bool isSecure() const; - - /** - * Set tag associated to this block. - * - * @param The tag value. - */ - void setTag(const Addr tag); - - /** - * Get tag associated to this block. - * - * @return The tag value. - */ - Addr getTag() const; - /** * Increase the number of valid sub-blocks. */ @@ -212,11 +160,6 @@ class SectorBlk : public ReplaceableEntry */ void invalidateSubBlk(); - /** - * Set secure bit. - */ - void setSecure(); - /** * Sets the position of the sub-entries, besides its own. * @@ -224,14 +167,6 @@ class SectorBlk : public ReplaceableEntry * @param way The way of this entry and sub-entries. */ void setPosition(const uint32_t set, const uint32_t way) override; - - /** - * Checks if the given information corresponds to this block's. - * - * @param tag The tag value to compare to. - * @param is_secure Whether secure bit is set. - */ - virtual bool matchTag(Addr tag, bool is_secure) const; }; #endif //__MEM_CACHE_TAGS_SECTOR_BLK_HH__ diff --git a/src/mem/cache/tags/tagged_entry.hh b/src/mem/cache/tags/tagged_entry.hh new file mode 100644 index 000000000..be927a407 --- /dev/null +++ b/src/mem/cache/tags/tagged_entry.hh @@ -0,0 +1,154 @@ +/** + * Copyright (c) 2020 Inria + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __CACHE_TAGGED_ENTRY_HH__ +#define __CACHE_TAGGED_ENTRY_HH__ + +#include + +#include "base/cprintf.hh" +#include "base/types.hh" +#include "mem/cache/replacement_policies/replaceable_entry.hh" + +/** + * A tagged entry is an entry containing a tag. Each tag is accompanied by a + * secure bit, which informs whether it belongs to a secure address space. + * A tagged entry's contents are only relevant if it is marked as valid. + */ +class TaggedEntry : public ReplaceableEntry +{ + public: + TaggedEntry() : _valid(false), _secure(false), _tag(MaxAddr) {} + ~TaggedEntry() = default; + + /** + * Checks if the entry is valid. + * + * @return True if the entry is valid. + */ + virtual bool isValid() const { return _valid; } + + /** + * Check if this block holds data from the secure memory space. + * + * @return True if the block holds data from the secure memory space. + */ + bool isSecure() const { return _secure; } + + /** + * Get tag associated to this block. + * + * @return The tag value. + */ + virtual Addr getTag() const { return _tag; } + + /** + * Checks if the given tag information corresponds to this entry's. + * + * @param tag The tag value to compare to. + * @param is_secure Whether secure bit is set. + * @return True if the tag information match this entry's. + */ + virtual bool + matchTag(Addr tag, bool is_secure) const + { + return isValid() && (getTag() == tag) && (isSecure() == is_secure); + } + + /** + * Insert the block by assigning it a tag and marking it valid. Touches + * block if it hadn't been touched previously. + * + * @param tag The tag value. + */ + virtual void + insert(const Addr tag, const bool is_secure) + { + setValid(); + setTag(tag); + if (is_secure) { + setSecure(); + } + } + + /** Invalidate the block. Its contents are no longer valid. */ + virtual void invalidate() + { + _valid = false; + setTag(MaxAddr); + clearSecure(); + } + + std::string + print() const override + { + return csprintf("tag: %#x secure: %d valid: %d | %s", getTag(), + isSecure(), isValid(), ReplaceableEntry::print()); + } + + protected: + /** + * Set tag associated to this block. + * + * @param tag The tag value. + */ + virtual void setTag(Addr tag) { _tag = tag; } + + /** Set secure bit. */ + virtual void setSecure() { _secure = true; } + + /** Set valid bit. The block must be invalid beforehand. */ + virtual void + setValid() + { + assert(!isValid()); + _valid = true; + } + + private: + /** + * Valid bit. The contents of this entry are only valid if this bit is set. + * @sa invalidate() + * @sa insert() + */ + bool _valid; + + /** + * Secure bit. Marks whether this entry refers to an address in the secure + * memory space. Must always be modified along with the tag. + */ + bool _secure; + + /** The entry's tag. */ + Addr _tag; + + /** Clear secure bit. Should be only used by the invalidation function. */ + void clearSecure() { _secure = false; } +}; + +#endif//__CACHE_TAGGED_ENTRY_HH__