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"
65 template <
class DynInstPtr>
71 fault->invoke(tc, curStaticInst);
72 thread->decoder->reset();
75 if (curStaticInst->isLastMicroop())
84 template <
class DynInstPtr>
88 DPRINTF(
Checker,
"IRQ detected at PC: %s with %d insts in buffer\n",
89 thread->
pcState(), instList.size());
91 if (!instList.empty()) {
96 for (itr = instList.begin(); itr != instList.end(); itr++) {
97 (*itr)->setCompleted();
100 inst = instList.front();
101 boundaryInst = instList.back();
105 if ((!boundaryInst && curMacroStaticInst &&
106 curStaticInst->isDelayedCommit() &&
107 !curStaticInst->isLastMicroop()) ||
108 (boundaryInst && boundaryInst->isDelayedCommit() &&
109 !boundaryInst->isLastMicroop())) {
110 panic(
"%lli: Trying to take an interrupt in middle of "
111 "a non-interuptable instruction!",
curTick());
114 thread->decoder->reset();
118 template <
class DynInstPtr>
127 if ((completed_inst->isSerializing() ||
128 completed_inst->isSerializeBefore()) &&
130 (instList.front()->seqNum != completed_inst->seqNum) : 0)) {
131 panic(
"%lli: Instruction sn:%lli at PC %s is serializing before but is"
132 " entering instList with other instructions\n",
curTick(),
133 completed_inst->seqNum, completed_inst->pcState());
141 if (!instList.empty()) {
142 if (youngestSN < completed_inst->seqNum) {
144 completed_inst->seqNum, completed_inst->
pcState());
145 instList.push_back(completed_inst);
146 youngestSN = completed_inst->seqNum;
149 if (!instList.front()->isCompleted()) {
152 inst = instList.front();
153 instList.pop_front();
156 if (!completed_inst->isCompleted()) {
157 if (youngestSN < completed_inst->seqNum) {
159 completed_inst->seqNum, completed_inst->
pcState());
160 instList.push_back(completed_inst);
161 youngestSN = completed_inst->seqNum;
165 if (youngestSN < completed_inst->seqNum) {
166 inst = completed_inst;
167 youngestSN = completed_inst->seqNum;
176 if (inst->isSerializeAfter() && !instList.empty()) {
177 panic(
"%lli: Instruction sn:%lli at PC %s is serializing after but is"
178 " exiting instList with other instructions\n",
curTick(),
179 completed_inst->seqNum, completed_inst->pcState());
181 unverifiedInst = inst;
184 auto &
decoder = thread->decoder;
192 unverifiedInst->seqNum, unverifiedInst->
pcState());
193 unverifiedReq = NULL;
194 unverifiedReq = unverifiedInst->reqToVerify;
195 unverifiedMemData = unverifiedInst->memData;
197 while (!result.empty()) {
200 baseStats.numCycles++;
205 thread->setIntReg(zeroReg, 0);
214 if (*newPCState == thread->pcState()) {
217 warn(
"%lli: Changed PC does not match expected PC, "
218 "changed: %s, expected: %s",
219 curTick(), thread->pcState(), *newPCState);
222 willChangePC =
false;
228 uint64_t fetchOffset = 0;
229 bool fetchDone =
false;
231 Addr fetch_PC = thread->pcState().instAddr();
232 fetch_PC = (fetch_PC & pc_mask) + fetchOffset;
235 if (!curMacroStaticInst) {
237 auto mem_req = std::make_shared<Request>(
238 fetch_PC,
decoder->moreBytesSize(), 0, requestorId,
239 fetch_PC, thread->contextId());
241 mem_req->setVirt(fetch_PC,
decoder->moreBytesSize(),
243 thread->pcState().instAddr());
245 fault = mmu->translateFunctional(
249 if (unverifiedInst->getFault() ==
NoFault) {
255 warn(
"%lli: Instruction PC %s was not found in the "
256 "ITB!",
curTick(), thread->pcState());
257 handleError(unverifiedInst);
263 unverifiedInst = NULL;
269 fault = unverifiedInst->getFault();
276 icachePort->sendFunctional(pkt);
283 std::unique_ptr<PCStateBase> pc_state(
284 thread->pcState().clone());
288 curStaticInst =
decoder->fetchRomMicroop(
289 pc_state->microPC(),
nullptr);
290 }
else if (!curMacroStaticInst) {
297 (pc_state->instAddr() & pc_mask) + fetchOffset;
298 decoder->moreBytes(*pc_state, fetch_pc);
305 instPtr =
decoder->decode(*pc_state);
306 thread->pcState(*pc_state);
309 fetchOffset +=
decoder->moreBytesSize();
315 curMacroStaticInst = instPtr;
319 curStaticInst = instPtr;
334 Fault unverifiedFault;
336 unverifiedFault = unverifiedInst->getFault();
340 validateInst(unverifiedInst);
352 if (!unverifiedInst->isUnverifiable()) {
358 fault = curStaticInst->execute(
this, traceData);
367 validateExecution(unverifiedInst);
369 if (curStaticInst->isLoad()) {
373 panic(
"%lli: sn: %lli at PC: %s took a fault in checker "
374 "but not in driver CPU\n",
curTick(),
375 unverifiedInst->seqNum, unverifiedInst->pcState());
377 panic(
"%lli: sn: %lli at PC: %s took a fault in driver "
378 "CPU but not in checker\n",
curTick(),
379 unverifiedInst->seqNum, unverifiedInst->pcState());
386 fault->invoke(tc, curStaticInst);
388 set(newPCState, thread->pcState());
403 oldpc = thread->pcState().instAddr();
404 thread->pcEventQueue.service(oldpc, tc);
406 }
while (oldpc != thread->pcState().instAddr());
409 set(newPCState, thread->pcState());
420 if (instList.empty()) {
422 }
else if (instList.front()->isCompleted()) {
423 unverifiedInst = NULL;
424 unverifiedInst = instList.front();
425 instList.pop_front();
430 unverifiedInst = NULL;
433 template <
class DynInstPtr>
440 template <
class DynInstPtr>
443 template <
class DynInstPtr>
447 if (inst->pcState().instAddr() != thread->pcState().instAddr()) {
448 warn(
"%lli: PCs do not match! Inst: %s, checker: %s",
449 curTick(), inst->pcState(), thread->pcState());
451 warn(
"%lli: Changed PCs recently, may not be an error",
458 if (curStaticInst != inst->staticInst) {
459 warn(
"%lli: StaticInstPtrs don't match. (%s, %s).\n",
curTick(),
460 curStaticInst->getName(), inst->staticInst->getName());
464 template <
class DynInstPtr>
471 bool result_mismatch =
false;
472 bool scalar_mismatch =
false;
474 if (inst->isUnverifiable()) {
479 }
else if (inst->numDestRegs() > 0 && !result.empty()) {
480 DPRINTF(
Checker,
"Dest regs %d, number of checker dest regs %d\n",
481 inst->numDestRegs(), result.size());
482 for (
int i = 0;
i < inst->numDestRegs() && !result.empty();
i++) {
483 checker_val = result.front();
486 if (checker_val != inst_val) {
487 result_mismatch =
true;
489 scalar_mismatch = checker_val.
is<
RegVal>();
498 if (result_mismatch) {
499 if (scalar_mismatch) {
500 warn(
"%lli: Instruction results (%i) do not match! (Values may"
501 " not actually be integers) Inst: %#x, checker: %#x",
513 if (inst->isLoad() && warnOnlyOnLoadError) {
514 copyResult(inst, inst_val, idx);
520 if (inst->pcState() != thread->pcState()) {
521 warn(
"%lli: Instruction PCs do not match! Inst: %s, checker: %s",
522 curTick(), inst->pcState(), thread->pcState());
531 while (!miscRegIdxs.empty()) {
532 int misc_reg_idx = miscRegIdxs.front();
535 if (inst->tcBase()->readMiscRegNoEffect(misc_reg_idx) !=
536 thread->readMiscRegNoEffect(misc_reg_idx)) {
537 warn(
"%lli: Misc reg idx %i (side effect) does not match! "
538 "Inst: %#x, checker: %#x",
540 inst->tcBase()->readMiscRegNoEffect(misc_reg_idx),
541 thread->readMiscRegNoEffect(misc_reg_idx));
551 template <
class DynInstPtr>
555 if (updateThisCycle) {
557 panic(
"%lli: Instruction PC %#x results didn't match up, copying all "
558 "registers from main CPU",
curTick(),
559 unverifiedInst->pcState().instAddr());
562 bool no_squash_from_TC = unverifiedInst->thread->noSquashFromTC;
563 unverifiedInst->thread->noSquashFromTC =
true;
566 thread->copyArchRegs(unverifiedInst->tcBase());
567 unverifiedInst->thread->noSquashFromTC = no_squash_from_TC;
570 curStaticInst = unverifiedInst->staticInst;
573 updateThisCycle =
false;
577 template <
class DynInstPtr>
584 if (start_idx >= 0) {
585 const RegId& idx = inst->destRegIdx(start_idx);
597 thread->setVecElem(idx, mismatch_val.
as<
RegVal>());
611 for (
int i = start_idx;
i < inst->numDestRegs();
i++) {
612 const RegId& idx = inst->destRegIdx(
i);
613 res = inst->popResult();
625 thread->setVecElem(idx, res.
as<
RegVal>());
632 thread->setMiscReg(idx.
index(), 0);
641 template <
class DynInstPtr>
645 cprintf(
"Error detected, instruction information:\n");
646 cprintf(
"PC:%s\n[sn:%lli]\n[tid:%i]\n"
651 inst->isCompleted());
656 template <
class DynInstPtr>
664 cprintf(
"Inst list size: %i\n", instList.size());
666 while (inst_list_it != instList.end())
671 cprintf(
"PC:%s\n[sn:%lli]\n[tid:%i]\n"
673 (*inst_list_it)->pcState(),
674 (*inst_list_it)->seqNum,
675 (*inst_list_it)->threadNumber,
676 (*inst_list_it)->isCompleted());
688 #endif//__CPU_CHECKER_CPU_IMPL_HH__