inorder: fault handling
authorKorey Sewell <ksewell@umich.edu>
Fri, 4 Feb 2011 05:09:20 +0000 (00:09 -0500)
committerKorey Sewell <ksewell@umich.edu>
Fri, 4 Feb 2011 05:09:20 +0000 (00:09 -0500)
Maintain all information about an instruction's fault in the DynInst object rather
than any cpu-request object. Also, if there is a fault during the execution stage
then just save the fault inside the instruction and trap once the instruction
tries to graduate

14 files changed:
src/cpu/inorder/pipeline_stage.cc
src/cpu/inorder/resource.cc
src/cpu/inorder/resource.hh
src/cpu/inorder/resources/agen_unit.cc
src/cpu/inorder/resources/branch_predictor.cc
src/cpu/inorder/resources/cache_unit.cc
src/cpu/inorder/resources/cache_unit.hh
src/cpu/inorder/resources/decode_unit.cc
src/cpu/inorder/resources/execution_unit.cc
src/cpu/inorder/resources/fetch_seq_unit.cc
src/cpu/inorder/resources/fetch_unit.cc
src/cpu/inorder/resources/graduation_unit.cc
src/cpu/inorder/resources/inst_buffer.cc
src/cpu/inorder/resources/mult_div_unit.cc

index e10ceb3266f1c57af061f053f754b5245a7d2a82..744ffd4d2be81f03242d3b91bd8cc9514c102650 100644 (file)
@@ -944,12 +944,7 @@ PipelineStage::processInstSchedule(DynInstPtr inst,int &reqs_processed)
                         "completed.\n", tid, inst->seqNum, 
                         cpu->resPool->name(res_num));
 
-                if (req->fault == NoFault) {
-                    inst->popSchedEntry();
-                } else {
-                    panic("%i: encountered %s fault!\n",
-                          curTick(), req->fault->name());
-                }
+                inst->popSchedEntry();
 
                 reqs_processed++;                
 
index 8c5f86c73e6f6fed7f2876b54a3e8a59d35665a5..51beb5aa0ee23dc604a59a2136fca14a979dc47d 100644 (file)
@@ -277,7 +277,6 @@ Resource::execute(int slot_idx)
     DPRINTF(Resource, "[tid:%i]: Executing %s resource.\n",
             reqMap[slot_idx]->getTid(), name());
     reqMap[slot_idx]->setCompleted(true);
-    reqMap[slot_idx]->fault = NoFault;
     reqMap[slot_idx]->done();
 }
 
index 5684dc166faa6b854b22e6dac5dffbde1c2277a4..bd9ec48ca32d7434a6c9ad7b8ab304a30fce130c 100644 (file)
@@ -350,9 +350,6 @@ class ResourceRequest
     /** Not guaranteed to be set, used for debugging */
     InstSeqNum seqNum;
     
-    /** Fault Associated With This Resource Request */
-    Fault fault;
-
     /** Command For This Resource */
     unsigned cmd;
 
