inorder-stc: update interface to handle store conditionals
authorKorey Sewell <ksewell@umich.edu>
Tue, 12 May 2009 19:01:15 +0000 (15:01 -0400)
committerKorey Sewell <ksewell@umich.edu>
Tue, 12 May 2009 19:01:15 +0000 (15:01 -0400)
src/cpu/inorder/cpu.cc
src/cpu/inorder/cpu.hh
src/cpu/inorder/inorder_dyn_inst.cc
src/cpu/inorder/resource.hh
src/cpu/inorder/resources/cache_unit.cc
src/cpu/inorder/resources/cache_unit.hh

index e17d82041c36e131fde80fd2d842415ec64bc962..51f763112a14b190e31a87176fdae0ff5ef90b40 100644 (file)
@@ -1258,10 +1258,10 @@ InOrderCPU::read(DynInstPtr inst)
 }
 
 Fault
-InOrderCPU::write(DynInstPtr inst)
+InOrderCPU::write(DynInstPtr inst, uint64_t *res)
 {
     Resource *mem_res = resPool->getResource(dataPortIdx);
-    return mem_res->doDataAccess(inst);
+    return mem_res->doDataAccess(inst, res);
 }
 
 void
index 9426171c127eccfa3617dba8de025640ca83e641..e3bfbb7f0952b5c8b26fdd8c91ea71c90b66e998 100644 (file)
@@ -495,7 +495,7 @@ class InOrderCPU : public BaseCPU
     /** Forwards an instruction write. to the appropriate data
      *  resource (indexes into Resource Pool thru "dataPortIdx")
      */
-    Fault write(DynInstPtr inst);
+    Fault write(DynInstPtr inst, uint64_t *res = NULL);
 
     /** Forwards an instruction prefetch to the appropriate data
      *  resource (indexes into Resource Pool thru "dataPortIdx")
index 9609db22fa66f155df99602d3d192d0ce1b16f49..3983821e7c8d1e9e402b0af2ef02c38c32e1da2e 100644 (file)
@@ -657,7 +657,7 @@ InOrderDynInst::write(T data, Addr addr, unsigned flags, uint64_t *res)
 
     DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting store data to %#x.\n",
             threadNumber, seqNum, memData);
-    return cpu->write(this);
+    return cpu->write(this, res);
 }
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
index 0c0aad758c3f0e4a527ae5e3d3b275c502c708d3..0378c0f503b72f8ba4acc065a0b83062d581ef3a 100644 (file)
@@ -140,7 +140,7 @@ class Resource {
      *  if instruction is actually in resource before
      *  trying to do access.Needs to be defined for derived units.
      */
-    virtual Fault doDataAccess(DynInstPtr inst)
+    virtual Fault doDataAccess(DynInstPtr inst, uint64_t *res=NULL)
     { panic("doDataAccess undefined for %s", name()); return NoFault; }
 
     virtual void prefetch(DynInstPtr inst)
