inorder: SE mode TLB faults
authorKorey Sewell <ksewell@umich.edu>
Mon, 20 Jun 2011 01:43:42 +0000 (21:43 -0400)
committerKorey Sewell <ksewell@umich.edu>
Mon, 20 Jun 2011 01:43:42 +0000 (21:43 -0400)
handle them like we do in FS mode, by blocking the TLB until the fault
is handled by the fault->invoke()

src/cpu/inorder/resource.cc
src/cpu/inorder/resources/cache_unit.cc
src/cpu/inorder/resources/cache_unit.hh
src/cpu/inorder/resources/use_def.cc

index dfca83a8f8b7f6d9f08fc47af923956b9dcaca3e..d2327795ec2b81824c1b2eeb7e1161f02e36f5f6 100644 (file)
@@ -46,7 +46,8 @@ using namespace std;
 Resource::Resource(string res_name, int res_id, int res_width,
                    int res_latency, InOrderCPU *_cpu)
     : resName(res_name), id(res_id),
-      width(res_width), latency(res_latency), cpu(_cpu)
+      width(res_width), latency(res_latency), cpu(_cpu),
+      resourceEvent(NULL)
 {
     reqs.resize(width);
 
@@ -75,15 +76,13 @@ Resource::init()
     // If the resource has a zero-cycle (no latency)
     // function, then no reason to have events
     // that will process them for the right tick
-    if (latency > 0) {
-        resourceEvent = new ResourceEvent[width];
-    } else {
-        resourceEvent = NULL;
-    }
+    if (latency > 0)
+      resourceEvent = new ResourceEvent[width];
+
+
+    for (int i = 0; i < width; i++)
+      reqs[i] = new ResourceRequest(this);
 
-    for (int i = 0; i < width; i++) {
-        reqs[i] = new ResourceRequest(this);
-    }
 
     initSlots();
 }
index 350e2d1dd81eb735b99937d8fe78aafddc6b49be..8b487dd3f3d2bcf38db190180ffacacf74fc8eaf 100644 (file)
@@ -178,10 +178,6 @@ CacheUnit::init()
         reqs[i] = new CacheRequest(this);
     }
 
-    // Currently Used to Model TLB Latency. Eventually
-    // Switch to Timing TLB translations.
-    resourceEvent = new CacheUnitEvent[width];
-
     cacheBlkSize = this->cachePort->peerBlockSize();
     cacheBlkMask = cacheBlkSize  - 1;
 
@@ -433,30 +429,22 @@ CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
     ThreadContext *tc = cpu->thread[tid]->getTC();
     PCState old_pc = tc->pcState();
     tc->pcState() = inst->pcState();
+
     inst->fault =
         _tlb->translateAtomic(cache_req->memReq, tc, tlb_mode);
     tc->pcState() = old_pc;
 
     if (inst->fault != NoFault) {
         DPRINTF(InOrderTLB, "[tid:%i]: %s encountered while translating "
-                "addr:%08p for [sn:%i].\n", tid, inst->fault->name(),
+                "addr:%08p for [sn:%i].\n", tid, tlb_fault->name(),
                 cache_req->memReq->getVaddr(), inst->seqNum);
 
         tlbBlocked[tid] = true;
         tlbBlockSeqNum[tid] = inst->seqNum;
 
-#if !FULL_SYSTEM
-        unsigned stage_num = cache_req->getStageNum();
-
-        cpu->pipelineStage[stage_num]->setResStall(cache_req, tid);
-        cache_req->tlbStall = true;
-
-        // schedule a time to process the tlb miss.
-        // latency hardcoded to 1 (for now), but will be updated
-        // when timing translation gets added in
-        unsigned slot_idx = cache_req->getSlot();
-        scheduleEvent(slot_idx, 1);
-#endif
+        // Make sure nothing gets executed until after this faulting
+        // instruction gets handled.
+        inst->setSerializeAfter();
 
         // Mark it as complete so it can pass through next stage.
         // Fault Handling will happen at commit/graduation
@@ -467,8 +455,15 @@ CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
                 cache_req->memReq->getVaddr(),
                 cache_req->memReq->getPaddr());
     }
+}
 
+#if !FULL_SYSTEM
+void
+CacheUnit::trap(Fault fault, ThreadID tid, DynInstPtr inst)
+{
+    tlbBlocked[tid] = false;
 }
+#endif
 
 Fault
 CacheUnit::read(DynInstPtr inst, Addr addr,
@@ -703,6 +698,14 @@ CacheUnit::execute(int slot_num)
         return;
     }
 
+    if (inst->isSquashed()) {
+        DPRINTF(InOrderCachePort,
+                "[tid:%i]: [sn:%i]: Detected squashed instruction "
+                "next stage.\n", inst->readTid(), inst->seqNum);
+        finishCacheUnitReq(inst, cache_req);
+        return;
+    }
+
 #if TRACING_ON
     ThreadID tid = inst->readTid();
     std::string acc_type = "write";
index 611ab62f25afc8f2ca15f47a52df58093c3dc441..f74a9136d3c5f818fd8cd50d082611f50703a4c5 100644 (file)
@@ -157,6 +157,9 @@ class CacheUnit : public Resource
 
     bool processSquash(CacheReqPacket *cache_pkt);
 
+#if !FULL_SYSTEM
+    void trap(Fault fault, ThreadID tid, DynInstPtr inst);
+#endif
     void recvRetry();
 
     /** Returns a specific port. */
index 9d0100565c5de6ad0100ac230be0b3ecd50d7d48..38a2eb040489719bc20f25bdf9c79bd62b9d2b3f 100644 (file)
@@ -159,15 +159,6 @@ UseDefUnit::execute(int slot_idx)
     InstSeqNum seq_num = inst->seqNum;
     int ud_idx = ud_req->useDefIdx;
 
-    if (inst->fault != NoFault) {
-        DPRINTF(InOrderUseDef,
-                "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
-                "next stage.\n", inst->readTid(), inst->seqNum, inst->fault->name(),
-                inst->pcState());
-        ud_req->done();
-        return;
-    }
-
     if (serializeOnNextInst[tid] &&
         seq_num > serializeAfterSeqNum[tid]) {
         inst->setSerializeBefore();
@@ -187,6 +178,15 @@ UseDefUnit::execute(int slot_idx)
         serializeAfterSeqNum[tid] = seq_num;
     }
 
+    if (inst->fault != NoFault) {
+        DPRINTF(InOrderUseDef,
+                "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
+                "next stage.\n", inst->readTid(), inst->seqNum, inst->fault->name(),
+                inst->pcState());
+        ud_req->done();
+        return;
+    }
+
     // If there is a non-speculative instruction
     // in the pipeline then stall instructions here
     // ---