summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mem/cache/cache.hh12
-rw-r--r--src/mem/cache/cache_impl.hh40
2 files changed, 33 insertions, 19 deletions
diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh
index 5df725683..6b062ef40 100644
--- a/src/mem/cache/cache.hh
+++ b/src/mem/cache/cache.hh
@@ -278,6 +278,18 @@ class Cache : public BaseCache
*/
bool invalidateVisitor(BlkType &blk);
+ /**
+ * Flush a cache line due to an uncacheable memory access to the
+ * line.
+ *
+ * @note This shouldn't normally happen, but we need to handle it
+ * since some architecture models don't implement cache
+ * maintenance operations. We won't even try to get a decent
+ * timing here since the line should have been flushed earlier by
+ * a cache maintenance operation.
+ */
+ void uncacheableFlush(PacketPtr pkt);
+
public:
/** Instantiates a basic cache object. */
Cache(const Params *p, TagStore *tags);
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index fc01e2c06..a1d945103 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -279,16 +279,7 @@ Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk,
Cycles &lat, PacketList &writebacks)
{
if (pkt->req->isUncacheable()) {
- if (pkt->req->isClearLL()) {
- tags->clearLocks();
- } else if (pkt->isWrite()) {
- blk = tags->findBlock(pkt->getAddr());
- if (blk != NULL) {
- tags->invalidate(blk);
- blk->invalidate();
- }
- }
-
+ uncacheableFlush(pkt);
blk = NULL;
lat = hitLatency;
return false;
@@ -444,15 +435,7 @@ Cache<TagStore>::timingAccess(PacketPtr pkt)
}
if (pkt->req->isUncacheable()) {
- if (pkt->req->isClearLL()) {
- tags->clearLocks();
- } else if (pkt->isWrite()) {
- BlkType *blk = tags->findBlock(pkt->getAddr());
- if (blk != NULL) {
- tags->invalidate(blk);
- blk->invalidate();
- }
- }
+ uncacheableFlush(pkt);
// writes go in write buffer, reads use MSHR
if (pkt->isWrite() && !pkt->isRead()) {
@@ -1104,6 +1087,25 @@ Cache<TagStore>::invalidateVisitor(BlkType &blk)
}
template<class TagStore>
+void
+Cache<TagStore>::uncacheableFlush(PacketPtr pkt)
+{
+ DPRINTF(Cache, "%s%s %x uncacheable\n", pkt->cmdString(),
+ pkt->req->isInstFetch() ? " (ifetch)" : "",
+ pkt->getAddr());
+
+ if (pkt->req->isClearLL())
+ tags->clearLocks();
+
+ BlkType *blk(tags->findBlock(pkt->getAddr()));
+ if (blk) {
+ writebackVisitor(*blk);
+ invalidateVisitor(*blk);
+ }
+}
+
+
+template<class TagStore>
typename Cache<TagStore>::BlkType*
Cache<TagStore>::allocateBlock(Addr addr, PacketList &writebacks)
{