cpu.cc (8737:770ccf3af571) | cpu.cc (8766:b0773af78423) |
---|---|
1/* | 1/* |
2 * Copyright (c) 2011 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * | |
14 * Copyright (c) 2004-2006 The Regents of The University of Michigan 15 * Copyright (c) 2011 Regents of the University of California 16 * All rights reserved. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions are 20 * met: redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer; --- 41 unchanged lines hidden (view full) --- 63#if FULL_SYSTEM 64#include "cpu/quiesce_event.hh" 65#else 66#include "sim/process.hh" 67#endif 68 69#if USE_CHECKER 70#include "cpu/checker/cpu.hh" | 2 * Copyright (c) 2004-2006 The Regents of The University of Michigan 3 * Copyright (c) 2011 Regents of the University of California 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer; --- 41 unchanged lines hidden (view full) --- 51#if FULL_SYSTEM 52#include "cpu/quiesce_event.hh" 53#else 54#include "sim/process.hh" 55#endif 56 57#if USE_CHECKER 58#include "cpu/checker/cpu.hh" |
71#include "cpu/checker/thread_context.hh" | |
72#endif 73 74#if THE_ISA == ALPHA_ISA 75#include "arch/alpha/osfpal.hh" 76#include "debug/Activity.hh" 77#endif 78 | 59#endif 60 61#if THE_ISA == ALPHA_ISA 62#include "arch/alpha/osfpal.hh" 63#include "debug/Activity.hh" 64#endif 65 |
79struct BaseCPUParams; | 66class BaseCPUParams; |
80 81using namespace TheISA; 82using namespace std; 83 84BaseO3CPU::BaseO3CPU(BaseCPUParams *params) 85 : BaseCPU(params) 86{ 87} 88 89void 90BaseO3CPU::regStats() 91{ 92 BaseCPU::regStats(); 93} 94 | 67 68using namespace TheISA; 69using namespace std; 70 71BaseO3CPU::BaseO3CPU(BaseCPUParams *params) 72 : BaseCPU(params) 73{ 74} 75 76void 77BaseO3CPU::regStats() 78{ 79 BaseCPU::regStats(); 80} 81 |
95template<class Impl> 96bool 97FullO3CPU<Impl>::IcachePort::recvTiming(PacketPtr pkt) 98{ 99 DPRINTF(O3CPU, "Fetch unit received timing\n"); 100 if (pkt->isResponse()) { 101 // We shouldn't ever get a block in ownership state 102 assert(!(pkt->memInhibitAsserted() && !pkt->sharedAsserted())); 103 104 fetch->processCacheCompletion(pkt); 105 } 106 //else Snooped a coherence request, just return 107 return true; 108} 109 110template<class Impl> 111void 112FullO3CPU<Impl>::IcachePort::recvRetry() 113{ 114 fetch->recvRetry(); 115} 116 | |
117template <class Impl> | 82template <class Impl> |
118bool 119FullO3CPU<Impl>::DcachePort::recvTiming(PacketPtr pkt) 120{ 121 return lsq->recvTiming(pkt); 122} 123 124template <class Impl> 125void 126FullO3CPU<Impl>::DcachePort::recvRetry() 127{ 128 lsq->recvRetry(); 129} 130 131template <class Impl> | |
132FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c) 133 : Event(CPU_Tick_Pri), cpu(c) 134{ 135} 136 137template <class Impl> 138void 139FullO3CPU<Impl>::TickEvent::process() --- 98 unchanged lines hidden (view full) --- 238 params->numThreads), 239 240 scoreboard(params->numThreads, 241 TheISA::NumIntRegs, params->numPhysIntRegs, 242 TheISA::NumFloatRegs, params->numPhysFloatRegs, 243 TheISA::NumMiscRegs * numThreads, 244 TheISA::ZeroReg), 245 | 83FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c) 84 : Event(CPU_Tick_Pri), cpu(c) 85{ 86} 87 88template <class Impl> 89void 90FullO3CPU<Impl>::TickEvent::process() --- 98 unchanged lines hidden (view full) --- 189 params->numThreads), 190 191 scoreboard(params->numThreads, 192 TheISA::NumIntRegs, params->numPhysIntRegs, 193 TheISA::NumFloatRegs, params->numPhysFloatRegs, 194 TheISA::NumMiscRegs * numThreads, 195 TheISA::ZeroReg), 196 |
246 icachePort(&fetch, this), 247 dcachePort(&iew.ldstQueue, this), 248 | |
249 timeBuffer(params->backComSize, params->forwardComSize), 250 fetchQueue(params->backComSize, params->forwardComSize), 251 decodeQueue(params->backComSize, params->forwardComSize), 252 renameQueue(params->backComSize, params->forwardComSize), 253 iewQueue(params->backComSize, params->forwardComSize), 254 activityRec(name(), NumStages, 255 params->backComSize + params->forwardComSize, 256 params->activity), --- 7 unchanged lines hidden (view full) --- 264 _status = Running; 265 } else { 266 _status = Idle; 267 } 268 269#if USE_CHECKER 270 if (params->checker) { 271 BaseCPU *temp_checker = params->checker; | 197 timeBuffer(params->backComSize, params->forwardComSize), 198 fetchQueue(params->backComSize, params->forwardComSize), 199 decodeQueue(params->backComSize, params->forwardComSize), 200 renameQueue(params->backComSize, params->forwardComSize), 201 iewQueue(params->backComSize, params->forwardComSize), 202 activityRec(name(), NumStages, 203 params->backComSize + params->forwardComSize, 204 params->activity), --- 7 unchanged lines hidden (view full) --- 212 _status = Running; 213 } else { 214 _status = Idle; 215 } 216 217#if USE_CHECKER 218 if (params->checker) { 219 BaseCPU *temp_checker = params->checker; |
272 checker = dynamic_cast<Checker<Impl> *>(temp_checker); 273 checker->setIcachePort(&icachePort); | 220 checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker); |
274#if FULL_SYSTEM 275 checker->setSystem(params->system); 276#endif 277 } else { 278 checker = NULL; 279 } 280#endif // USE_CHECKER 281 --- 123 unchanged lines hidden (view full) --- 405 406 // Setup any thread state. 407 this->thread.resize(this->numThreads); 408 409 for (ThreadID tid = 0; tid < this->numThreads; ++tid) { 410#if FULL_SYSTEM 411 // SMT is not supported in FS mode yet. 412 assert(this->numThreads == 1); | 221#if FULL_SYSTEM 222 checker->setSystem(params->system); 223#endif 224 } else { 225 checker = NULL; 226 } 227#endif // USE_CHECKER 228 --- 123 unchanged lines hidden (view full) --- 352 353 // Setup any thread state. 354 this->thread.resize(this->numThreads); 355 356 for (ThreadID tid = 0; tid < this->numThreads; ++tid) { 357#if FULL_SYSTEM 358 // SMT is not supported in FS mode yet. 359 assert(this->numThreads == 1); |
413 this->thread[tid] = new Thread(this, 0); | 360 this->thread[tid] = new Thread(this, 0, NULL); |
414#else 415 if (tid < params->workload.size()) { 416 DPRINTF(O3CPU, "Workload[%i] process is %#x", 417 tid, this->thread[tid]); 418 this->thread[tid] = new typename FullO3CPU<Impl>::Thread( 419 (typename Impl::O3CPU *)(this), 420 tid, params->workload[tid]); 421 --- 68 unchanged lines hidden (view full) --- 490 .prereq(timesIdled); 491 492 idleCycles 493 .name(name() + ".idleCycles") 494 .desc("Total number of cycles that the CPU has spent unscheduled due " 495 "to idling") 496 .prereq(idleCycles); 497 | 361#else 362 if (tid < params->workload.size()) { 363 DPRINTF(O3CPU, "Workload[%i] process is %#x", 364 tid, this->thread[tid]); 365 this->thread[tid] = new typename FullO3CPU<Impl>::Thread( 366 (typename Impl::O3CPU *)(this), 367 tid, params->workload[tid]); 368 --- 68 unchanged lines hidden (view full) --- 437 .prereq(timesIdled); 438 439 idleCycles 440 .name(name() + ".idleCycles") 441 .desc("Total number of cycles that the CPU has spent unscheduled due " 442 "to idling") 443 .prereq(idleCycles); 444 |
498 quiesceCycles 499 .name(name() + ".quiesceCycles") 500 .desc("Total number of cycles that CPU has spent quiesced or waiting " 501 "for an interrupt") 502 .prereq(quiesceCycles); 503 | |
504 // Number of Instructions simulated 505 // -------------------------------- 506 // Should probably be in Base CPU but need templated 507 // MaxThreads so put in here instead 508 committedInsts 509 .init(numThreads) 510 .name(name() + ".committedInsts") 511 .desc("Number of Instructions Simulated"); --- 64 unchanged lines hidden (view full) --- 576 .prereq(miscRegfileWrites); 577} 578 579template <class Impl> 580Port * 581FullO3CPU<Impl>::getPort(const std::string &if_name, int idx) 582{ 583 if (if_name == "dcache_port") | 445 // Number of Instructions simulated 446 // -------------------------------- 447 // Should probably be in Base CPU but need templated 448 // MaxThreads so put in here instead 449 committedInsts 450 .init(numThreads) 451 .name(name() + ".committedInsts") 452 .desc("Number of Instructions Simulated"); --- 64 unchanged lines hidden (view full) --- 517 .prereq(miscRegfileWrites); 518} 519 520template <class Impl> 521Port * 522FullO3CPU<Impl>::getPort(const std::string &if_name, int idx) 523{ 524 if (if_name == "dcache_port") |
584 return &dcachePort; | 525 return iew.getDcachePort(); |
585 else if (if_name == "icache_port") | 526 else if (if_name == "icache_port") |
586 return &icachePort; | 527 return fetch.getIcachePort(); |
587 else 588 panic("No Such Port\n"); 589} 590 591template <class Impl> 592void 593FullO3CPU<Impl>::tick() 594{ --- 59 unchanged lines hidden (view full) --- 654{ 655 BaseCPU::init(); 656 657 // Set inSyscall so that the CPU doesn't squash when initially 658 // setting up registers. 659 for (ThreadID tid = 0; tid < numThreads; ++tid) 660 thread[tid]->inSyscall = true; 661 | 528 else 529 panic("No Such Port\n"); 530} 531 532template <class Impl> 533void 534FullO3CPU<Impl>::tick() 535{ --- 59 unchanged lines hidden (view full) --- 595{ 596 BaseCPU::init(); 597 598 // Set inSyscall so that the CPU doesn't squash when initially 599 // setting up registers. 600 for (ThreadID tid = 0; tid < numThreads; ++tid) 601 thread[tid]->inSyscall = true; 602 |
662 // this CPU could still be unconnected if we are restoring from a 663 // checkpoint and this CPU is to be switched in, thus we can only 664 // do this here if the instruction port is actually connected, if 665 // not we have to do it as part of takeOverFrom 666 if (icachePort.isConnected()) 667 fetch.setIcache(); 668 | |
669#if FULL_SYSTEM 670 for (ThreadID tid = 0; tid < numThreads; tid++) { 671 ThreadContext *src_tc = threadContexts[tid]; 672 TheISA::initCPU(src_tc, src_tc->contextId()); | 603#if FULL_SYSTEM 604 for (ThreadID tid = 0; tid < numThreads; tid++) { 605 ThreadContext *src_tc = threadContexts[tid]; 606 TheISA::initCPU(src_tc, src_tc->contextId()); |
673 // Initialise the ThreadContext's memory proxies 674 thread[tid]->initMemProxies(thread[tid]->getTC()); | |
675 } 676#endif 677 678 // Clear inSyscall. 679 for (int tid = 0; tid < numThreads; ++tid) 680 thread[tid]->inSyscall = false; 681 682 // Initialize stages. --- 68 unchanged lines hidden (view full) --- 751 if (lastActivatedCycle < curTick()) { 752 scheduleTickEvent(delay); 753 754 // Be sure to signal that there's some activity so the CPU doesn't 755 // deschedule itself. 756 activityRec.activity(); 757 fetch.wakeFromQuiesce(); 758 | 607 } 608#endif 609 610 // Clear inSyscall. 611 for (int tid = 0; tid < numThreads; ++tid) 612 thread[tid]->inSyscall = false; 613 614 // Initialize stages. --- 68 unchanged lines hidden (view full) --- 683 if (lastActivatedCycle < curTick()) { 684 scheduleTickEvent(delay); 685 686 // Be sure to signal that there's some activity so the CPU doesn't 687 // deschedule itself. 688 activityRec.activity(); 689 fetch.wakeFromQuiesce(); 690 |
759 quiesceCycles += tickToCycles((curTick() - 1) - lastRunningCycle); 760 | |
761 lastActivatedCycle = curTick(); 762 763 _status = Running; 764 } 765} 766 767template <class Impl> 768bool | 691 lastActivatedCycle = curTick(); 692 693 _status = Running; 694 } 695} 696 697template <class Impl> 698bool |
769FullO3CPU<Impl>::scheduleDeallocateContext(ThreadID tid, bool remove, 770 int delay) | 699FullO3CPU<Impl>::deallocateContext(ThreadID tid, bool remove, int delay) |
771{ 772 // Schedule removal of thread data from CPU 773 if (delay){ 774 DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to deallocate " 775 "on cycle %d\n", tid, curTick() + ticks(delay)); 776 scheduleDeallocateContextEvent(tid, remove, delay); 777 return false; 778 } else { --- 4 unchanged lines hidden (view full) --- 783 } 784} 785 786template <class Impl> 787void 788FullO3CPU<Impl>::suspendContext(ThreadID tid) 789{ 790 DPRINTF(O3CPU,"[tid: %i]: Suspending Thread Context.\n", tid); | 700{ 701 // Schedule removal of thread data from CPU 702 if (delay){ 703 DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to deallocate " 704 "on cycle %d\n", tid, curTick() + ticks(delay)); 705 scheduleDeallocateContextEvent(tid, remove, delay); 706 return false; 707 } else { --- 4 unchanged lines hidden (view full) --- 712 } 713} 714 715template <class Impl> 716void 717FullO3CPU<Impl>::suspendContext(ThreadID tid) 718{ 719 DPRINTF(O3CPU,"[tid: %i]: Suspending Thread Context.\n", tid); |
791 bool deallocated = scheduleDeallocateContext(tid, false, 1); | 720 bool deallocated = deallocateContext(tid, false, 1); |
792 // If this was the last thread then unschedule the tick event. 793 if ((activeThreads.size() == 1 && !deallocated) || 794 activeThreads.size() == 0) 795 unscheduleTickEvent(); | 721 // If this was the last thread then unschedule the tick event. 722 if ((activeThreads.size() == 1 && !deallocated) || 723 activeThreads.size() == 0) 724 unscheduleTickEvent(); |
796 797 DPRINTF(Quiesce, "Suspending Context\n"); 798 lastRunningCycle = curTick(); | |
799 _status = Idle; 800} 801 802template <class Impl> 803void 804FullO3CPU<Impl>::haltContext(ThreadID tid) 805{ 806 //For now, this is the same as deallocate 807 DPRINTF(O3CPU,"[tid:%i]: Halt Context called. Deallocating", tid); | 725 _status = Idle; 726} 727 728template <class Impl> 729void 730FullO3CPU<Impl>::haltContext(ThreadID tid) 731{ 732 //For now, this is the same as deallocate 733 DPRINTF(O3CPU,"[tid:%i]: Halt Context called. Deallocating", tid); |
808 scheduleDeallocateContext(tid, true, 1); | 734 deallocateContext(tid, true, 1); |
809} 810 811template <class Impl> 812void 813FullO3CPU<Impl>::insertThread(ThreadID tid) 814{ 815 DPRINTF(O3CPU,"[tid:%i] Initializing thread into CPU"); 816 // Will change now that the PC and thread state is internal to the CPU --- 215 unchanged lines hidden (view full) --- 1032 1033 assert(interrupt != NoFault); 1034 this->interrupts->updateIntrInfo(this->threadContexts[0]); 1035 1036 DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name()); 1037 this->trap(interrupt, 0, NULL); 1038} 1039 | 735} 736 737template <class Impl> 738void 739FullO3CPU<Impl>::insertThread(ThreadID tid) 740{ 741 DPRINTF(O3CPU,"[tid:%i] Initializing thread into CPU"); 742 // Will change now that the PC and thread state is internal to the CPU --- 215 unchanged lines hidden (view full) --- 958 959 assert(interrupt != NoFault); 960 this->interrupts->updateIntrInfo(this->threadContexts[0]); 961 962 DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name()); 963 this->trap(interrupt, 0, NULL); 964} 965 |
966template <class Impl> 967void 968FullO3CPU<Impl>::updateMemPorts() 969{ 970 // Update all ThreadContext's memory ports (Functional/Virtual 971 // Ports) 972 ThreadID size = thread.size(); 973 for (ThreadID i = 0; i < size; ++i) 974 thread[i]->connectMemPorts(thread[i]->getTC()); 975} |
|
1040#endif 1041 1042template <class Impl> 1043void 1044FullO3CPU<Impl>::trap(Fault fault, ThreadID tid, StaticInstPtr inst) 1045{ 1046 // Pass the thread's TC into the invoke method. 1047 fault->invoke(this->threadContexts[tid], inst); --- 178 unchanged lines hidden (view full) --- 1226 fetchQueue.advance(); 1227 decodeQueue.advance(); 1228 renameQueue.advance(); 1229 iewQueue.advance(); 1230 } 1231 1232 activityRec.reset(); 1233 | 976#endif 977 978template <class Impl> 979void 980FullO3CPU<Impl>::trap(Fault fault, ThreadID tid, StaticInstPtr inst) 981{ 982 // Pass the thread's TC into the invoke method. 983 fault->invoke(this->threadContexts[tid], inst); --- 178 unchanged lines hidden (view full) --- 1162 fetchQueue.advance(); 1163 decodeQueue.advance(); 1164 renameQueue.advance(); 1165 iewQueue.advance(); 1166 } 1167 1168 activityRec.reset(); 1169 |
1234 BaseCPU::takeOverFrom(oldCPU); | 1170 BaseCPU::takeOverFrom(oldCPU, fetch.getIcachePort(), iew.getDcachePort()); |
1235 1236 fetch.takeOverFrom(); 1237 decode.takeOverFrom(); 1238 rename.takeOverFrom(); 1239 iew.takeOverFrom(); 1240 commit.takeOverFrom(); 1241 1242 assert(!tickEvent.scheduled() || tickEvent.squashed()); --- 21 unchanged lines hidden (view full) --- 1264 ThreadContext *tc = threadContexts[i]; 1265 if (tc->status() == ThreadContext::Active && _status != Running) { 1266 _status = Running; 1267 reschedule(tickEvent, nextCycle(), true); 1268 } 1269 } 1270 if (!tickEvent.scheduled()) 1271 schedule(tickEvent, nextCycle()); | 1171 1172 fetch.takeOverFrom(); 1173 decode.takeOverFrom(); 1174 rename.takeOverFrom(); 1175 iew.takeOverFrom(); 1176 commit.takeOverFrom(); 1177 1178 assert(!tickEvent.scheduled() || tickEvent.squashed()); --- 21 unchanged lines hidden (view full) --- 1200 ThreadContext *tc = threadContexts[i]; 1201 if (tc->status() == ThreadContext::Active && _status != Running) { 1202 _status = Running; 1203 reschedule(tickEvent, nextCycle(), true); 1204 } 1205 } 1206 if (!tickEvent.scheduled()) 1207 schedule(tickEvent, nextCycle()); |
1272 1273 lastRunningCycle = curTick(); | |
1274} 1275 1276template <class Impl> 1277TheISA::MiscReg 1278FullO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, ThreadID tid) 1279{ 1280 return this->isa[tid].readMiscRegNoEffect(misc_reg); 1281} --- 432 unchanged lines hidden (view full) --- 1714template <class Impl> 1715void 1716FullO3CPU<Impl>::updateThreadPriority() 1717{ 1718 if (activeThreads.size() > 1) { 1719 //DEFAULT TO ROUND ROBIN SCHEME 1720 //e.g. Move highest priority to end of thread list 1721 list<ThreadID>::iterator list_begin = activeThreads.begin(); | 1208} 1209 1210template <class Impl> 1211TheISA::MiscReg 1212FullO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, ThreadID tid) 1213{ 1214 return this->isa[tid].readMiscRegNoEffect(misc_reg); 1215} --- 432 unchanged lines hidden (view full) --- 1648template <class Impl> 1649void 1650FullO3CPU<Impl>::updateThreadPriority() 1651{ 1652 if (activeThreads.size() > 1) { 1653 //DEFAULT TO ROUND ROBIN SCHEME 1654 //e.g. Move highest priority to end of thread list 1655 list<ThreadID>::iterator list_begin = activeThreads.begin(); |
1656 list<ThreadID>::iterator list_end = activeThreads.end(); |
|
1722 1723 unsigned high_thread = *list_begin; 1724 1725 activeThreads.erase(list_begin); 1726 1727 activeThreads.push_back(high_thread); 1728 } 1729} 1730 1731// Forward declaration of FullO3CPU. 1732template class FullO3CPU<O3CPUImpl>; | 1657 1658 unsigned high_thread = *list_begin; 1659 1660 activeThreads.erase(list_begin); 1661 1662 activeThreads.push_back(high_thread); 1663 } 1664} 1665 1666// Forward declaration of FullO3CPU. 1667template class FullO3CPU<O3CPUImpl>; |