summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mem/cache/base.cc23
-rw-r--r--src/mem/cache/base.hh12
-rw-r--r--src/mem/cache/blk.cc2
-rw-r--r--src/mem/cache/blk.hh63
-rw-r--r--src/mem/cache/cache.cc2
5 files changed, 90 insertions, 12 deletions
diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc
index 604aab621..efdb3be2c 100644
--- a/src/mem/cache/base.cc
+++ b/src/mem/cache/base.cc
@@ -113,7 +113,7 @@ BaseCache::BaseCache(const BaseCacheParams *p, unsigned blk_size)
// forward snoops is overridden in init() once we can query
// whether the connected master is actually snooping or not
- tempBlock = new CacheBlk();
+ tempBlock = new TempCacheBlk();
tempBlock->data = new uint8_t[blkSize];
tags->setCache(this);
@@ -164,6 +164,16 @@ BaseCache::CacheSlavePort::processSendRetry()
sendRetryReq();
}
+Addr
+BaseCache::regenerateBlkAddr(CacheBlk* blk)
+{
+ if (blk != tempBlock) {
+ return tags->regenerateBlkAddr(blk);
+ } else {
+ return tempBlock->getAddr();
+ }
+}
+
void
BaseCache::init()
{
@@ -1123,8 +1133,7 @@ BaseCache::handleFill(PacketPtr pkt, CacheBlk *blk, PacketList &writebacks,
// current request and then get rid of it
assert(!tempBlock->isValid());
blk = tempBlock;
- tempBlock->set = tags->extractSet(addr);
- tempBlock->tag = tags->extractTag(addr);
+ tempBlock->insert(addr, is_secure);
DPRINTF(Cache, "using temp block for %#llx (%s)\n", addr,
is_secure ? "s" : "ns");
} else {
@@ -1207,7 +1216,7 @@ BaseCache::allocateBlock(Addr addr, bool is_secure, PacketList &writebacks)
return nullptr;
if (blk->isValid()) {
- Addr repl_addr = tags->regenerateBlkAddr(blk);
+ Addr repl_addr = regenerateBlkAddr(blk);
MSHR *repl_mshr = mshrQueue.findMatch(repl_addr, blk->isSecure());
if (repl_mshr) {
// must be an outstanding upgrade or clean request
@@ -1251,7 +1260,7 @@ BaseCache::writebackBlk(CacheBlk *blk)
writebacks[Request::wbMasterId]++;
- Request *req = new Request(tags->regenerateBlkAddr(blk), blkSize, 0,
+ Request *req = new Request(regenerateBlkAddr(blk), blkSize, 0,
Request::wbMasterId);
if (blk->isSecure())
req->setFlags(Request::SECURE);
@@ -1286,7 +1295,7 @@ BaseCache::writebackBlk(CacheBlk *blk)
PacketPtr
BaseCache::writecleanBlk(CacheBlk *blk, Request::Flags dest, PacketId id)
{
- Request *req = new Request(tags->regenerateBlkAddr(blk), blkSize, 0,
+ Request *req = new Request(regenerateBlkAddr(blk), blkSize, 0,
Request::wbMasterId);
if (blk->isSecure()) {
req->setFlags(Request::SECURE);
@@ -1346,7 +1355,7 @@ BaseCache::writebackVisitor(CacheBlk &blk)
if (blk.isDirty()) {
assert(blk.isValid());
- Request request(tags->regenerateBlkAddr(&blk),
+ Request request(regenerateBlkAddr(&blk),
blkSize, 0, Request::funcMasterId);
request.taskId(blk.task_id);
if (blk.isSecure()) {
diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh
index 04225c12f..6600aeba6 100644
--- a/src/mem/cache/base.hh
+++ b/src/mem/cache/base.hh
@@ -334,7 +334,7 @@ class BaseCache : public MemObject
* is an outstanding request that accesses the victim block) or
* when we want to avoid allocation (e.g., exclusive caches)
*/
- CacheBlk *tempBlock;
+ TempCacheBlk *tempBlock;
/**
* Upstream caches need this packet until true is returned, so
@@ -390,6 +390,16 @@ class BaseCache : public MemObject
}
/**
+ * Regenerate block address using tags.
+ * Block address regeneration depends on whether we're using a temporary
+ * block or not.
+ *
+ * @param blk The block to regenerate address.
+ * @return The block's address.
+ */
+ Addr regenerateBlkAddr(CacheBlk* blk);
+
+ /**
* Does all the processing necessary to perform the provided request.
* @param pkt The memory request to perform.
* @param blk The cache block to be updated.
diff --git a/src/mem/cache/blk.cc b/src/mem/cache/blk.cc
index ad0c20a6f..45bd9bfd4 100644
--- a/src/mem/cache/blk.cc
+++ b/src/mem/cache/blk.cc
@@ -43,7 +43,7 @@
#include "base/cprintf.hh"
void
-CacheBlk::insert(const Addr tag, const State is_secure,
+CacheBlk::insert(const Addr tag, const bool is_secure,
const int src_master_ID, const uint32_t task_ID)
{
// Set block tag
diff --git a/src/mem/cache/blk.hh b/src/mem/cache/blk.hh
index c94c3ba7d..c4ec12ff3 100644
--- a/src/mem/cache/blk.hh
+++ b/src/mem/cache/blk.hh
@@ -166,7 +166,6 @@ class CacheBlk : public ReplaceableEntry
std::list<Lock> lockList;
public:
-
CacheBlk()
{
invalidate();
@@ -261,7 +260,7 @@ class CacheBlk : public ReplaceableEntry
* @param src_master_ID The source requestor ID.
* @param task_ID The new task ID.
*/
- void insert(const Addr tag, const State is_secure, const int src_master_ID,
+ void insert(const Addr tag, const bool is_secure, const int src_master_ID,
const uint32_t task_ID);
/**
@@ -394,6 +393,66 @@ class CacheBlk : public ReplaceableEntry
};
/**
+ * Special instance of CacheBlk for use with tempBlk that deals with its
+ * block address regeneration.
+ * @sa Cache
+ */
+class TempCacheBlk final : public CacheBlk
+{
+ private:
+ /**
+ * Copy of the block's address, used to regenerate tempBlock's address.
+ */
+ Addr _addr;
+
+ public:
+ TempCacheBlk() : CacheBlk() {}
+ TempCacheBlk(const TempCacheBlk&) = delete;
+ TempCacheBlk& operator=(const TempCacheBlk&) = delete;
+ ~TempCacheBlk() {};
+
+ /**
+ * Invalidate the block and clear all state.
+ */
+ void invalidate() override {
+ CacheBlk::invalidate();
+
+ _addr = MaxAddr;
+ }
+
+ /**
+ * Set member variables when a block insertion occurs. A TempCacheBlk does
+ * not have all the information required to regenerate the block's address,
+ * so it is provided the address itself for easy regeneration.
+ *
+ * @param addr Block address.
+ * @param is_secure Whether the block is in secure space or not.
+ */
+ void insert(const Addr addr, const bool is_secure)
+ {
+ // Set block address
+ _addr = addr;
+
+ // Set secure state
+ if (is_secure) {
+ status = BlkSecure;
+ } else {
+ status = 0;
+ }
+ }
+
+ /**
+ * Get block's address.
+ *
+ * @return addr Address value.
+ */
+ Addr getAddr() const
+ {
+ return _addr;
+ }
+};
+
+/**
* Simple class to provide virtual print() method on cache blocks
* without allocating a vtable pointer for every single cache block.
* Just wrap the CacheBlk object in an instance of this before passing
diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc
index 9177ebea8..34f3dc5b9 100644
--- a/src/mem/cache/cache.cc
+++ b/src/mem/cache/cache.cc
@@ -873,7 +873,7 @@ Cache::cleanEvictBlk(CacheBlk *blk)
assert(blk && blk->isValid() && !blk->isDirty());
// Creating a zero sized write, a message to the snoop filter
Request *req =
- new Request(tags->regenerateBlkAddr(blk), blkSize, 0,
+ new Request(regenerateBlkAddr(blk), blkSize, 0,
Request::wbMasterId);
if (blk->isSecure())
req->setFlags(Request::SECURE);