From: Korey Sewell Date: Fri, 4 Feb 2011 05:09:20 +0000 (-0500) Subject: inorder: fault handling X-Git-Tag: stable_2012_02_02~607 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e396a34b0155d5054a099c67a91baa66c095d3d8;p=gem5.git inorder: fault handling 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 --- diff --git a/src/cpu/inorder/pipeline_stage.cc b/src/cpu/inorder/pipeline_stage.cc index e10ceb326..744ffd4d2 100644 --- a/src/cpu/inorder/pipeline_stage.cc +++ b/src/cpu/inorder/pipeline_stage.cc @@ -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++; diff --git a/src/cpu/inorder/resource.cc b/src/cpu/inorder/resource.cc index 8c5f86c73..51beb5aa0 100644 --- a/src/cpu/inorder/resource.cc +++ b/src/cpu/inorder/resource.cc @@ -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(); } diff --git a/src/cpu/inorder/resource.hh b/src/cpu/inorder/resource.hh index 5684dc166..bd9ec48ca 100644 --- a/src/cpu/inorder/resource.hh +++ b/src/cpu/inorder/resource.hh @@ -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; diff --git a/src/cpu/inorder/resources/agen_unit.cc b/src/cpu/inorder/resources/agen_unit.cc index 2de586c82..f1862b94a 100644 --- a/src/cpu/inorder/resources/agen_unit.cc +++ b/src/cpu/inorder/resources/agen_unit.cc @@ -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++; diff --git a/src/cpu/inorder/resources/branch_predictor.cc b/src/cpu/inorder/resources/branch_predictor.cc index c849ba163..8ca5a9718 100644 --- a/src/cpu/inorder/resources/branch_predictor.cc +++ b/src/cpu/inorder/resources/branch_predictor.cc @@ -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) { diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc index 6c9da67f5..8b4dd4402 100644 --- a/src/cpu/inorder/resources/cache_unit.cc +++ b/src/cpu/inorder/resources/cache_unit.cc @@ -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 diff --git a/src/cpu/inorder/resources/cache_unit.hh b/src/cpu/inorder/resources/cache_unit.hh index 0d911999d..afcb36a24 100644 --- a/src/cpu/inorder/resources/cache_unit.hh +++ b/src/cpu/inorder/resources/cache_unit.hh @@ -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); diff --git a/src/cpu/inorder/resources/decode_unit.cc b/src/cpu/inorder/resources/decode_unit.cc index 50cf6c7b7..c2f7ae22d 100644 --- a/src/cpu/inorder/resources/decode_unit.cc +++ b/src/cpu/inorder/resources/decode_unit.cc @@ -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: diff --git a/src/cpu/inorder/resources/execution_unit.cc b/src/cpu/inorder/resources/execution_unit.cc index cae007deb..36bf2a4dc 100644 --- a/src/cpu/inorder/resources/execution_unit.cc +++ b/src/cpu/inorder/resources/execution_unit.cc @@ -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; diff --git a/src/cpu/inorder/resources/fetch_seq_unit.cc b/src/cpu/inorder/resources/fetch_seq_unit.cc index 6ed949df3..6f84a333d 100644 --- a/src/cpu/inorder/resources/fetch_seq_unit.cc +++ b/src/cpu/inorder/resources/fetch_seq_unit.cc @@ -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]); diff --git a/src/cpu/inorder/resources/fetch_unit.cc b/src/cpu/inorder/resources/fetch_unit.cc index 7bbeffadd..0e9866708 100644 --- a/src/cpu/inorder/resources/fetch_unit.cc +++ b/src/cpu/inorder/resources/fetch_unit.cc @@ -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(), diff --git a/src/cpu/inorder/resources/graduation_unit.cc b/src/cpu/inorder/resources/graduation_unit.cc index 9d19c2eef..8ccdaa36a 100644 --- a/src/cpu/inorder/resources/graduation_unit.cc +++ b/src/cpu/inorder/resources/graduation_unit.cc @@ -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; diff --git a/src/cpu/inorder/resources/inst_buffer.cc b/src/cpu/inorder/resources/inst_buffer.cc index 1db618b61..18dd26a78 100644 --- a/src/cpu/inorder/resources/inst_buffer.cc +++ b/src/cpu/inorder/resources/inst_buffer.cc @@ -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: diff --git a/src/cpu/inorder/resources/mult_div_unit.cc b/src/cpu/inorder/resources/mult_div_unit.cc index 55df1cc43..5aa0b0aa1 100644 --- a/src/cpu/inorder/resources/mult_div_unit.cc +++ b/src/cpu/inorder/resources/mult_div_unit.cc @@ -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()); } }