cpu.cc (2669:f2b336e89d2a) | cpu.cc (2679:737e9f158843) |
---|---|
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; --- 50 unchanged lines hidden (view full) --- 59void 60CheckerCPU::init() 61{ 62} 63 64CheckerCPU::CheckerCPU(Params *p) 65 : BaseCPU(p), cpuXC(NULL), xcProxy(NULL) 66{ | 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; --- 50 unchanged lines hidden (view full) --- 59void 60CheckerCPU::init() 61{ 62} 63 64CheckerCPU::CheckerCPU(Params *p) 65 : BaseCPU(p), cpuXC(NULL), xcProxy(NULL) 66{ |
67 memReq = new Request(); 68// memReq->data = new uint8_t[64]; | 67 memReq = NULL; |
69 70 numInst = 0; 71 startNumInst = 0; 72 numLoad = 0; 73 startNumLoad = 0; 74 youngestSN = 0; 75 76 changedPC = willChangePC = changedNextPC = false; 77 78 exitOnError = p->exitOnError; 79#if FULL_SYSTEM 80 itb = p->itb; 81 dtb = p->dtb; 82 systemPtr = NULL; 83 memPtr = NULL; | 68 69 numInst = 0; 70 startNumInst = 0; 71 numLoad = 0; 72 startNumLoad = 0; 73 youngestSN = 0; 74 75 changedPC = willChangePC = changedNextPC = false; 76 77 exitOnError = p->exitOnError; 78#if FULL_SYSTEM 79 itb = p->itb; 80 dtb = p->dtb; 81 systemPtr = NULL; 82 memPtr = NULL; |
83#else 84 process = p->process; |
|
84#endif 85} 86 87CheckerCPU::~CheckerCPU() 88{ 89} 90 91void 92CheckerCPU::setMemory(MemObject *mem) 93{ 94 memPtr = mem; 95#if !FULL_SYSTEM | 85#endif 86} 87 88CheckerCPU::~CheckerCPU() 89{ 90} 91 92void 93CheckerCPU::setMemory(MemObject *mem) 94{ 95 memPtr = mem; 96#if !FULL_SYSTEM |
96 cpuXC = new CPUExecContext(this, /* thread_num */ 0, NULL, | 97 cpuXC = new CPUExecContext(this, /* thread_num */ 0, process, |
97 /* asid */ 0, mem); 98 99 cpuXC->setStatus(ExecContext::Suspended); 100 xcProxy = cpuXC->getProxy(); 101 execContexts.push_back(xcProxy); 102#else 103 if (systemPtr) { 104 cpuXC = new CPUExecContext(this, 0, systemPtr, itb, dtb, memPtr, false); --- 23 unchanged lines hidden (view full) --- 128 memReq->xc = xcProxy; 129 delete cpuXC->kernelStats; 130 cpuXC->kernelStats = NULL; 131 } 132} 133#endif 134 135void | 98 /* asid */ 0, mem); 99 100 cpuXC->setStatus(ExecContext::Suspended); 101 xcProxy = cpuXC->getProxy(); 102 execContexts.push_back(xcProxy); 103#else 104 if (systemPtr) { 105 cpuXC = new CPUExecContext(this, 0, systemPtr, itb, dtb, memPtr, false); --- 23 unchanged lines hidden (view full) --- 129 memReq->xc = xcProxy; 130 delete cpuXC->kernelStats; 131 cpuXC->kernelStats = NULL; 132 } 133} 134#endif 135 136void |
137CheckerCPU::setIcachePort(Port *icache_port) 138{ 139 icachePort = icache_port; 140} 141 142void 143CheckerCPU::setDcachePort(Port *dcache_port) 144{ 145 dcachePort = dcache_port; 146} 147 148void |
|
136CheckerCPU::serialize(ostream &os) 137{ 138/* 139 BaseCPU::serialize(os); 140 SERIALIZE_SCALAR(inst); 141 nameOut(os, csprintf("%s.xc", name())); 142 cpuXC->serialize(os); 143 cacheCompletionEvent.serialize(os); --- 21 unchanged lines hidden (view full) --- 165{ 166 panic("Unimplemented!"); 167} 168 169template <class T> 170Fault 171CheckerCPU::read(Addr addr, T &data, unsigned flags) 172{ | 149CheckerCPU::serialize(ostream &os) 150{ 151/* 152 BaseCPU::serialize(os); 153 SERIALIZE_SCALAR(inst); 154 nameOut(os, csprintf("%s.xc", name())); 155 cpuXC->serialize(os); 156 cacheCompletionEvent.serialize(os); --- 21 unchanged lines hidden (view full) --- 178{ 179 panic("Unimplemented!"); 180} 181 182template <class T> 183Fault 184CheckerCPU::read(Addr addr, T &data, unsigned flags) 185{ |
173/* 174 memReq->reset(addr, sizeof(T), flags); | 186 // need to fill in CPU & thread IDs here 187 memReq = new Request(); |
175 | 188 |
189 memReq->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC()); 190 |
|
176 // translate to physical address 177 translateDataReadReq(memReq); 178 | 191 // translate to physical address 192 translateDataReadReq(memReq); 193 |
179 memReq->cmd = Read; 180 memReq->completionEvent = NULL; 181 memReq->time = curTick; 182 memReq->flags &= ~INST_READ; | 194 Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast); |
183 | 195 |
184 if (!(memReq->flags & UNCACHEABLE)) { | 196 pkt->dataStatic(&data); 197 198 if (!(memReq->getFlags() & UNCACHEABLE)) { |
185 // Access memory to see if we have the same data | 199 // Access memory to see if we have the same data |
186 cpuXC->read(memReq, data); | 200 dcachePort->sendFunctional(pkt); |
187 } else { 188 // Assume the data is correct if it's an uncached access 189 memcpy(&data, &unverifiedResult.integer, sizeof(T)); 190 } | 201 } else { 202 // Assume the data is correct if it's an uncached access 203 memcpy(&data, &unverifiedResult.integer, sizeof(T)); 204 } |
191*/ | 205 206 delete pkt; 207 |
192 return NoFault; 193} 194 195#ifndef DOXYGEN_SHOULD_SKIP_THIS 196 197template 198Fault 199CheckerCPU::read(Addr addr, uint64_t &data, unsigned flags); --- 32 unchanged lines hidden (view full) --- 232{ 233 return read(addr, (uint32_t&)data, flags); 234} 235 236template <class T> 237Fault 238CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) 239{ | 208 return NoFault; 209} 210 211#ifndef DOXYGEN_SHOULD_SKIP_THIS 212 213template 214Fault 215CheckerCPU::read(Addr addr, uint64_t &data, unsigned flags); --- 32 unchanged lines hidden (view full) --- 248{ 249 return read(addr, (uint32_t&)data, flags); 250} 251 252template <class T> 253Fault 254CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) 255{ |
240/* 241 memReq->reset(addr, sizeof(T), flags); | 256 // need to fill in CPU & thread IDs here 257 memReq = new Request(); |
242 | 258 |
259 memReq->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC()); 260 |
|
243 // translate to physical address 244 cpuXC->translateDataWriteReq(memReq); 245 246 // Can compare the write data and result only if it's cacheable, 247 // not a store conditional, or is a store conditional that 248 // succeeded. 249 // @todo: Verify that actual memory matches up with these values. 250 // Right now it only verifies that the instruction data is the 251 // same as what was in the request that got sent to memory; there 252 // is no verification that it is the same as what is in memory. 253 // This is because the LSQ would have to be snooped in the CPU to 254 // verify this data. 255 if (unverifiedReq && | 261 // translate to physical address 262 cpuXC->translateDataWriteReq(memReq); 263 264 // Can compare the write data and result only if it's cacheable, 265 // not a store conditional, or is a store conditional that 266 // succeeded. 267 // @todo: Verify that actual memory matches up with these values. 268 // Right now it only verifies that the instruction data is the 269 // same as what was in the request that got sent to memory; there 270 // is no verification that it is the same as what is in memory. 271 // This is because the LSQ would have to be snooped in the CPU to 272 // verify this data. 273 if (unverifiedReq && |
256 !(unverifiedReq->flags & UNCACHEABLE) && 257 (!(unverifiedReq->flags & LOCKED) || 258 ((unverifiedReq->flags & LOCKED) && 259 unverifiedReq->result == 1))) { 260#if 0 261 memReq->cmd = Read; 262 memReq->completionEvent = NULL; 263 memReq->time = curTick; 264 memReq->flags &= ~INST_READ; 265 cpuXC->read(memReq, inst_data); 266#endif | 274 !(unverifiedReq->getFlags() & UNCACHEABLE) && 275 (!(unverifiedReq->getFlags() & LOCKED) || 276 ((unverifiedReq->getFlags() & LOCKED) && 277 unverifiedReq->getScResult() == 1))) { |
267 T inst_data; | 278 T inst_data; |
268 memcpy(&inst_data, unverifiedReq->data, sizeof(T)); | 279/* 280 // This code would work if the LSQ allowed for snooping. 281 Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast); 282 pkt.dataStatic(&inst_data); |
269 | 283 |
284 dcachePort->sendFunctional(pkt); 285 286 delete pkt; 287*/ 288 memcpy(&inst_data, unverifiedMemData, sizeof(T)); 289 |
|
270 if (data != inst_data) { 271 warn("%lli: Store value does not match value in memory! " 272 "Instruction: %#x, memory: %#x", 273 curTick, inst_data, data); 274 handleError(); 275 } 276 } 277 278 // Assume the result was the same as the one passed in. This checker 279 // doesn't check if the SC should succeed or fail, it just checks the 280 // value. | 290 if (data != inst_data) { 291 warn("%lli: Store value does not match value in memory! " 292 "Instruction: %#x, memory: %#x", 293 curTick, inst_data, data); 294 handleError(); 295 } 296 } 297 298 // Assume the result was the same as the one passed in. This checker 299 // doesn't check if the SC should succeed or fail, it just checks the 300 // value. |
281 if (res) 282 *res = unverifiedReq->result; 283 */ | 301 if (res && unverifiedReq->scResultValid()) 302 *res = unverifiedReq->getScResult(); 303 |
284 return NoFault; 285} 286 287 288#ifndef DOXYGEN_SHOULD_SKIP_THIS 289template 290Fault 291CheckerCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res); --- 154 unchanged lines hidden (view full) --- 446 // Try to check all instructions that are completed, ending if we 447 // run out of instructions to check or if an instruction is not 448 // yet completed. 449 while (1) { 450 DPRINTF(Checker, "Processing instruction [sn:%lli] PC:%#x.\n", 451 inst->seqNum, inst->readPC()); 452 unverifiedResult.integer = inst->readIntResult(); 453 unverifiedReq = inst->req; | 304 return NoFault; 305} 306 307 308#ifndef DOXYGEN_SHOULD_SKIP_THIS 309template 310Fault 311CheckerCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res); --- 154 unchanged lines hidden (view full) --- 466 // Try to check all instructions that are completed, ending if we 467 // run out of instructions to check or if an instruction is not 468 // yet completed. 469 while (1) { 470 DPRINTF(Checker, "Processing instruction [sn:%lli] PC:%#x.\n", 471 inst->seqNum, inst->readPC()); 472 unverifiedResult.integer = inst->readIntResult(); 473 unverifiedReq = inst->req; |
474 unverifiedMemData = inst->memData; |
|
454 numCycles++; 455 456 Fault fault = NoFault; 457 458 // maintain $r0 semantics 459 cpuXC->setIntReg(ZeroReg, 0); 460#ifdef TARGET_ALPHA 461 cpuXC->setFloatRegDouble(ZeroReg, 0.0); --- 27 unchanged lines hidden (view full) --- 489 // Try to fetch the instruction 490 491#if FULL_SYSTEM 492#define IFETCH_FLAGS(pc) ((pc) & 1) ? PHYSICAL : 0 493#else 494#define IFETCH_FLAGS(pc) 0 495#endif 496 | 475 numCycles++; 476 477 Fault fault = NoFault; 478 479 // maintain $r0 semantics 480 cpuXC->setIntReg(ZeroReg, 0); 481#ifdef TARGET_ALPHA 482 cpuXC->setFloatRegDouble(ZeroReg, 0.0); --- 27 unchanged lines hidden (view full) --- 510 // Try to fetch the instruction 511 512#if FULL_SYSTEM 513#define IFETCH_FLAGS(pc) ((pc) & 1) ? PHYSICAL : 0 514#else 515#define IFETCH_FLAGS(pc) 0 516#endif 517 |
518 uint64_t fetch_PC = cpuXC->readPC() & ~3; 519 |
|
497 // set up memory request for instruction fetch | 520 // set up memory request for instruction fetch |
498// memReq->cmd = Read; 499// memReq->reset(cpuXC->readPC() & ~3, sizeof(uint32_t), 500// IFETCH_FLAGS(cpuXC->readPC())); | 521 memReq = new Request(inst->threadNumber, fetch_PC, 522 sizeof(uint32_t), 523 IFETCH_FLAGS(cpuXC->readPC()), 524 fetch_PC, cpuXC->readCpuId(), inst->threadNumber); |
501 502 bool succeeded = translateInstReq(memReq); 503 504 if (!succeeded) { 505 if (inst->getFault() == NoFault) { 506 // In this case the instruction was not a dummy 507 // instruction carrying an ITB fault. In the single 508 // threaded case the ITB should still be able to --- 12 unchanged lines hidden (view full) --- 521 // The instruction is carrying an ITB fault. Handle 522 // the fault and see if our results match the CPU on 523 // the next tick(). 524 fault = inst->getFault(); 525 } 526 } 527 528 if (fault == NoFault) { | 525 526 bool succeeded = translateInstReq(memReq); 527 528 if (!succeeded) { 529 if (inst->getFault() == NoFault) { 530 // In this case the instruction was not a dummy 531 // instruction carrying an ITB fault. In the single 532 // threaded case the ITB should still be able to --- 12 unchanged lines hidden (view full) --- 545 // The instruction is carrying an ITB fault. Handle 546 // the fault and see if our results match the CPU on 547 // the next tick(). 548 fault = inst->getFault(); 549 } 550 } 551 552 if (fault == NoFault) { |
529// cpuXC->read(memReq, machInst); | 553 Packet *pkt = new Packet(memReq, Packet::ReadReq, 554 Packet::Broadcast); |
530 | 555 |
556 pkt->dataStatic(&machInst); 557 558 icachePort->sendFunctional(pkt); 559 560 delete pkt; 561 |
|
531 // keep an instruction count 532 numInst++; 533 534 // decode the instruction 535 machInst = gtoh(machInst); 536 // Checks that the instruction matches what we expected it to be. 537 // Checks both the machine instruction and the PC. 538 validateInst(inst); 539 540 curStaticInst = StaticInst::decode(makeExtMI(machInst, 541 cpuXC->readPC())); 542 543#if FULL_SYSTEM 544 cpuXC->setInst(machInst); 545#endif // FULL_SYSTEM 546 547 fault = inst->getFault(); 548 } 549 | 562 // keep an instruction count 563 numInst++; 564 565 // decode the instruction 566 machInst = gtoh(machInst); 567 // Checks that the instruction matches what we expected it to be. 568 // Checks both the machine instruction and the PC. 569 validateInst(inst); 570 571 curStaticInst = StaticInst::decode(makeExtMI(machInst, 572 cpuXC->readPC())); 573 574#if FULL_SYSTEM 575 cpuXC->setInst(machInst); 576#endif // FULL_SYSTEM 577 578 fault = inst->getFault(); 579 } 580 |
581 // Discard fetch's memReq. 582 delete memReq; 583 memReq = NULL; 584 |
|
550 // Either the instruction was a fault and we should process the fault, 551 // or we should just go ahead execute the instruction. This assumes 552 // that the instruction is properly marked as a fault. 553 if (fault == NoFault) { 554 555 cpuXC->func_exe_inst++; 556 557 fault = curStaticInst->execute(this, NULL); --- 46 unchanged lines hidden (view full) --- 604 DPRINTF(Checker, "PC Event, PC is now %#x\n", newPC); 605 } 606#endif 607 608 // @todo: Optionally can check all registers. (Or just those 609 // that have been modified). 610 validateState(); 611 | 585 // Either the instruction was a fault and we should process the fault, 586 // or we should just go ahead execute the instruction. This assumes 587 // that the instruction is properly marked as a fault. 588 if (fault == NoFault) { 589 590 cpuXC->func_exe_inst++; 591 592 fault = curStaticInst->execute(this, NULL); --- 46 unchanged lines hidden (view full) --- 639 DPRINTF(Checker, "PC Event, PC is now %#x\n", newPC); 640 } 641#endif 642 643 // @todo: Optionally can check all registers. (Or just those 644 // that have been modified). 645 validateState(); 646 |
647 if (memReq) { 648 delete memReq; 649 memReq = NULL; 650 } 651 |
|
612 // Continue verifying instructions if there's another completed 613 // instruction waiting to be verified. 614 if (instList.empty()) { 615 break; 616 } else if (instList.front()->isCompleted()) { 617 inst = instList.front(); 618 instList.pop_front(); 619 } else { --- 54 unchanged lines hidden (view full) --- 674 if (idx < TheISA::FP_Base_DepTag) { 675 cpuXC->setIntReg(idx, inst->readIntResult()); 676 } else if (idx < TheISA::Fpcr_DepTag) { 677 cpuXC->setFloatRegBits(idx, inst->readIntResult()); 678 } else { 679 cpuXC->setMiscReg(idx, inst->readIntResult()); 680 } 681 } else if (result.integer != inst->readIntResult()) { | 652 // Continue verifying instructions if there's another completed 653 // instruction waiting to be verified. 654 if (instList.empty()) { 655 break; 656 } else if (instList.front()->isCompleted()) { 657 inst = instList.front(); 658 instList.pop_front(); 659 } else { --- 54 unchanged lines hidden (view full) --- 714 if (idx < TheISA::FP_Base_DepTag) { 715 cpuXC->setIntReg(idx, inst->readIntResult()); 716 } else if (idx < TheISA::Fpcr_DepTag) { 717 cpuXC->setFloatRegBits(idx, inst->readIntResult()); 718 } else { 719 cpuXC->setMiscReg(idx, inst->readIntResult()); 720 } 721 } else if (result.integer != inst->readIntResult()) { |
682 warn("%lli: Instruction results do not match! (Results may not " | 722 warn("%lli: Instruction results do not match! (Values may not " |
683 "actually be integers) Inst: %#x, checker: %#x", 684 curTick, inst->readIntResult(), result.integer); 685 handleError(); 686 } 687 } 688 689 if (inst->readNextPC() != cpuXC->readNextPC()) { 690 warn("%lli: Instruction next PCs do not match! Inst: %#x, " --- 67 unchanged lines hidden --- | 723 "actually be integers) Inst: %#x, checker: %#x", 724 curTick, inst->readIntResult(), result.integer); 725 handleError(); 726 } 727 } 728 729 if (inst->readNextPC() != cpuXC->readNextPC()) { 730 warn("%lli: Instruction next PCs do not match! Inst: %#x, " --- 67 unchanged lines hidden --- |