X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmem%2Fcache%2Fcache_blk.hh;h=c16e59980abf05675ffb2f131d038fdb1f817941;hb=91d83cc8a12883f2d7493b37f50487cd7f03a9e6;hp=99f854594015e01de4d0315fc27aa6b6156cb376;hpb=392c1ced53827198652f5eda58e1874246b024f4;p=gem5.git diff --git a/src/mem/cache/cache_blk.hh b/src/mem/cache/cache_blk.hh index 99f854594..c16e59980 100644 --- a/src/mem/cache/cache_blk.hh +++ b/src/mem/cache/cache_blk.hh @@ -11,6 +11,7 @@ * unmodified and in its entirety in all distributions of the software, * modified or unmodified, in source code or in binary form. * + * Copyright (c) 2020 Inria * Copyright (c) 2003-2005 The Regents of The University of Michigan * All rights reserved. * @@ -53,42 +54,42 @@ #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" - -/** - * 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) */ - BlkReadable = 0x04, - /** dirty (modified) */ - 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 -}; +#include "sim/core.hh" /** * A Basic Cache block. - * Contains the tag, status, and a pointer to data. + * Contains information regarding its coherence, prefetching status, as + * well as a pointer to its data. */ -class CacheBlk : public ReplaceableEntry +class CacheBlk : public TaggedEntry { public: - /** Task Id associated with this block */ - uint32_t task_id; + /** + * Cache block's enum listing the supported coherence bits. The valid + * bit is not defined here because it is part of a TaggedEntry. + */ + enum CoherenceBits : unsigned + { + /** write permission */ + WritableBit = 0x02, + /** + * Read permission. Note that a block can be valid but not readable + * if there is an outstanding write upgrade miss. + */ + ReadableBit = 0x04, + /** dirty (modified) */ + DirtyBit = 0x08, + + /** + * Helper enum value that includes all other bits. Whenever a new + * bits is added, this should be updated. + */ + AllBits = 0x0E, + }; - /** Data block tag value. */ - Addr tag; /** * Contains a copy of the data in this block for easy access. This is used * for efficient execution when the data could be actually stored in @@ -98,30 +99,12 @@ class CacheBlk : public ReplaceableEntry */ uint8_t *data; - /** block state: OR of CacheBlkStatusBit */ - typedef unsigned State; - - /** The current status of this block. @sa CacheBlockStatusBits */ - State status; - /** * Which curTick() will this block be accessible. Its value is only * meaningful if the block is valid. */ Tick whenReady; - /** Number of references to this block since it was brought in. */ - unsigned refCount; - - /** holds the source requestor ID for this block. */ - int srcRequestorId; - - /** - * Tick on which the block was inserted in the cache. Its value is only - * meaningful if the block is valid. - */ - Tick tickInserted; - protected: /** * Represents that the indicated thread context has a "lock" on @@ -165,7 +148,7 @@ class CacheBlk : public ReplaceableEntry std::list lockList; public: - CacheBlk() : data(nullptr), tickInserted(0) + CacheBlk() : TaggedEntry(), data(nullptr), _tickInserted(0) { invalidate(); } @@ -175,57 +158,50 @@ class CacheBlk : public ReplaceableEntry virtual ~CacheBlk() {}; /** - * Checks the write permissions of this block. - * @return True if the block is writable. + * Invalidate the block and clear all state. */ - bool isWritable() const + virtual void invalidate() { - const State needed_bits = BlkWritable | BlkValid; - return (status & needed_bits) == needed_bits; - } + TaggedEntry::invalidate(); - /** - * Checks the read permissions of this block. Note that a block - * can be valid but not readable if there is an outstanding write - * upgrade miss. - * @return True if the block is readable. - */ - bool isReadable() const - { - const State needed_bits = BlkReadable | BlkValid; - return (status & needed_bits) == needed_bits; + clearPrefetched(); + clearCoherenceBits(AllBits); + + setTaskId(ContextSwitchTaskId::Unknown); + whenReady = MaxTick; + setRefCount(0); + setSrcRequestorId(Request::invldRequestorId); + lockList.clear(); } /** - * Checks that a block is valid. - * @return True if the block is valid. + * Sets the corresponding coherence bits. + * + * @param bits The coherence bits to be set. */ - bool isValid() const + void + setCoherenceBits(unsigned bits) { - return (status & BlkValid) != 0; + assert(isValid()); + coherence |= bits; } /** - * Invalidate the block and clear all state. + * Clear the corresponding coherence bits. + * + * @param bits The coherence bits to be cleared. */ - virtual void invalidate() - { - tag = MaxAddr; - task_id = ContextSwitchTaskId::Unknown; - status = 0; - whenReady = MaxTick; - refCount = 0; - srcRequestorId = Request::invldRequestorId; - lockList.clear(); - } + void clearCoherenceBits(unsigned bits) { coherence &= ~bits; } /** - * Check to see if a block has been written. - * @return True if the block is dirty. + * Checks the given coherence bits are set. + * + * @return True if the block is readable. */ - bool isDirty() const + bool + isSet(unsigned bits) const { - return (status & BlkDirty) != 0; + return isValid() && (coherence & bits); } /** @@ -233,36 +209,16 @@ class CacheBlk : public ReplaceableEntry * be touched. * @return True if the block was a hardware prefetch, unaccesed. */ - bool wasPrefetched() const - { - return (status & BlkHWPrefetched) != 0; - } - - /** - * 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; - } + bool wasPrefetched() const { return _prefetched; } /** - * Set valid bit. + * Clear the prefetching bit. Either because it was recently used, or due + * to the block being invalidated. */ - virtual void setValid() - { - assert(!isValid()); - status |= BlkValid; - } + void clearPrefetched() { _prefetched = false; } - /** - * Set secure bit. - */ - virtual void setSecure() - { - status |= BlkSecure; - } + /** Marks this blocks as a recently prefetched block. */ + void setPrefetched() { _prefetched = false; } /** * Get tick at which block's data will be available for access. @@ -284,10 +240,34 @@ class CacheBlk : public ReplaceableEntry */ void setWhenReady(const Tick tick) { - assert(tick >= tickInserted); + assert(tick >= _tickInserted); whenReady = tick; } + /** Get the task id associated to this block. */ + uint32_t getTaskId() const { return _taskId; } + + /** Get the requestor id associated to this block. */ + uint32_t getSrcRequestorId() const { return _srcRequestorId; } + + /** Get the number of references to this block since insertion. */ + unsigned getRefCount() const { return _refCount; } + + /** Get the number of references to this block since insertion. */ + void increaseRefCount() { _refCount++; } + + /** + * Get the block's age, that is, the number of ticks since its insertion. + * + * @return The block's age. + */ + Tick + getAge() const + { + assert(_tickInserted <= curTick()); + return curTick() - _tickInserted; + } + /** * Set member variables when a block insertion occurs. Resets reference * count to 1 (the insertion counts as a reference), and touch block if @@ -299,8 +279,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 @@ -360,7 +341,7 @@ class CacheBlk : public ReplaceableEntry * * Note that only one cache ever has a block in Modified or * Owned state, i.e., only one cache owns the block, or - * equivalently has the BlkDirty bit set. However, multiple + * equivalently has the DirtyBit bit set. However, multiple * caches on the same path to memory can have a block in the * Exclusive state (despite the name). Exclusive means this * cache has the only copy at this level of the hierarchy, @@ -369,7 +350,8 @@ class CacheBlk : public ReplaceableEntry * this branch of the hierarchy, and no caches at or above * this level on any other branch have copies either. **/ - unsigned state = isWritable() << 2 | isDirty() << 1 | isValid(); + unsigned state = + isSet(WritableBit) << 2 | isSet(DirtyBit) << 1 | isValid(); char s = '?'; switch (state) { case 0b111: s = 'M'; break; @@ -379,10 +361,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(), tag, - ReplaceableEntry::print()); + return csprintf("state: %x (%c) writable: %d readable: %d " + "dirty: %d | %s", coherence, s, isSet(WritableBit), + isSet(ReadableBit), isSet(DirtyBit), TaggedEntry::print()); } /** @@ -431,6 +412,46 @@ class CacheBlk : public ReplaceableEntry return true; } } + + protected: + /** The current coherence status of this block. @sa CoherenceBits */ + unsigned coherence; + + // The following setters have been marked as protected because their + // respective variables should only be modified at 2 moments: + // invalidation and insertion. Because of that, they shall only be + // called by the functions that perform those actions. + + /** Set the task id value. */ + void setTaskId(const uint32_t task_id) { _taskId = task_id; } + + /** Set the source requestor id. */ + void setSrcRequestorId(const uint32_t id) { _srcRequestorId = id; } + + /** Set the number of references to this block since insertion. */ + void setRefCount(const unsigned count) { _refCount = count; } + + /** Set the current tick as this block's insertion tick. */ + void setTickInserted() { _tickInserted = curTick(); } + + private: + /** Task Id associated with this block */ + uint32_t _taskId; + + /** holds the source requestor ID for this block. */ + int _srcRequestorId; + + /** Number of references to this block since it was brought in. */ + unsigned _refCount; + + /** + * Tick on which the block was inserted in the cache. Its value is only + * meaningful if the block is valid. + */ + Tick _tickInserted; + + /** Whether this block is an unaccessed hardware prefetch. */ + bool _prefetched; }; /** @@ -468,23 +489,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(); } /**