diff options
author | Ron Dreslinski <rdreslin@umich.edu> | 2006-10-11 18:28:33 -0400 |
---|---|---|
committer | Ron Dreslinski <rdreslin@umich.edu> | 2006-10-11 18:28:33 -0400 |
commit | 567afbf6ce5b2d6fe573878c39679e56a1bf5d15 (patch) | |
tree | ae5caee54ed390314e88a6eaa1dcb988cad96556 /src/mem | |
parent | 03c42ea5904ea5f9f5e8d634f6bc61992abef746 (diff) | |
download | gem5-567afbf6ce5b2d6fe573878c39679e56a1bf5d15.tar.xz |
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
Diffstat (limited to 'src/mem')
-rw-r--r-- | src/mem/bus.cc | 17 | ||||
-rw-r--r-- | src/mem/bus.hh | 2 | ||||
-rw-r--r-- | src/mem/cache/cache_impl.hh | 43 | ||||
-rw-r--r-- | src/mem/packet.cc | 29 |
4 files changed, 76 insertions, 15 deletions
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<int> 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<int> 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<TagStore,Buffering,Coherence>::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<uint8_t>(), blk->data, blkSize); PacketList writebacks; @@ -324,8 +326,9 @@ Cache<TagStore,Buffering,Coherence>::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<TagStore,Buffering,Coherence>::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<TagStore,Buffering,Coherence>::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<TagStore,Buffering,Coherence>::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<TagStore,Buffering,Coherence>::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("<other>"); 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; } } |