diff options
Diffstat (limited to 'src/mem')
-rw-r--r-- | src/mem/cache/base_cache.cc | 2 | ||||
-rw-r--r-- | src/mem/cache/cache_impl.hh | 241 | ||||
-rw-r--r-- | src/mem/cache/coherence/uni_coherence.cc | 4 | ||||
-rw-r--r-- | src/mem/packet.cc | 3 | ||||
-rw-r--r-- | src/mem/packet.hh | 3 |
5 files changed, 128 insertions, 125 deletions
diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index 51b4ed55e..936a9c1fa 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -332,7 +332,7 @@ BaseCache::CacheEvent::process() pkt = cachePort->cache->getCoherencePacket(); MSHR* cshr = (MSHR*) pkt->senderState; bool success = cachePort->sendTiming(pkt); - cachePort->cache->sendResult(pkt, cshr, success); + cachePort->cache->sendCoherenceResult(pkt, cshr, success); cachePort->waitingOnRetry = !success; if (cachePort->waitingOnRetry) DPRINTF(CachePort, "%s now waiting on a retry\n", cachePort->name()); diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 214a495e0..b5d7e1960 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -526,6 +526,13 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, } } + if (!update && (pkt->isWrite() || (otherSidePort == cpuSidePort))) { + // Still need to change data in all locations. + otherSidePort->sendFunctional(pkt); + if (pkt->isRead() && pkt->result == Packet::Success) + return 0; + } + PacketList writebacks; int lat; BlkType *blk = tags->handleAccess(pkt, lat, writebacks, update); @@ -534,83 +541,48 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, 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); - - // There can only be one matching outstanding miss. - MSHR* mshr = missQueue->findMSHR(blk_addr); - - // There can be many matching outstanding writes. - std::vector<MSHR*> writes; - missQueue->findWrites(blk_addr, writes); - - if (!update) { - otherSidePort->sendFunctional(pkt); - - // Check for data in MSHR and writebuffer. - if (mshr) { - warn("Found outstanding miss on an non-update probe"); - MSHR::TargetList *targets = mshr->getTargetList(); - MSHR::TargetList::iterator i = targets->begin(); - MSHR::TargetList::iterator end = targets->end(); - for (; i != end; ++i) { - Packet * target = *i; - // If the target contains data, and it overlaps the - // probed request, need to update data - if (target->isWrite() && target->intersect(pkt)) { - uint8_t* pkt_data; - uint8_t* write_data; - int data_size; - if (target->getAddr() < pkt->getAddr()) { - int offset = pkt->getAddr() - target->getAddr(); - pkt_data = pkt->getPtr<uint8_t>(); - write_data = target->getPtr<uint8_t>() + offset; - data_size = target->getSize() - offset; - assert(data_size > 0); - if (data_size > pkt->getSize()) - data_size = pkt->getSize(); - } else { - int offset = target->getAddr() - pkt->getAddr(); - pkt_data = pkt->getPtr<uint8_t>() + offset; - write_data = target->getPtr<uint8_t>(); - data_size = pkt->getSize() - offset; - assert(data_size > pkt->getSize()); - if (data_size > target->getSize()) - data_size = target->getSize(); - } - - if (pkt->isWrite()) { - memcpy(pkt_data, write_data, data_size); - } else { - memcpy(write_data, pkt_data, data_size); - } - } - } - } - for (int i = 0; i < writes.size(); ++i) { - Packet * write = writes[i]->pkt; - if (write->intersect(pkt)) { - warn("Found outstanding write on an non-update probe"); + + // Need to check for outstanding misses and writes + Addr blk_addr = pkt->getAddr() & ~(blkSize - 1); + + // There can only be one matching outstanding miss. + MSHR* mshr = missQueue->findMSHR(blk_addr); + + // There can be many matching outstanding writes. + std::vector<MSHR*> writes; + missQueue->findWrites(blk_addr, writes); + + if (!update) { + // Check for data in MSHR and writebuffer. + if (mshr) { + warn("Found outstanding miss on an non-update probe"); + MSHR::TargetList *targets = mshr->getTargetList(); + MSHR::TargetList::iterator i = targets->begin(); + MSHR::TargetList::iterator end = targets->end(); + for (; i != end; ++i) { + Packet * target = *i; + // If the target contains data, and it overlaps the + // probed request, need to update data + if (target->isWrite() && target->intersect(pkt)) { uint8_t* pkt_data; uint8_t* write_data; int data_size; - if (write->getAddr() < pkt->getAddr()) { - int offset = pkt->getAddr() - write->getAddr(); + if (target->getAddr() < pkt->getAddr()) { + int offset = pkt->getAddr() - target->getAddr(); pkt_data = pkt->getPtr<uint8_t>(); - write_data = write->getPtr<uint8_t>() + offset; - data_size = write->getSize() - offset; + write_data = target->getPtr<uint8_t>() + offset; + data_size = target->getSize() - offset; assert(data_size > 0); if (data_size > pkt->getSize()) data_size = pkt->getSize(); } else { - int offset = write->getAddr() - pkt->getAddr(); + int offset = target->getAddr() - pkt->getAddr(); pkt_data = pkt->getPtr<uint8_t>() + offset; - write_data = write->getPtr<uint8_t>(); + write_data = target->getPtr<uint8_t>(); data_size = pkt->getSize() - offset; assert(data_size > pkt->getSize()); - if (data_size > write->getSize()) - data_size = write->getSize(); + if (data_size > target->getSize()) + data_size = target->getSize(); } if (pkt->isWrite()) { @@ -618,77 +590,108 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, } else { memcpy(write_data, pkt_data, data_size); } - } } - return 0; - } else { - // update the cache state and statistics - if (mshr || !writes.empty()){ - // Can't handle it, return pktuest unsatisfied. - panic("Atomic access ran into outstanding MSHR's or WB's!"); + } + for (int i = 0; i < writes.size(); ++i) { + Packet * write = writes[i]->pkt; + if (write->intersect(pkt)) { + warn("Found outstanding write on an non-update probe"); + uint8_t* pkt_data; + uint8_t* write_data; + int data_size; + if (write->getAddr() < pkt->getAddr()) { + int offset = pkt->getAddr() - write->getAddr(); + pkt_data = pkt->getPtr<uint8_t>(); + write_data = write->getPtr<uint8_t>() + offset; + data_size = write->getSize() - offset; + assert(data_size > 0); + if (data_size > pkt->getSize()) + data_size = pkt->getSize(); + } else { + int offset = write->getAddr() - pkt->getAddr(); + pkt_data = pkt->getPtr<uint8_t>() + offset; + write_data = write->getPtr<uint8_t>(); + data_size = pkt->getSize() - offset; + assert(data_size > pkt->getSize()); + if (data_size > write->getSize()) + data_size = write->getSize(); + } + + if (pkt->isWrite()) { + memcpy(pkt_data, write_data, data_size); + } else { + memcpy(write_data, pkt_data, data_size); + } + } - if (!pkt->req->isUncacheable()) { + } + } else if (!blk) { + // update the cache state and statistics + if (mshr || !writes.empty()){ + // Can't handle it, return pktuest unsatisfied. + panic("Atomic access ran into outstanding MSHR's or WB's!"); + } + if (!pkt->req->isUncacheable()) { // Fetch the cache block to fill - BlkType *blk = tags->findBlock(pkt); - Packet::Command temp_cmd = coherence->getBusCmd(pkt->cmd, - (blk)? blk->status : 0); + BlkType *blk = tags->findBlock(pkt); + Packet::Command temp_cmd = coherence->getBusCmd(pkt->cmd, + (blk)? blk->status : 0); - Packet * busPkt = new Packet(pkt->req,temp_cmd, -1, blkSize); + Packet * busPkt = new Packet(pkt->req,temp_cmd, -1, blkSize); - busPkt->allocate(); + busPkt->allocate(); - busPkt->time = curTick; + 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)); + 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); + lat = memSidePort->sendAtomic(busPkt); - //Be sure to flip the response to a request for coherence - if (busPkt->needsResponse()) { - busPkt->makeAtomicResponse(); - } + //Be sure to flip the response to a request for coherence + if (busPkt->needsResponse()) { + busPkt->makeAtomicResponse(); + } /* if (!(busPkt->flags & SATISFIED)) { - // blocked at a higher level, just return - return 0; - } +// blocked at a higher level, just return +return 0; +} */ 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, + 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) + 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, - new_state, - writebacks, pkt); - //Free the packet - delete busPkt; - - // Handle writebacks if needed - while (!writebacks.empty()){ - Packet *wbPkt = writebacks.front(); - memSidePort->sendAtomic(wbPkt); - writebacks.pop_front(); - delete wbPkt; - } - return lat + hitLatency; - } else { - return memSidePort->sendAtomic(pkt); + tags->handleFill(blk, busPkt, + new_state, + writebacks, pkt); + //Free the packet + delete busPkt; + + // Handle writebacks if needed + while (!writebacks.empty()){ + Packet *wbPkt = writebacks.front(); + memSidePort->sendAtomic(wbPkt); + writebacks.pop_front(); + delete wbPkt; } + return lat + hitLatency; + } else { + return memSidePort->sendAtomic(pkt); } } else { // There was a cache hit. @@ -698,12 +701,8 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, writebacks.pop_front(); } - if (update) { - hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++; - } else if (pkt->isWrite()) { - // Still need to change data in all locations. - otherSidePort->sendFunctional(pkt); - } + hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++; + return hitLatency; } fatal("Probe not handled.\n"); diff --git a/src/mem/cache/coherence/uni_coherence.cc b/src/mem/cache/coherence/uni_coherence.cc index 751de4801..464266a29 100644 --- a/src/mem/cache/coherence/uni_coherence.cc +++ b/src/mem/cache/coherence/uni_coherence.cc @@ -53,11 +53,11 @@ UniCoherence::sendResult(Packet * &pkt, MSHR* cshr, bool success) if (success) { bool unblock = cshrs.isFull(); - cshrs.markInService(cshr); +// cshrs.markInService(cshr); + cshrs.deallocate(cshr); if (!cshrs.havePending()) { cache->clearSlaveRequest(Request_Coherence); } - cshrs.deallocate(cshr); if (unblock) { //since CSHRs are always used as buffers, should always get rid of one assert(!cshrs.isFull()); diff --git a/src/mem/packet.cc b/src/mem/packet.cc index 64c65dcca..a16e590e3 100644 --- a/src/mem/packet.cc +++ b/src/mem/packet.cc @@ -51,6 +51,7 @@ 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 WriteInvalidateRespString("WriteInvalidateResp"); static const std::string UpgradeReqString("UpgradeReq"); static const std::string ReadExReqString("ReadExReq"); static const std::string ReadExRespString("ReadExResp"); @@ -71,6 +72,7 @@ Packet::cmdString() const case HardPFResp: return HardPFRespString; case InvalidateReq: return InvalidateReqString; case WriteInvalidateReq:return WriteInvalidateReqString; + case WriteInvalidateResp:return WriteInvalidateRespString; case UpgradeReq: return UpgradeReqString; case ReadExReq: return ReadExReqString; case ReadExResp: return ReadExRespString; @@ -93,6 +95,7 @@ Packet::cmdIdxToString(Packet::Command idx) case HardPFResp: return HardPFRespString; case InvalidateReq: return InvalidateReqString; case WriteInvalidateReq:return WriteInvalidateReqString; + case WriteInvalidateResp:return WriteInvalidateRespString; case UpgradeReq: return UpgradeReqString; case ReadExReq: return ReadExReqString; case ReadExResp: return ReadExRespString; diff --git a/src/mem/packet.hh b/src/mem/packet.hh index 319a4e534..f6197885e 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -204,7 +204,8 @@ class Packet InvalidateReq = IsInvalidate | IsRequest, WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest | HasData | NeedsResponse, - WriteInvalidateResp = IsWrite | IsInvalidate | IsRequest | NeedsResponse, + WriteInvalidateResp = IsWrite | IsInvalidate | IsRequest | NeedsResponse + | IsResponse, UpgradeReq = IsInvalidate | IsRequest | IsUpgrade, ReadExReq = IsRead | IsInvalidate | IsRequest | NeedsResponse, ReadExResp = IsRead | IsInvalidate | IsResponse |