42 #ifndef __CPU_CHECKER_CPU_IMPL_HH__ 43 #define __CPU_CHECKER_CPU_IMPL_HH__ 48 #include "arch/isa_traits.hh" 50 #include "config/the_isa.hh" 58 #include "debug/Checker.hh" 72 fault->invoke(tc, curStaticInst);
73 thread->decoder.reset();
76 if (curStaticInst->isLastMicroop())
80 thread->pcState(pcState);
91 DPRINTF(
Checker,
"IRQ detected at PC: %s with %d insts in buffer\n",
92 thread->
pcState(), instList.size());
94 if (!instList.empty()) {
99 for (itr = instList.begin(); itr != instList.end(); itr++) {
100 (*itr)->setCompleted();
103 inst = instList.front();
104 boundaryInst = instList.back();
108 if ((!boundaryInst && curMacroStaticInst &&
109 curStaticInst->isDelayedCommit() &&
110 !curStaticInst->isLastMicroop()) ||
111 (boundaryInst && boundaryInst->isDelayedCommit() &&
112 !boundaryInst->isLastMicroop())) {
113 panic(
"%lli: Trying to take an interrupt in middle of " 114 "a non-interuptable instruction!",
curTick());
117 thread->decoder.reset();
121 template <
class Impl>
130 if ((completed_inst->isSerializing() ||
131 completed_inst->isSerializeBefore()) &&
133 (instList.front()->seqNum != completed_inst->seqNum) : 0)) {
134 panic(
"%lli: Instruction sn:%lli at PC %s is serializing before but is" 135 " entering instList with other instructions\n",
curTick(),
136 completed_inst->seqNum, completed_inst->pcState());
144 if (!instList.empty()) {
145 if (youngestSN < completed_inst->seqNum) {
147 completed_inst->seqNum, completed_inst->
pcState());
148 instList.push_back(completed_inst);
149 youngestSN = completed_inst->seqNum;
152 if (!instList.front()->isCompleted()) {
155 inst = instList.front();
156 instList.pop_front();
159 if (!completed_inst->isCompleted()) {
160 if (youngestSN < completed_inst->seqNum) {
162 completed_inst->seqNum, completed_inst->
pcState());
163 instList.push_back(completed_inst);
164 youngestSN = completed_inst->seqNum;
168 if (youngestSN < completed_inst->seqNum) {
169 inst = completed_inst;
170 youngestSN = completed_inst->seqNum;
179 if (inst->isSerializeAfter() && !instList.empty()) {
180 panic(
"%lli: Instruction sn:%lli at PC %s is serializing after but is" 181 " exiting instList with other instructions\n",
curTick(),
182 completed_inst->seqNum, completed_inst->pcState());
184 unverifiedInst = inst;
192 unverifiedInst->seqNum, unverifiedInst->
pcState());
193 unverifiedReq = NULL;
194 unverifiedReq = unverifiedInst->reqToVerify;
195 unverifiedMemData = unverifiedInst->memData;
197 while (!result.empty()) {
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;
232 Addr fetch_PC = thread->instAddr();
233 fetch_PC = (fetch_PC & PCMask) + fetchOffset;
238 if (!curMacroStaticInst) {
240 auto mem_req = std::make_shared<Request>(
241 fetch_PC,
sizeof(
MachInst), 0, masterId, fetch_PC,
242 thread->contextId());
244 mem_req->setVirt(fetch_PC,
sizeof(
MachInst),
248 fault = itb->translateFunctional(
252 if (unverifiedInst->getFault() ==
NoFault) {
258 warn(
"%lli: Instruction PC %s was not found in the " 259 "ITB!",
curTick(), thread->pcState());
260 handleError(unverifiedInst);
266 unverifiedInst = NULL;
272 fault = unverifiedInst->getFault();
279 icachePort->sendFunctional(pkt);
291 microcodeRom.fetchMicroop(pcState.microPC(), NULL);
292 }
else if (!curMacroStaticInst) {
298 Addr fetchPC = (pcState.instAddr() & PCMask) + fetchOffset;
299 thread->decoder.moreBytes(pcState, fetchPC, machInst);
304 if (thread->decoder.instReady()) {
306 instPtr = thread->decoder.decode(pcState);
307 thread->pcState(pcState);
316 curMacroStaticInst = instPtr;
320 curStaticInst = instPtr;
331 thread->decoder.reset();
335 Fault unverifiedFault;
337 unverifiedFault = unverifiedInst->getFault();
341 validateInst(unverifiedInst);
353 if (!unverifiedInst->isUnverifiable()) {
359 fault = curStaticInst->execute(
this, traceData);
367 thread->funcExeInst++;
369 validateExecution(unverifiedInst);
371 if (curStaticInst->isLoad()) {
375 panic(
"%lli: sn: %lli at PC: %s took a fault in checker " 376 "but not in driver CPU\n",
curTick(),
377 unverifiedInst->seqNum, unverifiedInst->pcState());
379 panic(
"%lli: sn: %lli at PC: %s took a fault in driver " 380 "CPU but not in checker\n",
curTick(),
381 unverifiedInst->seqNum, unverifiedInst->pcState());
388 fault->invoke(tc, curStaticInst);
390 newPCState = thread->pcState();
405 oldpc = thread->instAddr();
406 thread->pcEventQueue.service(oldpc, tc);
408 }
while (oldpc != thread->instAddr());
411 newPCState = thread->pcState();
422 if (instList.empty()) {
424 }
else if (instList.front()->isCompleted()) {
425 unverifiedInst = NULL;
426 unverifiedInst = instList.front();
427 instList.pop_front();
432 unverifiedInst = NULL;
435 template <
class Impl>
442 template <
class Impl>
448 template <
class Impl>
452 if (inst->instAddr() != thread->instAddr()) {
453 warn(
"%lli: PCs do not match! Inst: %s, checker: %s",
454 curTick(), inst->pcState(), thread->pcState());
456 warn(
"%lli: Changed PCs recently, may not be an error",
463 if (curStaticInst != inst->staticInst) {
464 warn(
"%lli: StaticInstPtrs don't match. (%s, %s).\n",
curTick(),
465 curStaticInst->getName(), inst->staticInst->getName());
469 template <
class Impl>
476 bool result_mismatch =
false;
477 bool scalar_mismatch =
false;
478 bool vector_mismatch =
false;
480 if (inst->isUnverifiable()) {
485 }
else if (inst->numDestRegs() > 0 && !result.empty()) {
486 DPRINTF(
Checker,
"Dest regs %d, number of checker dest regs %d\n",
487 inst->numDestRegs(), result.size());
488 for (
int i = 0;
i < inst->numDestRegs() && !result.empty();
i++) {
489 checker_val = result.front();
491 inst_val = inst->popResult(
493 if (checker_val != inst_val) {
494 result_mismatch =
true;
496 scalar_mismatch = checker_val.
isScalar();
497 vector_mismatch = checker_val.
isVector();
498 panic_if(!(scalar_mismatch || vector_mismatch),
499 "Unknown type of result\n");
508 if (result_mismatch) {
509 if (scalar_mismatch) {
510 warn(
"%lli: Instruction results (%i) do not match! (Values may" 511 " not actually be integers) Inst: %#x, checker: %#x",
523 if (inst->isLoad() && warnOnlyOnLoadError) {
524 copyResult(inst, inst_val, idx);
530 if (inst->nextInstAddr() != thread->nextInstAddr()) {
531 warn(
"%lli: Instruction next PCs do not match! Inst: %#x, " 533 curTick(), inst->nextInstAddr(), thread->nextInstAddr());
542 while (!miscRegIdxs.empty()) {
543 int misc_reg_idx = miscRegIdxs.front();
546 if (inst->tcBase()->readMiscRegNoEffect(misc_reg_idx) !=
547 thread->readMiscRegNoEffect(misc_reg_idx)) {
548 warn(
"%lli: Misc reg idx %i (side effect) does not match! " 549 "Inst: %#x, checker: %#x",
551 inst->tcBase()->readMiscRegNoEffect(misc_reg_idx),
552 thread->readMiscRegNoEffect(misc_reg_idx));
562 template <
class Impl>
566 if (updateThisCycle) {
568 panic(
"%lli: Instruction PC %#x results didn't match up, copying all " 569 "registers from main CPU",
curTick(), unverifiedInst->instAddr());
572 bool no_squash_from_TC = unverifiedInst->thread->noSquashFromTC;
573 unverifiedInst->thread->noSquashFromTC =
true;
576 thread->copyArchRegs(unverifiedInst->tcBase());
577 unverifiedInst->thread->noSquashFromTC = no_squash_from_TC;
580 curStaticInst = unverifiedInst->staticInst;
583 updateThisCycle =
false;
587 template <
class Impl>
590 const InstResult& mismatch_val,
int start_idx)
594 if (start_idx >= 0) {
595 const RegId& idx = inst->destRegIdx(start_idx);
607 thread->setVecReg(idx, mismatch_val.
asVector());
611 "Unexpected type of result");
628 for (
int i = start_idx;
i < inst->numDestRegs();
i++) {
629 const RegId& idx = inst->destRegIdx(
i);
630 res = inst->popResult();
642 thread->setVecReg(idx, res.
asVector());
655 thread->setMiscReg(idx.
index(), 0);
664 template <
class Impl>
668 cprintf(
"Error detected, instruction information:\n");
669 cprintf(
"PC:%s, nextPC:%#x\n[sn:%lli]\n[tid:%i]\n" 672 inst->nextInstAddr(),
675 inst->isCompleted());
680 template <
class Impl>
688 cprintf(
"Inst list size: %i\n", instList.size());
690 while (inst_list_it != instList.end())
695 cprintf(
"PC:%s\n[sn:%lli]\n[tid:%i]\n" 697 (*inst_list_it)->pcState(),
698 (*inst_list_it)->seqNum,
699 (*inst_list_it)->threadNumber,
700 (*inst_list_it)->isCompleted());
710 #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.
The request was an instruction fetch.
void advancePC(PCState &pc, const StaticInstPtr &inst)
bool isScalar() const
Checks.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
static bool isRomMicroPC(MicroPC upc)
const VecRegContainer & asVector() const
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.
GenericISA::DelaySlotPCState< MachInst > PCState
#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.