index 2de586c82691e841c91df0edcdadb491ba895bd8..f1862b94a7a5b1ace65c99ac35a224510da195c4 100644 (file)
@@ -52,14 +52,11 @@ AGENUnit::execute(int slot_num)
 {
     ResourceRequest* agen_req = reqMap[slot_num];
     DynInstPtr inst = reqMap[slot_num]->inst;
-    Fault fault = reqMap[slot_num]->fault;
 #if TRACING_ON
     ThreadID tid = inst->readTid();
 #endif
     int seq_num = inst->seqNum;
 
-    agen_req->fault = NoFault;
-
     switch (agen_req->cmd)
     {
       case GenerateAddr:
@@ -70,18 +67,18 @@ AGENUnit::execute(int slot_num)
                         "[tid:%i] Generating Address for [sn:%i] (%s).\n",
                         tid, seq_num, inst->staticInst->getName());
 
-                fault = inst->calcEA();
+                inst->fault = inst->calcEA();
                 inst->setMemAddr(inst->getEA());
 
                 DPRINTF(InOrderAGEN,
                     "[tid:%i] [sn:%i] Effective address calculated as: %#x\n",
                     tid, seq_num, inst->getEA());
 
-                if (fault == NoFault) {
+                if (inst->fault == NoFault) {
                     agen_req->done();
                 } else {
                     fatal("%s encountered while calculating address [sn:%i]",
-                          fault->name(), seq_num);
+                          inst->fault->name(), seq_num);
                 }
 
                 agens++;
index c849ba163dd804a4829f46087198824b1eb133aa..8ca5a9718679280b71fb530b122de60e122f355e 100644 (file)
@@ -67,13 +67,9 @@ BranchPredictor::execute(int slot_num)
     // After this is working, change this to a reinterpret cast
     // for performance considerations
     ResourceRequest* bpred_req = reqMap[slot_num];
-
     DynInstPtr inst = bpred_req->inst;
     ThreadID tid = inst->readTid();
     int seq_num = inst->seqNum;
-    //int stage_num = bpred_req->getStageNum();
-
-    bpred_req->fault = NoFault;
 
     switch (bpred_req->cmd)
     {
index 6c9da67f5cc4864dc61e921322662edf1cd23e21..8b4dd4402ccd65615698a12ccb8ea8234ea34ed2 100644 (file)
@@ -405,7 +405,7 @@ CacheUnit::setupMemRequest(DynInstPtr inst, CacheReqPtr cache_req,
     }
 }
 
-Fault
+void
 CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
                        int flags, TheISA::TLB::Mode tlb_mode)
 {
@@ -416,13 +416,13 @@ CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
 
     setupMemRequest(inst, cache_req, acc_size, flags);
 
-    cache_req->fault =
+    inst->fault =
         _tlb->translateAtomic(cache_req->memReq,
                               cpu->thread[tid]->getTC(), tlb_mode);
 
-    if (cache_req->fault != NoFault) {
+    if (inst->fault != NoFault) {
         DPRINTF(InOrderTLB, "[tid:%i]: %s encountered while translating "
-                "addr:%08p for [sn:%i].\n", tid, cache_req->fault->name(),
+                "addr:%08p for [sn:%i].\n", tid, inst->fault->name(),
                 cache_req->memReq->getVaddr(), inst->seqNum);
 
         cpu->pipelineStage[stage_num]->setResStall(cache_req, tid);
@@ -433,7 +433,7 @@ CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
 
         scheduleEvent(slot_idx, 1);
 
-        cpu->trap(cache_req->fault, tid, inst);
+        cpu->trap(inst->fault, tid, inst);
     } else {
         DPRINTF(InOrderTLB, "[tid:%i]: [sn:%i] virt. addr %08p translated "
                 "to phys. addr:%08p.\n", tid, inst->seqNum,
@@ -441,7 +441,6 @@ CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
                 cache_req->memReq->getPaddr());
     }
 
-    return cache_req->fault;
 }
 
 Fault
@@ -531,7 +530,7 @@ CacheUnit::read(DynInstPtr inst, Addr addr,
     
     doTLBAccess(inst, cache_req, size, flags, TheISA::TLB::Read);
 
-    if (cache_req->fault == NoFault) {
+    if (inst->fault == NoFault) {
         if (!cache_req->splitAccess) {            
             cache_req->reqData = new uint8_t[size];
             doCacheAccess(inst, NULL);
@@ -546,7 +545,7 @@ CacheUnit::read(DynInstPtr inst, Addr addr,
         }        
     }
 
-    return cache_req->fault;
+    return inst->fault;
 }
 
 Fault
@@ -638,7 +637,7 @@ CacheUnit::write(DynInstPtr inst, uint8_t *data, unsigned size,
         
     doTLBAccess(inst, cache_req, size, flags, TheISA::TLB::Write);
 
-    if (cache_req->fault == NoFault) {
+    if (inst->fault == NoFault) {
         if (!cache_req->splitAccess) {            
             // Remove this line since storeData is saved in INST?
             cache_req->reqData = new uint8_t[size];
@@ -649,7 +648,7 @@ CacheUnit::write(DynInstPtr inst, uint8_t *data, unsigned size,
         
     }
     
-    return cache_req->fault;
+    return inst->fault;
 }
 
 
@@ -672,7 +671,7 @@ CacheUnit::execute(int slot_num)
     std::string acc_type = "write";
 #endif
 
-    cache_req->fault = NoFault;
+    inst->fault = NoFault;
 
     switch (cache_req->cmd)
     {
@@ -785,7 +784,7 @@ CacheUnit::execute(int slot_num)
 }
 
 // @TODO: Split into doCacheRead() and doCacheWrite()
-Fault
+void
 CacheUnit::doCacheAccess(DynInstPtr inst, uint64_t *write_res,
                          CacheReqPtr split_req)
 {
@@ -883,7 +882,6 @@ CacheUnit::doCacheAccess(DynInstPtr inst, uint64_t *write_res,
         cache_req->setCompleted(false);
     }
 
-    return fault;
 }
 
 void
index 0d911999ddc1ac13fdb11d0904c241bf863252a2..afcb36a24ae26fa5a9ca9356dc5430353e7c2c26 100644 (file)
@@ -161,13 +161,13 @@ class CacheUnit : public Resource
     Fault write(DynInstPtr inst, uint8_t *data, unsigned size,
                 Addr addr, unsigned flags, uint64_t *res);
 
-    Fault doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
+    void doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
                       int flags,  TheISA::TLB::Mode tlb_mode);
 
     /** Read/Write on behalf of an instruction.
      *  curResSlot needs to be a valid value in instruction.
      */
-    Fault doCacheAccess(DynInstPtr inst, uint64_t *write_result=NULL,
+    void doCacheAccess(DynInstPtr inst, uint64_t *write_result=NULL,
                         CacheReqPtr split_req=NULL);
 
     uint64_t getMemData(Packet *packet);
index 50cf6c7b7c7f5d3fb99cba4aec3cbda697722d5b..c2f7ae22d86f8f3a013fb794360e625fcb1cb1e1 100644 (file)
@@ -51,11 +51,8 @@ DecodeUnit::execute(int slot_num)
 {
     ResourceRequest* decode_req = reqMap[slot_num];
     DynInstPtr inst = reqMap[slot_num]->inst;
-    Fault fault = reqMap[slot_num]->fault;
     ThreadID tid = inst->readTid();
 
-    decode_req->fault = NoFault;
-
     switch (decode_req->cmd)
     {
       case DecodeInst:
index cae007debe8a1c6e659e3dcfc95b96c9c7ee6015..36bf2a4dccf36ec698540da69313c6047da3332b 100644 (file)
@@ -84,14 +84,11 @@ ExecutionUnit::execute(int slot_num)
 {
     ResourceRequest* exec_req = reqMap[slot_num];
     DynInstPtr inst = reqMap[slot_num]->inst;
-    Fault fault = reqMap[slot_num]->fault;
-    ThreadID tid = inst->readTid();
+    Fault fault = NoFault;
     int seq_num = inst->seqNum;
 
-    exec_req->fault = NoFault;
-
     DPRINTF(InOrderExecute, "[tid:%i] Executing [sn:%i] [PC:%s] %s.\n",
-            tid, seq_num, inst->pcState(), inst->instName());
+            inst->readTid(), seq_num, inst->pcState(), inst->instName());
 
     switch (exec_req->cmd)
     {
@@ -126,7 +123,6 @@ ExecutionUnit::execute(int slot_num)
                     if (inst->mispredicted()) {
                         int stage_num = exec_req->getStageNum();
                         ThreadID tid = inst->readTid();
-
                         // If it's a branch ...
                         if (inst->isDirectCtrl()) {
                             assert(!inst->isIndirectCtrl());
@@ -247,13 +243,13 @@ ExecutionUnit::execute(int slot_num)
                             seq_num,
                             (inst->resultType(0) == InOrderDynInst::Float) ?
                             inst->readFloatResult(0) : inst->readIntResult(0));
-
-                    exec_req->done();
                 } else {
-                    warn("inst [sn:%i] had a %s fault",
-                         seq_num, fault->name());
-                    cpu->trap(fault, tid, inst);
+                    DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i]: had a %s "
+                            "fault.\n", inst->readTid(), seq_num, fault->name());
+                    inst->fault = fault;
                 }
+
+                exec_req->done();
             }
         }
         break;
index 6ed949df31ee1053dcc8f7fba4f7ddb131de16e8..6f84a333dc20c55472a34545e645b98588e4d2d9 100644 (file)
@@ -74,8 +74,6 @@ FetchSeqUnit::execute(int slot_num)
     int stage_num = fs_req->getStageNum();
     int seq_num = inst->seqNum;
 
-    fs_req->fault = NoFault;
-
     DPRINTF(InOrderFetchSeq, "[tid:%i]: Current PC is %s\n", tid,
             pc[tid]);
 
index 7bbeffaddb64bb8fe9a6082993d2fad118c17b58..0e9866708623bacda87aa9a0b860af696a36a24c 100644 (file)
@@ -227,7 +227,8 @@ FetchUnit::execute(int slot_num)
     ThreadID tid = inst->readTid();
     Addr block_addr = cacheBlockAlign(inst->getMemAddr());
     int asid = cpu->asid[tid];
-    cache_req->fault = NoFault;
+
+    inst->fault = NoFault;
 
     switch (cache_req->cmd)
     {
@@ -275,7 +276,7 @@ FetchUnit::execute(int slot_num)
 
             doTLBAccess(inst, cache_req, cacheBlkSize, 0, TheISA::TLB::Execute);
 
-            if (cache_req->fault == NoFault) {
+            if (inst->fault == NoFault) {
                 DPRINTF(InOrderCachePort,
                         "[tid:%u]: Initiating fetch access to %s for "
                         "addr:%#x (block:%#x)\n", tid, name(),
index 9d19c2eefea5abd618766b9be827ed81ff379545..8ccdaa36a9ec1a9aabf1b387c9e68eb5bdaccdc3 100644 (file)
@@ -51,31 +51,23 @@ GraduationUnit::execute(int slot_num)
 {
     ResourceRequest* grad_req = reqMap[slot_num];
     DynInstPtr inst = reqMap[slot_num]->inst;
-    Fault fault = reqMap[slot_num]->fault;
     ThreadID tid = inst->readTid();
     int stage_num = inst->resSched.top()->stageNum;
 
-    grad_req->fault = NoFault;
-
     switch (grad_req->cmd)
     {
       case GraduateInst:
         {
-            // @TODO: Instructions should never really get to this point since
-            // this should be handled through the request interface. Check to
-            // make sure this happens and delete this code.
-            if (lastCycleGrad != curTick()) {
-                lastCycleGrad = curTick();
-                numCycleGrad = 0;
-            } else if (numCycleGrad > width) {
-                DPRINTF(InOrderGraduation,
-                        "Graduation bandwidth reached for this cycle.\n");
-                return;
-            }
-
             // Make sure this is the last thing on the resource schedule
             assert(inst->resSched.size() == 1);
 
+             // Handle Any Faults Before Graduating Instruction
+            if (inst->fault != NoFault) {
+                cpu->trap(inst->fault, tid, inst);
+                grad_req->setCompleted(false);
+                 return;
+            }
+
             DPRINTF(InOrderGraduation,
                     "[tid:%i] Graduating instruction [sn:%i].\n",
                     tid, inst->seqNum);
@@ -97,9 +89,6 @@ GraduationUnit::execute(int slot_num)
             // Tell CPU that instruction is finished processing
             cpu->instDone(inst, tid);
 
-            //cpu->pipelineStage[stage_num]->toPrevStages->
-            //stageInfo[stage_num][tid].doneSeqNum = inst->seqNum;
-
             grad_req->done();
         }
         break;
index 1db618b61b0e12beaf2992435f77f722a292d8fe..18dd26a78f5fee3755b2bd324de85488ce0183cc 100644 (file)
@@ -67,8 +67,6 @@ InstBuffer::execute(int slot_idx)
     ThreadID tid = inst->readTid();
     int stage_num = ib_req->getStageNum();
 
-    ib_req->fault = NoFault;
-
     switch (ib_req->cmd)
     {
       case ScheduleOrBypass:
index 55df1cc43c3e434f73e44e6e75f5f51d3f773fcc..5aa0b0aa1891da341aa6b5d01822e301c5d6bd82 100644 (file)
@@ -204,11 +204,7 @@ MultDivUnit::execute(int slot_num)
 {
     ResourceRequest* mult_div_req = reqMap[slot_num];
     DynInstPtr inst = reqMap[slot_num]->inst;
-    Fault fault = reqMap[slot_num]->fault;
  
-    //ThreadID tid = inst->readTid();
-    //int seq_num = inst->seqNum;
-
     switch (mult_div_req->cmd)
     {
       case StartMultDiv:
@@ -281,11 +277,8 @@ MultDivUnit::exeMulDiv(int slot_num)
 {
     ResourceRequest* mult_div_req = reqMap[slot_num];
     DynInstPtr inst = reqMap[slot_num]->inst;
-    Fault fault = reqMap[slot_num]->fault;
-    ThreadID tid = inst->readTid();
-    int seq_num = inst->seqNum;
 
-    fault = inst->execute();
+    inst->fault = inst->execute();
 
     if (inst->opClass() == IntMultOp) {
         multiplies++;
@@ -293,15 +286,15 @@ MultDivUnit::exeMulDiv(int slot_num)
         divides++;
     }
 
-    if (fault == NoFault) {
+    if (inst->fault == NoFault) {
         inst->setExecuted();
         mult_div_req->setCompleted();
 
-        DPRINTF(Resource, "[tid:%i]: The result of execution is 0x%x.\n",
+        DPRINTF(InOrderMDU, "[tid:%i]: The result of execution is 0x%x.\n",
                 inst->readTid(), inst->readIntResult(0));
     } else {
-        warn("inst [sn:%i] had a %s fault", seq_num, fault->name());
-        cpu->trap(fault, tid, inst);
+        DPRINTF(InOrderMDU, "[tid:%i]: [sn:%i]: had a %s "
+                "fault.\n", inst->readTid(), inst->seqNum, inst->fault->name());
     }    
 }