*/
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);
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;
}
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()) {
return true;
}
+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)