summaryrefslogtreecommitdiff
path: root/src/mem/cache/cache_impl.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/cache/cache_impl.hh')
-rw-r--r--src/mem/cache/cache_impl.hh44
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));
+ }
}
}