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:
Daniel R. Carvalho
2020-10-06 12:25:06 +02:00
committed by Daniel Carvalho
parent fd3a17b916
commit e3edf5e78f
7 changed files with 190 additions and 321 deletions

View File

@@ -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

View File

@@ -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();
}
/**

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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
View 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__