summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Reinhardt <stever@gmail.com>2008-03-25 10:01:21 -0400
committerSteve Reinhardt <stever@gmail.com>2008-03-25 10:01:21 -0400
commit29be31ce3139c36f596e6edafbd3d253ee2200b3 (patch)
tree1a5f4364401b96594da0c4ae18f9d03a5b1ed19e
parent623dd7ed3a66e71e241dc8365c079cb5b42fa918 (diff)
downloadgem5-29be31ce3139c36f596e6edafbd3d253ee2200b3.tar.xz
Fix handling of writeback-induced writebacks in atomic mode.
--HG-- extra : convert_revision : 4fa64f8a929f1aa36a9d5a71b8d1816b497aca4c
-rw-r--r--src/mem/cache/cache.hh3
-rw-r--r--src/mem/cache/cache_impl.hh50
2 files changed, 24 insertions, 29 deletions
diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh
index f5f65d4dd..88c9deb7b 100644
--- a/src/mem/cache/cache.hh
+++ b/src/mem/cache/cache.hh
@@ -162,7 +162,8 @@ class Cache : public BaseCache
* @return Pointer to the cache block touched by the request. NULL if it
* was a miss.
*/
- bool access(PacketPtr pkt, BlkType *&blk, int &lat);
+ bool access(PacketPtr pkt, BlkType *&blk,
+ int &lat, PacketList &writebacks);
/**
*Handle doing the Compare and Swap function for SPARC.
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 47d20f915..7bab3012b 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -260,7 +260,8 @@ Cache<TagStore>::squash(int threadNum)
template<class TagStore>
bool
-Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk, int &lat)
+Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk,
+ int &lat, PacketList &writebacks)
{
if (pkt->req->isUncacheable()) {
blk = NULL;
@@ -308,7 +309,6 @@ Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk, int &lat)
// into the cache without having a writeable copy (or any copy at
// all).
if (pkt->cmd == MemCmd::Writeback) {
- PacketList writebacks;
assert(blkSize == pkt->getSize());
if (blk == NULL) {
// need to do a replacement
@@ -323,12 +323,6 @@ Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk, int &lat)
}
std::memcpy(blk->data, pkt->getPtr<uint8_t>(), blkSize);
blk->status |= BlkDirty;
- // copy writebacks from replacement to write buffer
- while (!writebacks.empty()) {
- PacketPtr wbPkt = writebacks.front();
- allocateWriteBuffer(wbPkt, curTick + hitLatency, true);
- writebacks.pop_front();
- }
// nothing else to do; writeback doesn't expect response
assert(!pkt->needsResponse());
hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++;
@@ -427,13 +421,13 @@ Cache<TagStore>::timingAccess(PacketPtr pkt)
int lat = hitLatency;
BlkType *blk = NULL;
- bool satisfied = access(pkt, blk, lat);
+ PacketList writebacks;
+
+ bool satisfied = access(pkt, blk, lat, writebacks);
#if 0
/** @todo make the fast write alloc (wh64) work with coherence. */
- PacketList writebacks;
-
// If this is a block size write/hint (WH64) allocate the block here
// if the coherence protocol allows it.
if (!blk && pkt->getSize() >= blkSize && coherence->allowFastWrites() &&
@@ -451,13 +445,6 @@ Cache<TagStore>::timingAccess(PacketPtr pkt)
++fastWrites;
}
}
-
- // copy writebacks to write buffer
- while (!writebacks.empty()) {
- PacketPtr wbPkt = writebacks.front();
- allocateWriteBuffer(wbPkt, time, true);
- writebacks.pop_front();
- }
#endif
bool needsResponse = pkt->needsResponse();
@@ -527,6 +514,13 @@ Cache<TagStore>::timingAccess(PacketPtr pkt)
}
}
+ // copy writebacks to write buffer
+ while (!writebacks.empty()) {
+ PacketPtr wbPkt = writebacks.front();
+ allocateWriteBuffer(wbPkt, time, true);
+ writebacks.pop_front();
+ }
+
return true;
}
@@ -614,8 +608,9 @@ Cache<TagStore>::atomicAccess(PacketPtr pkt)
// access in timing mode
BlkType *blk = NULL;
+ PacketList writebacks;
- if (!access(pkt, blk, lat)) {
+ if (!access(pkt, blk, lat, writebacks)) {
// MISS
PacketPtr busPkt = getBusPacket(pkt, blk, pkt->needsExclusive());
@@ -646,21 +641,20 @@ Cache<TagStore>::atomicAccess(PacketPtr pkt)
pkt->makeAtomicResponse();
pkt->copyError(busPkt);
} else if (isCacheFill && !is_error) {
- PacketList writebacks;
blk = handleFill(busPkt, blk, writebacks);
satisfyCpuSideRequest(pkt, blk);
delete busPkt;
-
- // Handle writebacks if needed
- while (!writebacks.empty()){
- PacketPtr wbPkt = writebacks.front();
- memSidePort->sendAtomic(wbPkt);
- writebacks.pop_front();
- delete wbPkt;
- }
}
}
+ // Handle writebacks if needed
+ while (!writebacks.empty()){
+ PacketPtr wbPkt = writebacks.front();
+ memSidePort->sendAtomic(wbPkt);
+ writebacks.pop_front();
+ delete wbPkt;
+ }
+
// We now have the block one way or another (hit or completed miss)
if (pkt->needsResponse()) {