cpu, o3: consider split requests for LSQ checksnoop operations
authorHongil Yoon <ongal@cs.wisc.edu>
Tue, 15 Sep 2015 13:14:06 +0000 (08:14 -0500)
committerHongil Yoon <ongal@cs.wisc.edu>
Tue, 15 Sep 2015 13:14:06 +0000 (08:14 -0500)
This patch enables instructions in LSQ to track two physical addresses for
corresponding two split requests. Later, the information is used in
checksnoop() to search for/invalidate the corresponding LD instructions.

The current implementation has kept track of only the physical address that is
referenced by the first split request. Thus, for checksnoop(), the line
accessed by the second request has not been considered, causing potential
correctness issues.

Committed by: Nilay Vaish <nilay@cs.wisc.edu>

src/cpu/base_dyn_inst.hh
src/cpu/base_dyn_inst_impl.hh
src/cpu/o3/iew_impl.hh
src/cpu/o3/lsq_unit_impl.hh

index aae3af495e3992d0f30e1c4fa482b94a44aac523..c2ef253a78ac70fe6115f8922d07da6611493d09 100644 (file)
@@ -215,7 +215,12 @@ class BaseDynInst : public ExecContext, public RefCounted
     Addr effAddr;
 
     /** The effective physical address. */
-    Addr physEffAddr;
+    Addr physEffAddrLow;
+
+    /** The effective physical address
+     *  of the second request for a split request
+     */
+    Addr physEffAddrHigh;
 
     /** The memory request flags (from translation). */
     unsigned memReqFlags;
@@ -1056,7 +1061,15 @@ BaseDynInst<Impl>::finishTranslation(WholeTranslationState *state)
     instFlags[IsStrictlyOrdered] = state->isStrictlyOrdered();
 
     if (fault == NoFault) {
-        physEffAddr = state->getPaddr();
+        // save Paddr for a single req
+        physEffAddrLow = state->getPaddr();
+
+        // case for the request that has been split
+        if (state->isSplit) {
+          physEffAddrLow = state->sreqLow->getPaddr();
+          physEffAddrHigh = state->sreqHigh->getPaddr();
+        }
+
         memReqFlags = state->getFlags();
 
         if (state->mainReq->isCondSwap()) {
index 976e9ceb0726bc340bd8b1bfb913218066eb5a90..f55bd8ed5395f56adeac3203839044343d5d7f48 100644 (file)
@@ -88,7 +88,8 @@ BaseDynInst<Impl>::initVars()
 {
     memData = NULL;
     effAddr = 0;
-    physEffAddr = 0;
+    physEffAddrLow = 0;
+    physEffAddrHigh = 0;
     readyRegs = 0;
     memReqFlags = 0;
 
index 730eb0cfe4931973d4088884ecd7c0ccdbc67fb5..29596db092bad45e439b44fdd185374ef0d84191 100644 (file)
@@ -1347,7 +1347,7 @@ DefaultIEW<Impl>::executeInsts()
                 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: %s "
                         "[sn:%lli], inst PC: %s [sn:%lli]. Addr is: %#x.\n",
                         violator->pcState(), violator->seqNum,
-                        inst->pcState(), inst->seqNum, inst->physEffAddr);
+                        inst->pcState(), inst->seqNum, inst->physEffAddrLow);
 
                 fetchRedirect[tid] = true;
 
@@ -1370,7 +1370,7 @@ DefaultIEW<Impl>::executeInsts()
                 DPRINTF(IEW, "LDSTQ detected a violation.  Violator PC: "
                         "%s, inst PC: %s.  Addr is: %#x.\n",
                         violator->pcState(), inst->pcState(),
-                        inst->physEffAddr);
+                        inst->physEffAddrLow);
                 DPRINTF(IEW, "Violation will not be handled because "
                         "already squashing\n");
 
index 3019e80d27d05c5bf8d2c518045fabede5455204..0377faffa1e43672109c2ea8e1e95c4e886e06e6 100644 (file)
@@ -453,10 +453,13 @@ LSQUnit<Impl>::checkSnoop(PacketPtr pkt)
 
     DynInstPtr ld_inst = loadQueue[load_idx];
     if (ld_inst) {
-        Addr load_addr = ld_inst->physEffAddr & cacheBlockMask;
+        Addr load_addr_low = ld_inst->physEffAddrLow & cacheBlockMask;
+        Addr load_addr_high = ld_inst->physEffAddrHigh & cacheBlockMask;
+
         // Check that this snoop didn't just invalidate our lock flag
-        if (ld_inst->effAddrValid() && load_addr == invalidate_addr &&
-            ld_inst->memReqFlags & Request::LLSC)
+        if (ld_inst->effAddrValid() && (load_addr_low == invalidate_addr
+                                        || load_addr_high == invalidate_addr)
+            && ld_inst->memReqFlags & Request::LLSC)
             TheISA::handleLockedSnoopHit(ld_inst.get());
     }
 
@@ -476,11 +479,14 @@ LSQUnit<Impl>::checkSnoop(PacketPtr pkt)
             continue;
         }
 
-        Addr load_addr = ld_inst->physEffAddr & cacheBlockMask;
+        Addr load_addr_low = ld_inst->physEffAddrLow & cacheBlockMask;
+        Addr load_addr_high = ld_inst->physEffAddrHigh & cacheBlockMask;
+
         DPRINTF(LSQUnit, "-- inst [sn:%lli] load_addr: %#x to pktAddr:%#x\n",
-                    ld_inst->seqNum, load_addr, invalidate_addr);
+                    ld_inst->seqNum, load_addr_low, invalidate_addr);
 
-        if (load_addr == invalidate_addr || force_squash) {
+        if ((load_addr_low == invalidate_addr
+             || load_addr_high == invalidate_addr) || force_squash) {
             if (needsTSO) {
                 // If we have a TSO system, as all loads must be ordered with
                 // all other loads, this load as well as *all* subsequent loads