Check the response queue on functional accesses.
authorRon Dreslinski <rdreslin@umich.edu>
Thu, 12 Oct 2006 17:59:03 +0000 (13:59 -0400)
committerRon Dreslinski <rdreslin@umich.edu>
Thu, 12 Oct 2006 17:59:03 +0000 (13:59 -0400)
The response queue is not tying up an MSHR, should we change that or assume infinite storage for responses?

src/mem/cache/base_cache.cc:
src/mem/tport.cc:
    Add in functional check of retry queued packets.

--HG--
extra : convert_revision : 0cb40b3a96d37a5e9eec95312d660ec6a9ce526a

src/mem/cache/base_cache.cc
src/mem/tport.cc

index 71ea58416819f1e9b42516e7672ec41974a89cb2..4a4a81f7374fac7aa61d6273f81ea12e57b7d82f 100644 (file)
@@ -107,6 +107,42 @@ BaseCache::CachePort::recvAtomic(Packet *pkt)
 void
 BaseCache::CachePort::recvFunctional(Packet *pkt)
 {
+    //Check storage here first
+    list<Packet *>::iterator i = drainList.begin();
+    list<Packet *>::iterator end = drainList.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->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);
+            }
+        }
+    }
     cache->doFunctionalAccess(pkt, isCpuSide);
 }
 
index 456878d0a9d64b9dd39140c18a98d136cf67d411..50aab31c47654f7bd8c65a468528dc23f1831d6d 100644 (file)
 void
 SimpleTimingPort::recvFunctional(Packet *pkt)
 {
-    // just do an atomic access and throw away the returned latency
+    //First check queued events
+    std::list<Packet *>::iterator i = transmitList.begin();
+    std::list<Packet *>::iterator end = transmitList.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->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);
+            }
+        }
+    }
+    //Then just do an atomic access and throw away the returned latency
     recvAtomic(pkt);
 }