summaryrefslogtreecommitdiff
path: root/src/mem/cache/cache_impl.hh
diff options
context:
space:
mode:
authorAndreas Sandberg <Andreas.Sandberg@arm.com>2012-11-02 11:32:02 -0500
committerAndreas Sandberg <Andreas.Sandberg@arm.com>2012-11-02 11:32:02 -0500
commitddd6af414cdd4939f4ff382f0e83e7dfa695781d (patch)
tree5149831ec4714dea40a550665ba87e1299d4485a /src/mem/cache/cache_impl.hh
parent050f24c7964cbe65633261e431e1105d1d5e8070 (diff)
downloadgem5-ddd6af414cdd4939f4ff382f0e83e7dfa695781d.tar.xz
mem: Add support for writing back and flushing caches
This patch adds support for the following optional drain methods in the classical memory system's cache model: memWriteback() - Write back all dirty cache lines to memory using functional accesses. memInvalidate() - Invalidate all cache lines. Dirty cache lines are lost unless a writeback is requested. Since memWriteback() is called when checkpointing systems, this patch adds support for checkpointing systems with caches. The serialization code now checks whether there are any dirty lines in the cache. If there are dirty lines in the cache, the checkpoint is flagged as bad and a warning is printed.
Diffstat (limited to 'src/mem/cache/cache_impl.hh')
-rw-r--r--src/mem/cache/cache_impl.hh90
1 files changed, 79 insertions, 11 deletions
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 44acaef5b..a7c9a4a55 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -43,6 +43,7 @@
* Nathan Binkert
* Steve Reinhardt
* Ron Dreslinski
+ * Andreas Sandberg
*/
/**
@@ -1035,6 +1036,69 @@ Cache<TagStore>::writebackBlk(BlkType *blk)
return writeback;
}
+template<class TagStore>
+void
+Cache<TagStore>::memWriteback()
+{
+ WrappedBlkVisitor visitor(*this, &Cache<TagStore>::writebackVisitor);
+ tags->forEachBlk(visitor);
+}
+
+template<class TagStore>
+void
+Cache<TagStore>::memInvalidate()
+{
+ WrappedBlkVisitor visitor(*this, &Cache<TagStore>::invalidateVisitor);
+ tags->forEachBlk(visitor);
+}
+
+template<class TagStore>
+bool
+Cache<TagStore>::isDirty() const
+{
+ CacheBlkIsDirtyVisitor<BlkType> visitor;
+ tags->forEachBlk(visitor);
+
+ return visitor.isDirty();
+}
+
+template<class TagStore>
+bool
+Cache<TagStore>::writebackVisitor(BlkType &blk)
+{
+ if (blk.isDirty()) {
+ assert(blk.isValid());
+
+ Request request(tags->regenerateBlkAddr(blk.tag, blk.set),
+ blkSize, 0, Request::funcMasterId);
+
+ Packet packet(&request, MemCmd::WriteReq);
+ packet.dataStatic(blk.data);
+
+ memSidePort->sendFunctional(&packet);
+
+ blk.status &= ~BlkDirty;
+ }
+
+ return true;
+}
+
+template<class TagStore>
+bool
+Cache<TagStore>::invalidateVisitor(BlkType &blk)
+{
+
+ if (blk.isDirty())
+ warn_once("Invalidating dirty cache lines. Expect things to break.\n");
+
+ if (blk.isValid()) {
+ assert(!blk.isDirty());
+ tags->invalidate(dynamic_cast< BlkType *>(&blk));
+ blk.invalidate();
+ }
+
+ return true;
+}
template<class TagStore>
typename Cache<TagStore>::BlkType*
@@ -1565,16 +1629,20 @@ template<class TagStore>
void
Cache<TagStore>::serialize(std::ostream &os)
{
- warn("*** Creating checkpoints with caches is not supported. ***\n");
- warn(" Remove any caches before taking checkpoints\n");
- warn(" This checkpoint will not restore correctly and dirty data in "
- "the cache will be lost!\n");
+ bool dirty(isDirty());
- // Since we don't write back the data dirty in the caches to the physical
- // memory if caches exist in the system we won't be able to restore
- // from the checkpoint as any data dirty in the caches will be lost.
+ if (dirty) {
+ warn("*** The cache still contains dirty data. ***\n");
+ warn(" Make sure to drain the system using the correct flags.\n");
+ warn(" This checkpoint will not restore correctly and dirty data in "
+ "the cache will be lost!\n");
+ }
- bool bad_checkpoint = true;
+ // Since we don't checkpoint the data in the cache, any dirty data
+ // will be lost when restoring from a checkpoint of a system that
+ // wasn't drained properly. Flag the checkpoint as invalid if the
+ // cache contains dirty data.
+ bool bad_checkpoint(dirty);
SERIALIZE_SCALAR(bad_checkpoint);
}
@@ -1585,9 +1653,9 @@ Cache<TagStore>::unserialize(Checkpoint *cp, const std::string &section)
bool bad_checkpoint;
UNSERIALIZE_SCALAR(bad_checkpoint);
if (bad_checkpoint) {
- fatal("Restoring from checkpoints with caches is not supported in the "
- "classic memory system. Please remove any caches before taking "
- "checkpoints.\n");
+ fatal("Restoring from checkpoints with dirty caches is not supported "
+ "in the classic memory system. Please remove any caches or "
+ " drain them properly before taking checkpoints.\n");
}
}