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"
68 using namespace TheISA;
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.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 memReq =
new Request(unverifiedInst->threadNumber, fetch_PC,
251 fetch_PC, thread->contextId());
259 if (unverifiedInst->getFault() ==
NoFault) {
265 warn(
"%lli: Instruction PC %s was not found in the "
266 "ITB!",
curTick(), thread->pcState());
267 handleError(unverifiedInst);
274 unverifiedInst = NULL;
280 fault = unverifiedInst->getFault();
288 icachePort->sendFunctional(pkt);
289 machInst =
gtoh(machInst);
302 microcodeRom.fetchMicroop(pcState.microPC(), NULL);
303 }
else if (!curMacroStaticInst) {
309 Addr fetchPC = (pcState.instAddr() & PCMask) + fetchOffset;
310 thread->decoder.moreBytes(pcState, fetchPC, machInst);
315 if (thread->decoder.instReady()) {
317 instPtr = thread->decoder.decode(pcState);
318 thread->pcState(pcState);
327 curMacroStaticInst = instPtr;
331 curStaticInst = instPtr;
342 thread->decoder.reset();
346 Fault unverifiedFault;
348 unverifiedFault = unverifiedInst->getFault();
352 validateInst(unverifiedInst);
364 if (!unverifiedInst->isUnverifiable()) {
370 fault = curStaticInst->execute(
this, traceData);
378 thread->funcExeInst++;
380 validateExecution(unverifiedInst);
382 if (curStaticInst->isLoad()) {
386 panic(
"%lli: sn: %lli at PC: %s took a fault in checker "
387 "but not in driver CPU\n",
curTick(),
388 unverifiedInst->seqNum, unverifiedInst->pcState());
390 panic(
"%lli: sn: %lli at PC: %s took a fault in driver "
391 "CPU but not in checker\n",
curTick(),
392 unverifiedInst->seqNum, unverifiedInst->pcState());
399 fault->invoke(tc, curStaticInst);
401 newPCState = thread->pcState();
416 oldpc = thread->instAddr();
417 system->pcEventQueue.service(tc);
419 }
while (oldpc != thread->instAddr());
422 newPCState = thread->pcState();
433 if (instList.empty()) {
435 }
else if (instList.front()->isCompleted()) {
436 unverifiedInst = NULL;
437 unverifiedInst = instList.front();
438 instList.pop_front();
443 unverifiedInst = NULL;
446 template <
class Impl>
453 template <
class Impl>
459 template <
class Impl>
463 if (inst->instAddr() != thread->instAddr()) {
464 warn(
"%lli: PCs do not match! Inst: %s, checker: %s",
465 curTick(), inst->pcState(), thread->pcState());
467 warn(
"%lli: Changed PCs recently, may not be an error",
474 if (curStaticInst != inst->staticInst) {
475 warn(
"%lli: StaticInstPtrs don't match. (%s, %s).\n",
curTick(),
476 curStaticInst->getName(), inst->staticInst->getName());
480 template <
class Impl>
484 uint64_t checker_val;
487 bool result_mismatch =
false;
489 if (inst->isUnverifiable()) {
493 copyResult(inst, 0, idx);
494 }
else if (inst->numDestRegs() > 0 && !result.empty()) {
495 DPRINTF(
Checker,
"Dest regs %d, number of checker dest regs %d\n",
496 inst->numDestRegs(), result.size());
497 for (
int i = 0;
i < inst->numDestRegs() && !result.empty();
i++) {
498 result.front().get(checker_val);
501 inst->template popResult<uint64_t>(inst_val);
502 if (checker_val != inst_val) {
503 result_mismatch =
true;
514 if (result_mismatch) {
515 warn(
"%lli: Instruction results do not match! (Values may not "
516 "actually be integers) Inst: %#x, checker: %#x",
517 curTick(), inst_val, checker_val);
526 if (inst->isLoad() && warnOnlyOnLoadError) {
527 copyResult(inst, inst_val, idx);
533 if (inst->nextInstAddr() != thread->nextInstAddr()) {
534 warn(
"%lli: Instruction next PCs do not match! Inst: %#x, "
536 curTick(), inst->nextInstAddr(), thread->nextInstAddr());
545 while (!miscRegIdxs.empty()) {
546 int misc_reg_idx = miscRegIdxs.front();
549 if (inst->tcBase()->readMiscRegNoEffect(misc_reg_idx) !=
550 thread->readMiscRegNoEffect(misc_reg_idx)) {
551 warn(
"%lli: Misc reg idx %i (side effect) does not match! "
552 "Inst: %#x, checker: %#x",
554 inst->tcBase()->readMiscRegNoEffect(misc_reg_idx),
555 thread->readMiscRegNoEffect(misc_reg_idx));
565 template <
class Impl>
569 if (updateThisCycle) {
571 panic(
"%lli: Instruction PC %#x results didn't match up, copying all "
572 "registers from main CPU",
curTick(), unverifiedInst->instAddr());
575 bool no_squash_from_TC = unverifiedInst->thread->noSquashFromTC;
576 unverifiedInst->thread->noSquashFromTC =
true;
579 thread->copyArchRegs(unverifiedInst->tcBase());
580 unverifiedInst->thread->noSquashFromTC = no_squash_from_TC;
583 curStaticInst = unverifiedInst->staticInst;
586 updateThisCycle =
false;
590 template <
class Impl>
597 if (start_idx >= 0) {
598 RegIndex idx = inst->destRegIdx(start_idx);
601 thread->setIntReg(idx, mismatch_val);
617 for (
int i = start_idx;
i < inst->numDestRegs();
i++) {
619 inst->template popResult<uint64_t>(res);
622 thread->setIntReg(idx, res);
639 template <
class Impl>
643 cprintf(
"Error detected, instruction information:\n");
644 cprintf(
"PC:%s, nextPC:%#x\n[sn:%lli]\n[tid:%i]\n"
647 inst->nextInstAddr(),
650 inst->isCompleted());
655 template <
class Impl>
663 cprintf(
"Inst list size: %i\n", instList.size());
665 while (inst_list_it != instList.end())
670 cprintf(
"PC:%s\n[sn:%lli]\n[tid:%i]\n"
672 (*inst_list_it)->pcState(),
673 (*inst_list_it)->seqNum,
674 (*inst_list_it)->threadNumber,
675 (*inst_list_it)->isCompleted());
685 #endif//__CPU_CHECKER_CPU_IMPL_HH__
decltype(nullptr) constexpr NoFault
std::list< DynInstPtr >::iterator InstListIt
Impl::DynInstPtr DynInstPtr
void validateInst(DynInstPtr &inst)
void copyResult(DynInstPtr &inst, uint64_t mismatch_val, int start_idx)
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
virtual StaticInstPtr fetchMicroop(MicroPC upc) const
Return the microop that goes with a particular micropc.
void validateExecution(DynInstPtr &inst)
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
void verify(DynInstPtr &inst)
Classes for managing reference counted objects.
Tick curTick()
The current simulated tick.
TheISA::PCState pcState() const override
void advancePC(const Fault &fault)
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)
GenericISA::SimplePCState< MachInst > PCState
The request was an instruction fetch.
void setVirt(int asid, Addr vaddr, unsigned size, Flags flags, MasterID mid, Addr pc)
Set up a virtual (e.g., CPU) request in a previously allocated Request object.
void takeOverFrom(BaseCPU *oldCPU)
Defines a dynamic instruction context.
TheISA::MachInst MachInst
RegClass regIdxToClass(TheISA::RegIndex reg_idx, TheISA::RegIndex *rel_reg_idx=NULL)
Map a 'unified' architectural register index to its register class.
static StaticInstPtr nullStaticInstPtr
Pointer to a statically allocated "null" instruction object.
std::shared_ptr< FaultBase > Fault
void cprintf(const char *format, const Args &...args)
ProbePointArg< PacketInfo > Packet
Packet probe point.