42 #ifndef __CPU_CHECKER_CPU_IMPL_HH__
43 #define __CPU_CHECKER_CPU_IMPL_HH__
49 #include "config/the_isa.hh"
57 #include "debug/Checker.hh"
71 fault->invoke(tc, curStaticInst);
72 thread->decoder.reset();
75 if (curStaticInst->isLastMicroop())
79 thread->pcState(pcState);
90 DPRINTF(
Checker,
"IRQ detected at PC: %s with %d insts in buffer\n",
91 thread->
pcState(), instList.size());
93 if (!instList.empty()) {
98 for (itr = instList.begin(); itr != instList.end(); itr++) {
99 (*itr)->setCompleted();
102 inst = instList.front();
103 boundaryInst = instList.back();
107 if ((!boundaryInst && curMacroStaticInst &&
108 curStaticInst->isDelayedCommit() &&
109 !curStaticInst->isLastMicroop()) ||
110 (boundaryInst && boundaryInst->isDelayedCommit() &&
111 !boundaryInst->isLastMicroop())) {
112 panic(
"%lli: Trying to take an interrupt in middle of "
113 "a non-interuptable instruction!",
curTick());
116 thread->decoder.reset();
120 template <
class Impl>
129 if ((completed_inst->isSerializing() ||
130 completed_inst->isSerializeBefore()) &&
132 (instList.front()->seqNum != completed_inst->seqNum) : 0)) {
133 panic(
"%lli: Instruction sn:%lli at PC %s is serializing before but is"
134 " entering instList with other instructions\n",
curTick(),
135 completed_inst->seqNum, completed_inst->pcState());
143 if (!instList.empty()) {
144 if (youngestSN < completed_inst->seqNum) {
146 completed_inst->seqNum, completed_inst->
pcState());
147 instList.push_back(completed_inst);
148 youngestSN = completed_inst->seqNum;
151 if (!instList.front()->isCompleted()) {
154 inst = instList.front();
155 instList.pop_front();
158 if (!completed_inst->isCompleted()) {
159 if (youngestSN < completed_inst->seqNum) {
161 completed_inst->seqNum, completed_inst->
pcState());
162 instList.push_back(completed_inst);
163 youngestSN = completed_inst->seqNum;
167 if (youngestSN < completed_inst->seqNum) {
168 inst = completed_inst;
169 youngestSN = completed_inst->seqNum;
178 if (inst->isSerializeAfter() && !instList.empty()) {
179 panic(
"%lli: Instruction sn:%lli at PC %s is serializing after but is"
180 " exiting instList with other instructions\n",
curTick(),
181 completed_inst->seqNum, completed_inst->pcState());
183 unverifiedInst = inst;
191 unverifiedInst->seqNum, unverifiedInst->
pcState());
192 unverifiedReq = NULL;
193 unverifiedReq = unverifiedInst->reqToVerify;
194 unverifiedMemData = unverifiedInst->memData;
196 while (!result.empty()) {
213 if (newPCState == thread->pcState()) {
216 warn(
"%lli: Changed PC does not match expected PC, "
217 "changed: %s, expected: %s",
218 curTick(), thread->pcState(), newPCState);
221 willChangePC =
false;
227 uint64_t fetchOffset = 0;
228 bool fetchDone =
false;
231 Addr fetch_PC = thread->instAddr();
232 fetch_PC = (fetch_PC & PCMask) + fetchOffset;
237 if (!curMacroStaticInst) {
239 auto mem_req = std::make_shared<Request>(
240 fetch_PC,
sizeof(
MachInst), 0, requestorId, fetch_PC,
241 thread->contextId());
243 mem_req->setVirt(fetch_PC,
sizeof(
MachInst),
247 fault = itb->translateFunctional(
251 if (unverifiedInst->getFault() ==
NoFault) {
257 warn(
"%lli: Instruction PC %s was not found in the "
258 "ITB!",
curTick(), thread->pcState());
259 handleError(unverifiedInst);
265 unverifiedInst = NULL;
271 fault = unverifiedInst->getFault();
278 icachePort->sendFunctional(pkt);
289 curStaticInst = thread->decoder.fetchRomMicroop(
290 pcState.microPC(),
nullptr);
291 }
else if (!curMacroStaticInst) {
297 Addr fetchPC = (pcState.instAddr() & PCMask) + fetchOffset;
298 thread->decoder.moreBytes(pcState, fetchPC, machInst);
303 if (thread->decoder.instReady()) {
305 instPtr = thread->decoder.decode(pcState);
306 thread->pcState(pcState);
315 curMacroStaticInst = instPtr;
319 curStaticInst = instPtr;
330 thread->decoder.reset();
334 Fault unverifiedFault;
336 unverifiedFault = unverifiedInst->getFault();
340 validateInst(unverifiedInst);
352 if (!unverifiedInst->isUnverifiable()) {
358 fault = curStaticInst->execute(
this, traceData);
366 thread->funcExeInst++;
368 validateExecution(unverifiedInst);
370 if (curStaticInst->isLoad()) {
374 panic(
"%lli: sn: %lli at PC: %s took a fault in checker "
375 "but not in driver CPU\n",
curTick(),
376 unverifiedInst->seqNum, unverifiedInst->pcState());
378 panic(
"%lli: sn: %lli at PC: %s took a fault in driver "
379 "CPU but not in checker\n",
curTick(),
380 unverifiedInst->seqNum, unverifiedInst->pcState());
387 fault->invoke(tc, curStaticInst);
389 newPCState = thread->pcState();
404 oldpc = thread->instAddr();
405 thread->pcEventQueue.service(oldpc, tc);
407 }
while (oldpc != thread->instAddr());
410 newPCState = thread->pcState();
421 if (instList.empty()) {
423 }
else if (instList.front()->isCompleted()) {
424 unverifiedInst = NULL;
425 unverifiedInst = instList.front();
426 instList.pop_front();
431 unverifiedInst = NULL;
434 template <
class Impl>
441 template <
class Impl>
447 template <
class Impl>
451 if (inst->instAddr() != thread->instAddr()) {
452 warn(
"%lli: PCs do not match! Inst: %s, checker: %s",
453 curTick(), inst->pcState(), thread->pcState());
455 warn(
"%lli: Changed PCs recently, may not be an error",
462 if (curStaticInst != inst->staticInst) {
463 warn(
"%lli: StaticInstPtrs don't match. (%s, %s).\n",
curTick(),
464 curStaticInst->getName(), inst->staticInst->getName());
468 template <
class Impl>
475 bool result_mismatch =
false;
476 bool scalar_mismatch =
false;
477 bool vector_mismatch =
false;
479 if (inst->isUnverifiable()) {
484 }
else if (inst->numDestRegs() > 0 && !result.empty()) {
485 DPRINTF(
Checker,
"Dest regs %d, number of checker dest regs %d\n",
486 inst->numDestRegs(), result.size());
487 for (
int i = 0;
i < inst->numDestRegs() && !result.empty();
i++) {
488 checker_val = result.front();
490 inst_val = inst->popResult(
492 if (checker_val != inst_val) {
493 result_mismatch =
true;
495 scalar_mismatch = checker_val.
isScalar();
496 vector_mismatch = checker_val.
isVector();
497 panic_if(!(scalar_mismatch || vector_mismatch),
498 "Unknown type of result\n");
507 if (result_mismatch) {
508 if (scalar_mismatch) {
509 warn(
"%lli: Instruction results (%i) do not match! (Values may"
510 " not actually be integers) Inst: %#x, checker: %#x",
522 if (inst->isLoad() && warnOnlyOnLoadError) {
523 copyResult(inst, inst_val, idx);
529 if (inst->nextInstAddr() != thread->nextInstAddr()) {
530 warn(
"%lli: Instruction next PCs do not match! Inst: %#x, "
532 curTick(), inst->nextInstAddr(), thread->nextInstAddr());
541 while (!miscRegIdxs.empty()) {
542 int misc_reg_idx = miscRegIdxs.front();
545 if (inst->tcBase()->readMiscRegNoEffect(misc_reg_idx) !=
546 thread->readMiscRegNoEffect(misc_reg_idx)) {
547 warn(
"%lli: Misc reg idx %i (side effect) does not match! "
548 "Inst: %#x, checker: %#x",
550 inst->tcBase()->readMiscRegNoEffect(misc_reg_idx),
551 thread->readMiscRegNoEffect(misc_reg_idx));
561 template <
class Impl>
565 if (updateThisCycle) {
567 panic(
"%lli: Instruction PC %#x results didn't match up, copying all "
568 "registers from main CPU",
curTick(), unverifiedInst->instAddr());
571 bool no_squash_from_TC = unverifiedInst->thread->noSquashFromTC;
572 unverifiedInst->thread->noSquashFromTC =
true;
575 thread->copyArchRegs(unverifiedInst->tcBase());
576 unverifiedInst->thread->noSquashFromTC = no_squash_from_TC;
579 curStaticInst = unverifiedInst->staticInst;
582 updateThisCycle =
false;
586 template <
class Impl>
589 const InstResult& mismatch_val,
int start_idx)
593 if (start_idx >= 0) {
594 const RegId& idx = inst->destRegIdx(start_idx);
606 thread->setVecReg(idx, mismatch_val.
asVector());
610 "Unexpected type of result");
627 for (
int i = start_idx;
i < inst->numDestRegs();
i++) {
628 const RegId& idx = inst->destRegIdx(
i);
629 res = inst->popResult();
641 thread->setVecReg(idx, res.
asVector());
654 thread->setMiscReg(idx.
index(), 0);
663 template <
class Impl>
667 cprintf(
"Error detected, instruction information:\n");
668 cprintf(
"PC:%s, nextPC:%#x\n[sn:%lli]\n[tid:%i]\n"
671 inst->nextInstAddr(),
674 inst->isCompleted());
679 template <
class Impl>
687 cprintf(
"Inst list size: %i\n", instList.size());
689 while (inst_list_it != instList.end())
694 cprintf(
"PC:%s\n[sn:%lli]\n[tid:%i]\n"
696 (*inst_list_it)->pcState(),
697 (*inst_list_it)->seqNum,
698 (*inst_list_it)->threadNumber,
699 (*inst_list_it)->isCompleted());
709 #endif//__CPU_CHECKER_CPU_IMPL_HH__