X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmem%2Fcache%2Fcache_impl.hh;h=ea30dbba67d7cb62b9d52426751e05e97a86f0b0;hb=7245d4530d0c8367fa7b1adadcb55e1e8bd466e7;hp=b5d7e1960ec7277be07950dd9ef84a8a2e33e103;hpb=9cf063eb8e0b9d4af40f0e8fe609f9135be899f5;p=gem5.git diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index b5d7e1960..ea30dbba6 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -373,10 +373,15 @@ Cache::snoop(Packet * &pkt) //Revisit this for multi level coherence return; } + + //Send a timing (true) invalidate up if the protocol calls for it + coherence->propogateInvalidate(pkt, true); + Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1)); BlkType *blk = tags->findBlock(pkt); MSHR *mshr = missQueue->findMSHR(blk_addr); - if (coherence->hasProtocol()) { //@todo Move this into handle bus req + if (coherence->hasProtocol() || pkt->isInvalidate()) { + //@todo Move this into handle bus req //If we find an mshr, and it is in service, we need to NACK or //invalidate if (mshr) { @@ -580,7 +585,7 @@ Cache::probe(Packet * &pkt, bool update, pkt_data = pkt->getPtr() + offset; write_data = target->getPtr(); data_size = pkt->getSize() - offset; - assert(data_size > pkt->getSize()); + assert(data_size >= pkt->getSize()); if (data_size > target->getSize()) data_size = target->getSize(); } @@ -588,6 +593,8 @@ Cache::probe(Packet * &pkt, bool update, if (pkt->isWrite()) { memcpy(pkt_data, write_data, data_size); } else { + pkt->flags |= SATISFIED; + pkt->result = Packet::Success; memcpy(write_data, pkt_data, data_size); } } @@ -613,7 +620,7 @@ Cache::probe(Packet * &pkt, bool update, pkt_data = pkt->getPtr() + offset; write_data = write->getPtr(); data_size = pkt->getSize() - offset; - assert(data_size > pkt->getSize()); + assert(data_size >= pkt->getSize()); if (data_size > write->getSize()) data_size = write->getSize(); } @@ -621,11 +628,20 @@ Cache::probe(Packet * &pkt, bool update, if (pkt->isWrite()) { memcpy(pkt_data, write_data, data_size); } else { + pkt->flags |= SATISFIED; + pkt->result = Packet::Success; memcpy(write_data, pkt_data, data_size); } } } + if (pkt->isRead() + && pkt->result != Packet::Success + && otherSidePort == memSidePort) { + otherSidePort->sendFunctional(pkt); + assert(pkt->result == Packet::Success); + } + return 0; } else if (!blk) { // update the cache state and statistics if (mshr || !writes.empty()){ @@ -713,24 +729,27 @@ template Tick 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) { - DPRINTF(Cache, "Cache snooped a %s request for addr %x and " - "now supplying data, new state is %i\n", - pkt->cmdString(), blk_addr, new_state); + //Send a atomic (false) invalidate up if the protocol calls for it + coherence->propogateInvalidate(pkt, false); + + 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) { + DPRINTF(Cache, "Cache snooped a %s request for addr %x and " + "now supplying data, new state is %i\n", + pkt->cmdString(), blk_addr, new_state); tags->handleSnoop(blk, new_state, pkt); return hitLatency; - } - if (blk) - DPRINTF(Cache, "Cache snooped a %s request for addr %x, " - "new state is %i\n", + } + 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; + tags->handleSnoop(blk, new_state); + return 0; }