timing.cc (3169:65bef767b5de) | timing.cc (3170:37fd1e73f836) |
---|---|
1/* 2 * Copyright (c) 2002-2005 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; --- 14 unchanged lines hidden (view full) --- 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. 27 * 28 * Authors: Steve Reinhardt 29 */ 30 | 1/* 2 * Copyright (c) 2002-2005 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; --- 14 unchanged lines hidden (view full) --- 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. 27 * 28 * Authors: Steve Reinhardt 29 */ 30 |
31#include "arch/locked_mem.hh" |
|
31#include "arch/utility.hh" 32#include "cpu/exetrace.hh" 33#include "cpu/simple/timing.hh" 34#include "mem/packet_impl.hh" 35#include "sim/builder.hh" 36#include "sim/system.hh" 37 38using namespace std; --- 50 unchanged lines hidden (view full) --- 89void 90TimingSimpleCPU::CpuPort::TickEvent::schedule(Packet *_pkt, Tick t) 91{ 92 pkt = _pkt; 93 Event::schedule(t); 94} 95 96TimingSimpleCPU::TimingSimpleCPU(Params *p) | 32#include "arch/utility.hh" 33#include "cpu/exetrace.hh" 34#include "cpu/simple/timing.hh" 35#include "mem/packet_impl.hh" 36#include "sim/builder.hh" 37#include "sim/system.hh" 38 39using namespace std; --- 50 unchanged lines hidden (view full) --- 90void 91TimingSimpleCPU::CpuPort::TickEvent::schedule(Packet *_pkt, Tick t) 92{ 93 pkt = _pkt; 94 Event::schedule(t); 95} 96 97TimingSimpleCPU::TimingSimpleCPU(Params *p) |
97 : BaseSimpleCPU(p), icachePort(this, p->clock), dcachePort(this, p->clock) | 98 : BaseSimpleCPU(p), icachePort(this, p->clock), dcachePort(this, p->clock), 99 cpu_id(p->cpu_id) |
98{ 99 _status = Idle; 100 ifetch_pkt = dcache_pkt = NULL; 101 drainEvent = NULL; 102 fetchEvent = NULL; 103 changeState(SimObject::Running); 104} 105 --- 118 unchanged lines hidden (view full) --- 224 225 226template <class T> 227Fault 228TimingSimpleCPU::read(Addr addr, T &data, unsigned flags) 229{ 230 Request *req = 231 new Request(/* asid */ 0, addr, sizeof(T), flags, thread->readPC(), | 100{ 101 _status = Idle; 102 ifetch_pkt = dcache_pkt = NULL; 103 drainEvent = NULL; 104 fetchEvent = NULL; 105 changeState(SimObject::Running); 106} 107 --- 118 unchanged lines hidden (view full) --- 226 227 228template <class T> 229Fault 230TimingSimpleCPU::read(Addr addr, T &data, unsigned flags) 231{ 232 Request *req = 233 new Request(/* asid */ 0, addr, sizeof(T), flags, thread->readPC(), |
232 /* CPU ID */ 0, /* thread ID */ 0); | 234 cpu_id, /* thread ID */ 0); |
233 234 if (traceData) { 235 traceData->setAddr(req->getVaddr()); 236 } 237 238 // translate to physical address 239 Fault fault = thread->translateDataReadReq(req); 240 --- 64 unchanged lines hidden (view full) --- 305 306 307template <class T> 308Fault 309TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) 310{ 311 Request *req = 312 new Request(/* asid */ 0, addr, sizeof(T), flags, thread->readPC(), | 235 236 if (traceData) { 237 traceData->setAddr(req->getVaddr()); 238 } 239 240 // translate to physical address 241 Fault fault = thread->translateDataReadReq(req); 242 --- 64 unchanged lines hidden (view full) --- 307 308 309template <class T> 310Fault 311TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) 312{ 313 Request *req = 314 new Request(/* asid */ 0, addr, sizeof(T), flags, thread->readPC(), |
313 /* CPU ID */ 0, /* thread ID */ 0); | 315 cpu_id, /* thread ID */ 0); |
314 315 // translate to physical address 316 Fault fault = thread->translateDataWriteReq(req); 317 318 // Now do the access. 319 if (fault == NoFault) { 320 assert(dcache_pkt == NULL); 321 dcache_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast); 322 dcache_pkt->allocate(); 323 dcache_pkt->set(data); 324 | 316 317 // translate to physical address 318 Fault fault = thread->translateDataWriteReq(req); 319 320 // Now do the access. 321 if (fault == NoFault) { 322 assert(dcache_pkt == NULL); 323 dcache_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast); 324 dcache_pkt->allocate(); 325 dcache_pkt->set(data); 326 |
325 if (!dcachePort.sendTiming(dcache_pkt)) { 326 _status = DcacheRetry; 327 } else { 328 _status = DcacheWaitResponse; 329 // memory system takes ownership of packet 330 dcache_pkt = NULL; | 327 bool do_access = true; // flag to suppress cache access 328 329 if (req->isLocked()) { 330 do_access = TheISA::handleLockedWrite(thread, req); |
331 } | 331 } |
332 333 if (do_access) { 334 if (!dcachePort.sendTiming(dcache_pkt)) { 335 _status = DcacheRetry; 336 } else { 337 _status = DcacheWaitResponse; 338 // memory system takes ownership of packet 339 dcache_pkt = NULL; 340 } 341 } |
|
332 } 333 334 // This will need a new way to tell if it's hooked up to a cache or not. 335 if (req->getFlags() & UNCACHEABLE) 336 recordEvent("Uncached Write"); 337 338 // If the write needs to have a fault on the access, consider calling 339 // changeStatus() and changing it to "bad addr write" or something. --- 47 unchanged lines hidden (view full) --- 387} 388 389 390void 391TimingSimpleCPU::fetch() 392{ 393 checkForInterrupts(); 394 | 342 } 343 344 // This will need a new way to tell if it's hooked up to a cache or not. 345 if (req->getFlags() & UNCACHEABLE) 346 recordEvent("Uncached Write"); 347 348 // If the write needs to have a fault on the access, consider calling 349 // changeStatus() and changing it to "bad addr write" or something. --- 47 unchanged lines hidden (view full) --- 397} 398 399 400void 401TimingSimpleCPU::fetch() 402{ 403 checkForInterrupts(); 404 |
395 // need to fill in CPU & thread IDs here | |
396 Request *ifetch_req = new Request(); | 405 Request *ifetch_req = new Request(); |
397 ifetch_req->setThreadContext(0,0); //Need CPU/Thread IDS HERE | 406 ifetch_req->setThreadContext(cpu_id, /* thread ID */ 0); |
398 Fault fault = setupFetchRequest(ifetch_req); 399 400 ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast); 401 ifetch_pkt->dataStatic(&inst); 402 403 if (fault == NoFault) { 404 if (!icachePort.sendTiming(ifetch_pkt)) { 405 // Need to wait for retry --- 42 unchanged lines hidden (view full) --- 448 completeDrain(); 449 return; 450 } 451 452 preExecute(); 453 if (curStaticInst->isMemRef() && !curStaticInst->isDataPrefetch()) { 454 // load or store: just send to dcache 455 Fault fault = curStaticInst->initiateAcc(this, traceData); | 407 Fault fault = setupFetchRequest(ifetch_req); 408 409 ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast); 410 ifetch_pkt->dataStatic(&inst); 411 412 if (fault == NoFault) { 413 if (!icachePort.sendTiming(ifetch_pkt)) { 414 // Need to wait for retry --- 42 unchanged lines hidden (view full) --- 457 completeDrain(); 458 return; 459 } 460 461 preExecute(); 462 if (curStaticInst->isMemRef() && !curStaticInst->isDataPrefetch()) { 463 // load or store: just send to dcache 464 Fault fault = curStaticInst->initiateAcc(this, traceData); |
456 if (fault == NoFault) { 457 // successfully initiated access: instruction will 458 // complete in dcache response callback 459 assert(_status == DcacheWaitResponse); | 465 if (_status != Running) { 466 // instruction will complete in dcache response callback 467 assert(_status == DcacheWaitResponse || _status == DcacheRetry); 468 assert(fault == NoFault); |
460 } else { | 469 } else { |
461 // fault: complete now to invoke fault handler | 470 if (fault == NoFault) { 471 // early fail on store conditional: complete now 472 assert(dcache_pkt != NULL); 473 fault = curStaticInst->completeAcc(dcache_pkt, this, 474 traceData); 475 delete dcache_pkt->req; 476 delete dcache_pkt; 477 dcache_pkt = NULL; 478 } |
462 postExecute(); 463 advanceInst(fault); 464 } 465 } else { 466 // non-memory instruction: execute completely now 467 Fault fault = curStaticInst->execute(this, traceData); 468 postExecute(); 469 advanceInst(fault); --- 4 unchanged lines hidden (view full) --- 474TimingSimpleCPU::IcachePort::ITickEvent::process() 475{ 476 cpu->completeIfetch(pkt); 477} 478 479bool 480TimingSimpleCPU::IcachePort::recvTiming(Packet *pkt) 481{ | 479 postExecute(); 480 advanceInst(fault); 481 } 482 } else { 483 // non-memory instruction: execute completely now 484 Fault fault = curStaticInst->execute(this, traceData); 485 postExecute(); 486 advanceInst(fault); --- 4 unchanged lines hidden (view full) --- 491TimingSimpleCPU::IcachePort::ITickEvent::process() 492{ 493 cpu->completeIfetch(pkt); 494} 495 496bool 497TimingSimpleCPU::IcachePort::recvTiming(Packet *pkt) 498{ |
482 // These next few lines could be replaced with something faster 483 // who knows what though | 499 // delay processing of returned data until next CPU clock edge |
484 Tick time = pkt->req->getTime(); 485 while (time < curTick) 486 time += lat; 487 488 if (time == curTick) 489 cpu->completeIfetch(pkt); 490 else 491 tickEvent.schedule(pkt, time); --- 30 unchanged lines hidden (view full) --- 522 delete pkt->req; 523 delete pkt; 524 525 return; 526 } 527 528 Fault fault = curStaticInst->completeAcc(pkt, this, traceData); 529 | 500 Tick time = pkt->req->getTime(); 501 while (time < curTick) 502 time += lat; 503 504 if (time == curTick) 505 cpu->completeIfetch(pkt); 506 else 507 tickEvent.schedule(pkt, time); --- 30 unchanged lines hidden (view full) --- 538 delete pkt->req; 539 delete pkt; 540 541 return; 542 } 543 544 Fault fault = curStaticInst->completeAcc(pkt, this, traceData); 545 |
546 if (pkt->isRead() && pkt->req->isLocked()) { 547 TheISA::handleLockedRead(thread, pkt->req); 548 } 549 |
|
530 delete pkt->req; 531 delete pkt; 532 533 postExecute(); 534 advanceInst(fault); 535} 536 537 538void 539TimingSimpleCPU::completeDrain() 540{ 541 DPRINTF(Config, "Done draining\n"); 542 changeState(SimObject::Drained); 543 drainEvent->process(); 544} 545 546bool 547TimingSimpleCPU::DcachePort::recvTiming(Packet *pkt) 548{ | 550 delete pkt->req; 551 delete pkt; 552 553 postExecute(); 554 advanceInst(fault); 555} 556 557 558void 559TimingSimpleCPU::completeDrain() 560{ 561 DPRINTF(Config, "Done draining\n"); 562 changeState(SimObject::Drained); 563 drainEvent->process(); 564} 565 566bool 567TimingSimpleCPU::DcachePort::recvTiming(Packet *pkt) 568{ |
569 // delay processing of returned data until next CPU clock edge |
|
549 Tick time = pkt->req->getTime(); 550 while (time < curTick) 551 time += lat; 552 553 if (time == curTick) 554 cpu->completeDataAccess(pkt); 555 else 556 tickEvent.schedule(pkt, time); --- 12 unchanged lines hidden (view full) --- 569{ 570 // we shouldn't get a retry unless we have a packet that we're 571 // waiting to transmit 572 assert(cpu->dcache_pkt != NULL); 573 assert(cpu->_status == DcacheRetry); 574 Packet *tmp = cpu->dcache_pkt; 575 if (sendTiming(tmp)) { 576 cpu->_status = DcacheWaitResponse; | 570 Tick time = pkt->req->getTime(); 571 while (time < curTick) 572 time += lat; 573 574 if (time == curTick) 575 cpu->completeDataAccess(pkt); 576 else 577 tickEvent.schedule(pkt, time); --- 12 unchanged lines hidden (view full) --- 590{ 591 // we shouldn't get a retry unless we have a packet that we're 592 // waiting to transmit 593 assert(cpu->dcache_pkt != NULL); 594 assert(cpu->_status == DcacheRetry); 595 Packet *tmp = cpu->dcache_pkt; 596 if (sendTiming(tmp)) { 597 cpu->_status = DcacheWaitResponse; |
598 // memory system takes ownership of packet |
|
577 cpu->dcache_pkt = NULL; 578 } 579} 580 581 582//////////////////////////////////////////////////////////////////////// 583// 584// TimingSimpleCPU Simulation Object 585// 586BEGIN_DECLARE_SIM_OBJECT_PARAMS(TimingSimpleCPU) 587 588 Param<Counter> max_insts_any_thread; 589 Param<Counter> max_insts_all_threads; 590 Param<Counter> max_loads_any_thread; 591 Param<Counter> max_loads_all_threads; 592 Param<Tick> progress_interval; 593 SimObjectParam<MemObject *> mem; 594 SimObjectParam<System *> system; | 599 cpu->dcache_pkt = NULL; 600 } 601} 602 603 604//////////////////////////////////////////////////////////////////////// 605// 606// TimingSimpleCPU Simulation Object 607// 608BEGIN_DECLARE_SIM_OBJECT_PARAMS(TimingSimpleCPU) 609 610 Param<Counter> max_insts_any_thread; 611 Param<Counter> max_insts_all_threads; 612 Param<Counter> max_loads_any_thread; 613 Param<Counter> max_loads_all_threads; 614 Param<Tick> progress_interval; 615 SimObjectParam<MemObject *> mem; 616 SimObjectParam<System *> system; |
617 Param<int> cpu_id; |
|
595 596#if FULL_SYSTEM 597 SimObjectParam<AlphaITB *> itb; 598 SimObjectParam<AlphaDTB *> dtb; | 618 619#if FULL_SYSTEM 620 SimObjectParam<AlphaITB *> itb; 621 SimObjectParam<AlphaDTB *> dtb; |
599 Param<int> cpu_id; | |
600 Param<Tick> profile; 601#else 602 SimObjectParam<Process *> workload; 603#endif // FULL_SYSTEM 604 605 Param<int> clock; 606 607 Param<bool> defer_registration; --- 12 unchanged lines hidden (view full) --- 620 "terminate when all threads have reached this inst count"), 621 INIT_PARAM(max_loads_any_thread, 622 "terminate when any thread reaches this load count"), 623 INIT_PARAM(max_loads_all_threads, 624 "terminate when all threads have reached this load count"), 625 INIT_PARAM(progress_interval, "Progress interval"), 626 INIT_PARAM(mem, "memory"), 627 INIT_PARAM(system, "system object"), | 622 Param<Tick> profile; 623#else 624 SimObjectParam<Process *> workload; 625#endif // FULL_SYSTEM 626 627 Param<int> clock; 628 629 Param<bool> defer_registration; --- 12 unchanged lines hidden (view full) --- 642 "terminate when all threads have reached this inst count"), 643 INIT_PARAM(max_loads_any_thread, 644 "terminate when any thread reaches this load count"), 645 INIT_PARAM(max_loads_all_threads, 646 "terminate when all threads have reached this load count"), 647 INIT_PARAM(progress_interval, "Progress interval"), 648 INIT_PARAM(mem, "memory"), 649 INIT_PARAM(system, "system object"), |
650 INIT_PARAM(cpu_id, "processor ID"), |
|
628 629#if FULL_SYSTEM 630 INIT_PARAM(itb, "Instruction TLB"), 631 INIT_PARAM(dtb, "Data TLB"), | 651 652#if FULL_SYSTEM 653 INIT_PARAM(itb, "Instruction TLB"), 654 INIT_PARAM(dtb, "Data TLB"), |
632 INIT_PARAM(cpu_id, "processor ID"), | |
633 INIT_PARAM(profile, ""), 634#else 635 INIT_PARAM(workload, "processes to run"), 636#endif // FULL_SYSTEM 637 638 INIT_PARAM(clock, "clock speed"), 639 INIT_PARAM(defer_registration, "defer system registration (for sampling)"), 640 INIT_PARAM(width, "cpu width"), --- 15 unchanged lines hidden (view full) --- 656 params->max_loads_all_threads = max_loads_all_threads; 657 params->progress_interval = progress_interval; 658 params->deferRegistration = defer_registration; 659 params->clock = clock; 660 params->functionTrace = function_trace; 661 params->functionTraceStart = function_trace_start; 662 params->mem = mem; 663 params->system = system; | 655 INIT_PARAM(profile, ""), 656#else 657 INIT_PARAM(workload, "processes to run"), 658#endif // FULL_SYSTEM 659 660 INIT_PARAM(clock, "clock speed"), 661 INIT_PARAM(defer_registration, "defer system registration (for sampling)"), 662 INIT_PARAM(width, "cpu width"), --- 15 unchanged lines hidden (view full) --- 678 params->max_loads_all_threads = max_loads_all_threads; 679 params->progress_interval = progress_interval; 680 params->deferRegistration = defer_registration; 681 params->clock = clock; 682 params->functionTrace = function_trace; 683 params->functionTraceStart = function_trace_start; 684 params->mem = mem; 685 params->system = system; |
686 params->cpu_id = cpu_id; |
|
664 665#if FULL_SYSTEM 666 params->itb = itb; 667 params->dtb = dtb; | 687 688#if FULL_SYSTEM 689 params->itb = itb; 690 params->dtb = dtb; |
668 params->cpu_id = cpu_id; | |
669 params->profile = profile; 670#else 671 params->process = workload; 672#endif 673 674 TimingSimpleCPU *cpu = new TimingSimpleCPU(params); 675 return cpu; 676} 677 678REGISTER_SIM_OBJECT("TimingSimpleCPU", TimingSimpleCPU) 679 | 691 params->profile = profile; 692#else 693 params->process = workload; 694#endif 695 696 TimingSimpleCPU *cpu = new TimingSimpleCPU(params); 697 return cpu; 698} 699 700REGISTER_SIM_OBJECT("TimingSimpleCPU", TimingSimpleCPU) 701 |