cpu.cc (2723:4c47709f88ab) cpu.cc (2732:d2443ce353d2)
1/*
2 * Copyright (c) 2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
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;

--- 64 unchanged lines hidden (view full) ---

73 startNumInst = 0;
74 numLoad = 0;
75 startNumLoad = 0;
76 youngestSN = 0;
77
78 changedPC = willChangePC = changedNextPC = false;
79
80 exitOnError = p->exitOnError;
1/*
2 * Copyright (c) 2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
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;

--- 64 unchanged lines hidden (view full) ---

73 startNumInst = 0;
74 numLoad = 0;
75 startNumLoad = 0;
76 youngestSN = 0;
77
78 changedPC = willChangePC = changedNextPC = false;
79
80 exitOnError = p->exitOnError;
81 warnOnlyOnLoadError = p->warnOnlyOnLoadError;
81#if FULL_SYSTEM
82 itb = p->itb;
83 dtb = p->dtb;
84 systemPtr = NULL;
85#else
86 process = p->process;
87#endif
88

--- 315 unchanged lines hidden (view full) ---

404 flags = flags & (mask);
405 if (flags == req->getFlags()) {
406 return false;
407 } else {
408 return true;
409 }
410}
411
82#if FULL_SYSTEM
83 itb = p->itb;
84 dtb = p->dtb;
85 systemPtr = NULL;
86#else
87 process = p->process;
88#endif
89

--- 315 unchanged lines hidden (view full) ---

405 flags = flags & (mask);
406 if (flags == req->getFlags()) {
407 return false;
408 } else {
409 return true;
410 }
411}
412
413void
414CheckerCPU::dumpAndExit()
415{
416 warn("%lli: Checker PC:%#x, next PC:%#x",
417 curTick, thread->readPC(), thread->readNextPC());
418 panic("Checker found an error!");
419}
420
412template <class DynInstPtr>
413void
421template <class DynInstPtr>
422void
414Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
423Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
415{
416 DynInstPtr inst;
417
418 // Either check this instruction, or add it to a list of
419 // instructions waiting to be checked. Instructions must be
420 // checked in program order, so if a store has committed yet not
421 // completed, there may be some instructions that are waiting
422 // behind it that have completed and must be checked.

--- 57 unchanged lines hidden (view full) ---

480 thread->readPC());
481 if (willChangePC) {
482 if (newPC == thread->readPC()) {
483 DPRINTF(Checker, "Changed PC matches expected PC\n");
484 } else {
485 warn("%lli: Changed PC does not match expected PC, "
486 "changed: %#x, expected: %#x",
487 curTick, thread->readPC(), newPC);
424{
425 DynInstPtr inst;
426
427 // Either check this instruction, or add it to a list of
428 // instructions waiting to be checked. Instructions must be
429 // checked in program order, so if a store has committed yet not
430 // completed, there may be some instructions that are waiting
431 // behind it that have completed and must be checked.

--- 57 unchanged lines hidden (view full) ---

489 thread->readPC());
490 if (willChangePC) {
491 if (newPC == thread->readPC()) {
492 DPRINTF(Checker, "Changed PC matches expected PC\n");
493 } else {
494 warn("%lli: Changed PC does not match expected PC, "
495 "changed: %#x, expected: %#x",
496 curTick, thread->readPC(), newPC);
488 handleError();
497 CheckerCPU::handleError();
489 }
490 willChangePC = false;
491 }
492 changedPC = false;
493 }
494 if (changedNextPC) {
495 DPRINTF(Checker, "Changed NextPC recently to %#x\n",
496 thread->readNextPC());

--- 22 unchanged lines hidden (view full) ---

519 if (inst->getFault() == NoFault) {
520 // In this case the instruction was not a dummy
521 // instruction carrying an ITB fault. In the single
522 // threaded case the ITB should still be able to
523 // translate this instruction; in the SMT case it's
524 // possible that its ITB entry was kicked out.
525 warn("%lli: Instruction PC %#x was not found in the ITB!",
526 curTick, thread->readPC());
498 }
499 willChangePC = false;
500 }
501 changedPC = false;
502 }
503 if (changedNextPC) {
504 DPRINTF(Checker, "Changed NextPC recently to %#x\n",
505 thread->readNextPC());

--- 22 unchanged lines hidden (view full) ---

528 if (inst->getFault() == NoFault) {
529 // In this case the instruction was not a dummy
530 // instruction carrying an ITB fault. In the single
531 // threaded case the ITB should still be able to
532 // translate this instruction; in the SMT case it's
533 // possible that its ITB entry was kicked out.
534 warn("%lli: Instruction PC %#x was not found in the ITB!",
535 curTick, thread->readPC());
527 handleError();
536 handleError(inst);
528
529 // go to the next instruction
530 thread->setPC(thread->readNextPC());
531 thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
532
533 return;
534 } else {
535 // The instruction is carrying an ITB fault. Handle

--- 135 unchanged lines hidden (view full) ---

671{
672 if (inst->readPC() != thread->readPC()) {
673 warn("%lli: PCs do not match! Inst: %#x, checker: %#x",
674 curTick, inst->readPC(), thread->readPC());
675 if (changedPC) {
676 warn("%lli: Changed PCs recently, may not be an error",
677 curTick);
678 } else {
537
538 // go to the next instruction
539 thread->setPC(thread->readNextPC());
540 thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
541
542 return;
543 } else {
544 // The instruction is carrying an ITB fault. Handle

--- 135 unchanged lines hidden (view full) ---

680{
681 if (inst->readPC() != thread->readPC()) {
682 warn("%lli: PCs do not match! Inst: %#x, checker: %#x",
683 curTick, inst->readPC(), thread->readPC());
684 if (changedPC) {
685 warn("%lli: Changed PCs recently, may not be an error",
686 curTick);
687 } else {
679 handleError();
688 handleError(inst);
680 }
681 }
682
683 MachInst mi = static_cast<MachInst>(inst->staticInst->machInst);
684
685 if (mi != machInst) {
686 warn("%lli: Binary instructions do not match! Inst: %#x, "
687 "checker: %#x",
688 curTick, mi, machInst);
689 }
690 }
691
692 MachInst mi = static_cast<MachInst>(inst->staticInst->machInst);
693
694 if (mi != machInst) {
695 warn("%lli: Binary instructions do not match! Inst: %#x, "
696 "checker: %#x",
697 curTick, mi, machInst);
689 handleError();
698 handleError(inst);
690 }
691}
692
693template <class DynInstPtr>
694void
695Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
696{
699 }
700}
701
702template <class DynInstPtr>
703void
704Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
705{
706 bool result_mismatch = false;
697 if (inst->numDestRegs()) {
698 // @todo: Support more destination registers.
699 if (inst->isUnverifiable()) {
700 // Unverifiable instructions assume they were executed
701 // properly by the CPU. Grab the result from the
702 // instruction and write it to the register.
707 if (inst->numDestRegs()) {
708 // @todo: Support more destination registers.
709 if (inst->isUnverifiable()) {
710 // Unverifiable instructions assume they were executed
711 // properly by the CPU. Grab the result from the
712 // instruction and write it to the register.
703 RegIndex idx = inst->destRegIdx(0);
704 if (idx < TheISA::FP_Base_DepTag) {
705 thread->setIntReg(idx, inst->readIntResult());
706 } else if (idx < TheISA::Fpcr_DepTag) {
707 thread->setFloatRegBits(idx, inst->readIntResult());
708 } else {
709 thread->setMiscReg(idx, inst->readIntResult());
710 }
713 copyResult(inst);
711 } else if (result.integer != inst->readIntResult()) {
714 } else if (result.integer != inst->readIntResult()) {
712 warn("%lli: Instruction results do not match! (Values may not "
713 "actually be integers) Inst: %#x, checker: %#x",
714 curTick, inst->readIntResult(), result.integer);
715 handleError();
715 result_mismatch = true;
716 }
717 }
718
716 }
717 }
718
719 if (result_mismatch) {
720 warn("%lli: Instruction results do not match! (Values may not "
721 "actually be integers) Inst: %#x, checker: %#x",
722 curTick, inst->readIntResult(), result.integer);
723
724 // It's useful to verify load values from memory, but in MP
725 // systems the value obtained at execute may be different than
726 // the value obtained at completion. Similarly DMA can
727 // present the same problem on even UP systems. Thus there is
728 // the option to only warn on loads having a result error.
729 if (inst->isLoad() && warnOnlyOnLoadError) {
730 copyResult(inst);
731 } else {
732 handleError(inst);
733 }
734 }
735
719 if (inst->readNextPC() != thread->readNextPC()) {
720 warn("%lli: Instruction next PCs do not match! Inst: %#x, "
721 "checker: %#x",
722 curTick, inst->readNextPC(), thread->readNextPC());
736 if (inst->readNextPC() != thread->readNextPC()) {
737 warn("%lli: Instruction next PCs do not match! Inst: %#x, "
738 "checker: %#x",
739 curTick, inst->readNextPC(), thread->readNextPC());
723 handleError();
740 handleError(inst);
724 }
725
726 // Checking side effect registers can be difficult if they are not
727 // checked simultaneously with the execution of the instruction.
728 // This is because other valid instructions may have modified
729 // these registers in the meantime, and their values are not
730 // stored within the DynInst.
731 while (!miscRegIdxs.empty()) {
732 int misc_reg_idx = miscRegIdxs.front();
733 miscRegIdxs.pop();
734
735 if (inst->tcBase()->readMiscReg(misc_reg_idx) !=
736 thread->readMiscReg(misc_reg_idx)) {
737 warn("%lli: Misc reg idx %i (side effect) does not match! "
738 "Inst: %#x, checker: %#x",
739 curTick, misc_reg_idx,
740 inst->tcBase()->readMiscReg(misc_reg_idx),
741 thread->readMiscReg(misc_reg_idx));
741 }
742
743 // Checking side effect registers can be difficult if they are not
744 // checked simultaneously with the execution of the instruction.
745 // This is because other valid instructions may have modified
746 // these registers in the meantime, and their values are not
747 // stored within the DynInst.
748 while (!miscRegIdxs.empty()) {
749 int misc_reg_idx = miscRegIdxs.front();
750 miscRegIdxs.pop();
751
752 if (inst->tcBase()->readMiscReg(misc_reg_idx) !=
753 thread->readMiscReg(misc_reg_idx)) {
754 warn("%lli: Misc reg idx %i (side effect) does not match! "
755 "Inst: %#x, checker: %#x",
756 curTick, misc_reg_idx,
757 inst->tcBase()->readMiscReg(misc_reg_idx),
758 thread->readMiscReg(misc_reg_idx));
742 handleError();
759 handleError(inst);
743 }
744 }
745}
746
747template <class DynInstPtr>
748void
749Checker<DynInstPtr>::validateState()
750{
751}
752
753template <class DynInstPtr>
754void
760 }
761 }
762}
763
764template <class DynInstPtr>
765void
766Checker<DynInstPtr>::validateState()
767{
768}
769
770template <class DynInstPtr>
771void
772Checker<DynInstPtr>::copyResult(DynInstPtr &inst)
773{
774 RegIndex idx = inst->destRegIdx(0);
775 if (idx < TheISA::FP_Base_DepTag) {
776 thread->setIntReg(idx, inst->readIntResult());
777 } else if (idx < TheISA::Fpcr_DepTag) {
778 thread->setFloatRegBits(idx, inst->readIntResult());
779 } else {
780 thread->setMiscReg(idx, inst->readIntResult());
781 }
782}
783
784template <class DynInstPtr>
785void
786Checker<DynInstPtr>::dumpAndExit(DynInstPtr &inst)
787{
788 cprintf("Error detected, instruction information:\n");
789 cprintf("PC:%#x, nextPC:%#x\n[sn:%lli]\n[tid:%i]\n"
790 "Completed:%i\n",
791 inst->readPC(),
792 inst->readNextPC(),
793 inst->seqNum,
794 inst->threadNumber,
795 inst->isCompleted());
796 inst->dump();
797 CheckerCPU::dumpAndExit();
798}
799
800template <class DynInstPtr>
801void
755Checker<DynInstPtr>::dumpInsts()
756{
757 int num = 0;
758
759 InstListIt inst_list_it = --(instList.end());
760
761 cprintf("Inst list size: %i\n", instList.size());
762

--- 25 unchanged lines hidden ---
802Checker<DynInstPtr>::dumpInsts()
803{
804 int num = 0;
805
806 InstListIt inst_list_it = --(instList.end());
807
808 cprintf("Inst list size: %i\n", instList.size());
809

--- 25 unchanged lines hidden ---