diff -r e4679f18edb9 -r 84339ca32391 src/mem/cache/cache.cc --- a/src/mem/cache/cache.cc Tue Dec 22 16:23:08 2015 +0000 +++ b/src/mem/cache/cache.cc Tue Dec 22 16:23:47 2015 +0000 @@ -1902,6 +1902,11 @@ bool invalidate = pkt->isInvalidate(); bool M5_VAR_USED needs_writable = pkt->needsWritable(); + // sanity check + panic_if(invalidate && pkt->req->isUncacheable(), + "%s got an invalidating uncacheable snoop request %s to %#llx", + name(), pkt->cmdString(), pkt->getAddr()); + uint32_t snoop_delay = 0; if (forwardSnoops) { @@ -1986,15 +1991,18 @@ return snoop_delay; } - if (!pkt->req->isUncacheable() && pkt->isRead() && !invalidate) { - // reading without requiring the line in a writable state, - // note that we retain the block as Owned if it is Modified - // (dirty data), with the response taken care of below, and - // otherwhise simply downgrade from Exclusive to Shared (or - // remain in Shared) + if (pkt->isRead() && !invalidate) { + // reading without requiring the line in a writable state assert(!needs_writable); pkt->setPassNonWritable(); - blk->status &= ~BlkWritable; + + // if the requesting packet is uncacheable, retain the line in + // the current state, otherwhise unset the writable flag, + // which means we go from Modified to Owned (and will respond + // below), remain in Owned (and will respond below), from + // Exclusive to Shared, or remain in Shared + if (!pkt->req->isUncacheable()) + blk->status &= ~BlkWritable; } if (respond) { @@ -2021,6 +2029,13 @@ // hits the next cache } + // if we are returning a writable and dirty (Modified) line, + // we should be invalidating the line + panic_if(!invalidate && pkt->passWritable(), + "%s is passing a Modified line through %s to %#llx, " + "but keeping the block", + name(), pkt->cmdString(), pkt->getAddr()); + if (is_timing) { doTimingSupplyResponse(pkt, blk->data, is_deferred, pending_inval); } else {