diff options
author | Steve Reinhardt <steve.reinhardt@amd.com> | 2010-06-16 15:25:57 -0700 |
---|---|---|
committer | Steve Reinhardt <steve.reinhardt@amd.com> | 2010-06-16 15:25:57 -0700 |
commit | 57f2b7db11c9a16f3104588c137e6246bd124041 (patch) | |
tree | da67f375e76ebbda46b5528d7c2398efebca1307 /src/mem/cache | |
parent | f90319d3b850e6bb773b3bf8548508529970aea2 (diff) | |
download | gem5-57f2b7db11c9a16f3104588c137e6246bd124041.tar.xz |
cache: fix dirty bit setting
Only set the dirty bit when we actually write to a block
(not if we thought we might but didn't, as in a failed
SC or CAS). This requires makeing sure the dirty bit
stays set when we get an exclusive (writable) copy
in a cache-to-cache transfer from another owner, which
n turn requires copying the mem-inhibit flag from
timing-mode requests to their associated responses.
Diffstat (limited to 'src/mem/cache')
-rw-r--r-- | src/mem/cache/cache_impl.hh | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 206361f88..e4341af26 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2010 Advanced Micro Devices, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -169,9 +170,9 @@ Cache<TagStore>::satisfyCpuSideRequest(PacketPtr pkt, BlkType *blk) if (pkt->cmd == MemCmd::SwapReq) { cmpAndSwap(blk, pkt); } else if (pkt->isWrite()) { - blk->status |= BlkDirty; if (blk->checkWrite(pkt)) { pkt->writeDataToBlock(blk->data, blkSize); + blk->status |= BlkDirty; } } else if (pkt->isRead()) { if (pkt->isLLSC()) { @@ -988,11 +989,19 @@ Cache<TagStore>::handleFill(PacketPtr pkt, BlkType *blk, assert(pkt->hasData() || blk->isValid()); } + blk->status = BlkValid | BlkReadable; + if (!pkt->sharedAsserted()) { - blk->status = BlkValid | BlkReadable | BlkWritable; - } else { - assert(!pkt->needsExclusive()); - blk->status = BlkValid | BlkReadable; + blk->status |= BlkWritable; + // If we got this via cache-to-cache transfer (i.e., from a + // cache that was an owner) and took away that owner's copy, + // then we need to write it back. Normally this happens + // anyway as a side effect of getting a copy to write it, but + // there are cases (such as failed store conditionals or + // compare-and-swaps) where we'll demand an exclusive copy but + // end up not writing it. + if (pkt->memInhibitAsserted()) + blk->status |= BlkDirty; } DPRINTF(Cache, "Block addr %x moving from state %i to %i\n", @@ -1023,14 +1032,8 @@ doTimingSupplyResponse(PacketPtr req_pkt, uint8_t *blk_data, { // timing-mode snoop responses require a new packet, unless we // already made a copy... - PacketPtr pkt = already_copied ? req_pkt : new Packet(req_pkt, true); - if (!req_pkt->isInvalidate()) { - // note that we're ignoring the shared flag on req_pkt... it's - // basically irrelevant, as we'll always assert shared unless - // it's an exclusive request, in which case the shared line - // should never be asserted1 - pkt->assertShared(); - } + PacketPtr pkt = already_copied ? req_pkt : new Packet(req_pkt); + assert(req_pkt->isInvalidate() || pkt->sharedAsserted()); pkt->allocate(); pkt->makeTimingResponse(); if (pkt->isRead()) { |