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/bus.cc | 17 +++++++++++++---- src/mem/bus.hh | 2 +- src/mem/cache/cache_impl.hh | 43 ++++++++++++++++++++++++++++++++++--------- src/mem/packet.cc | 29 ++++++++++++++++++++++++++++- 4 files changed, 76 insertions(+), 15 deletions(-) (limited to 'src/mem') diff --git a/src/mem/bus.cc b/src/mem/bus.cc index 3998666c7..b34944ed7 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -293,16 +293,22 @@ Bus::findSnoopPorts(Addr addr, int id) return ports; } -void +Tick Bus::atomicSnoop(Packet *pkt) { std::vector ports = findSnoopPorts(pkt->getAddr(), pkt->getSrc()); + Tick response_time = 0; while (!ports.empty()) { - interfaces[ports.back()]->sendAtomic(pkt); + Tick response = interfaces[ports.back()]->sendAtomic(pkt); + if (response) { + assert(!response_time); //Multiple responders + response_time = response; + } ports.pop_back(); } + return response_time; } void @@ -341,8 +347,11 @@ Bus::recvAtomic(Packet *pkt) DPRINTF(Bus, "recvAtomic: packet src %d dest %d addr 0x%x cmd %s\n", pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString()); assert(pkt->getDest() == Packet::Broadcast); - atomicSnoop(pkt); - return findPort(pkt->getAddr(), pkt->getSrc())->sendAtomic(pkt); + Tick snoopTime = atomicSnoop(pkt); + if (snoopTime) + return snoopTime; //Snoop satisfies it + else + return findPort(pkt->getAddr(), pkt->getSrc())->sendAtomic(pkt); } /** Function called by the port when the bus is receiving a Functional diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 3d0d07a7f..a168c3c49 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -107,7 +107,7 @@ class Bus : public MemObject std::vector findSnoopPorts(Addr addr, int id); /** Snoop all relevant ports atomicly. */ - void atomicSnoop(Packet *pkt); + Tick atomicSnoop(Packet *pkt); /** Snoop all relevant ports functionally. */ void functionalSnoop(Packet *pkt); 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; diff --git a/src/mem/packet.cc b/src/mem/packet.cc index 7b8fa4a96..4758fda89 100644 --- a/src/mem/packet.cc +++ b/src/mem/packet.cc @@ -39,9 +39,18 @@ static const std::string ReadReqString("ReadReq"); static const std::string WriteReqString("WriteReq"); -static const std::string WriteReqNoAckString("WriteReqNoAck"); +static const std::string WriteReqNoAckString("WriteReqNoAck|Writeback"); static const std::string ReadRespString("ReadResp"); static const std::string WriteRespString("WriteResp"); +static const std::string SoftPFReqString("SoftPFReq"); +static const std::string SoftPFRespString("SoftPFResp"); +static const std::string HardPFReqString("HardPFReq"); +static const std::string HardPFRespString("HardPFResp"); +static const std::string InvalidateReqString("InvalidateReq"); +static const std::string WriteInvalidateReqString("WriteInvalidateReq"); +static const std::string UpgradeReqString("UpgradeReq"); +static const std::string ReadExReqString("ReadExReq"); +static const std::string ReadExRespString("ReadExResp"); static const std::string OtherCmdString(""); const std::string & @@ -53,6 +62,15 @@ Packet::cmdString() const case WriteReqNoAck: return WriteReqNoAckString; case ReadResp: return ReadRespString; case WriteResp: return WriteRespString; + case SoftPFReq: return SoftPFReqString; + case SoftPFResp: return SoftPFRespString; + case HardPFReq: return HardPFReqString; + case HardPFResp: return HardPFRespString; + case InvalidateReq: return InvalidateReqString; + case WriteInvalidateReq:return WriteInvalidateReqString; + case UpgradeReq: return UpgradeReqString; + case ReadExReq: return ReadExReqString; + case ReadExResp: return ReadExRespString; default: return OtherCmdString; } } @@ -66,6 +84,15 @@ Packet::cmdIdxToString(Packet::Command idx) case WriteReqNoAck: return WriteReqNoAckString; case ReadResp: return ReadRespString; case WriteResp: return WriteRespString; + case SoftPFReq: return SoftPFReqString; + case SoftPFResp: return SoftPFRespString; + case HardPFReq: return HardPFReqString; + case HardPFResp: return HardPFRespString; + case InvalidateReq: return InvalidateReqString; + case WriteInvalidateReq:return WriteInvalidateReqString; + case UpgradeReq: return UpgradeReqString; + case ReadExReq: return ReadExReqString; + case ReadExResp: return ReadExRespString; default: return OtherCmdString; } } -- cgit v1.2.3