index 4ac1fb77e1bc8f700538b19470bba9a4a41ac654..c5d35dfb3dc5622c3cf2fc3e3ad8ec47ec29599b 100644 (file)
@@ -175,7 +175,7 @@ CacheUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
                 inst->readTid(), req_size, inst->seqNum, inst->getMemAddr());
     } else if (sched_entry->cmd == InitiateFetch){
         pkt_cmd = MemCmd::ReadReq;
-        req_size = sizeof(MachInst); //@TODO: mips16e
+        req_size = sizeof(MachInst);
 
         DPRINTF(InOrderCachePort,
                 "[tid:%i]: %i byte Fetch request from [sn:%i] for addr %08p\n",
@@ -356,7 +356,7 @@ CacheUnit::writeHint(DynInstPtr inst)
 }
 
 Fault
-CacheUnit::doDataAccess(DynInstPtr inst)
+CacheUnit::doDataAccess(DynInstPtr inst, uint64_t *write_res)
 {
     Fault fault = NoFault;
     int tid = 0;
@@ -367,6 +367,17 @@ CacheUnit::doDataAccess(DynInstPtr inst)
         = dynamic_cast<CacheReqPtr>(reqMap[inst->getCurResSlot()]);
     assert(cache_req);
 
+    // Check for LL/SC and if so change command
+    if (cache_req->memReq->isLLSC() && cache_req->pktCmd == MemCmd::ReadReq) {
+        cache_req->pktCmd = MemCmd::LoadLockedReq;
+    }
+
+    if (cache_req->pktCmd == MemCmd::WriteReq) {
+        cache_req->pktCmd =
+            cache_req->memReq->isSwap() ? MemCmd::SwapReq :
+            (cache_req->memReq->isLLSC() ? MemCmd::StoreCondReq : MemCmd::WriteReq);
+    }
+
     cache_req->dataPkt = new CacheReqPacket(cache_req, cache_req->pktCmd,
                                             Packet::Broadcast);
 
@@ -374,6 +385,11 @@ CacheUnit::doDataAccess(DynInstPtr inst)
         cache_req->dataPkt->dataStatic(cache_req->reqData);
     } else if (cache_req->dataPkt->isWrite()) {
         cache_req->dataPkt->dataStatic(&cache_req->inst->storeData);
+
+        if (cache_req->memReq->isCondSwap()) {
+            assert(write_res);
+            cache_req->memReq->setExtraData(*write_res);
+        }
     }
 
     cache_req->dataPkt->time = curTick;
@@ -382,7 +398,7 @@ CacheUnit::doDataAccess(DynInstPtr inst)
 
     Request *memReq = cache_req->dataPkt->req;
 
-    if (cache_req->dataPkt->isWrite() && memReq->isLLSC()) {
+    if (cache_req->dataPkt->isWrite() && cache_req->memReq->isLLSC()) {
         assert(cache_req->inst->isStoreConditional());
         DPRINTF(InOrderCachePort, "Evaluating Store Conditional access\n");
         do_access = TheISA::handleLockedWrite(cpu, memReq);
@@ -392,11 +408,7 @@ CacheUnit::doDataAccess(DynInstPtr inst)
             "[tid:%i] [sn:%i] attempting to access cache\n",
             tid, inst->seqNum);
 
-    //@TODO: If you want to ignore failed store conditional accesses, then
-    //       enable this. However, this might skew memory stats because
-    //       the failed store conditional access will get ignored.
-    // - Remove optionality here ...
-    if (1/*do_access*/) {
+    if (do_access) {
         if (!cachePort->sendTiming(cache_req->dataPkt)) {
             DPRINTF(InOrderCachePort,
                     "[tid:%i] [sn:%i] is waiting to retry request\n",
@@ -431,13 +443,7 @@ CacheUnit::doDataAccess(DynInstPtr inst)
                 "[tid:%i]: T%i Ignoring Failed Store Conditional Access\n",
                 tid, tid);
 
-        cache_req->dataPkt->req->setExtraData(0);
-
         processCacheCompletion(cache_req->dataPkt);
-
-        // Automatically set these since we ignored the memory access
-        //cache_req->setMemAccPending(false);
-        //cache_req->setMemAccCompleted();
     } else {
         // Make cache request again since access due to
         // inability to access
@@ -535,7 +541,7 @@ CacheUnit::processCacheCompletion(PacketPtr pkt)
                     TheISA::handleLockedRead(cpu, cache_pkt->req);
                 }
 
-                // @TODO: Hardcoded to for load instructions. Assumes that
+                // @NOTE: Hardcoded to for load instructions. Assumes that
                 // the dest. idx 0 is always where the data is loaded to.
                 DPRINTF(InOrderCachePort,
                         "[tid:%u]: [sn:%i]: Data loaded was: %08p\n",
index 06ccf3bec7ff6281d867a5debc3d3f5d92dac880..226a35a525124a0e241c2486782625979b8c680e 100644 (file)
@@ -162,7 +162,7 @@ class CacheUnit : public Resource
     /** Read/Write on behalf of an instruction.
      *  curResSlot needs to be a valid value in instruction.
      */
-    Fault doDataAccess(DynInstPtr inst);
+    Fault doDataAccess(DynInstPtr inst, uint64_t *write_result=NULL);
 
     void prefetch(DynInstPtr inst);
 
@@ -245,6 +245,8 @@ class CacheRequest : public ResourceRequest
             memReq = inst->dataMemReq;
         }
 
+        //@ Only matters for Fetch / Read requests
+        //  Don't allocate for Writes!
         reqData = new uint8_t[req_size];
         retryPkt = NULL;
     }