2 * Copyright (c) 2006 The Regents of The University of Michigan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "base/refcnt.hh"
35 #include "cpu/base.hh"
36 #include "cpu/base_dyn_inst.hh"
37 #include "cpu/checker/cpu.hh"
38 #include "cpu/simple_thread.hh"
39 #include "cpu/thread_context.hh"
40 #include "cpu/static_inst.hh"
41 #include "mem/packet_impl.hh"
42 #include "sim/byteswap.hh"
43 #include "sim/sim_object.hh"
44 #include "sim/stats.hh"
47 #include "sim/system.hh"
48 #include "arch/vtophys.hh"
49 #include "kern/kernel_stats.hh"
53 //The CheckerCPU does alpha only
54 using namespace AlphaISA;
61 CheckerCPU::CheckerCPU(Params *p)
62 : BaseCPU(p), thread(NULL), tc(NULL)
72 changedPC = willChangePC = changedNextPC = false;
74 exitOnError = p->exitOnError;
75 warnOnlyOnLoadError = p->warnOnlyOnLoadError;
87 CheckerCPU::~CheckerCPU()
92 CheckerCPU::setMemory(MemObject *mem)
96 thread = new SimpleThread(this, /* thread_num */ 0, process,
99 thread->setStatus(ThreadContext::Suspended);
100 tc = thread->getTC();
101 threadContexts.push_back(tc);
106 CheckerCPU::setSystem(System *system)
111 thread = new SimpleThread(this, 0, systemPtr, itb, dtb, false);
113 thread->setStatus(ThreadContext::Suspended);
114 tc = thread->getTC();
115 threadContexts.push_back(tc);
116 delete thread->kernelStats;
117 thread->kernelStats = NULL;
122 CheckerCPU::setIcachePort(Port *icache_port)
124 icachePort = icache_port;
128 CheckerCPU::setDcachePort(Port *dcache_port)
130 dcachePort = dcache_port;
134 CheckerCPU::serialize(ostream &os)
137 BaseCPU::serialize(os);
138 SERIALIZE_SCALAR(inst);
139 nameOut(os, csprintf("%s.xc", name()));
140 thread->serialize(os);
141 cacheCompletionEvent.serialize(os);
146 CheckerCPU::unserialize(Checkpoint *cp, const string §ion)
149 BaseCPU::unserialize(cp, section);
150 UNSERIALIZE_SCALAR(inst);
151 thread->unserialize(cp, csprintf("%s.xc", section));
156 CheckerCPU::copySrcTranslate(Addr src)
158 panic("Unimplemented!");
162 CheckerCPU::copy(Addr dest)
164 panic("Unimplemented!");
169 CheckerCPU::read(Addr addr, T &data, unsigned flags)
171 // need to fill in CPU & thread IDs here
172 memReq = new Request();
174 memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC());
176 // translate to physical address
177 translateDataReadReq(memReq);
179 Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
181 pkt->dataStatic(&data);
183 if (!(memReq->getFlags() & UNCACHEABLE)) {
184 // Access memory to see if we have the same data
185 dcachePort->sendFunctional(pkt);
187 // Assume the data is correct if it's an uncached access
188 memcpy(&data, &unverifiedResult.integer, sizeof(T));
196 #ifndef DOXYGEN_SHOULD_SKIP_THIS
200 CheckerCPU::read(Addr addr, uint64_t &data, unsigned flags);
204 CheckerCPU::read(Addr addr, uint32_t &data, unsigned flags);
208 CheckerCPU::read(Addr addr, uint16_t &data, unsigned flags);
212 CheckerCPU::read(Addr addr, uint8_t &data, unsigned flags);
214 #endif //DOXYGEN_SHOULD_SKIP_THIS
218 CheckerCPU::read(Addr addr, double &data, unsigned flags)
220 return read(addr, *(uint64_t*)&data, flags);
225 CheckerCPU::read(Addr addr, float &data, unsigned flags)
227 return read(addr, *(uint32_t*)&data, flags);
232 CheckerCPU::read(Addr addr, int32_t &data, unsigned flags)
234 return read(addr, (uint32_t&)data, flags);
239 CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
241 // need to fill in CPU & thread IDs here
242 memReq = new Request();
244 memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC());
246 // translate to physical address
247 thread->translateDataWriteReq(memReq);
249 // Can compare the write data and result only if it's cacheable,
250 // not a store conditional, or is a store conditional that
252 // @todo: Verify that actual memory matches up with these values.
253 // Right now it only verifies that the instruction data is the
254 // same as what was in the request that got sent to memory; there
255 // is no verification that it is the same as what is in memory.
256 // This is because the LSQ would have to be snooped in the CPU to
259 !(unverifiedReq->getFlags() & UNCACHEABLE) &&
260 (!(unverifiedReq->getFlags() & LOCKED) ||
261 ((unverifiedReq->getFlags() & LOCKED) &&
262 unverifiedReq->getScResult() == 1))) {
265 // This code would work if the LSQ allowed for snooping.
266 Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
267 pkt.dataStatic(&inst_data);
269 dcachePort->sendFunctional(pkt);
273 memcpy(&inst_data, unverifiedMemData, sizeof(T));
275 if (data != inst_data) {
276 warn("%lli: Store value does not match value in memory! "
277 "Instruction: %#x, memory: %#x",
278 curTick, inst_data, data);
283 // Assume the result was the same as the one passed in. This checker
284 // doesn't check if the SC should succeed or fail, it just checks the
286 if (res && unverifiedReq->scResultValid())
287 *res = unverifiedReq->getScResult();
293 #ifndef DOXYGEN_SHOULD_SKIP_THIS
296 CheckerCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res);
300 CheckerCPU::write(uint32_t data, Addr addr, unsigned flags, uint64_t *res);
304 CheckerCPU::write(uint16_t data, Addr addr, unsigned flags, uint64_t *res);
308 CheckerCPU::write(uint8_t data, Addr addr, unsigned flags, uint64_t *res);
310 #endif //DOXYGEN_SHOULD_SKIP_THIS
314 CheckerCPU::write(double data, Addr addr, unsigned flags, uint64_t *res)
316 return write(*(uint64_t*)&data, addr, flags, res);
321 CheckerCPU::write(float data, Addr addr, unsigned flags, uint64_t *res)
323 return write(*(uint32_t*)&data, addr, flags, res);
328 CheckerCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res)
330 return write((uint32_t)data, addr, flags, res);
336 CheckerCPU::dbg_vtophys(Addr addr)
338 return vtophys(tc, addr);
340 #endif // FULL_SYSTEM
343 CheckerCPU::translateInstReq(Request *req)
346 return (thread->translateInstReq(req) == NoFault);
348 thread->translateInstReq(req);
354 CheckerCPU::translateDataReadReq(Request *req)
356 thread->translateDataReadReq(req);
358 if (req->getVaddr() != unverifiedReq->getVaddr()) {
359 warn("%lli: Request virtual addresses do not match! Inst: %#x, "
361 curTick, unverifiedReq->getVaddr(), req->getVaddr());
364 req->setPaddr(unverifiedReq->getPaddr());
366 if (checkFlags(req)) {
367 warn("%lli: Request flags do not match! Inst: %#x, checker: %#x",
368 curTick, unverifiedReq->getFlags(), req->getFlags());
374 CheckerCPU::translateDataWriteReq(Request *req)
376 thread->translateDataWriteReq(req);
378 if (req->getVaddr() != unverifiedReq->getVaddr()) {
379 warn("%lli: Request virtual addresses do not match! Inst: %#x, "
381 curTick, unverifiedReq->getVaddr(), req->getVaddr());
384 req->setPaddr(unverifiedReq->getPaddr());
386 if (checkFlags(req)) {
387 warn("%lli: Request flags do not match! Inst: %#x, checker: %#x",
388 curTick, unverifiedReq->getFlags(), req->getFlags());
394 CheckerCPU::checkFlags(Request *req)
396 // Remove any dynamic flags that don't have to do with the request itself.
397 unsigned flags = unverifiedReq->getFlags();
398 unsigned mask = LOCKED | PHYSICAL | VPTE | ALTMODE | UNCACHEABLE | NO_FAULT;
399 flags = flags & (mask);
400 if (flags == req->getFlags()) {
408 CheckerCPU::dumpAndExit()
410 warn("%lli: Checker PC:%#x, next PC:%#x",
411 curTick, thread->readPC(), thread->readNextPC());
412 panic("Checker found an error!");
415 template <class DynInstPtr>
417 Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
421 // Either check this instruction, or add it to a list of
422 // instructions waiting to be checked. Instructions must be
423 // checked in program order, so if a store has committed yet not
424 // completed, there may be some instructions that are waiting
425 // behind it that have completed and must be checked.
426 if (!instList.empty()) {
427 if (youngestSN < completed_inst->seqNum) {
428 DPRINTF(Checker, "Adding instruction [sn:%lli] PC:%#x to list.\n",
429 completed_inst->seqNum, completed_inst->readPC());
430 instList.push_back(completed_inst);
431 youngestSN = completed_inst->seqNum;
434 if (!instList.front()->isCompleted()) {
437 inst = instList.front();
438 instList.pop_front();
441 if (!completed_inst->isCompleted()) {
442 if (youngestSN < completed_inst->seqNum) {
443 DPRINTF(Checker, "Adding instruction [sn:%lli] PC:%#x to list.\n",
444 completed_inst->seqNum, completed_inst->readPC());
445 instList.push_back(completed_inst);
446 youngestSN = completed_inst->seqNum;
450 if (youngestSN < completed_inst->seqNum) {
451 inst = completed_inst;
452 youngestSN = completed_inst->seqNum;
459 // Try to check all instructions that are completed, ending if we
460 // run out of instructions to check or if an instruction is not
463 DPRINTF(Checker, "Processing instruction [sn:%lli] PC:%#x.\n",
464 inst->seqNum, inst->readPC());
465 unverifiedResult.integer = inst->readIntResult();
466 unverifiedReq = inst->req;
467 unverifiedMemData = inst->memData;
470 Fault fault = NoFault;
472 // maintain $r0 semantics
473 thread->setIntReg(ZeroReg, 0);
475 thread->setFloatRegDouble(ZeroReg, 0.0);
476 #endif // TARGET_ALPHA
478 // Check if any recent PC changes match up with anything we
479 // expect to happen. This is mostly to check if traps or
480 // PC-based events have occurred in both the checker and CPU.
482 DPRINTF(Checker, "Changed PC recently to %#x\n",
485 if (newPC == thread->readPC()) {
486 DPRINTF(Checker, "Changed PC matches expected PC\n");
488 warn("%lli: Changed PC does not match expected PC, "
489 "changed: %#x, expected: %#x",
490 curTick, thread->readPC(), newPC);
491 CheckerCPU::handleError();
493 willChangePC = false;
498 DPRINTF(Checker, "Changed NextPC recently to %#x\n",
499 thread->readNextPC());
500 changedNextPC = false;
503 // Try to fetch the instruction
506 #define IFETCH_FLAGS(pc) ((pc) & 1) ? PHYSICAL : 0
508 #define IFETCH_FLAGS(pc) 0
511 uint64_t fetch_PC = thread->readPC() & ~3;
513 // set up memory request for instruction fetch
514 memReq = new Request(inst->threadNumber, fetch_PC,
516 IFETCH_FLAGS(thread->readPC()),
517 fetch_PC, thread->readCpuId(), inst->threadNumber);
519 bool succeeded = translateInstReq(memReq);
522 if (inst->getFault() == NoFault) {
523 // In this case the instruction was not a dummy
524 // instruction carrying an ITB fault. In the single
525 // threaded case the ITB should still be able to
526 // translate this instruction; in the SMT case it's
527 // possible that its ITB entry was kicked out.
528 warn("%lli: Instruction PC %#x was not found in the ITB!",
529 curTick, thread->readPC());
532 // go to the next instruction
533 thread->setPC(thread->readNextPC());
534 thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
538 // The instruction is carrying an ITB fault. Handle
539 // the fault and see if our results match the CPU on
541 fault = inst->getFault();
545 if (fault == NoFault) {
546 Packet *pkt = new Packet(memReq, Packet::ReadReq,
549 pkt->dataStatic(&machInst);
551 icachePort->sendFunctional(pkt);
555 // keep an instruction count
558 // decode the instruction
559 machInst = gtoh(machInst);
560 // Checks that the instruction matches what we expected it to be.
561 // Checks both the machine instruction and the PC.
564 curStaticInst = StaticInst::decode(makeExtMI(machInst,
568 thread->setInst(machInst);
569 #endif // FULL_SYSTEM
571 fault = inst->getFault();
574 // Discard fetch's memReq.
578 // Either the instruction was a fault and we should process the fault,
579 // or we should just go ahead execute the instruction. This assumes
580 // that the instruction is properly marked as a fault.
581 if (fault == NoFault) {
583 thread->funcExeInst++;
585 fault = curStaticInst->execute(this, NULL);
587 // Checks to make sure instrution results are correct.
588 validateExecution(inst);
590 if (curStaticInst->isLoad()) {
595 if (fault != NoFault) {
599 newPC = thread->readPC();
600 DPRINTF(Checker, "Fault, PC is now %#x\n", newPC);
601 #else // !FULL_SYSTEM
602 fatal("fault (%d) detected @ PC 0x%08p", fault, thread->readPC());
603 #endif // FULL_SYSTEM
605 #if THE_ISA != MIPS_ISA
606 // go to the next instruction
607 thread->setPC(thread->readNextPC());
608 thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
610 // go to the next instruction
611 thread->setPC(thread->readNextPC());
612 thread->setNextPC(thread->readNextNPC());
613 thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
619 // @todo: Determine if these should happen only if the
620 // instruction hasn't faulted. In the SimpleCPU case this may
621 // not be true, but in the O3 or Ozone case this may be true.
625 oldpc = thread->readPC();
626 system->pcEventQueue.service(tc);
628 } while (oldpc != thread->readPC());
631 newPC = thread->readPC();
632 DPRINTF(Checker, "PC Event, PC is now %#x\n", newPC);
636 // @todo: Optionally can check all registers. (Or just those
637 // that have been modified).
645 // Continue verifying instructions if there's another completed
646 // instruction waiting to be verified.
647 if (instList.empty()) {
649 } else if (instList.front()->isCompleted()) {
650 inst = instList.front();
651 instList.pop_front();
658 template <class DynInstPtr>
660 Checker<DynInstPtr>::switchOut(Sampler *s)
665 template <class DynInstPtr>
667 Checker<DynInstPtr>::takeOverFrom(BaseCPU *oldCPU)
671 template <class DynInstPtr>
673 Checker<DynInstPtr>::validateInst(DynInstPtr &inst)
675 if (inst->readPC() != thread->readPC()) {
676 warn("%lli: PCs do not match! Inst: %#x, checker: %#x",
677 curTick, inst->readPC(), thread->readPC());
679 warn("%lli: Changed PCs recently, may not be an error",
686 MachInst mi = static_cast<MachInst>(inst->staticInst->machInst);
688 if (mi != machInst) {
689 warn("%lli: Binary instructions do not match! Inst: %#x, "
691 curTick, mi, machInst);
696 template <class DynInstPtr>
698 Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
700 bool result_mismatch = false;
701 if (inst->numDestRegs()) {
702 // @todo: Support more destination registers.
703 if (inst->isUnverifiable()) {
704 // Unverifiable instructions assume they were executed
705 // properly by the CPU. Grab the result from the
706 // instruction and write it to the register.
708 } else if (result.integer != inst->readIntResult()) {
709 result_mismatch = true;
713 if (result_mismatch) {
714 warn("%lli: Instruction results do not match! (Values may not "
715 "actually be integers) Inst: %#x, checker: %#x",
716 curTick, inst->readIntResult(), result.integer);
718 // It's useful to verify load values from memory, but in MP
719 // systems the value obtained at execute may be different than
720 // the value obtained at completion. Similarly DMA can
721 // present the same problem on even UP systems. Thus there is
722 // the option to only warn on loads having a result error.
723 if (inst->isLoad() && warnOnlyOnLoadError) {
730 if (inst->readNextPC() != thread->readNextPC()) {
731 warn("%lli: Instruction next PCs do not match! Inst: %#x, "
733 curTick, inst->readNextPC(), thread->readNextPC());
737 // Checking side effect registers can be difficult if they are not
738 // checked simultaneously with the execution of the instruction.
739 // This is because other valid instructions may have modified
740 // these registers in the meantime, and their values are not
741 // stored within the DynInst.
742 while (!miscRegIdxs.empty()) {
743 int misc_reg_idx = miscRegIdxs.front();
746 if (inst->tcBase()->readMiscReg(misc_reg_idx) !=
747 thread->readMiscReg(misc_reg_idx)) {
748 warn("%lli: Misc reg idx %i (side effect) does not match! "
749 "Inst: %#x, checker: %#x",
750 curTick, misc_reg_idx,
751 inst->tcBase()->readMiscReg(misc_reg_idx),
752 thread->readMiscReg(misc_reg_idx));
758 template <class DynInstPtr>
760 Checker<DynInstPtr>::validateState()
764 template <class DynInstPtr>
766 Checker<DynInstPtr>::copyResult(DynInstPtr &inst)
768 RegIndex idx = inst->destRegIdx(0);
769 if (idx < TheISA::FP_Base_DepTag) {
770 thread->setIntReg(idx, inst->readIntResult());
771 } else if (idx < TheISA::Fpcr_DepTag) {
772 thread->setFloatRegBits(idx, inst->readIntResult());
774 thread->setMiscReg(idx, inst->readIntResult());
778 template <class DynInstPtr>
780 Checker<DynInstPtr>::dumpAndExit(DynInstPtr &inst)
782 cprintf("Error detected, instruction information:\n");
783 cprintf("PC:%#x, nextPC:%#x\n[sn:%lli]\n[tid:%i]\n"
789 inst->isCompleted());
791 CheckerCPU::dumpAndExit();
794 template <class DynInstPtr>
796 Checker<DynInstPtr>::dumpInsts()
800 InstListIt inst_list_it = --(instList.end());
802 cprintf("Inst list size: %i\n", instList.size());
804 while (inst_list_it != instList.end())
806 cprintf("Instruction:%i\n",
809 cprintf("PC:%#x\n[sn:%lli]\n[tid:%i]\n"
811 (*inst_list_it)->readPC(),
812 (*inst_list_it)->seqNum,
813 (*inst_list_it)->threadNumber,
814 (*inst_list_it)->isCompleted());