cpu.cc (2680:246e7104f744) | cpu.cc (2683:d6b72bb2ed97) |
---|---|
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; --- 19 unchanged lines hidden (view full) --- 28 29#include <list> 30#include <string> 31 32#include "base/refcnt.hh" 33#include "cpu/base.hh" 34#include "cpu/base_dyn_inst.hh" 35#include "cpu/checker/cpu.hh" | 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; --- 19 unchanged lines hidden (view full) --- 28 29#include <list> 30#include <string> 31 32#include "base/refcnt.hh" 33#include "cpu/base.hh" 34#include "cpu/base_dyn_inst.hh" 35#include "cpu/checker/cpu.hh" |
36#include "cpu/cpu_exec_context.hh" | 36#include "cpu/simple_thread.hh" |
37#include "cpu/thread_context.hh" 38#include "cpu/static_inst.hh" 39#include "sim/byteswap.hh" 40#include "sim/sim_object.hh" 41#include "sim/stats.hh" 42 43#include "cpu/o3/alpha_dyn_inst.hh" 44#include "cpu/o3/alpha_impl.hh" --- 12 unchanged lines hidden (view full) --- 57using namespace AlphaISA; 58 59void 60CheckerCPU::init() 61{ 62} 63 64CheckerCPU::CheckerCPU(Params *p) | 37#include "cpu/thread_context.hh" 38#include "cpu/static_inst.hh" 39#include "sim/byteswap.hh" 40#include "sim/sim_object.hh" 41#include "sim/stats.hh" 42 43#include "cpu/o3/alpha_dyn_inst.hh" 44#include "cpu/o3/alpha_impl.hh" --- 12 unchanged lines hidden (view full) --- 57using namespace AlphaISA; 58 59void 60CheckerCPU::init() 61{ 62} 63 64CheckerCPU::CheckerCPU(Params *p) |
65 : BaseCPU(p), cpuXC(NULL), tc(NULL) | 65 : BaseCPU(p), thread(NULL), tc(NULL) |
66{ 67 memReq = NULL; 68 69 numInst = 0; 70 startNumInst = 0; 71 numLoad = 0; 72 startNumLoad = 0; 73 youngestSN = 0; --- 15 unchanged lines hidden (view full) --- 89{ 90} 91 92void 93CheckerCPU::setMemory(MemObject *mem) 94{ 95 memPtr = mem; 96#if !FULL_SYSTEM | 66{ 67 memReq = NULL; 68 69 numInst = 0; 70 startNumInst = 0; 71 numLoad = 0; 72 startNumLoad = 0; 73 youngestSN = 0; --- 15 unchanged lines hidden (view full) --- 89{ 90} 91 92void 93CheckerCPU::setMemory(MemObject *mem) 94{ 95 memPtr = mem; 96#if !FULL_SYSTEM |
97 cpuXC = new CPUExecContext(this, /* thread_num */ 0, process, 98 /* asid */ 0, mem); | 97 thread = new SimpleThread(this, /* thread_num */ 0, process, 98 /* asid */ 0, mem); |
99 | 99 |
100 cpuXC->setStatus(ThreadContext::Suspended); 101 tc = cpuXC->getTC(); | 100 thread->setStatus(ThreadContext::Suspended); 101 tc = thread->getTC(); |
102 threadContexts.push_back(tc); 103#else 104 if (systemPtr) { | 102 threadContexts.push_back(tc); 103#else 104 if (systemPtr) { |
105 cpuXC = new CPUExecContext(this, 0, systemPtr, itb, dtb, memPtr, false); | 105 thread = new SimpleThread(this, 0, systemPtr, itb, dtb, memPtr, false); |
106 | 106 |
107 cpuXC->setStatus(ThreadContext::Suspended); 108 tc = cpuXC->getTC(); | 107 thread->setStatus(ThreadContext::Suspended); 108 tc = thread->getTC(); |
109 threadContexts.push_back(tc); | 109 threadContexts.push_back(tc); |
110 delete cpuXC->kernelStats; 111 cpuXC->kernelStats = NULL; | 110 delete thread->kernelStats; 111 thread->kernelStats = NULL; |
112 } 113#endif 114} 115 116#if FULL_SYSTEM 117void 118CheckerCPU::setSystem(System *system) 119{ 120 systemPtr = system; 121 122 if (memPtr) { | 112 } 113#endif 114} 115 116#if FULL_SYSTEM 117void 118CheckerCPU::setSystem(System *system) 119{ 120 systemPtr = system; 121 122 if (memPtr) { |
123 cpuXC = new CPUExecContext(this, 0, systemPtr, itb, dtb, memPtr, false); | 123 thread = new SimpleThread(this, 0, systemPtr, itb, dtb, memPtr, false); |
124 | 124 |
125 cpuXC->setStatus(ThreadContext::Suspended); 126 tc = cpuXC->getTC(); | 125 thread->setStatus(ThreadContext::Suspended); 126 tc = thread->getTC(); |
127 threadContexts.push_back(tc); | 127 threadContexts.push_back(tc); |
128 delete cpuXC->kernelStats; 129 cpuXC->kernelStats = NULL; | 128 delete thread->kernelStats; 129 thread->kernelStats = NULL; |
130 } 131} 132#endif 133 134void 135CheckerCPU::setIcachePort(Port *icache_port) 136{ 137 icachePort = icache_port; --- 7 unchanged lines hidden (view full) --- 145 146void 147CheckerCPU::serialize(ostream &os) 148{ 149/* 150 BaseCPU::serialize(os); 151 SERIALIZE_SCALAR(inst); 152 nameOut(os, csprintf("%s.xc", name())); | 130 } 131} 132#endif 133 134void 135CheckerCPU::setIcachePort(Port *icache_port) 136{ 137 icachePort = icache_port; --- 7 unchanged lines hidden (view full) --- 145 146void 147CheckerCPU::serialize(ostream &os) 148{ 149/* 150 BaseCPU::serialize(os); 151 SERIALIZE_SCALAR(inst); 152 nameOut(os, csprintf("%s.xc", name())); |
153 cpuXC->serialize(os); | 153 thread->serialize(os); |
154 cacheCompletionEvent.serialize(os); 155*/ 156} 157 158void 159CheckerCPU::unserialize(Checkpoint *cp, const string §ion) 160{ 161/* 162 BaseCPU::unserialize(cp, section); 163 UNSERIALIZE_SCALAR(inst); | 154 cacheCompletionEvent.serialize(os); 155*/ 156} 157 158void 159CheckerCPU::unserialize(Checkpoint *cp, const string §ion) 160{ 161/* 162 BaseCPU::unserialize(cp, section); 163 UNSERIALIZE_SCALAR(inst); |
164 cpuXC->unserialize(cp, csprintf("%s.xc", section)); | 164 thread->unserialize(cp, csprintf("%s.xc", section)); |
165*/ 166} 167 168Fault 169CheckerCPU::copySrcTranslate(Addr src) 170{ 171 panic("Unimplemented!"); 172} --- 6 unchanged lines hidden (view full) --- 179 180template <class T> 181Fault 182CheckerCPU::read(Addr addr, T &data, unsigned flags) 183{ 184 // need to fill in CPU & thread IDs here 185 memReq = new Request(); 186 | 165*/ 166} 167 168Fault 169CheckerCPU::copySrcTranslate(Addr src) 170{ 171 panic("Unimplemented!"); 172} --- 6 unchanged lines hidden (view full) --- 179 180template <class T> 181Fault 182CheckerCPU::read(Addr addr, T &data, unsigned flags) 183{ 184 // need to fill in CPU & thread IDs here 185 memReq = new Request(); 186 |
187 memReq->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC()); | 187 memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC()); |
188 189 // translate to physical address 190 translateDataReadReq(memReq); 191 192 Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast); 193 194 pkt->dataStatic(&data); 195 --- 53 unchanged lines hidden (view full) --- 249 250template <class T> 251Fault 252CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) 253{ 254 // need to fill in CPU & thread IDs here 255 memReq = new Request(); 256 | 188 189 // translate to physical address 190 translateDataReadReq(memReq); 191 192 Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast); 193 194 pkt->dataStatic(&data); 195 --- 53 unchanged lines hidden (view full) --- 249 250template <class T> 251Fault 252CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) 253{ 254 // need to fill in CPU & thread IDs here 255 memReq = new Request(); 256 |
257 memReq->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC()); | 257 memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC()); |
258 259 // translate to physical address | 258 259 // translate to physical address |
260 cpuXC->translateDataWriteReq(memReq); | 260 thread->translateDataWriteReq(memReq); |
261 262 // Can compare the write data and result only if it's cacheable, 263 // not a store conditional, or is a store conditional that 264 // succeeded. 265 // @todo: Verify that actual memory matches up with these values. 266 // Right now it only verifies that the instruction data is the 267 // same as what was in the request that got sent to memory; there 268 // is no verification that it is the same as what is in memory. --- 82 unchanged lines hidden (view full) --- 351 return vtophys(xcProxy, addr); 352} 353#endif // FULL_SYSTEM 354 355bool 356CheckerCPU::translateInstReq(Request *req) 357{ 358#if FULL_SYSTEM | 261 262 // Can compare the write data and result only if it's cacheable, 263 // not a store conditional, or is a store conditional that 264 // succeeded. 265 // @todo: Verify that actual memory matches up with these values. 266 // Right now it only verifies that the instruction data is the 267 // same as what was in the request that got sent to memory; there 268 // is no verification that it is the same as what is in memory. --- 82 unchanged lines hidden (view full) --- 351 return vtophys(xcProxy, addr); 352} 353#endif // FULL_SYSTEM 354 355bool 356CheckerCPU::translateInstReq(Request *req) 357{ 358#if FULL_SYSTEM |
359 return (cpuXC->translateInstReq(req) == NoFault); | 359 return (thread->translateInstReq(req) == NoFault); |
360#else | 360#else |
361 cpuXC->translateInstReq(req); | 361 thread->translateInstReq(req); |
362 return true; 363#endif 364} 365 366void 367CheckerCPU::translateDataReadReq(Request *req) 368{ | 362 return true; 363#endif 364} 365 366void 367CheckerCPU::translateDataReadReq(Request *req) 368{ |
369 cpuXC->translateDataReadReq(req); | 369 thread->translateDataReadReq(req); |
370 371 if (req->getVaddr() != unverifiedReq->getVaddr()) { 372 warn("%lli: Request virtual addresses do not match! Inst: %#x, " 373 "checker: %#x", 374 curTick, unverifiedReq->getVaddr(), req->getVaddr()); 375 handleError(); 376 } 377 req->setPaddr(unverifiedReq->getPaddr()); 378 379 if (checkFlags(req)) { 380 warn("%lli: Request flags do not match! Inst: %#x, checker: %#x", 381 curTick, unverifiedReq->getFlags(), req->getFlags()); 382 handleError(); 383 } 384} 385 386void 387CheckerCPU::translateDataWriteReq(Request *req) 388{ | 370 371 if (req->getVaddr() != unverifiedReq->getVaddr()) { 372 warn("%lli: Request virtual addresses do not match! Inst: %#x, " 373 "checker: %#x", 374 curTick, unverifiedReq->getVaddr(), req->getVaddr()); 375 handleError(); 376 } 377 req->setPaddr(unverifiedReq->getPaddr()); 378 379 if (checkFlags(req)) { 380 warn("%lli: Request flags do not match! Inst: %#x, checker: %#x", 381 curTick, unverifiedReq->getFlags(), req->getFlags()); 382 handleError(); 383 } 384} 385 386void 387CheckerCPU::translateDataWriteReq(Request *req) 388{ |
389 cpuXC->translateDataWriteReq(req); | 389 thread->translateDataWriteReq(req); |
390 391 if (req->getVaddr() != unverifiedReq->getVaddr()) { 392 warn("%lli: Request virtual addresses do not match! Inst: %#x, " 393 "checker: %#x", 394 curTick, unverifiedReq->getVaddr(), req->getVaddr()); 395 handleError(); 396 } 397 req->setPaddr(unverifiedReq->getPaddr()); --- 72 unchanged lines hidden (view full) --- 470 unverifiedResult.integer = inst->readIntResult(); 471 unverifiedReq = inst->req; 472 unverifiedMemData = inst->memData; 473 numCycles++; 474 475 Fault fault = NoFault; 476 477 // maintain $r0 semantics | 390 391 if (req->getVaddr() != unverifiedReq->getVaddr()) { 392 warn("%lli: Request virtual addresses do not match! Inst: %#x, " 393 "checker: %#x", 394 curTick, unverifiedReq->getVaddr(), req->getVaddr()); 395 handleError(); 396 } 397 req->setPaddr(unverifiedReq->getPaddr()); --- 72 unchanged lines hidden (view full) --- 470 unverifiedResult.integer = inst->readIntResult(); 471 unverifiedReq = inst->req; 472 unverifiedMemData = inst->memData; 473 numCycles++; 474 475 Fault fault = NoFault; 476 477 // maintain $r0 semantics |
478 cpuXC->setIntReg(ZeroReg, 0); | 478 thread->setIntReg(ZeroReg, 0); |
479#ifdef TARGET_ALPHA | 479#ifdef TARGET_ALPHA |
480 cpuXC->setFloatRegDouble(ZeroReg, 0.0); | 480 thread->setFloatRegDouble(ZeroReg, 0.0); |
481#endif // TARGET_ALPHA 482 483 // Check if any recent PC changes match up with anything we 484 // expect to happen. This is mostly to check if traps or 485 // PC-based events have occurred in both the checker and CPU. 486 if (changedPC) { 487 DPRINTF(Checker, "Changed PC recently to %#x\n", | 481#endif // TARGET_ALPHA 482 483 // Check if any recent PC changes match up with anything we 484 // expect to happen. This is mostly to check if traps or 485 // PC-based events have occurred in both the checker and CPU. 486 if (changedPC) { 487 DPRINTF(Checker, "Changed PC recently to %#x\n", |
488 cpuXC->readPC()); | 488 thread->readPC()); |
489 if (willChangePC) { | 489 if (willChangePC) { |
490 if (newPC == cpuXC->readPC()) { | 490 if (newPC == thread->readPC()) { |
491 DPRINTF(Checker, "Changed PC matches expected PC\n"); 492 } else { 493 warn("%lli: Changed PC does not match expected PC, " 494 "changed: %#x, expected: %#x", | 491 DPRINTF(Checker, "Changed PC matches expected PC\n"); 492 } else { 493 warn("%lli: Changed PC does not match expected PC, " 494 "changed: %#x, expected: %#x", |
495 curTick, cpuXC->readPC(), newPC); | 495 curTick, thread->readPC(), newPC); |
496 handleError(); 497 } 498 willChangePC = false; 499 } 500 changedPC = false; 501 } 502 if (changedNextPC) { 503 DPRINTF(Checker, "Changed NextPC recently to %#x\n", | 496 handleError(); 497 } 498 willChangePC = false; 499 } 500 changedPC = false; 501 } 502 if (changedNextPC) { 503 DPRINTF(Checker, "Changed NextPC recently to %#x\n", |
504 cpuXC->readNextPC()); | 504 thread->readNextPC()); |
505 changedNextPC = false; 506 } 507 508 // Try to fetch the instruction 509 510#if FULL_SYSTEM 511#define IFETCH_FLAGS(pc) ((pc) & 1) ? PHYSICAL : 0 512#else 513#define IFETCH_FLAGS(pc) 0 514#endif 515 | 505 changedNextPC = false; 506 } 507 508 // Try to fetch the instruction 509 510#if FULL_SYSTEM 511#define IFETCH_FLAGS(pc) ((pc) & 1) ? PHYSICAL : 0 512#else 513#define IFETCH_FLAGS(pc) 0 514#endif 515 |
516 uint64_t fetch_PC = cpuXC->readPC() & ~3; | 516 uint64_t fetch_PC = thread->readPC() & ~3; |
517 518 // set up memory request for instruction fetch 519 memReq = new Request(inst->threadNumber, fetch_PC, 520 sizeof(uint32_t), | 517 518 // set up memory request for instruction fetch 519 memReq = new Request(inst->threadNumber, fetch_PC, 520 sizeof(uint32_t), |
521 IFETCH_FLAGS(cpuXC->readPC()), 522 fetch_PC, cpuXC->readCpuId(), inst->threadNumber); | 521 IFETCH_FLAGS(thread->readPC()), 522 fetch_PC, thread->readCpuId(), inst->threadNumber); |
523 524 bool succeeded = translateInstReq(memReq); 525 526 if (!succeeded) { 527 if (inst->getFault() == NoFault) { 528 // In this case the instruction was not a dummy 529 // instruction carrying an ITB fault. In the single 530 // threaded case the ITB should still be able to 531 // translate this instruction; in the SMT case it's 532 // possible that its ITB entry was kicked out. 533 warn("%lli: Instruction PC %#x was not found in the ITB!", | 523 524 bool succeeded = translateInstReq(memReq); 525 526 if (!succeeded) { 527 if (inst->getFault() == NoFault) { 528 // In this case the instruction was not a dummy 529 // instruction carrying an ITB fault. In the single 530 // threaded case the ITB should still be able to 531 // translate this instruction; in the SMT case it's 532 // possible that its ITB entry was kicked out. 533 warn("%lli: Instruction PC %#x was not found in the ITB!", |
534 curTick, cpuXC->readPC()); | 534 curTick, thread->readPC()); |
535 handleError(); 536 537 // go to the next instruction | 535 handleError(); 536 537 // go to the next instruction |
538 cpuXC->setPC(cpuXC->readNextPC()); 539 cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst)); | 538 thread->setPC(thread->readNextPC()); 539 thread->setNextPC(thread->readNextPC() + sizeof(MachInst)); |
540 541 return; 542 } else { 543 // The instruction is carrying an ITB fault. Handle 544 // the fault and see if our results match the CPU on 545 // the next tick(). 546 fault = inst->getFault(); 547 } --- 14 unchanged lines hidden (view full) --- 562 563 // decode the instruction 564 machInst = gtoh(machInst); 565 // Checks that the instruction matches what we expected it to be. 566 // Checks both the machine instruction and the PC. 567 validateInst(inst); 568 569 curStaticInst = StaticInst::decode(makeExtMI(machInst, | 540 541 return; 542 } else { 543 // The instruction is carrying an ITB fault. Handle 544 // the fault and see if our results match the CPU on 545 // the next tick(). 546 fault = inst->getFault(); 547 } --- 14 unchanged lines hidden (view full) --- 562 563 // decode the instruction 564 machInst = gtoh(machInst); 565 // Checks that the instruction matches what we expected it to be. 566 // Checks both the machine instruction and the PC. 567 validateInst(inst); 568 569 curStaticInst = StaticInst::decode(makeExtMI(machInst, |
570 cpuXC->readPC())); | 570 thread->readPC())); |
571 572#if FULL_SYSTEM | 571 572#if FULL_SYSTEM |
573 cpuXC->setInst(machInst); | 573 thread->setInst(machInst); |
574#endif // FULL_SYSTEM 575 576 fault = inst->getFault(); 577 } 578 579 // Discard fetch's memReq. 580 delete memReq; 581 memReq = NULL; 582 583 // Either the instruction was a fault and we should process the fault, 584 // or we should just go ahead execute the instruction. This assumes 585 // that the instruction is properly marked as a fault. 586 if (fault == NoFault) { 587 | 574#endif // FULL_SYSTEM 575 576 fault = inst->getFault(); 577 } 578 579 // Discard fetch's memReq. 580 delete memReq; 581 memReq = NULL; 582 583 // Either the instruction was a fault and we should process the fault, 584 // or we should just go ahead execute the instruction. This assumes 585 // that the instruction is properly marked as a fault. 586 if (fault == NoFault) { 587 |
588 cpuXC->func_exe_inst++; | 588 thread->funcExeInst++; |
589 590 fault = curStaticInst->execute(this, NULL); 591 592 // Checks to make sure instrution results are correct. 593 validateExecution(inst); 594 595 if (curStaticInst->isLoad()) { 596 ++numLoad; 597 } 598 } 599 600 if (fault != NoFault) { 601#if FULL_SYSTEM 602 fault->invoke(xcProxy); 603 willChangePC = true; | 589 590 fault = curStaticInst->execute(this, NULL); 591 592 // Checks to make sure instrution results are correct. 593 validateExecution(inst); 594 595 if (curStaticInst->isLoad()) { 596 ++numLoad; 597 } 598 } 599 600 if (fault != NoFault) { 601#if FULL_SYSTEM 602 fault->invoke(xcProxy); 603 willChangePC = true; |
604 newPC = cpuXC->readPC(); | 604 newPC = thread->readPC(); |
605 DPRINTF(Checker, "Fault, PC is now %#x\n", newPC); 606#else // !FULL_SYSTEM | 605 DPRINTF(Checker, "Fault, PC is now %#x\n", newPC); 606#else // !FULL_SYSTEM |
607 fatal("fault (%d) detected @ PC 0x%08p", fault, cpuXC->readPC()); | 607 fatal("fault (%d) detected @ PC 0x%08p", fault, thread->readPC()); |
608#endif // FULL_SYSTEM 609 } else { 610#if THE_ISA != MIPS_ISA 611 // go to the next instruction | 608#endif // FULL_SYSTEM 609 } else { 610#if THE_ISA != MIPS_ISA 611 // go to the next instruction |
612 cpuXC->setPC(cpuXC->readNextPC()); 613 cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst)); | 612 thread->setPC(thread->readNextPC()); 613 thread->setNextPC(thread->readNextPC() + sizeof(MachInst)); |
614#else 615 // go to the next instruction | 614#else 615 // go to the next instruction |
616 cpuXC->setPC(cpuXC->readNextPC()); 617 cpuXC->setNextPC(cpuXC->readNextNPC()); 618 cpuXC->setNextNPC(cpuXC->readNextNPC() + sizeof(MachInst)); | 616 thread->setPC(thread->readNextPC()); 617 thread->setNextPC(thread->readNextNPC()); 618 thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst)); |
619#endif 620 621 } 622 623#if FULL_SYSTEM 624 // @todo: Determine if these should happen only if the 625 // instruction hasn't faulted. In the SimpleCPU case this may 626 // not be true, but in the O3 or Ozone case this may be true. 627 Addr oldpc; 628 int count = 0; 629 do { | 619#endif 620 621 } 622 623#if FULL_SYSTEM 624 // @todo: Determine if these should happen only if the 625 // instruction hasn't faulted. In the SimpleCPU case this may 626 // not be true, but in the O3 or Ozone case this may be true. 627 Addr oldpc; 628 int count = 0; 629 do { |
630 oldpc = cpuXC->readPC(); | 630 oldpc = thread->readPC(); |
631 system->pcEventQueue.service(xcProxy); 632 count++; | 631 system->pcEventQueue.service(xcProxy); 632 count++; |
633 } while (oldpc != cpuXC->readPC()); | 633 } while (oldpc != thread->readPC()); |
634 if (count > 1) { 635 willChangePC = true; | 634 if (count > 1) { 635 willChangePC = true; |
636 newPC = cpuXC->readPC(); | 636 newPC = thread->readPC(); |
637 DPRINTF(Checker, "PC Event, PC is now %#x\n", newPC); 638 } 639#endif 640 641 // @todo: Optionally can check all registers. (Or just those 642 // that have been modified). 643 validateState(); 644 --- 27 unchanged lines hidden (view full) --- 672Checker<DynInstPtr>::takeOverFrom(BaseCPU *oldCPU) 673{ 674} 675 676template <class DynInstPtr> 677void 678Checker<DynInstPtr>::validateInst(DynInstPtr &inst) 679{ | 637 DPRINTF(Checker, "PC Event, PC is now %#x\n", newPC); 638 } 639#endif 640 641 // @todo: Optionally can check all registers. (Or just those 642 // that have been modified). 643 validateState(); 644 --- 27 unchanged lines hidden (view full) --- 672Checker<DynInstPtr>::takeOverFrom(BaseCPU *oldCPU) 673{ 674} 675 676template <class DynInstPtr> 677void 678Checker<DynInstPtr>::validateInst(DynInstPtr &inst) 679{ |
680 if (inst->readPC() != cpuXC->readPC()) { | 680 if (inst->readPC() != thread->readPC()) { |
681 warn("%lli: PCs do not match! Inst: %#x, checker: %#x", | 681 warn("%lli: PCs do not match! Inst: %#x, checker: %#x", |
682 curTick, inst->readPC(), cpuXC->readPC()); | 682 curTick, inst->readPC(), thread->readPC()); |
683 if (changedPC) { 684 warn("%lli: Changed PCs recently, may not be an error", 685 curTick); 686 } else { 687 handleError(); 688 } 689 } 690 --- 14 unchanged lines hidden (view full) --- 705 if (inst->numDestRegs()) { 706 // @todo: Support more destination registers. 707 if (inst->isUnverifiable()) { 708 // Unverifiable instructions assume they were executed 709 // properly by the CPU. Grab the result from the 710 // instruction and write it to the register. 711 RegIndex idx = inst->destRegIdx(0); 712 if (idx < TheISA::FP_Base_DepTag) { | 683 if (changedPC) { 684 warn("%lli: Changed PCs recently, may not be an error", 685 curTick); 686 } else { 687 handleError(); 688 } 689 } 690 --- 14 unchanged lines hidden (view full) --- 705 if (inst->numDestRegs()) { 706 // @todo: Support more destination registers. 707 if (inst->isUnverifiable()) { 708 // Unverifiable instructions assume they were executed 709 // properly by the CPU. Grab the result from the 710 // instruction and write it to the register. 711 RegIndex idx = inst->destRegIdx(0); 712 if (idx < TheISA::FP_Base_DepTag) { |
713 cpuXC->setIntReg(idx, inst->readIntResult()); | 713 thread->setIntReg(idx, inst->readIntResult()); |
714 } else if (idx < TheISA::Fpcr_DepTag) { | 714 } else if (idx < TheISA::Fpcr_DepTag) { |
715 cpuXC->setFloatRegBits(idx, inst->readIntResult()); | 715 thread->setFloatRegBits(idx, inst->readIntResult()); |
716 } else { | 716 } else { |
717 cpuXC->setMiscReg(idx, inst->readIntResult()); | 717 thread->setMiscReg(idx, inst->readIntResult()); |
718 } 719 } else if (result.integer != inst->readIntResult()) { 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 handleError(); 724 } 725 } 726 | 718 } 719 } else if (result.integer != inst->readIntResult()) { 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 handleError(); 724 } 725 } 726 |
727 if (inst->readNextPC() != cpuXC->readNextPC()) { | 727 if (inst->readNextPC() != thread->readNextPC()) { |
728 warn("%lli: Instruction next PCs do not match! Inst: %#x, " 729 "checker: %#x", | 728 warn("%lli: Instruction next PCs do not match! Inst: %#x, " 729 "checker: %#x", |
730 curTick, inst->readNextPC(), cpuXC->readNextPC()); | 730 curTick, inst->readNextPC(), thread->readNextPC()); |
731 handleError(); 732 } 733 734 // Checking side effect registers can be difficult if they are not 735 // checked simultaneously with the execution of the instruction. 736 // This is because other valid instructions may have modified 737 // these registers in the meantime, and their values are not 738 // stored within the DynInst. 739 while (!miscRegIdxs.empty()) { 740 int misc_reg_idx = miscRegIdxs.front(); 741 miscRegIdxs.pop(); 742 743 if (inst->tcBase()->readMiscReg(misc_reg_idx) != | 731 handleError(); 732 } 733 734 // Checking side effect registers can be difficult if they are not 735 // checked simultaneously with the execution of the instruction. 736 // This is because other valid instructions may have modified 737 // these registers in the meantime, and their values are not 738 // stored within the DynInst. 739 while (!miscRegIdxs.empty()) { 740 int misc_reg_idx = miscRegIdxs.front(); 741 miscRegIdxs.pop(); 742 743 if (inst->tcBase()->readMiscReg(misc_reg_idx) != |
744 cpuXC->readMiscReg(misc_reg_idx)) { | 744 thread->readMiscReg(misc_reg_idx)) { |
745 warn("%lli: Misc reg idx %i (side effect) does not match! " 746 "Inst: %#x, checker: %#x", 747 curTick, misc_reg_idx, 748 inst->tcBase()->readMiscReg(misc_reg_idx), | 745 warn("%lli: Misc reg idx %i (side effect) does not match! " 746 "Inst: %#x, checker: %#x", 747 curTick, misc_reg_idx, 748 inst->tcBase()->readMiscReg(misc_reg_idx), |
749 cpuXC->readMiscReg(misc_reg_idx)); | 749 thread->readMiscReg(misc_reg_idx)); |
750 handleError(); 751 } 752 } 753} 754 755template <class DynInstPtr> 756void 757Checker<DynInstPtr>::validateState() --- 38 unchanged lines hidden --- | 750 handleError(); 751 } 752 } 753} 754 755template <class DynInstPtr> 756void 757Checker<DynInstPtr>::validateState() --- 38 unchanged lines hidden --- |