summaryrefslogtreecommitdiff
path: root/cpu/checker/cpu.cc
diff options
context:
space:
mode:
authorKevin Lim <ktlim@umich.edu>2006-08-02 12:06:59 -0400
committerKevin Lim <ktlim@umich.edu>2006-08-02 12:06:59 -0400
commit5be592f870d1d59cffe9a5d1eebac66b225ff8ef (patch)
tree96542462dec9a6b760fb9723c58241ee2a58e69d /cpu/checker/cpu.cc
parentcbfbb7bc56630ddefb95625a6da87b3c1da9599d (diff)
downloadgem5-5be592f870d1d59cffe9a5d1eebac66b225ff8ef.tar.xz
Make checker handle not executing the same instruction as the main CPU a little better.
Also add the option for the checker to update itself with the main CPU's state if it executes an instruction differently (so it will handle DMA timing errors properly). --HG-- extra : convert_revision : 760d11ec1a249bc75e2807d320866b5d08c2b6f2
Diffstat (limited to 'cpu/checker/cpu.cc')
-rw-r--r--cpu/checker/cpu.cc30
1 files changed, 26 insertions, 4 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>