diff options
-rw-r--r-- | cpu/checker/cpu.cc | 30 | ||||
-rw-r--r-- | cpu/checker/cpu.hh | 23 | ||||
-rw-r--r-- | cpu/checker/cpu_builder.cc | 3 |
3 files changed, 46 insertions, 10 deletions
diff --git a/cpu/checker/cpu.cc b/cpu/checker/cpu.cc index 41ff6e769..f195c8842 100644 --- a/cpu/checker/cpu.cc +++ b/cpu/checker/cpu.cc @@ -78,6 +78,7 @@ CheckerCPU::CheckerCPU(Params *p) changedPC = willChangePC = changedNextPC = false; exitOnError = p->exitOnError; + updateOnError = p->updateOnError; #if FULL_SYSTEM itb = p->itb; dtb = p->dtb; @@ -350,7 +351,12 @@ CheckerCPU::translateDataReadReq(MemReqPtr &req) { cpuXC->translateDataReadReq(req); - if (req->vaddr != unverifiedReq->vaddr) { + if (!unverifiedReq) { + warn("%lli: Request virtual addresses do not match! Inst: N/A, " + "checker: %#x", + curTick, req->vaddr); + return; + } else if (req->vaddr != unverifiedReq->vaddr) { warn("%lli: Request virtual addresses do not match! Inst: %#x, " "checker: %#x", curTick, unverifiedReq->vaddr, req->vaddr); @@ -370,7 +376,12 @@ CheckerCPU::translateDataWriteReq(MemReqPtr &req) { cpuXC->translateDataWriteReq(req); - if (req->vaddr != unverifiedReq->vaddr) { + if (!unverifiedReq) { + warn("%lli: Request virtual addresses do not match! Inst: N/A, " + "checker: %#x", + curTick, req->vaddr); + return; + } else if (req->vaddr != unverifiedReq->vaddr) { warn("%lli: Request virtual addresses do not match! Inst: %#x, " "checker: %#x", curTick, unverifiedReq->vaddr, req->vaddr); @@ -443,6 +454,8 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst) } } + unverifiedInst = inst; + // Try to check all instructions that are completed, ending if we // run out of instructions to check or if an instruction is not // yet completed. @@ -516,7 +529,7 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst) cpuXC->setPC(cpuXC->readNextPC()); cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst)); - return; + break; } else { // The instruction is carrying an ITB fault. Handle // the fault and see if our results match the CPU on @@ -554,7 +567,8 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst) cpuXC->func_exe_inst++; - fault = curStaticInst->execute(this, NULL); + if (!inst->isUnverifiable()) + fault = curStaticInst->execute(this, NULL); // Checks to make sure instrution results are correct. validateExecution(inst); @@ -620,6 +634,7 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst) break; } } + unverifiedInst = NULL; } template <class DynInstPtr> @@ -718,6 +733,13 @@ template <class DynInstPtr> void Checker<DynInstPtr>::validateState() { + if (updateThisCycle) { + warn("%lli: Instruction PC %#x results didn't match up, copying all " + "registers from main CPU", unverifiedInst->readPC()); + // Heavy-weight copying of all registers + cpuXC->copyArchRegs(unverifiedInst->xcBase()); + updateThisCycle = false; + } } template <class DynInstPtr> diff --git a/cpu/checker/cpu.hh b/cpu/checker/cpu.hh index 9fcd1037f..f48d1135a 100644 --- a/cpu/checker/cpu.hh +++ b/cpu/checker/cpu.hh @@ -98,6 +98,7 @@ class CheckerCPU : public BaseCPU Process *process; #endif bool exitOnError; + bool updateOnError; }; public: @@ -294,11 +295,8 @@ class CheckerCPU : public BaseCPU void syscall() { } #endif - void handleError() - { - if (exitOnError) - panic("Checker found error!"); - } + virtual void handleError() = 0; + bool checkFlags(MemReqPtr &req); ExecContext *xcBase() { return xcProxy; } @@ -312,6 +310,7 @@ class CheckerCPU : public BaseCPU uint64_t newPC; bool changedNextPC; bool exitOnError; + bool updateOnError; InstSeqNum youngestSN; }; @@ -327,7 +326,7 @@ class Checker : public CheckerCPU { public: Checker(Params *p) - : CheckerCPU(p) + : CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL) { } void switchOut(Sampler *s); @@ -339,6 +338,18 @@ class Checker : public CheckerCPU void validateExecution(DynInstPtr &inst); void validateState(); + virtual void handleError() + { + if (exitOnError) + panic("Checker found error!"); + else if (updateOnError) + updateThisCycle = true; + } + + bool updateThisCycle; + + DynInstPtr unverifiedInst; + std::list<DynInstPtr> instList; typedef typename std::list<DynInstPtr>::iterator InstListIt; void dumpInsts(); diff --git a/cpu/checker/cpu_builder.cc b/cpu/checker/cpu_builder.cc index d80daef97..802944e47 100644 --- a/cpu/checker/cpu_builder.cc +++ b/cpu/checker/cpu_builder.cc @@ -75,6 +75,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(OzoneChecker) Param<bool> defer_registration; Param<bool> exitOnError; + Param<bool> updateOnError; Param<bool> function_trace; Param<Tick> function_trace_start; @@ -108,6 +109,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(OzoneChecker) INIT_PARAM(defer_registration, "defer system registration (for sampling)"), INIT_PARAM(exitOnError, "exit on error"), + INIT_PARAM(updateOnError, "Update the checker with the main CPU's state on error"), INIT_PARAM(function_trace, "Enable function trace"), INIT_PARAM(function_trace_start, "Cycle to start function trace") @@ -124,6 +126,7 @@ CREATE_SIM_OBJECT(OzoneChecker) params->max_loads_any_thread = 0; params->max_loads_all_threads = 0; params->exitOnError = exitOnError; + params->updateOnError = updateOnError; params->deferRegistration = defer_registration; params->functionTrace = function_trace; params->functionTraceStart = function_trace_start; |