// 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);
sendRetryReq();
}
+Addr
+BaseCache::regenerateBlkAddr(CacheBlk* blk)
+{
+ if (blk != tempBlock) {
+ return tags->regenerateBlkAddr(blk);
+ } else {
+ return tempBlock->getAddr();
+ }
+}
+
void
BaseCache::init()
{
// 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 {
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
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);
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);
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()) {
* 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
cmd.isLLSC();
}
+ /**
+ * 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.
#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
std::list<Lock> lockList;
public:
-
CacheBlk()
{
invalidate();
* @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);
/**
}
};
+/**
+ * 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.
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);