diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mem/cache/base.cc | 23 | ||||
-rw-r--r-- | src/mem/cache/base.hh | 12 | ||||
-rw-r--r-- | src/mem/cache/blk.cc | 2 | ||||
-rw-r--r-- | src/mem/cache/blk.hh | 63 | ||||
-rw-r--r-- | src/mem/cache/cache.cc | 2 |
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); |