diff options
author | Steve Reinhardt <stever@eecs.umich.edu> | 2007-06-26 23:30:30 -0700 |
---|---|---|
committer | Steve Reinhardt <stever@eecs.umich.edu> | 2007-06-26 23:30:30 -0700 |
commit | c4903e088247ad187356864459d2e4be77d97154 (patch) | |
tree | 195ce9d5e233e3bb437d6a1222fb4c464226ca41 /src/mem/cache/cache_impl.hh | |
parent | 1b20df5607e86d3b384716792274fe01fa4f3f80 (diff) | |
download | gem5-c4903e088247ad187356864459d2e4be77d97154.tar.xz |
Revamp replacement-of-upgrade handling.
--HG--
extra : convert_revision : 9bc09d8ae6d50e6dfbb4ab21514612f9aa102a2e
Diffstat (limited to 'src/mem/cache/cache_impl.hh')
-rw-r--r-- | src/mem/cache/cache_impl.hh | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 599eecc82..3685bc8cb 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -58,6 +58,9 @@ Cache<TagStore,Coherence>::Cache(const std::string &_name, doFastWrites(params.doFastWrites), prefetchMiss(params.prefetchMiss) { + tempBlock = new BlkType(); + tempBlock->data = new uint8_t[blkSize]; + cpuSidePort = new CpuSidePort(_name + "-cpu_side_port", this); memSidePort = new MemSidePort(_name + "-mem_side_port", this); cpuSidePort->setOtherPort(memSidePort); @@ -678,11 +681,8 @@ Cache<TagStore,Coherence>::handleResponse(PacketPtr pkt) pkt->getAddr()); BlkType *blk = tags->findBlock(pkt->getAddr()); - if (!mshr->handleFill(pkt, blk)) { - mq->markPending(mshr); - requestMemSideBus((RequestCause)mq->index, pkt->finishTime); - return; - } + // give mshr a chance to do some dirty work + mshr->handleFill(pkt, blk); PacketList writebacks; blk = handleFill(pkt, blk, writebacks); @@ -693,6 +693,13 @@ Cache<TagStore,Coherence>::handleResponse(PacketPtr pkt) allocateBuffer(wbPkt, time, true); writebacks.pop_front(); } + // if we used temp block, clear it out + if (blk == tempBlock) { + if (blk->isDirty()) { + allocateBuffer(writebackBlk(blk), time, true); + } + tags->invalidateBlk(blk); + } } else { if (pkt->req->isUncacheable()) { mshr_uncacheable_lat[pkt->cmd.toInt()][0/*pkt->req->getThreadNum()*/] += @@ -764,15 +771,26 @@ Cache<TagStore,Coherence>::handleFill(PacketPtr pkt, BlkType *blk, Addr repl_addr = tags->regenerateBlkAddr(blk->tag, blk->set); MSHR *repl_mshr = mshrQueue.findMatch(repl_addr); if (repl_mshr) { - repl_mshr->handleReplacement(blk, blkSize); - } - - DPRINTF(Cache, "replacement: replacing %x with %x: %s\n", - repl_addr, addr, blk->isDirty() ? "writeback" : "clean"); + // must be an outstanding upgrade request on block + // we're about to replace... + assert(!blk->isWritable()); + assert(repl_mshr->needsExclusive); + // too hard to replace block with transient state; + // just use temporary storage to complete the current + // request and then get rid of it + assert(!tempBlock->isValid()); + blk = tempBlock; + tempBlock->set = tags->extractSet(addr); + DPRINTF(Cache, "using temp block for %x\n", addr); + } else { + DPRINTF(Cache, "replacement: replacing %x with %x: %s\n", + repl_addr, addr, + blk->isDirty() ? "writeback" : "clean"); - if (blk->isDirty()) { - // Save writeback packet for handling by caller - writebacks.push_back(writebackBlk(blk)); + if (blk->isDirty()) { + // Save writeback packet for handling by caller + writebacks.push_back(writebackBlk(blk)); + } } } |