refactor code for the packet, get rid of packet_impl.hh
[gem5.git] / src / mem / cache / cache_impl.hh
index b5d7e1960ec7277be07950dd9ef84a8a2e33e103..ea30dbba67d7cb62b9d52426751e05e97a86f0b0 100644 (file)
@@ -373,10 +373,15 @@ Cache<TagStore,Buffering,Coherence>::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<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update,
                         pkt_data = pkt->getPtr<uint8_t>() + offset;
                         write_data = target->getPtr<uint8_t>();
                         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<TagStore,Buffering,Coherence>::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<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update,
                     pkt_data = pkt->getPtr<uint8_t>() + offset;
                     write_data = write->getPtr<uint8_t>();
                     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<TagStore,Buffering,Coherence>::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<class TagStore, class Buffering, class Coherence>
 Tick
 Cache<TagStore,Buffering,Coherence>::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;
 }