Fixes for some outstanding issues in the LSQ. It should now be able to retry. It...
authorKevin Lim <ktlim@umich.edu>
Fri, 9 Jun 2006 15:46:35 +0000 (11:46 -0400)
committerKevin Lim <ktlim@umich.edu>
Fri, 9 Jun 2006 15:46:35 +0000 (11:46 -0400)
src/cpu/o3/lsq_unit.hh:
    Handle being able to retry (untested but hopefully very close to working).

    Handle lock flag for LL/SC hack.  Hopefully the memory system will add in LL/SC soon.

    Better output message.
src/cpu/o3/lsq_unit_impl.hh:
    Handle being able to retry (untested but should be very close to working).

    Make SC's work (hopefully) while the memory system doesn't have a LL/SC implementation.

--HG--
extra : convert_revision : bffa721b21405c88a9c6b3d9b9080957f8a2638f

src/cpu/o3/lsq_unit.hh
src/cpu/o3/lsq_unit_impl.hh

index 21f48ce02a6d39718bdfc663efcd7448f82cf997..3123e246d195ee50114df76feb1dab0953100ad7 100644 (file)
@@ -213,9 +213,14 @@ class LSQUnit {
   private:
     void writeback(DynInstPtr &inst, PacketPtr pkt);
 
+    void storePostSend(Packet *pkt);
+
     /** Completes the store at the specified index. */
     void completeStore(int store_idx);
 
+    /** Handles doing the retry. */
+    void recvRetry();
+
     /** Increments the given store index (circular queue). */
     inline void incrStIdx(int &store_idx);
     /** Decrements the given store index (circular queue). */
@@ -399,6 +404,8 @@ class LSQUnit {
     /** The index of the above store. */
     int stallingLoadIdx;
 
+    PacketPtr sendingPkt;
+
     bool isStoreBlocked;
 
     /** Whether or not a load is blocked due to the memory system. */
@@ -504,7 +511,7 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
             "storeHead: %i addr: %#x\n",
             load_idx, store_idx, storeHead, req->getPaddr());
 
-#if 0
+#if FULL_SYSTEM
     if (req->getFlags() & LOCKED) {
         cpu->lockAddr = req->getPaddr();
         cpu->lockFlag = true;
@@ -559,7 +566,7 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
 
             DPRINTF(LSQUnit, "Forwarding from store idx %i to load to "
                     "addr %#x, data %#x\n",
-                    store_idx, req->getVaddr(), *(load_inst->memData));
+                    store_idx, req->getVaddr(), data);
 
             PacketPtr data_pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
             data_pkt->dataStatic(load_inst->memData);
index 62bb96610d7b71f294caf12072dd7fcf7b1b9d41..a768b021ce73e98b0b07e2467d348c5f800da820 100644 (file)
@@ -125,18 +125,7 @@ template <class Impl>
 void
 LSQUnit<Impl>::DcachePort::recvRetry()
 {
-    panic("Retry unsupported for now!");
-    // we shouldn't get a retry unless we have a packet that we're
-    // waiting to transmit
-/*
-    assert(cpu->dcache_pkt != NULL);
-    assert(cpu->_status == DcacheRetry);
-    PacketPtr tmp = cpu->dcache_pkt;
-    if (sendTiming(tmp)) {
-        cpu->_status = DcacheWaitResponse;
-        cpu->dcache_pkt = NULL;
-    }
-*/
+    lsq->recvRetry();
 }
 
 template <class Impl>
@@ -615,55 +604,34 @@ LSQUnit<Impl>::writebackStores()
                 req->getPaddr(), *(inst->memData),
                 storeQueue[storeWBIdx].inst->seqNum);
 
