#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)
// 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);
// Insertion counts as a reference to the block
increaseRefCount();
-
- // Set secure state
- if (is_secure) {
- setSecure();
- }
-
- // Validate block
- setValid();
}
void
#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"
* 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) */
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:
/**
std::list<Lock> lockList;
public:
- CacheBlk() : data(nullptr), _tickInserted(0)
+ CacheBlk() : TaggedEntry(), data(nullptr), _tickInserted(0)
{
invalidate();
}
* 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
* 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;
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.
*
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
* @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
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());
}
/**
void setTickInserted() { _tickInserted = curTick(); }
private:
- /** Data block tag value. */
- Addr _tag;
-
/** Task Id associated with this block */
uint32_t _taskId;
_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();
}
/**
#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
void
AssociativeSet<Entry>::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);
}
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()
{
}
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
_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
{
}
SectorBlk::SectorBlk()
- : ReplaceableEntry(), _validCounter(0), _tag(MaxAddr), _secureBit(false)
+ : TaggedEntry(), _validCounter(0)
{
}
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()
{
// 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)
{
blk->setPosition(set, way);
}
}
-
-bool
-SectorBlk::matchTag(Addr tag, bool is_secure) const
-{
- return isValid() && (getTag() == tag) && (isSecure() == is_secure);
-}
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.
*
* 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:
/**
*/
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;
*
* @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.
*/
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.
*/
*/
void invalidateSubBlk();
- /**
- * Set secure bit.
- */
- void setSecure();
-
/**
* Sets the position of the sub-entries, besides its own.
*
* @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__
--- /dev/null
+/**
+ * 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 <cassert>
+
+#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__