return false;
}
- blk->status |= (BlkValid | BlkReadable);
+ blk->status |= BlkReadable;
}
// only mark the block dirty if we got a writeback command,
// and leave it as is for a clean writeback
return false;
}
- blk->status |= (BlkValid | BlkReadable);
+ blk->status |= BlkReadable;
}
}
// No replaceable block or a mostly exclusive
// cache... just use temporary storage to complete the
// current request and then get rid of it
- assert(!tempBlock->isValid());
blk = tempBlock;
tempBlock->insert(addr, is_secure);
DPRINTF(Cache, "using temp block for %#llx (%s)\n", addr,
is_secure ? "s" : "ns");
}
-
- // we should never be overwriting a valid block
- assert(!blk->isValid());
} else {
// existing block... probably an upgrade
- assert(regenerateBlkAddr(blk) == addr);
- assert(blk->isSecure() == is_secure);
- // either we're getting new data or the block should already be valid
- assert(pkt->hasData() || blk->isValid());
// don't clear block status... if block is already dirty we
// don't want to lose that
}
- blk->status |= BlkValid | BlkReadable;
+ // Block is guaranteed to be valid at this point
+ assert(blk->isValid());
+ assert(blk->isSecure() == is_secure);
+ assert(regenerateBlkAddr(blk) == addr);
+
+ blk->status |= BlkReadable;
// sanity check for whole-line writes, which should always be
// marked as writable as part of the fill, and then later marked
CacheBlk::insert(const Addr tag, const bool is_secure,
const int src_master_ID, const uint32_t task_ID)
{
+ // Make sure that the block has been properly invalidated
+ assert(status == 0);
+
// Set block tag
this->tag = tag;
// Set secure state
if (is_secure) {
- status = BlkSecure;
- } else {
- status = 0;
+ setSecure();
}
+
+ // Validate block
+ setValid();
}
void
return (status & BlkSecure) != 0;
}
+ /**
+ * Set valid bit.
+ */
+ virtual void setValid()
+ {
+ assert(!isValid());
+ status |= BlkValid;
+ }
+
+ /**
+ * Set secure bit.
+ */
+ virtual void setSecure()
+ {
+ status |= BlkSecure;
+ }
+
/**
* 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. Does not make block valid.
+ * current tick. Marks the block valid.
*
* @param tag Block address tag.
* @param is_secure Whether the block is in secure space or not.
void insert(const Addr addr, const bool is_secure,
const int src_master_ID=0, const uint32_t task_ID=0) override
{
+ // Make sure that the block has been properly invalidated
+ assert(status == 0);
+
// Set block address
_addr = addr;
// Set secure state
if (is_secure) {
- status = BlkSecure;
- } else {
- status = 0;
+ setSecure();
}
+
+ // Validate block
+ setValid();
}
/**
* 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. Does not make block valid.
+ * current tick. Marks the block valid.
*
* @param tag Block address tag.
* @param is_secure Whether the block is in secure space or not.
const int src_master_ID, const uint32_t task_ID,
CacheBlk *blk)
{
- // Do common block insertion functionality
- BaseTags::insertBlock(addr, is_secure, src_master_ID, task_ID, blk);
-
// Get block's sector
SectorSubBlk* sub_blk = static_cast<SectorSubBlk*>(blk);
const SectorBlk* sector_blk = sub_blk->getSectorBlock();
// When a block is inserted, the tag is only a newly used tag if the
// sector was not previously present in the cache.
- // This assumes BaseTags::insertBlock does not set the valid bit.
if (sector_blk->isValid()) {
// An existing entry's replacement data is just updated
replacementPolicy->touch(sector_blk->replacementData);
// A new entry resets the replacement data
replacementPolicy->reset(sector_blk->replacementData);
}
+
+ // Do common block insertion functionality
+ BaseTags::insertBlock(addr, is_secure, src_master_ID, task_ID, blk);
}
CacheBlk*