-        if (!dcachePort->sendTiming(data_pkt)) {
-            // Need to handle becoming blocked on a store.
-            isStoreBlocked = true;
-        } else {
-            if (isStalled() &&
-                storeQueue[storeWBIdx].inst->seqNum == stallingStoreIsn) {
-                DPRINTF(LSQUnit, "Unstalling, stalling store [sn:%lli] "
-                        "load idx:%i\n",
-                        stallingStoreIsn, stallingLoadIdx);
-                stalled = false;
-                stallingStoreIsn = 0;
-                iewStage->replayMemInst(loadQueue[stallingLoadIdx]);
-            }
-
-            if (!(req->getFlags() & LOCKED)) {
-                assert(!storeQueue[storeWBIdx].inst->isStoreConditional());
-                // Non-store conditionals do not need a writeback.
-                state->noWB = true;
-
-                // The store is basically completed at this time. This
-                // only works so long as the checker doesn't try to
-                // verify the value in memory for stores.
-                storeQueue[storeWBIdx].inst->setCompleted();
-                if (cpu->checker) {
-                    cpu->checker->tick(storeQueue[storeWBIdx].inst);
+        // @todo: Remove this SC hack once the memory system handles it.
+        if (req->getFlags() & LOCKED) {
+            if (req->getFlags() & UNCACHEABLE) {
+                req->setScResult(2);
+            } else {
+                if (cpu->lockFlag) {
+                    req->setScResult(1);
+                } else {
+                    req->setScResult(0);
+                    // Hack: Instantly complete this store.
+                    completeDataAccess(data_pkt);
+                    incrStIdx(storeWBIdx);
+                    continue;
                 }
             }
+        } else {
+            // Non-store conditionals do not need a writeback.
+            state->noWB = true;
+        }
 
-            if (data_pkt->result != Packet::Success) {
-                DPRINTF(LSQUnit,"D-Cache Write Miss on idx:%i!\n",
-                        storeWBIdx);
-
-                DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n",
-                        storeQueue[storeWBIdx].inst->seqNum);
-
-                //mshrSeqNums.push_back(storeQueue[storeWBIdx].inst->seqNum);
-
-                //DPRINTF(LSQUnit, "Added MSHR. count = %i\n",mshrSeqNums.size());
-
-                // @todo: Increment stat here.
-            } else {
-                DPRINTF(LSQUnit,"D-Cache: Write Hit on idx:%i !\n",
-                        storeWBIdx);
-
-                DPRINTF(Activity, "Active st accessing mem hit [sn:%lli]\n",
-                        storeQueue[storeWBIdx].inst->seqNum);
-            }
+        if (!dcachePort->sendTiming(data_pkt)) {
+            // Need to handle becoming blocked on a store.
+            isStoreBlocked = true;
 
-            incrStIdx(storeWBIdx);
+            assert(sendingPkt == NULL);
+            sendingPkt = data_pkt;
+        } else {
+            storePostSend(data_pkt);
         }
     }
 
@@ -767,6 +735,53 @@ LSQUnit<Impl>::squash(const InstSeqNum &squashed_num)
     }
 }
 
+template <class Impl>
+void
+LSQUnit<Impl>::storePostSend(Packet *pkt)
+{
+    if (isStalled() &&
+        storeQueue[storeWBIdx].inst->seqNum == stallingStoreIsn) {
+        DPRINTF(LSQUnit, "Unstalling, stalling store [sn:%lli] "
+                "load idx:%i\n",
+                stallingStoreIsn, stallingLoadIdx);
+        stalled = false;
+        stallingStoreIsn = 0;
+        iewStage->replayMemInst(loadQueue[stallingLoadIdx]);
+    }
+
+    if (!storeQueue[storeWBIdx].inst->isStoreConditional()) {
+        // The store is basically completed at this time. This
+        // only works so long as the checker doesn't try to
+        // verify the value in memory for stores.
+        storeQueue[storeWBIdx].inst->setCompleted();
+        if (cpu->checker) {
+            cpu->checker->tick(storeQueue[storeWBIdx].inst);
+        }
+    }
+
+    if (pkt->result != Packet::Success) {
+        DPRINTF(LSQUnit,"D-Cache Write Miss on idx:%i!\n",
+                storeWBIdx);
+
+        DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n",
+                storeQueue[storeWBIdx].inst->seqNum);
+
+        //mshrSeqNums.push_back(storeQueue[storeWBIdx].inst->seqNum);
+
+        //DPRINTF(LSQUnit, "Added MSHR. count = %i\n",mshrSeqNums.size());
+
+        // @todo: Increment stat here.
+    } else {
+        DPRINTF(LSQUnit,"D-Cache: Write Hit on idx:%i !\n",
+                storeWBIdx);
+
+        DPRINTF(Activity, "Active st accessing mem hit [sn:%lli]\n",
+                storeQueue[storeWBIdx].inst->seqNum);
+    }
+
+    incrStIdx(storeWBIdx);
+}
+
 template <class Impl>
 void
 LSQUnit<Impl>::writeback(DynInstPtr &inst, PacketPtr pkt)
@@ -839,6 +854,28 @@ LSQUnit<Impl>::completeStore(int store_idx)
     }
 }
 
+template <class Impl>
+void
+LSQUnit<Impl>::recvRetry()
+{
+    assert(sendingPkt != NULL);
+
+    if (isStoreBlocked) {
+        if (dcachePort->sendTiming(sendingPkt)) {
+            storePostSend(sendingPkt);
+            sendingPkt = NULL;
+            isStoreBlocked = false;
+        } else {
+            // Still blocked!
+        }
+    } else if (isLoadBlocked) {
+        DPRINTF(LSQUnit, "Loads squash themselves and all younger insts, "
+                "no need to resend packet.\n");
+    } else {
+        DPRINTF(LSQUnit, "Retry received but LSQ is no longer blocked.\n");
+    }
+}
+
 template <class Impl>
 inline void
 LSQUnit<Impl>::incrStIdx(int &store_idx)