changeset 8d26dc2d92b2 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=8d26dc2d92b2
description:
        inorder: squash and trap behind a tlb fault

diffstat:

 src/cpu/inorder/cpu.cc                       |   2 +
 src/cpu/inorder/resource.cc                  |  19 ++++++++++
 src/cpu/inorder/resource.hh                  |   3 +
 src/cpu/inorder/resources/cache_unit.cc      |  50 ++++++++++++++++++++++-----
 src/cpu/inorder/resources/cache_unit.hh      |   2 +-
 src/cpu/inorder/resources/graduation_unit.cc |  13 +------
 6 files changed, 66 insertions(+), 23 deletions(-)

diffs (216 lines):

diff -r bf2054aef42b -r 8d26dc2d92b2 src/cpu/inorder/cpu.cc
--- a/src/cpu/inorder/cpu.cc    Sun Jun 19 21:43:39 2011 -0400
+++ b/src/cpu/inorder/cpu.cc    Sun Jun 19 21:43:39 2011 -0400
@@ -847,6 +847,7 @@
 InOrderCPU::trap(Fault fault, ThreadID tid, DynInstPtr inst)
 {
     fault->invoke(tcBase(tid), inst->staticInst);
+    removePipelineStalls(tid);
 }
 
 void 
@@ -1650,6 +1651,7 @@
 void
 InOrderCPU::syscallContext(Fault fault, ThreadID tid, DynInstPtr inst, int 
delay)
 {
+    //@todo: squash behind syscall
     scheduleCpuEvent(Syscall, fault, tid, inst, delay, Syscall_Pri);
 }
 
diff -r bf2054aef42b -r 8d26dc2d92b2 src/cpu/inorder/resource.cc
--- a/src/cpu/inorder/resource.cc       Sun Jun 19 21:43:39 2011 -0400
+++ b/src/cpu/inorder/resource.cc       Sun Jun 19 21:43:39 2011 -0400
@@ -336,6 +336,25 @@
     squash(inst, stage_num, squash_seq_num, tid);    
 }
 
+void
+Resource::squashThenTrap(int stage_num, DynInstPtr inst)
+{
+    ThreadID tid = inst->readTid();
+
+    inst->setSquashInfo(stage_num);
+    setupSquash(inst, stage_num, tid);
+
+    if (inst->traceData && DTRACE(ExecFaulting)) {
+        inst->traceData->setStageCycle(stage_num, curTick());
+        inst->traceData->setFetchSeq(inst->seqNum);
+        inst->traceData->dump();
+        delete inst->traceData;
+        inst->traceData = NULL;
+    }
+
+    cpu->trapContext(inst->fault, tid, inst);
+}
+
 Tick
 Resource::ticks(int num_cycles)
 {
diff -r bf2054aef42b -r 8d26dc2d92b2 src/cpu/inorder/resource.hh
--- a/src/cpu/inorder/resource.hh       Sun Jun 19 21:43:39 2011 -0400
+++ b/src/cpu/inorder/resource.hh       Sun Jun 19 21:43:39 2011 -0400
@@ -168,6 +168,9 @@
     virtual void squashDueToMemStall(DynInstPtr inst, int stage_num,
                                      InstSeqNum squash_seq_num, ThreadID tid);
 
+    /** Handle Squash & Trap that occured from an instruction in a resource */
+    void squashThenTrap(int stage_num, DynInstPtr inst);
+
     /** The number of instructions available that this resource can
      *  can still process
      */
diff -r bf2054aef42b -r 8d26dc2d92b2 src/cpu/inorder/resources/cache_unit.cc
--- a/src/cpu/inorder/resources/cache_unit.cc   Sun Jun 19 21:43:39 2011 -0400
+++ b/src/cpu/inorder/resources/cache_unit.cc   Sun Jun 19 21:43:39 2011 -0400
@@ -119,6 +119,7 @@
 
     for (int i=0; i < MaxThreads; i++) {
         tlbBlocked[i] = false;
+        tlbBlockSeqNum[i] = 0;
     }
 }
 
@@ -391,12 +392,8 @@
                        int flags, TheISA::TLB::Mode tlb_mode)
 {
     ThreadID tid = inst->readTid();
-    //Addr aligned_addr = inst->getMemAddr();
-    unsigned stage_num = cache_req->getStageNum();
-    unsigned slot_idx = cache_req->getSlot();
 
     setupMemRequest(inst, cache_req, acc_size, flags);
-
     inst->fault =
         _tlb->translateAtomic(cache_req->memReq,
                               cpu->thread[tid]->getTC(), tlb_mode);
@@ -406,16 +403,25 @@
                 "addr:%08p for [sn:%i].\n", tid, inst->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);
-
-        tlbBlocked[tid] = true;
-
         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
         scheduleEvent(slot_idx, 1);
