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 --- |