From 45f881a4ced25105267799432c0f526400f0ba9e Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Thu, 5 Oct 2006 21:10:03 -0400 Subject: First pass at snooping stuff that compiles and doesn't break. Still need: -Handle NACK's on the recieve side -Distinguish top level caches -Handle repsonses from caches failing the fast path -Handle BusError and propogate it -Fix the invalidate packet associated with snooping in the cache src/mem/bus.cc: Make sure to snoop on functional accesses src/mem/cache/base_cache.cc: Wait to make a request into a response until it is ready to be issued src/mem/cache/base_cache.hh: Support range changes for snoops Set up snoop responses for cache->cache transfers src/mem/cache/cache_impl.hh: Only access the cache if it wasn't satisfied by cache->cache transfer Handle snoop phases (detect block, then snoop) Fix functional access to work properly (still need to fix snoop path for functional accesses) --HG-- extra : convert_revision : 4c25f11d7a996c1f56f4f7b55dde87a344e5fdf8 --- src/mem/cache/cache_impl.hh | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 11cd84e88..bea495f9f 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -63,14 +63,26 @@ doTimingAccess(Packet *pkt, CachePort *cachePort, bool isCpuSide) if (pkt->isWrite() && (pkt->req->getFlags() & LOCKED)) { pkt->req->setScResult(1); } - access(pkt); + if (!(pkt->flags & SATISFIED)) { + access(pkt); + } } else { if (pkt->isResponse()) handleResponse(pkt); - else - snoop(pkt); + else { + //Check if we are in phase1 + if (!snoopPhase2) { + snoopPhase2 = true; + } + else { + //Check if we should do the snoop + if (pkt->flags && SNOOP_COMMIT) + snoop(pkt); + snoopPhase2 = false; + } + } } return true; } @@ -117,7 +129,7 @@ doFunctionalAccess(Packet *pkt, bool isCpuSide) assert("Can't handle LL/SC on functional path\n"); } - probe(pkt, true); + probe(pkt, false); //TEMP ALWAYS SUCCESFUL FOR NOW pkt->result = Packet::Success; } @@ -126,7 +138,7 @@ doFunctionalAccess(Packet *pkt, bool isCpuSide) if (pkt->isResponse()) handleResponse(pkt); else - snoopProbe(pkt, true); + snoopProbe(pkt, false); } } @@ -372,7 +384,7 @@ template void Cache::snoop(Packet * &pkt) { - + DPRINTF(Cache, "SNOOPING"); Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1)); BlkType *blk = tags->findBlock(pkt); MSHR *mshr = missQueue->findMSHR(blk_addr); @@ -385,7 +397,10 @@ Cache::snoop(Packet * &pkt) //If the outstanding request was an invalidate (upgrade,readex,..) //Then we need to ACK the request until we get the data //Also NACK if the outstanding request is not a cachefill (writeback) + pkt->flags |= SATISFIED; pkt->flags |= NACKED_LINE; + assert("Don't detect these on the other side yet\n"); + respondToSnoop(pkt, curTick + hitLatency); return; } else { @@ -398,6 +413,7 @@ Cache::snoop(Packet * &pkt) //@todo Make it so that a read to a pending read can't be exclusive now. //Set the address so find match works + assert("Don't have invalidates yet\n"); invalidatePkt->addrOverride(pkt->getAddr()); //Append the invalidate on @@ -433,7 +449,7 @@ Cache::snoop(Packet * &pkt) assert(offset + pkt->getSize() <=blkSize); memcpy(pkt->getPtr(), mshr->pkt->getPtr() + offset, pkt->getSize()); - respondToSnoop(pkt); + respondToSnoop(pkt, curTick + hitLatency); } if (pkt->isInvalidate()) { @@ -449,7 +465,7 @@ Cache::snoop(Packet * &pkt) bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state); if (satisfy) { tags->handleSnoop(blk, new_state, pkt); - respondToSnoop(pkt); + respondToSnoop(pkt, curTick + hitLatency); return; } tags->handleSnoop(blk, new_state); @@ -517,7 +533,7 @@ Cache::probe(Packet * &pkt, bool update) missQueue->findWrites(blk_addr, writes); if (!update) { - memSidePort->sendFunctional(pkt); + memSidePort->sendFunctional(pkt); // Check for data in MSHR and writebuffer. if (mshr) { warn("Found outstanding miss on an non-update probe"); -- cgit v1.2.3 From 212c5aefb580375417d357d821255c67a8d90fdf Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Thu, 5 Oct 2006 23:28:03 -0400 Subject: Fixes for functional accesses to use the snoop path. And small other tweaks to snooping coherence. src/mem/cache/base_cache.hh: Make timing response at the time of send. src/mem/cache/cache.hh: src/mem/cache/cache_impl.hh: Update probe interface to be bi-directional for functional accesses src/mem/packet.hh: Add the function to create an atomic response to a given request --HG-- extra : convert_revision : 04075a117cf30a7df16e6d3ce485543cc77d4ca6 --- src/mem/cache/cache_impl.hh | 58 ++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index bea495f9f..228cd2d73 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -99,7 +99,7 @@ doAtomicAccess(Packet *pkt, bool isCpuSide) pkt->req->setScResult(1); } - probe(pkt, true); + probe(pkt, true, NULL); //TEMP ALWAYS SUCCES FOR NOW pkt->result = Packet::Success; } @@ -108,7 +108,7 @@ doAtomicAccess(Packet *pkt, bool isCpuSide) if (pkt->isResponse()) handleResponse(pkt); else - snoopProbe(pkt, true); + snoopProbe(pkt); } //Fix this timing info return hitLatency; @@ -129,16 +129,13 @@ doFunctionalAccess(Packet *pkt, bool isCpuSide) assert("Can't handle LL/SC on functional path\n"); } - probe(pkt, false); + probe(pkt, false, memSidePort); //TEMP ALWAYS SUCCESFUL FOR NOW pkt->result = Packet::Success; } else { - if (pkt->isResponse()) - handleResponse(pkt); - else - snoopProbe(pkt, false); + probe(pkt, false, cpuSidePort); } } @@ -251,7 +248,7 @@ Cache::access(PacketPtr &pkt) pkt->getAddr() & ~((Addr)blkSize - 1), pkt->req->getPC()); if (blk) { // Hit - hits[pkt->cmdToIndex()][pkt->req->getThreadNum()]++; + hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++; // clear dirty bit if write through if (pkt->needsResponse()) respond(pkt, curTick+lat); @@ -261,7 +258,7 @@ Cache::access(PacketPtr &pkt) // Miss if (!pkt->req->isUncacheable()) { - misses[pkt->cmdToIndex()][pkt->req->getThreadNum()]++; + misses[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++; /** @todo Move miss count code into BaseCache */ if (missCount) { --missCount; @@ -282,7 +279,7 @@ Cache::getPacket() Packet * pkt = missQueue->getPacket(); if (pkt) { if (!pkt->req->isUncacheable()) { - if (pkt->cmd == Packet::HardPFReq) misses[Packet::HardPFReq][pkt->req->getThreadNum()]++; + if (pkt->cmd == Packet::HardPFReq) misses[Packet::HardPFReq][0/*pkt->req->getThreadNum()*/]++; BlkType *blk = tags->findBlock(pkt); Packet::Command cmd = coherence->getBusCmd(pkt->cmd, (blk)? blk->status : 0); @@ -326,7 +323,7 @@ Cache::handleResponse(Packet * &pkt) PacketList writebacks; blk = tags->handleFill(blk, (MSHR*)pkt->senderState, coherence->getNewState(pkt,old_state), - writebacks); + writebacks, pkt); while (!writebacks.empty()) { missQueue->doWriteback(writebacks.front()); } @@ -384,7 +381,6 @@ template void Cache::snoop(Packet * &pkt) { - DPRINTF(Cache, "SNOOPING"); Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1)); BlkType *blk = tags->findBlock(pkt); MSHR *mshr = missQueue->findMSHR(blk_addr); @@ -502,7 +498,7 @@ Cache::invalidateBlk(Addr addr) */ template Tick -Cache::probe(Packet * &pkt, bool update) +Cache::probe(Packet * &pkt, bool update, CachePort* otherSidePort) { // MemDebug::cacheProbe(pkt); if (!pkt->req->isUncacheable()) { @@ -533,7 +529,8 @@ Cache::probe(Packet * &pkt, bool update) missQueue->findWrites(blk_addr, writes); if (!update) { - memSidePort->sendFunctional(pkt); + otherSidePort->sendFunctional(pkt); + // Check for data in MSHR and writebuffer. if (mshr) { warn("Found outstanding miss on an non-update probe"); @@ -628,12 +625,15 @@ Cache::probe(Packet * &pkt, bool update) lat = memSidePort->sendAtomic(busPkt); + //Be sure to flip the response to a request for coherence + busPkt->makeAtomicResponse(); + /* if (!(busPkt->flags & SATISFIED)) { // blocked at a higher level, just return return 0; } -*/ misses[pkt->cmdToIndex()][pkt->req->getThreadNum()]++; +*/ misses[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++; CacheBlk::State old_state = (blk) ? blk->status : 0; tags->handleFill(blk, busPkt, @@ -658,10 +658,10 @@ Cache::probe(Packet * &pkt, bool update) } if (update) { - hits[pkt->cmdToIndex()][pkt->req->getThreadNum()]++; + hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++; } else if (pkt->isWrite()) { // Still need to change data in all locations. - return memSidePort->sendAtomic(pkt); + return otherSidePort->sendAtomic(pkt); } return curTick + lat; } @@ -671,18 +671,18 @@ Cache::probe(Packet * &pkt, bool update) template Tick -Cache::snoopProbe(PacketPtr &pkt, bool update) +Cache::snoopProbe(PacketPtr &pkt) { - Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1)); - BlkType *blk = tags->findBlock(pkt); - MSHR *mshr = missQueue->findMSHR(blk_addr); - CacheBlk::State new_state = 0; - bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state); - if (satisfy) { - tags->handleSnoop(blk, new_state, pkt); - return hitLatency; - } - tags->handleSnoop(blk, new_state); - return 0; + Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1)); + BlkType *blk = tags->findBlock(pkt); + MSHR *mshr = missQueue->findMSHR(blk_addr); + CacheBlk::State new_state = 0; + bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state); + if (satisfy) { + tags->handleSnoop(blk, new_state, pkt); + return hitLatency; + } + tags->handleSnoop(blk, new_state); + return 0; } -- cgit v1.2.3 From 9c901225f8f18d0d2f5325436983d685a4fe2245 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Fri, 6 Oct 2006 01:27:02 -0400 Subject: there are two main thrusts of this changeset. 1) return the periodicity of checkpoints back into the code (i.e. make m5 checkpoint n m meaningful again). 2) to do this, i had to much around with being able to repeatedly schedule and SimLoopExitEvent, which led to changes in how exit simloop events are handled to make this easier. src/arch/alpha/isa/decoder.isa: src/mem/cache/cache_impl.hh: modify arg. order for new calling convention of exitSimLoop. src/cpu/base.cc: src/sim/main.cc: src/sim/pseudo_inst.cc: src/sim/root.cc: now, instead of creating a new SimLoopExitEvent, call a wrapper schedExitSimLoop which handles all the default args. src/sim/sim_events.cc: src/sim/sim_events.hh: src/sim/sim_exit.hh: add the periodicity of checkpointing back into the code. to facilitate this, there are now two wrappers (instead of just overloading exitSimLoop). exitSimLoop is only for exiting NOW (i.e. at curTick), while schedExitSimLoop schedules and exit event for the future. --HG-- extra : convert_revision : c61f4bf05517172edd2c83368fd10bb0f0678029 --- src/mem/cache/cache_impl.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 11cd84e88..593dbecf3 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -51,7 +51,7 @@ #include "mem/cache/miss/mshr.hh" #include "mem/cache/prefetch/prefetcher.hh" -#include "sim/sim_events.hh" // for SimExitEvent +#include "sim/sim_exit.hh" // for SimExitEvent template bool @@ -254,7 +254,7 @@ Cache::access(PacketPtr &pkt) if (missCount) { --missCount; if (missCount == 0) - new SimLoopExitEvent(curTick, "A cache reached the maximum miss count"); + exitSimLoop("A cache reached the maximum miss count"); } } missQueue->handleMiss(pkt, size, curTick + hitLatency); -- cgit v1.2.3 From 178d114fa5ed5927a2665a30ae5813ea2e2fbfea Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Sat, 7 Oct 2006 11:36:55 -0400 Subject: Fix infinite writebacks bug in cache. src/mem/cache/cache_impl.hh: Make sure to pop the list. Fixes infinite writeback bug. src/mem/cache/miss/mshr_queue.cc: Add an assert as sanity check in case .full() stops working again. --HG-- extra : convert_revision : d847e49a397eeb0b7c5ac060fcfc3eaeac921311 --- src/mem/cache/cache_impl.hh | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 00fecc2b7..46f4b0ebe 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -326,6 +326,7 @@ Cache::handleResponse(Packet * &pkt) writebacks, pkt); while (!writebacks.empty()) { missQueue->doWriteback(writebacks.front()); + writebacks.pop_front(); } } missQueue->handleResponse(pkt, curTick + hitLatency); -- cgit v1.2.3 From 5df93cc1cd5ce8272032ad1cbf5265b5fdb4713f Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sun, 8 Oct 2006 14:48:24 -0700 Subject: Replace tests of LOCKED/UNCACHEABLE flags with isLocked()/isUncacheable(). --HG-- extra : convert_revision : f22ce3221d270ecf8631d3dcaed05753accd5461 --- src/mem/cache/cache_impl.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 46f4b0ebe..63273adc6 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -60,7 +60,7 @@ doTimingAccess(Packet *pkt, CachePort *cachePort, bool isCpuSide) { if (isCpuSide) { - if (pkt->isWrite() && (pkt->req->getFlags() & LOCKED)) { + if (pkt->isWrite() && (pkt->req->isLocked())) { pkt->req->setScResult(1); } if (!(pkt->flags & SATISFIED)) { @@ -95,7 +95,7 @@ doAtomicAccess(Packet *pkt, bool isCpuSide) if (isCpuSide) { //Temporary solution to LL/SC - if (pkt->isWrite() && (pkt->req->getFlags() & LOCKED)) { + if (pkt->isWrite() && (pkt->req->isLocked())) { pkt->req->setScResult(1); } @@ -125,7 +125,7 @@ doFunctionalAccess(Packet *pkt, bool isCpuSide) pkt->req->setThreadContext(0,0); //Temporary solution to LL/SC - if (pkt->isWrite() && (pkt->req->getFlags() & LOCKED)) { + if (pkt->isWrite() && (pkt->req->isLocked())) { assert("Can't handle LL/SC on functional path\n"); } -- cgit v1.2.3 From 1345183a89a148bf48110c4559448dd708549252 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Sun, 8 Oct 2006 18:48:03 -0400 Subject: Move away from using the statusChange function on snoops. Clean up snooping code in general. --HG-- extra : convert_revision : 5a57bfd7742a212047fc32e8cae0dc602fdc915c --- src/mem/cache/cache_impl.hh | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 46f4b0ebe..0d625054c 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -72,16 +72,9 @@ doTimingAccess(Packet *pkt, CachePort *cachePort, bool isCpuSide) if (pkt->isResponse()) handleResponse(pkt); else { - //Check if we are in phase1 - if (!snoopPhase2) { - snoopPhase2 = true; - } - else { - //Check if we should do the snoop - if (pkt->flags && SNOOP_COMMIT) - snoop(pkt); - snoopPhase2 = false; - } + //Check if we should do the snoop + if (pkt->flags && SNOOP_COMMIT) + snoop(pkt); } } return true; -- cgit v1.2.3 From 4cfddc0d772eff614a5b6d61efa846aa7fa706a8 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Sun, 8 Oct 2006 20:47:50 -0400 Subject: Make sure to propogate sendFunctional calls with functional not atomic. src/mem/cache/cache_impl.hh: Fix a error case by putting a panic in. Make sure to propogate sendFunctional calls with functional not atomic. --HG-- extra : convert_revision : 05d03f729a40cfa3ecb68bcba172eb560b24e897 --- src/mem/cache/cache_impl.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 1f03065b6..9ce8f515d 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -603,7 +603,7 @@ Cache::probe(Packet * &pkt, bool update, CachePort // update the cache state and statistics if (mshr || !writes.empty()){ // Can't handle it, return pktuest unsatisfied. - return 0; + panic("Atomic access ran into outstanding MSHR's or WB's!"); } if (!pkt->req->isUncacheable()) { // Fetch the cache block to fill @@ -655,7 +655,7 @@ Cache::probe(Packet * &pkt, bool update, CachePort hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++; } else if (pkt->isWrite()) { // Still need to change data in all locations. - return otherSidePort->sendAtomic(pkt); + otherSidePort->sendFunctional(pkt); } return curTick + lat; } -- cgit v1.2.3 From 0087061681869c9aaab81c3797020b083a83d46a Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Mon, 9 Oct 2006 00:27:41 -0400 Subject: Don't create a response if one isn't needed. --HG-- extra : convert_revision : 37bd230f527f64eb12779157869aae9dcfdde7fd --- src/mem/cache/cache_impl.hh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 9ce8f515d..ac2d7af8b 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -620,7 +620,9 @@ Cache::probe(Packet * &pkt, bool update, CachePort lat = memSidePort->sendAtomic(busPkt); //Be sure to flip the response to a request for coherence - busPkt->makeAtomicResponse(); + if (busPkt->needsResponse()) { + busPkt->makeAtomicResponse(); + } /* if (!(busPkt->flags & SATISFIED)) { // blocked at a higher level, just return -- cgit v1.2.3 From afce51d10ad1441247b39edb2a61b85d3cd7af04 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Mon, 9 Oct 2006 16:37:02 -0400 Subject: Set size properly on uncache accesses Don't use the senderState after you get a succesful sendTiming. Not guarnteed to be correct src/mem/cache/base_cache.cc: src/mem/cache/base_cache.hh: src/mem/cache/cache.hh: src/mem/cache/cache_impl.hh: src/mem/cache/miss/blocking_buffer.cc: src/mem/cache/miss/blocking_buffer.hh: src/mem/cache/miss/miss_queue.hh: Don't use the senderState after you get a succesful sendTiming. Not guarnteed to be correct --HG-- extra : convert_revision : 2e8e812bf7fd3ba2b4cba7f7173cb41862f761af --- src/mem/cache/cache_impl.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index ac2d7af8b..32f561d71 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -287,10 +287,10 @@ Cache::getPacket() template void -Cache::sendResult(PacketPtr &pkt, bool success) +Cache::sendResult(PacketPtr &pkt, MSHR* mshr, bool success) { if (success) { - missQueue->markInService(pkt); + missQueue->markInService(pkt, mshr); //Temp Hack for UPGRADES if (pkt->cmd == Packet::UpgradeReq) { handleResponse(pkt); @@ -444,7 +444,7 @@ Cache::snoop(Packet * &pkt) if (pkt->isInvalidate()) { //This must be an upgrade or other cache will take ownership - missQueue->markInService(mshr->pkt); + missQueue->markInService(mshr->pkt, mshr); } return; } -- cgit v1.2.3 From 45732376f6f781cf3671b830321e96478a01dd3d Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Mon, 9 Oct 2006 16:47:55 -0400 Subject: Add more DPRINTF's fix a supply condition. src/mem/cache/cache_impl.hh: Add more usefull DPRINTF's REmove the PC to get rid of asserts --HG-- extra : convert_revision : 3f6d832b138d058dbe79bb5f42bd2db9c50b35b5 --- src/mem/cache/cache_impl.hh | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index ac2d7af8b..b6556f252 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -236,9 +236,9 @@ Cache::access(PacketPtr &pkt) missQueue->doWriteback(writebacks.front()); writebacks.pop_front(); } - DPRINTF(Cache, "%s %x %s blk_addr: %x pc %x\n", pkt->cmdString(), + DPRINTF(Cache, "%s %x %s blk_addr: %x\n", pkt->cmdString(), pkt->getAddr() & (((ULL(1))<<48)-1), (blk) ? "hit" : "miss", - pkt->getAddr() & ~((Addr)blkSize - 1), pkt->req->getPC()); + pkt->getAddr() & ~((Addr)blkSize - 1)); if (blk) { // Hit hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++; @@ -314,9 +314,11 @@ Cache::handleResponse(Packet * &pkt) blk = tags->findBlock(pkt); CacheBlk::State old_state = (blk) ? blk->status : 0; PacketList writebacks; + CacheBlk::State new_state = coherence->getNewState(pkt,old_state); + DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n", + pkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state); blk = tags->handleFill(blk, (MSHR*)pkt->senderState, - coherence->getNewState(pkt,old_state), - writebacks, pkt); + new_state, writebacks, pkt); while (!writebacks.empty()) { missQueue->doWriteback(writebacks.front()); writebacks.pop_front(); @@ -387,6 +389,7 @@ Cache::snoop(Packet * &pkt) //If the outstanding request was an invalidate (upgrade,readex,..) //Then we need to ACK the request until we get the data //Also NACK if the outstanding request is not a cachefill (writeback) + assert(!(pkt->flags & SATISFIED)); pkt->flags |= SATISFIED; pkt->flags |= NACKED_LINE; assert("Don't detect these on the other side yet\n"); @@ -426,6 +429,7 @@ Cache::snoop(Packet * &pkt) if (pkt->isRead()) { //Only Upgrades don't get here //Supply the data + assert(!(pkt->flags & SATISFIED)); pkt->flags |= SATISFIED; //If we are in an exclusive protocol, make it ask again @@ -454,10 +458,16 @@ Cache::snoop(Packet * &pkt) CacheBlk::State new_state; bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state); if (satisfy) { + DPRINTF(Cache, "Cache snooped a %c request and now supplying data," + "new state is %i\n", + pkt->cmdString(), new_state); + tags->handleSnoop(blk, new_state, pkt); respondToSnoop(pkt, curTick + hitLatency); return; } + if (blk) DPRINTF(Cache, "Cache snooped a %c request, new state is %i\n", + pkt->cmdString(), new_state); tags->handleSnoop(blk, new_state); } @@ -675,9 +685,15 @@ Cache::snoopProbe(PacketPtr &pkt) CacheBlk::State new_state = 0; bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state); if (satisfy) { + DPRINTF(Cache, "Cache snooped a %c request and now supplying data," + "new state is %i\n", + pkt->cmdString(), new_state); + tags->handleSnoop(blk, new_state, pkt); return hitLatency; } + if (blk) DPRINTF(Cache, "Cache snooped a %c request, new state is %i\n", + pkt->cmdString(), new_state); tags->handleSnoop(blk, new_state); return 0; } -- cgit v1.2.3 From fd27c229b6bae09098864361dd6e51065fbaec3c Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Mon, 9 Oct 2006 17:18:34 -0400 Subject: Fix a bitwise operation that was accidentally a logical operation. --HG-- extra : convert_revision : 30f64bcb6bea47fd8cd6d77b0df17eff04dbbad0 --- src/mem/cache/cache_impl.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 8d028e97f..7764b97c1 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -73,7 +73,7 @@ doTimingAccess(Packet *pkt, CachePort *cachePort, bool isCpuSide) handleResponse(pkt); else { //Check if we should do the snoop - if (pkt->flags && SNOOP_COMMIT) + if (pkt->flags & SNOOP_COMMIT) snoop(pkt); } } -- cgit v1.2.3 From c4dba7a8ed496c2e534b6caa8754678d642124c7 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Mon, 9 Oct 2006 17:30:54 -0400 Subject: Fix a typo in the printf --HG-- extra : convert_revision : bfa8ffae0a9bef25ceca168ff376ba816abf23f3 --- src/mem/cache/cache_impl.hh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 7764b97c1..bde7ac04b 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -458,7 +458,7 @@ Cache::snoop(Packet * &pkt) CacheBlk::State new_state; bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state); if (satisfy) { - DPRINTF(Cache, "Cache snooped a %c request and now supplying data," + DPRINTF(Cache, "Cache snooped a %s request and now supplying data," "new state is %i\n", pkt->cmdString(), new_state); @@ -466,7 +466,7 @@ Cache::snoop(Packet * &pkt) respondToSnoop(pkt, curTick + hitLatency); return; } - if (blk) DPRINTF(Cache, "Cache snooped a %c request, new state is %i\n", + if (blk) DPRINTF(Cache, "Cache snooped a %s request, new state is %i\n", pkt->cmdString(), new_state); tags->handleSnoop(blk, new_state); } @@ -685,14 +685,14 @@ Cache::snoopProbe(PacketPtr &pkt) CacheBlk::State new_state = 0; bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state); if (satisfy) { - DPRINTF(Cache, "Cache snooped a %c request and now supplying data," + DPRINTF(Cache, "Cache snooped a %s request and now supplying data," "new state is %i\n", pkt->cmdString(), new_state); tags->handleSnoop(blk, new_state, pkt); return hitLatency; } - if (blk) DPRINTF(Cache, "Cache snooped a %c request, new state is %i\n", + if (blk) DPRINTF(Cache, "Cache snooped a %s request, new state is %i\n", pkt->cmdString(), new_state); tags->handleSnoop(blk, new_state); return 0; -- cgit v1.2.3 From 13ac9a419dcf2e1e0335bc65b20837e538a9beee Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Mon, 9 Oct 2006 18:52:20 -0400 Subject: One step closet to having NACK's work. src/cpu/memtest/memtest.cc: Fix functional return path src/cpu/memtest/memtest.hh: Add snoop ranges in src/mem/cache/base_cache.cc: Properly signal NACKED src/mem/cache/cache_impl.hh: Catch nacked packet and panic for now --HG-- extra : convert_revision : 59a64e82254dfa206681c5f987e6939167754d67 --- src/mem/cache/cache_impl.hh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index bde7ac04b..af12b9255 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -306,6 +306,13 @@ Cache::handleResponse(Packet * &pkt) { BlkType *blk = NULL; if (pkt->senderState) { + if (pkt->result == Packet::Nacked) { + pkt->reinitFromRequest(); + panic("Unimplemented NACK of packet\n"); + } + if (pkt->result == Packet::BadAddress) { + //Make the response a Bad address and send it + } // MemDebug::cacheResponse(pkt); DPRINTF(Cache, "Handling reponse to %x, blk addr: %x\n",pkt->getAddr(), pkt->getAddr() & (((ULL(1))<<48)-1)); @@ -392,7 +399,6 @@ Cache::snoop(Packet * &pkt) assert(!(pkt->flags & SATISFIED)); pkt->flags |= SATISFIED; pkt->flags |= NACKED_LINE; - assert("Don't detect these on the other side yet\n"); respondToSnoop(pkt, curTick + hitLatency); return; } @@ -406,7 +412,7 @@ Cache::snoop(Packet * &pkt) //@todo Make it so that a read to a pending read can't be exclusive now. //Set the address so find match works - assert("Don't have invalidates yet\n"); + panic("Don't have invalidates yet\n"); invalidatePkt->addrOverride(pkt->getAddr()); //Append the invalidate on -- cgit v1.2.3 From e03b9c9939d7782198c023b23ed33cde131f48c5 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Mon, 9 Oct 2006 19:15:24 -0400 Subject: Fix how upgrades work. Remove some dead code. src/mem/cache/cache_impl.hh: Upgrades don't need a response. Moved satisfied check into bus so removed some dead code. src/mem/cache/coherence/coherence_protocol.cc: src/mem/packet.hh: Upgrades don't require a response --HG-- extra : convert_revision : dee0440ff19ba4c9e51bf9a47a5b0991265cfc1d --- src/mem/cache/cache_impl.hh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index af12b9255..c3c1c0881 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -63,9 +63,8 @@ doTimingAccess(Packet *pkt, CachePort *cachePort, bool isCpuSide) if (pkt->isWrite() && (pkt->req->isLocked())) { pkt->req->setScResult(1); } - if (!(pkt->flags & SATISFIED)) { - access(pkt); - } + access(pkt); + } else { @@ -204,9 +203,8 @@ Cache::access(PacketPtr &pkt) pkt->getAddr() & (((ULL(1))<<48)-1), pkt->getAddr() & ~((Addr)blkSize - 1)); - //@todo Should this return latency have the hit latency in it? -// respond(pkt,curTick+lat); pkt->flags |= SATISFIED; + //Invalidates/Upgrades need no response if they get the bus // return MA_HIT; //@todo, return values return true; } -- cgit v1.2.3 From ec8a437b2c11453e9b94978b0c18a31f12ec04ac Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Mon, 9 Oct 2006 20:18:00 -0400 Subject: Handle NACK's that occur from devices on the same bus. Not fully implemented yet, but good enough for single level cache coherence src/mem/packet.hh: Add a bit to distinguish invalidates and upgrades --HG-- extra : convert_revision : 5bf50d535857cea37fbdaf7993915d1332cb757e --- src/mem/cache/cache_impl.hh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index c3c1c0881..5c12075cd 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -287,13 +287,17 @@ template void Cache::sendResult(PacketPtr &pkt, MSHR* mshr, bool success) { - if (success) { + if (success && !(pkt->flags & NACKED_LINE)) { missQueue->markInService(pkt, mshr); //Temp Hack for UPGRADES if (pkt->cmd == Packet::UpgradeReq) { + pkt->flags &= ~CACHE_LINE_FILL; handleResponse(pkt); } } else if (pkt && !pkt->req->isUncacheable()) { + pkt->flags &= ~NACKED_LINE; + pkt->flags &= ~SATISFIED; + pkt->flags &= ~SNOOP_COMMIT; missQueue->restoreOrigCmd(pkt); } } @@ -305,8 +309,9 @@ Cache::handleResponse(Packet * &pkt) BlkType *blk = NULL; if (pkt->senderState) { if (pkt->result == Packet::Nacked) { - pkt->reinitFromRequest(); - panic("Unimplemented NACK of packet\n"); + //pkt->reinitFromRequest(); + warn("NACKs from devices not connected to the same bus not implemented\n"); + return; } if (pkt->result == Packet::BadAddress) { //Make the response a Bad address and send it @@ -397,7 +402,8 @@ Cache::snoop(Packet * &pkt) assert(!(pkt->flags & SATISFIED)); pkt->flags |= SATISFIED; pkt->flags |= NACKED_LINE; - respondToSnoop(pkt, curTick + hitLatency); + warn("NACKs from devices not connected to the same bus not implemented\n"); + //respondToSnoop(pkt, curTick + hitLatency); return; } else { -- cgit v1.2.3 From cc78d86661dfccaca2f144d5bdcc75761bf52521 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Tue, 10 Oct 2006 01:32:18 -0400 Subject: Fix several bugs pertaining to upgrades/mem leaks. src/mem/cache/base_cache.cc: Fix a bug about not having a request to send src/mem/cache/base_cache.hh: Fix a bug with the blocking code src/mem/cache/cache.hh: AFix a bug with snoop hits in WB buffer src/mem/cache/cache_impl.hh: Fix a bug with snoop hits in WB buffer Also, add better DPRINTF's src/mem/cache/miss/miss_queue.cc: Fix a bug with upgrades (Need to clean it up later) src/mem/cache/miss/mshr.cc: Fix a memory leak bug, still some outstanding with writebacks not being deleted src/mem/cache/miss/mshr_queue.cc: Fix a bug about upgrades (need to clean up later) src/mem/packet.hh: Fix for newly added cmd attribute for upgrades tests/configs/memtest.py: More interesting testcase --HG-- extra : convert_revision : fcb4f17dd58b537bb4f67a8c835f50e455e8c688 --- src/mem/cache/cache_impl.hh | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 5c12075cd..8c0521b52 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -163,10 +163,8 @@ Cache(const std::string &_name, prefetcher->setCache(this); prefetcher->setTags(tags); prefetcher->setBuffer(missQueue); -#if 0 - invalidatePkt = new Packet; - invalidatePkt->cmd = Packet::InvalidateReq; -#endif + invalidateReq = new Request((Addr) NULL, blkSize, 0); + invalidatePkt = new Packet(invalidateReq, Packet::InvalidateReq, 0); } template @@ -267,6 +265,7 @@ template Packet * Cache::getPacket() { + assert(missQueue->havePending()); Packet * pkt = missQueue->getPacket(); if (pkt) { if (!pkt->req->isUncacheable()) { @@ -292,7 +291,17 @@ Cache::sendResult(PacketPtr &pkt, MSHR* mshr, bool //Temp Hack for UPGRADES if (pkt->cmd == Packet::UpgradeReq) { pkt->flags &= ~CACHE_LINE_FILL; - handleResponse(pkt); + BlkType *blk = tags->findBlock(pkt); + CacheBlk::State old_state = (blk) ? blk->status : 0; + CacheBlk::State new_state = coherence->getNewState(pkt,old_state); + DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n", + pkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state); + //Set the state on the upgrade + memcpy(pkt->getPtr(), blk->data, blkSize); + PacketList writebacks; + tags->handleFill(blk, mshr, new_state, writebacks, pkt); + assert(writebacks.empty()); + missQueue->handleResponse(pkt, curTick + hitLatency); } } else if (pkt && !pkt->req->isUncacheable()) { pkt->flags &= ~NACKED_LINE; @@ -402,7 +411,8 @@ Cache::snoop(Packet * &pkt) assert(!(pkt->flags & SATISFIED)); pkt->flags |= SATISFIED; pkt->flags |= NACKED_LINE; - warn("NACKs from devices not connected to the same bus not implemented\n"); + ///@todo NACK's from other levels + //warn("NACKs from devices not connected to the same bus not implemented\n"); //respondToSnoop(pkt, curTick + hitLatency); return; } @@ -416,7 +426,7 @@ Cache::snoop(Packet * &pkt) //@todo Make it so that a read to a pending read can't be exclusive now. //Set the address so find match works - panic("Don't have invalidates yet\n"); + //panic("Don't have invalidates yet\n"); invalidatePkt->addrOverride(pkt->getAddr()); //Append the invalidate on @@ -447,7 +457,7 @@ Cache::snoop(Packet * &pkt) pkt->flags |= SHARED_LINE; assert(pkt->isRead()); - Addr offset = pkt->getAddr() & ~(blkSize - 1); + Addr offset = pkt->getAddr() & (blkSize - 1); assert(offset < blkSize); assert(pkt->getSize() <= blkSize); assert(offset + pkt->getSize() <=blkSize); @@ -468,16 +478,16 @@ Cache::snoop(Packet * &pkt) CacheBlk::State new_state; bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state); if (satisfy) { - DPRINTF(Cache, "Cache snooped a %s request and now supplying data," + DPRINTF(Cache, "Cache snooped a %s request for addr %x and now supplying data," "new state is %i\n", - pkt->cmdString(), new_state); + pkt->cmdString(), blk_addr, new_state); tags->handleSnoop(blk, new_state, pkt); respondToSnoop(pkt, curTick + hitLatency); return; } - if (blk) DPRINTF(Cache, "Cache snooped a %s request, new state is %i\n", - pkt->cmdString(), new_state); + if (blk) DPRINTF(Cache, "Cache snooped a %s request for addr %x, new state is %i\n", + pkt->cmdString(), blk_addr, new_state); tags->handleSnoop(blk, new_state); } @@ -695,15 +705,15 @@ Cache::snoopProbe(PacketPtr &pkt) CacheBlk::State new_state = 0; bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state); if (satisfy) { - DPRINTF(Cache, "Cache snooped a %s request and now supplying data," + DPRINTF(Cache, "Cache snooped a %s request for addr %x and now supplying data," "new state is %i\n", - pkt->cmdString(), new_state); + pkt->cmdString(), blk_addr, new_state); tags->handleSnoop(blk, new_state, pkt); return hitLatency; } - if (blk) DPRINTF(Cache, "Cache snooped a %s request, new state is %i\n", - pkt->cmdString(), new_state); + if (blk) DPRINTF(Cache, "Cache snooped a %s request for addr %x, new state is %i\n", + pkt->cmdString(), blk_addr, new_state); tags->handleSnoop(blk, new_state); return 0; } -- cgit v1.2.3 From 995146ead7bcf03b80bdea6281fa4a225ad48b72 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Tue, 10 Oct 2006 17:10:56 -0400 Subject: Fix some more mem leaks, still some left Update retry mechanism src/mem/cache/base_cache.cc: Rework the retry mechanism src/mem/cache/base_cache.hh: Rework the retry mechanism Try to fix memory bug src/mem/cache/cache_impl.hh: Rework upgrades to not be blocked by slave src/mem/cache/miss/mshr_queue.cc: Fix mem leak on writebacks --HG-- extra : convert_revision : 3cec234ee441edf398ec8d0f51a0c5d7ada1e2be --- src/mem/cache/cache_impl.hh | 48 ++++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 29 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 8c0521b52..58eb0bdbc 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -193,19 +193,6 @@ Cache::access(PacketPtr &pkt) prefetcher->handleMiss(pkt, curTick); } if (!pkt->req->isUncacheable()) { - if (pkt->isInvalidate() && !pkt->isRead() - && !pkt->isWrite()) { - //Upgrade or Invalidate - //Look into what happens if two slave caches on bus - DPRINTF(Cache, "%s %x ? blk_addr: %x\n", pkt->cmdString(), - pkt->getAddr() & (((ULL(1))<<48)-1), - pkt->getAddr() & ~((Addr)blkSize - 1)); - - pkt->flags |= SATISFIED; - //Invalidates/Upgrades need no response if they get the bus -// return MA_HIT; //@todo, return values - return true; - } blk = tags->handleAccess(pkt, lat, writebacks); } else { size = pkt->getSize(); @@ -241,7 +228,10 @@ Cache::access(PacketPtr &pkt) // clear dirty bit if write through if (pkt->needsResponse()) respond(pkt, curTick+lat); -// return MA_HIT; + if (pkt->cmd == Packet::Writeback) { + //Signal that you can kill the pkt/req + pkt->flags |= SATISFIED; + } return true; } @@ -287,22 +277,22 @@ void Cache::sendResult(PacketPtr &pkt, MSHR* mshr, bool success) { if (success && !(pkt->flags & NACKED_LINE)) { - missQueue->markInService(pkt, mshr); - //Temp Hack for UPGRADES - if (pkt->cmd == Packet::UpgradeReq) { - pkt->flags &= ~CACHE_LINE_FILL; - BlkType *blk = tags->findBlock(pkt); - CacheBlk::State old_state = (blk) ? blk->status : 0; - CacheBlk::State new_state = coherence->getNewState(pkt,old_state); - DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n", + missQueue->markInService(pkt, mshr); + //Temp Hack for UPGRADES + if (pkt->cmd == Packet::UpgradeReq) { + pkt->flags &= ~CACHE_LINE_FILL; + BlkType *blk = tags->findBlock(pkt); + CacheBlk::State old_state = (blk) ? blk->status : 0; + CacheBlk::State new_state = coherence->getNewState(pkt,old_state); + DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n", pkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state); - //Set the state on the upgrade - memcpy(pkt->getPtr(), blk->data, blkSize); - PacketList writebacks; - tags->handleFill(blk, mshr, new_state, writebacks, pkt); - assert(writebacks.empty()); - missQueue->handleResponse(pkt, curTick + hitLatency); - } + //Set the state on the upgrade + memcpy(pkt->getPtr(), blk->data, blkSize); + PacketList writebacks; + tags->handleFill(blk, mshr, new_state, writebacks, pkt); + assert(writebacks.empty()); + missQueue->handleResponse(pkt, curTick + hitLatency); + } } else if (pkt && !pkt->req->isUncacheable()) { pkt->flags &= ~NACKED_LINE; pkt->flags &= ~SATISFIED; -- cgit v1.2.3 From 567afbf6ce5b2d6fe573878c39679e56a1bf5d15 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Wed, 11 Oct 2006 18:28:33 -0400 Subject: More cache fixes. Atomic coherence now works as well. src/cpu/memtest/memtest.cc: src/cpu/memtest/memtest.hh: Make Memtester able to test atomic as well src/mem/bus.cc: src/mem/bus.hh: Handle atomic snoops properly for cache->cache transfers src/mem/cache/cache_impl.hh: Debug output. Clean up memleak in atomic mode. Set hitLatency. Still need to send back reasonable number for atomic return value. src/mem/packet.cc: Add command strings for new commands src/python/m5/objects/MemTest.py: Add param to test atomic memory. --HG-- extra : convert_revision : 43f880e29215776167c16ea90793ebf8122c785b --- src/mem/cache/cache_impl.hh | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) (limited to 'src/mem/cache/cache_impl.hh') diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 58eb0bdbc..a68418f24 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -100,7 +100,7 @@ doAtomicAccess(Packet *pkt, bool isCpuSide) if (pkt->isResponse()) handleResponse(pkt); else - snoopProbe(pkt); + return snoopProbe(pkt); } //Fix this timing info return hitLatency; @@ -148,7 +148,8 @@ Cache(const std::string &_name, prefetchAccess(params.prefetchAccess), tags(params.tags), missQueue(params.missQueue), coherence(params.coherence), prefetcher(params.prefetcher), - doCopy(params.doCopy), blockOnCopy(params.blockOnCopy) + doCopy(params.doCopy), blockOnCopy(params.blockOnCopy), + hitLatency(params.hitLatency) { //FIX BUS POINTERS // if (params.in == NULL) { @@ -284,8 +285,9 @@ Cache::sendResult(PacketPtr &pkt, MSHR* mshr, bool BlkType *blk = tags->findBlock(pkt); CacheBlk::State old_state = (blk) ? blk->status : 0; CacheBlk::State new_state = coherence->getNewState(pkt,old_state); - DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n", - pkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state); + if (old_state != new_state) + DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n", + pkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state); //Set the state on the upgrade memcpy(pkt->getPtr(), blk->data, blkSize); PacketList writebacks; @@ -324,8 +326,9 @@ Cache::handleResponse(Packet * &pkt) CacheBlk::State old_state = (blk) ? blk->status : 0; PacketList writebacks; CacheBlk::State new_state = coherence->getNewState(pkt,old_state); - DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n", - pkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state); + if (old_state != new_state) + DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n", + pkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state); blk = tags->handleFill(blk, (MSHR*)pkt->senderState, new_state, writebacks, pkt); while (!writebacks.empty()) { @@ -531,6 +534,10 @@ Cache::probe(Packet * &pkt, bool update, CachePort int lat; BlkType *blk = tags->handleAccess(pkt, lat, writebacks, update); + DPRINTF(Cache, "%s %x %s blk_addr: %x\n", pkt->cmdString(), + pkt->getAddr() & (((ULL(1))<<48)-1), (blk) ? "hit" : "miss", + pkt->getAddr() & ~((Addr)blkSize - 1)); + if (!blk) { // Need to check for outstanding misses and writes Addr blk_addr = pkt->getAddr() & ~(blkSize - 1); @@ -637,6 +644,11 @@ Cache::probe(Packet * &pkt, bool update, CachePort busPkt->time = curTick; + DPRINTF(Cache, "Sending a atomic %s for %x blk_addr: %x\n", + busPkt->cmdString(), + busPkt->getAddr() & (((ULL(1))<<48)-1), + busPkt->getAddr() & ~((Addr)blkSize - 1)); + lat = memSidePort->sendAtomic(busPkt); //Be sure to flip the response to a request for coherence @@ -652,13 +664,26 @@ Cache::probe(Packet * &pkt, bool update, CachePort */ misses[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++; CacheBlk::State old_state = (blk) ? blk->status : 0; + CacheBlk::State new_state = coherence->getNewState(busPkt, old_state); + DPRINTF(Cache, "Receive response:%s for blk addr %x in state %i\n", + busPkt->cmdString(), + busPkt->getAddr() & (((ULL(1))<<48)-1), old_state); + if (old_state != new_state) + DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n", + busPkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state); + tags->handleFill(blk, busPkt, - coherence->getNewState(busPkt, old_state), + new_state, writebacks, pkt); + //Free the packet + delete busPkt; + // Handle writebacks if needed while (!writebacks.empty()){ - memSidePort->sendAtomic(writebacks.front()); + Packet *wbPkt = writebacks.front(); + memSidePort->sendAtomic(wbPkt); writebacks.pop_front(); + delete wbPkt; } return lat + hitLatency; } else { @@ -679,7 +704,7 @@ Cache::probe(Packet * &pkt, bool update, CachePort // Still need to change data in all locations. otherSidePort->sendFunctional(pkt); } - return curTick + lat; + return hitLatency; } fatal("Probe not handled.\n"); return 0; -- cgit v1.2.3