+        unsigned slot_idx = cache_req->getSlot();
+#endif
+
+        // Mark it as complete so it can pass through next stage.
+        // Fault Handling will happen at commit/graduation
+        cache_req->setCompleted();
     } else {
         DPRINTF(InOrderTLB, "[tid:%i]: [sn:%i] virt. addr %08p translated "
                 "to phys. addr:%08p.\n", tid, inst->seqNum,
@@ -654,8 +660,6 @@
     std::string acc_type = "write";
 #endif
 
-    inst->fault = NoFault;
-
     switch (cache_req->cmd)
     {
 
@@ -712,6 +716,16 @@
         DPRINTF(InOrderCachePort,
                 "[tid:%i]: [sn:%i]: Trying to Complete Data Read Access\n",
                 tid, inst->seqNum);
+
+        if (inst->fault != NoFault) {
+            DPRINTF(InOrderCachePort,
+                "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
+                "next stage.\n", tid, inst->seqNum, inst->fault->name(),
+                inst->getMemAddr());
+            finishCacheUnitReq(inst, cache_req);
+            return;
+        }
+
         //@todo: timing translations need to check here...
         assert(!inst->isInstPrefetch() && "Can't Handle Inst. Prefecthes");
         if (cache_req->isMemAccComplete() || inst->isDataPrefetch()) {
@@ -730,6 +744,15 @@
                     "[tid:%i]: [sn:%i]: Trying to Complete Data Write 
Access\n",
                     tid, inst->seqNum);
 
+            if (inst->fault != NoFault) {
+                DPRINTF(InOrderCachePort,
+                        "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding 
to ",
+                        "next stage.\n", tid, inst->seqNum, 
inst->fault->name(),
+                        inst->getMemAddr());
+                finishCacheUnitReq(inst, cache_req);
+                return;
+            }
+
             //@todo: check that timing translation is finished here
             RequestPtr mem_req = cache_req->memReq;
             DPRINTF(InOrderCachePort,
@@ -789,7 +812,8 @@
                 "[tid:%i]: [sn:%i]: Trying to Complete Split Data Write "
                 "Access\n", tid, inst->seqNum);
         //@todo: illegal to have a unaligned cond.swap or llsc?
-        assert(!cache_req->memReq->isSwap() && 
!cache_req->memReq->isCondSwap() && !cache_req->memReq->isLLSC());
+        assert(!cache_req->memReq->isSwap() && !cache_req->memReq->isCondSwap()
+               && !cache_req->memReq->isLLSC());
 
         if (cache_req->isMemAccPending()) {
             cache_req->dataPkt->reqData = cache_req->reqData;
@@ -1224,6 +1248,12 @@
 CacheUnit::squash(DynInstPtr inst, int stage_num,
                   InstSeqNum squash_seq_num, ThreadID tid)
 {
+    if (tlbBlockSeqNum[tid] > squash_seq_num) {
+        DPRINTF(InOrderCachePort, "Releasing TLB Block due to "
+                " squash after [sn:%i].\n", squash_seq_num);
+        tlbBlocked[tid] = false;
+    }
+
     for (int i = 0; i < width; i++) {
         ResReqPtr req_ptr = reqs[i];
 
diff -r bf2054aef42b -r 8d26dc2d92b2 src/cpu/inorder/resources/cache_unit.hh
--- a/src/cpu/inorder/resources/cache_unit.hh   Sun Jun 19 21:43:39 2011 -0400
+++ b/src/cpu/inorder/resources/cache_unit.hh   Sun Jun 19 21:43:39 2011 -0400
@@ -203,9 +203,9 @@
     }
 
     bool tlbBlocked[ThePipeline::MaxThreads];
+    InstSeqNum tlbBlockSeqNum[ThePipeline::MaxThreads];
 
     TheISA::TLB* tlb();
-
     TheISA::TLB *_tlb;
 };
 
diff -r bf2054aef42b -r 8d26dc2d92b2 
src/cpu/inorder/resources/graduation_unit.cc
--- a/src/cpu/inorder/resources/graduation_unit.cc      Sun Jun 19 21:43:39 
2011 -0400
+++ b/src/cpu/inorder/resources/graduation_unit.cc      Sun Jun 19 21:43:39 
2011 -0400
@@ -70,18 +70,7 @@
                 DPRINTF(Fault, "[sn:%i]: fault %s found for %s\n",
                         inst->seqNum, inst->fault->name(),
                         inst->instName());
-                inst->setSquashInfo(stage_num);
-                setupSquash(inst, stage_num, tid);
-
-                if (inst->traceData && DTRACE(ExecFaulting)) {
-                    inst->traceData->setStageCycle(stage_num, curTick());
-                    inst->traceData->setFetchSeq(inst->seqNum);
-                    inst->traceData->dump();
-                    delete inst->traceData;
-                    inst->traceData = NULL;
-                }
-
-                cpu->trapContext(inst->fault, tid, inst);
+                squashThenTrap(stage_num, inst);
                 grad_req->done(false);
                 return;
             }
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to