42 #ifndef __CPU_CHECKER_CPU_IMPL_HH__
43 #define __CPU_CHECKER_CPU_IMPL_HH__
56 #include "debug/Checker.hh"
64 template <
class DynInstPtr>
70 fault->invoke(tc, curStaticInst);
71 thread->decoder->reset();
74 if (curStaticInst->isLastMicroop())
83 template <
class DynInstPtr>
87 DPRINTF(
Checker,
"IRQ detected at PC: %s with %d insts in buffer\n",
88 thread->
pcState(), instList.size());
90 if (!instList.empty()) {
95 for (itr = instList.begin(); itr != instList.end(); itr++) {
96 (*itr)->setCompleted();
99 inst = instList.front();
100 boundaryInst = instList.back();
104 if ((!boundaryInst && curMacroStaticInst &&
105 curStaticInst->isDelayedCommit() &&
106 !curStaticInst->isLastMicroop()) ||
107 (boundaryInst && boundaryInst->isDelayedCommit() &&
108 !boundaryInst->isLastMicroop())) {
109 panic(
"%lli: Trying to take an interrupt in middle of "
110 "a non-interuptable instruction!",
curTick());
113 thread->decoder->reset();
117 template <
class DynInstPtr>
126 if ((completed_inst->isSerializing() ||
127 completed_inst->isSerializeBefore()) &&
129 (instList.front()->seqNum != completed_inst->seqNum) : 0)) {
130 panic(
"%lli: Instruction sn:%lli at PC %s is serializing before but is"
131 " entering instList with other instructions\n",
curTick(),
132 completed_inst->seqNum, completed_inst->pcState());
140 if (!instList.empty()) {
141 if (youngestSN < completed_inst->seqNum) {
143 completed_inst->seqNum, completed_inst->
pcState());
144 instList.push_back(completed_inst);
145 youngestSN = completed_inst->seqNum;
148 if (!instList.front()->isCompleted()) {
151 inst = instList.front();
152 instList.pop_front();
155 if (!completed_inst->isCompleted()) {
156 if (youngestSN < completed_inst->seqNum) {
158 completed_inst->seqNum, completed_inst->
pcState());
159 instList.push_back(completed_inst);
160 youngestSN = completed_inst->seqNum;
164 if (youngestSN < completed_inst->seqNum) {
165 inst = completed_inst;
166 youngestSN = completed_inst->seqNum;
175 if (inst->isSerializeAfter() && !instList.empty()) {
176 panic(
"%lli: Instruction sn:%lli at PC %s is serializing after but is"
177 " exiting instList with other instructions\n",
curTick(),
178 completed_inst->seqNum, completed_inst->pcState());
180 unverifiedInst = inst;
183 auto &
decoder = thread->decoder;
191 unverifiedInst->seqNum, unverifiedInst->
pcState());
192 unverifiedReq = NULL;
193 unverifiedReq = unverifiedInst->reqToVerify;
194 unverifiedMemData = unverifiedInst->memData;
196 while (!result.empty()) {
199 baseStats.numCycles++;
210 if (*newPCState == thread->pcState()) {
213 warn(
"%lli: Changed PC does not match expected PC, "
214 "changed: %s, expected: %s",
215 curTick(), thread->pcState(), *newPCState);
218 willChangePC =
false;
224 uint64_t fetchOffset = 0;
225 bool fetchDone =
false;
227 Addr fetch_PC = thread->pcState().instAddr();
228 fetch_PC = (fetch_PC & pc_mask) + fetchOffset;
231 if (!curMacroStaticInst) {
233 auto mem_req = std::make_shared<Request>(
234 fetch_PC,
decoder->moreBytesSize(), 0, requestorId,
235 fetch_PC, thread->contextId());
237 mem_req->setVirt(fetch_PC,
decoder->moreBytesSize(),
239 thread->pcState().instAddr());
241 fault = mmu->translateFunctional(
245 if (unverifiedInst->getFault() ==
NoFault) {
251 warn(
"%lli: Instruction PC %s was not found in the "
252 "ITB!",
curTick(), thread->pcState());
253 handleError(unverifiedInst);
259 unverifiedInst = NULL;
265 fault = unverifiedInst->getFault();
272 icachePort->sendFunctional(pkt);
279 std::unique_ptr<PCStateBase> pc_state(
280 thread->pcState().clone());
284 curStaticInst =
decoder->fetchRomMicroop(
285 pc_state->microPC(),
nullptr);
286 }
else if (!curMacroStaticInst) {
293 (pc_state->instAddr() & pc_mask) + fetchOffset;
294 decoder->moreBytes(*pc_state, fetch_pc);
301 instPtr =
decoder->decode(*pc_state);
302 thread->pcState(*pc_state);
305 fetchOffset +=
decoder->moreBytesSize();
311 curMacroStaticInst = instPtr;
315 curStaticInst = instPtr;
330 Fault unverifiedFault;
332 unverifiedFault = unverifiedInst->getFault();
336 validateInst(unverifiedInst);
348 if (!unverifiedInst->isUnverifiable()) {
354 fault = curStaticInst->execute(
this, traceData);
363 validateExecution(unverifiedInst);
365 if (curStaticInst->isLoad()) {
369 panic(
"%lli: sn: %lli at PC: %s took a fault in checker "
370 "but not in driver CPU\n",
curTick(),
371 unverifiedInst->seqNum, unverifiedInst->pcState());
373 panic(
"%lli: sn: %lli at PC: %s took a fault in driver "
374 "CPU but not in checker\n",
curTick(),
375 unverifiedInst->seqNum, unverifiedInst->pcState());
382 fault->invoke(tc, curStaticInst);
384 set(newPCState, thread->pcState());
399 oldpc = thread->pcState().instAddr();
400 thread->pcEventQueue.service(oldpc, tc);
402 }
while (oldpc != thread->pcState().instAddr());
405 set(newPCState, thread->pcState());
416 if (instList.empty()) {
418 }
else if (instList.front()->isCompleted()) {
419 unverifiedInst = NULL;
420 unverifiedInst = instList.front();
421 instList.pop_front();
426 unverifiedInst = NULL;
429 template <
class DynInstPtr>
436 template <
class DynInstPtr>
439 template <
class DynInstPtr>
443 if (inst->pcState().instAddr() != thread->pcState().instAddr()) {
444 warn(
"%lli: PCs do not match! Inst: %s, checker: %s",
445 curTick(), inst->pcState(), thread->pcState());
447 warn(
"%lli: Changed PCs recently, may not be an error",
454 if (curStaticInst != inst->staticInst) {
455 warn(
"%lli: StaticInstPtrs don't match. (%s, %s).\n",
curTick(),
456 curStaticInst->getName(), inst->staticInst->getName());
460 template <
class DynInstPtr>
467 bool result_mismatch =
false;
469 if (inst->isUnverifiable()) {
474 }
else if (inst->numDestRegs() > 0 && !result.empty()) {
475 DPRINTF(
Checker,
"Dest regs %d, number of checker dest regs %d\n",
476 inst->numDestRegs(), result.size());
477 for (
int i = 0;
i < inst->numDestRegs() && !result.empty();
i++) {
478 checker_val = result.front();
480 inst_val = inst->popResult();
481 if (checker_val != inst_val) {
482 result_mismatch =
true;
492 if (result_mismatch) {
493 warn(
"%lli: Instruction results (%i) do not match! Inst: %s, "
504 if (inst->isLoad() && warnOnlyOnLoadError) {
505 copyResult(inst, inst_val, idx);
511 if (inst->pcState() != thread->pcState()) {
512 warn(
"%lli: Instruction PCs do not match! Inst: %s, checker: %s",
513 curTick(), inst->pcState(), thread->pcState());
522 while (!miscRegIdxs.empty()) {
523 int misc_reg_idx = miscRegIdxs.front();
526 if (inst->tcBase()->readMiscRegNoEffect(misc_reg_idx) !=
527 thread->readMiscRegNoEffect(misc_reg_idx)) {
528 warn(
"%lli: Misc reg idx %i (side effect) does not match! "
529 "Inst: %#x, checker: %#x",
531 inst->tcBase()->readMiscRegNoEffect(misc_reg_idx),
532 thread->readMiscRegNoEffect(misc_reg_idx));
542 template <
class DynInstPtr>
546 if (updateThisCycle) {
548 panic(
"%lli: Instruction PC %#x results didn't match up, copying all "
549 "registers from main CPU",
curTick(),
550 unverifiedInst->pcState().instAddr());
553 bool no_squash_from_TC = unverifiedInst->thread->noSquashFromTC;
554 unverifiedInst->thread->noSquashFromTC =
true;
557 thread->copyArchRegs(unverifiedInst->tcBase());
558 unverifiedInst->thread->noSquashFromTC = no_squash_from_TC;
561 curStaticInst = unverifiedInst->staticInst;
564 updateThisCycle =
false;
568 template <
class DynInstPtr>
575 if (start_idx >= 0) {
576 const RegId& idx = inst->destRegIdx(start_idx);
582 else if (mismatch_val.
isBlob())
583 thread->setReg(idx, mismatch_val.
asBlob());
585 thread->setReg(idx, mismatch_val.
asRegVal());
589 for (
int i = start_idx;
i < inst->numDestRegs();
i++) {
590 const RegId& idx = inst->destRegIdx(
i);
591 res = inst->popResult();
596 thread->setMiscReg(idx.
index(), 0);
598 thread->setReg(idx, res.
asBlob());
600 thread->setReg(idx, res.
asRegVal());
604 template <
class DynInstPtr>
608 cprintf(
"Error detected, instruction information:\n");
609 cprintf(
"PC:%s\n[sn:%lli]\n[tid:%i]\n"
614 inst->isCompleted());
619 template <
class DynInstPtr>
627 cprintf(
"Inst list size: %i\n", instList.size());
629 while (inst_list_it != instList.end())
634 cprintf(
"PC:%s\n[sn:%lli]\n[tid:%i]\n"
636 (*inst_list_it)->pcState(),
637 (*inst_list_it)->seqNum,
638 (*inst_list_it)->threadNumber,
639 (*inst_list_it)->isCompleted());
651 #endif//__CPU_CHECKER_CPU_IMPL_HH__