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 <odanrc@yahoo.com.br> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35698 Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com> Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
committed by
Daniel Carvalho
parent
fd3a17b916
commit
e3edf5e78f
17
src/mem/cache/cache_blk.cc
vendored
17
src/mem/cache/cache_blk.cc
vendored
@@ -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
|
||||
|
||||
116
src/mem/cache/cache_blk.hh
vendored
116
src/mem/cache/cache_blk.hh
vendored
@@ -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<Lock> 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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
77
src/mem/cache/prefetch/associative_set.hh
vendored
77
src/mem/cache/prefetch/associative_set.hh
vendored
@@ -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
|
||||
|
||||
@@ -109,9 +109,7 @@ template<class Entry>
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
72
src/mem/cache/tags/sector_blk.cc
vendored
72
src/mem/cache/tags/sector_blk.cc
vendored
@@ -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);
|
||||
}
|
||||
|
||||
71
src/mem/cache/tags/sector_blk.hh
vendored
71
src/mem/cache/tags/sector_blk.hh
vendored
@@ -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__
|
||||
|
||||
154
src/mem/cache/tags/tagged_entry.hh
vendored
Normal file
154
src/mem/cache/tags/tagged_entry.hh
vendored
Normal file
@@ -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 <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__
|
||||
Reference in New Issue
Block a user