45 #ifndef __CPU_CHECKER_CPU_IMPL_HH__ 46 #define __CPU_CHECKER_CPU_IMPL_HH__ 51 #include "arch/isa_traits.hh" 52 #include "arch/vtophys.hh" 54 #include "config/the_isa.hh" 62 #include "debug/Checker.hh" 76 fault->invoke(tc, curStaticInst);
77 thread->decoder.reset();
80 if (curStaticInst->isLastMicroop())
84 thread->pcState(pcState);
95 DPRINTF(
Checker,
"IRQ detected at PC: %s with %d insts in buffer\n",
96 thread->
pcState(), instList.size());
98 if (!instList.empty()) {
103 for (itr = instList.begin(); itr != instList.end(); itr++) {
104 (*itr)->setCompleted();
107 inst = instList.front();
108 boundaryInst = instList.back();
112 if ((!boundaryInst && curMacroStaticInst &&
113 curStaticInst->isDelayedCommit() &&
114 !curStaticInst->isLastMicroop()) ||
115 (boundaryInst && boundaryInst->isDelayedCommit() &&
116 !boundaryInst->isLastMicroop())) {
117 panic(
"%lli: Trying to take an interrupt in middle of " 118 "a non-interuptable instruction!",
curTick());
121 thread->decoder.reset();
125 template <
class Impl>
134 if ((completed_inst->isSerializing() ||
135 completed_inst->isSerializeBefore()) &&
137 (instList.front()->seqNum != completed_inst->seqNum) : 0)) {
138 panic(
"%lli: Instruction sn:%lli at PC %s is serializing before but is" 139 " entering instList with other instructions\n",
curTick(),
140 completed_inst->seqNum, completed_inst->pcState());
148 if (!instList.empty()) {
149 if (youngestSN < completed_inst->seqNum) {
151 completed_inst->seqNum, completed_inst->
pcState());
152 instList.push_back(completed_inst);
153 youngestSN = completed_inst->seqNum;
156 if (!instList.front()->isCompleted()) {
159 inst = instList.front();
160 instList.pop_front();
163 if (!completed_inst->isCompleted()) {
164 if (youngestSN < completed_inst->seqNum) {
166 completed_inst->seqNum, completed_inst->
pcState());
167 instList.push_back(completed_inst);
168 youngestSN = completed_inst->seqNum;
172 if (youngestSN < completed_inst->seqNum) {
173 inst = completed_inst;
174 youngestSN = completed_inst->seqNum;
183 if (inst->isSerializeAfter() && !instList.empty()) {
184 panic(
"%lli: Instruction sn:%lli at PC %s is serializing after but is" 185 " exiting instList with other instructions\n",
curTick(),
186 completed_inst->seqNum, completed_inst->pcState());
188 unverifiedInst = inst;
196 unverifiedInst->seqNum, unverifiedInst->
pcState());
197 unverifiedReq = NULL;
198 unverifiedReq = unverifiedInst->reqToVerify;
199 unverifiedMemData = unverifiedInst->memData;
201 while (!result.empty()) {
210 #if THE_ISA == ALPHA_ISA 211 thread->setFloatReg(
ZeroReg, 0);
221 if (newPCState == thread->pcState()) {
224 warn(
"%lli: Changed PC does not match expected PC, " 225 "changed: %s, expected: %s",
226 curTick(), thread->pcState(), newPCState);
229 willChangePC =
false;
235 uint64_t fetchOffset = 0;
236 bool fetchDone =
false;
239 Addr fetch_PC = thread->instAddr();
240 fetch_PC = (fetch_PC & PCMask) + fetchOffset;
245 if (!curMacroStaticInst) {
247 auto mem_req = std::make_shared<Request>(
248 unverifiedInst->threadNumber, fetch_PC,
249 sizeof(
MachInst), 0, masterId, fetch_PC,
250 thread->contextId());
252 mem_req->setVirt(0, fetch_PC,
sizeof(
MachInst),
256 fault = itb->translateFunctional(
260 if (unverifiedInst->getFault() ==
NoFault) {
266 warn(
"%lli: Instruction PC %s was not found in the " 267 "ITB!",
curTick(), thread->pcState());
268 handleError(unverifiedInst);
274 unverifiedInst = NULL;
280 fault = unverifiedInst->getFault();
287 icachePort->sendFunctional(pkt);
299 microcodeRom.fetchMicroop(pcState.microPC(), NULL);
300 }
else if (!curMacroStaticInst) {
306 Addr fetchPC = (pcState.instAddr() & PCMask) + fetchOffset;
307 thread->decoder.moreBytes(pcState, fetchPC, machInst);
312 if (thread->decoder.instReady()) {
314 instPtr = thread->decoder.decode(pcState);
315 thread->pcState(pcState);
324 curMacroStaticInst = instPtr;
328 curStaticInst = instPtr;
339 thread->decoder.reset();
343 Fault unverifiedFault;
345 unverifiedFault = unverifiedInst->getFault();
349 validateInst(unverifiedInst);
361 if (!unverifiedInst->isUnverifiable()) {
367 fault = curStaticInst->execute(
this, traceData);
375 thread->funcExeInst++;
377 validateExecution(unverifiedInst);
379 if (curStaticInst->isLoad()) {
383 panic(
"%lli: sn: %lli at PC: %s took a fault in checker " 384 "but not in driver CPU\n",
curTick(),
385 unverifiedInst->seqNum, unverifiedInst->pcState());
387 panic(
"%lli: sn: %lli at PC: %s took a fault in driver " 388 "CPU but not in checker\n",
curTick(),
389 unverifiedInst->seqNum, unverifiedInst->pcState());
396 fault->invoke(tc, curStaticInst);
398 newPCState = thread->pcState();
413 oldpc = thread->instAddr();
414 thread->pcEventQueue.service(oldpc, tc);
416 }
while (oldpc != thread->instAddr());
419 newPCState = thread->pcState();
430 if (instList.empty()) {
432 }
else if (instList.front()->isCompleted()) {
433 unverifiedInst = NULL;
434 unverifiedInst = instList.front();
435 instList.pop_front();
440 unverifiedInst = NULL;
443 template <
class Impl>
450 template <
class Impl>
456 template <
class Impl>
460 if (inst->instAddr() != thread->instAddr()) {
461 warn(
"%lli: PCs do not match! Inst: %s, checker: %s",
462 curTick(), inst->pcState(), thread->pcState());
464 warn(
"%lli: Changed PCs recently, may not be an error",
471 if (curStaticInst != inst->staticInst) {
472 warn(
"%lli: StaticInstPtrs don't match. (%s, %s).\n",
curTick(),
473 curStaticInst->getName(), inst->staticInst->getName());
477 template <
class Impl>
484 bool result_mismatch =
false;
485 bool scalar_mismatch =
false;
486 bool vector_mismatch =
false;
488 if (inst->isUnverifiable()) {
493 }
else if (inst->numDestRegs() > 0 && !result.empty()) {
494 DPRINTF(
Checker,
"Dest regs %d, number of checker dest regs %d\n",
495 inst->numDestRegs(), result.size());
496 for (
int i = 0;
i < inst->numDestRegs() && !result.empty();
i++) {
497 checker_val = result.front();
499 inst_val = inst->popResult(
501 if (checker_val != inst_val) {
502 result_mismatch =
true;
504 scalar_mismatch = checker_val.
isScalar();
505 vector_mismatch = checker_val.
isVector();
506 panic_if(!(scalar_mismatch || vector_mismatch),
507 "Unknown type of result\n");
516 if (result_mismatch) {
517 if (scalar_mismatch) {
518 warn(
"%lli: Instruction results (%i) do not match! (Values may" 519 " not actually be integers) Inst: %#x, checker: %#x",
531 if (inst->isLoad() && warnOnlyOnLoadError) {
532 copyResult(inst, inst_val, idx);
538 if (inst->nextInstAddr() != thread->nextInstAddr()) {
539 warn(
"%lli: Instruction next PCs do not match! Inst: %#x, " 541 curTick(), inst->nextInstAddr(), thread->nextInstAddr());
550 while (!miscRegIdxs.empty()) {
551 int misc_reg_idx = miscRegIdxs.front();
554 if (inst->tcBase()->readMiscRegNoEffect(misc_reg_idx) !=
555 thread->readMiscRegNoEffect(misc_reg_idx)) {
556 warn(
"%lli: Misc reg idx %i (side effect) does not match! " 557 "Inst: %#x, checker: %#x",
559 inst->tcBase()->readMiscRegNoEffect(misc_reg_idx),
560 thread->readMiscRegNoEffect(misc_reg_idx));
570 template <
class Impl>
574 if (updateThisCycle) {
576 panic(
"%lli: Instruction PC %#x results didn't match up, copying all " 577 "registers from main CPU",
curTick(), unverifiedInst->instAddr());
580 bool no_squash_from_TC = unverifiedInst->thread->noSquashFromTC;
581 unverifiedInst->thread->noSquashFromTC =
true;
584 thread->copyArchRegs(unverifiedInst->tcBase());
585 unverifiedInst->thread->noSquashFromTC = no_squash_from_TC;
588 curStaticInst = unverifiedInst->staticInst;
591 updateThisCycle =
false;
595 template <
class Impl>
598 const InstResult& mismatch_val,
int start_idx)
602 if (start_idx >= 0) {
603 const RegId& idx = inst->destRegIdx(start_idx);
615 thread->setVecReg(idx, mismatch_val.
asVector());
619 "Unexpected type of result");
636 for (
int i = start_idx;
i < inst->numDestRegs();
i++) {
637 const RegId& idx = inst->destRegIdx(
i);
638 res = inst->popResult();
650 thread->setVecReg(idx, res.
asVector());
663 thread->setMiscReg(idx.
index(), 0);
672 template <
class Impl>
676 cprintf(
"Error detected, instruction information:\n");
677 cprintf(
"PC:%s, nextPC:%#x\n[sn:%lli]\n[tid:%i]\n" 680 inst->nextInstAddr(),
683 inst->isCompleted());
688 template <
class Impl>
696 cprintf(
"Inst list size: %i\n", instList.size());
698 while (inst_list_it != instList.end())
703 cprintf(
"PC:%s\n[sn:%lli]\n[tid:%i]\n" 705 (*inst_list_it)->pcState(),
706 (*inst_list_it)->seqNum,
707 (*inst_list_it)->threadNumber,
708 (*inst_list_it)->isCompleted());
718 #endif//__CPU_CHECKER_CPU_IMPL_HH__ const uint64_t & asInteger() const
Explicit cast-like operations.
#define panic(...)
This implements a cprintf based panic() function.
const VecElem & asVectorElem() const
decltype(nullptr) constexpr NoFault
std::list< DynInstPtr >::iterator InstListIt
O3CPUImpl ::DynInstPtr DynInstPtr
void validateInst(const DynInstPtr &inst)
void verify(const DynInstPtr &inst)
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Overload hash function for BasicBlockRange type.
void copyResult(const DynInstPtr &inst, const InstResult &mismatch_val, int start_idx)
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
Vector Register Native Elem lane.
Classes for managing reference counted objects.
Tick curTick()
The current simulated tick.
TheISA::PCState pcState() const override
bool isVector() const
Is this a vector result?.
void advancePC(const Fault &fault)
virtual StaticInstPtr fetchMicroop(MicroPC upc) const
Return the microop that goes with a particular micropc.
bool isScalar() const
Checks.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
void advancePC(PCState &pc, const StaticInstPtr &inst)
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
static bool isRomMicroPC(MicroPC upc)
The request was an instruction fetch.
const VecRegContainer & asVector() const
GenericISA::SimplePCState< MachInst > PCState
const RegClass & classValue() const
Class accessor.
void takeOverFrom(BaseCPU *oldCPU)
Load the state of a CPU from the previous CPU object, invoked on all new CPUs that are about to be sw...
void validateExecution(const DynInstPtr &inst)
const RegIndex & index() const
Index accessors.
bool isVecElem() const
Is this a vector element result?.
void switchOut()
Prepare for another CPU to take over execution.
Defines a dynamic instruction context.
Register ID: describe an architectural register with its class and index.
TheISA::MachInst MachInst
bool isValid() const
Is this a valid result?.
static StaticInstPtr nullStaticInstPtr
Pointer to a statically allocated "null" instruction object.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
std::shared_ptr< FaultBase > Fault
void cprintf(const char *format, const Args &...args)
ProbePointArg< PacketInfo > Packet
Packet probe point.
const uint64_t & asIntegerNoAssert() const
Cast to integer without checking type.