diff options
Diffstat (limited to 'src/mem/cache')
-rw-r--r-- | src/mem/cache/cache.hh | 12 | ||||
-rw-r--r-- | src/mem/cache/cache_impl.hh | 40 |
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) { |