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/base_cache.hh | 2 -- src/mem/cache/cache.hh | 4 ++-- src/mem/cache/cache_impl.hh | 58 ++++++++++++++++++++++----------------------- src/mem/packet.hh | 14 ++++++++++- 4 files changed, 44 insertions(+), 34 deletions(-) (limited to 'src/mem') diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh index 49999dcb4..19cfe1335 100644 --- a/src/mem/cache/base_cache.hh +++ b/src/mem/cache/base_cache.hh @@ -515,8 +515,6 @@ class BaseCache : public MemObject */ void respond(Packet *pkt, Tick time) { - pkt->makeTimingResponse(); - pkt->result = Packet::Success; CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt); reqCpu->schedule(time); } diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index 989b8743e..4b8870c95 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -251,7 +251,7 @@ class Cache : public BaseCache * request. * @return The estimated completion time. */ - Tick probe(Packet * &pkt, bool update); + Tick probe(Packet * &pkt, bool update, CachePort * otherSidePort); /** * Snoop for the provided request in the cache and return the estimated @@ -262,7 +262,7 @@ class Cache : public BaseCache * request. * @return The estimated completion time. */ - Tick snoopProbe(Packet * &pkt, bool update); + Tick snoopProbe(Packet * &pkt); }; #endif // __CACHE_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; } diff --git a/src/mem/packet.hh b/src/mem/packet.hh index c7d28010c..be9bf5f57 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -312,7 +312,7 @@ class Packet * for returning as a response to that request. Used for timing * accesses only. For atomic and functional accesses, the * request packet is always implicitly passed back *without* - * modifying the command or destination fields, so this function + * modifying the destination fields, so this function * should not be called. */ void makeTimingResponse() { assert(needsResponse()); @@ -325,6 +325,18 @@ class Packet srcValid = false; } + /** Take a request packet and modify it in place to be suitable + * for returning as a response to that request. + */ + void makeAtomicResponse() { + assert(needsResponse()); + assert(isRequest()); + int icmd = (int)cmd; + icmd &= ~(IsRequest); + icmd |= IsResponse; + cmd = (Command)icmd; + } + /** Take a request packet that has been returned as NACKED and modify it so * that it can be sent out again. Only packets that need a response can be * NACKED, so verify that that is true. */ -- cgit v1.2.3