cpu.cc revision 2817
11689SN/A/* 22325SN/A * Copyright (c) 2004-2006 The Regents of The University of Michigan 31689SN/A * All rights reserved. 41689SN/A * 51689SN/A * Redistribution and use in source and binary forms, with or without 61689SN/A * modification, are permitted provided that the following conditions are 71689SN/A * met: redistributions of source code must retain the above copyright 81689SN/A * notice, this list of conditions and the following disclaimer; 91689SN/A * redistributions in binary form must reproduce the above copyright 101689SN/A * notice, this list of conditions and the following disclaimer in the 111689SN/A * documentation and/or other materials provided with the distribution; 121689SN/A * neither the name of the copyright holders nor the names of its 131689SN/A * contributors may be used to endorse or promote products derived from 141689SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Kevin Lim 292756Sksewell@umich.edu * Korey Sewell 301689SN/A */ 311689SN/A 321858SN/A#include "config/full_system.hh" 332733Sktlim@umich.edu#include "config/use_checker.hh" 341858SN/A 351858SN/A#if FULL_SYSTEM 361060SN/A#include "sim/system.hh" 371060SN/A#else 381060SN/A#include "sim/process.hh" 391060SN/A#endif 401060SN/A 412325SN/A#include "cpu/activity.hh" 422683Sktlim@umich.edu#include "cpu/simple_thread.hh" 432680Sktlim@umich.edu#include "cpu/thread_context.hh" 442817Sksewell@umich.edu#include "cpu/o3/isa_specific.hh" 451717SN/A#include "cpu/o3/cpu.hh" 461060SN/A 472325SN/A#include "sim/root.hh" 482292SN/A#include "sim/stat_control.hh" 492292SN/A 502794Sktlim@umich.edu#if USE_CHECKER 512794Sktlim@umich.edu#include "cpu/checker/cpu.hh" 522794Sktlim@umich.edu#endif 532794Sktlim@umich.edu 541060SN/Ausing namespace std; 552669Sktlim@umich.eduusing namespace TheISA; 561060SN/A 572733Sktlim@umich.eduBaseO3CPU::BaseO3CPU(Params *params) 582292SN/A : BaseCPU(params), cpu_id(0) 591060SN/A{ 601060SN/A} 611060SN/A 622292SN/Avoid 632733Sktlim@umich.eduBaseO3CPU::regStats() 642292SN/A{ 652292SN/A BaseCPU::regStats(); 662292SN/A} 672292SN/A 681060SN/Atemplate <class Impl> 691755SN/AFullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c) 701060SN/A : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c) 711060SN/A{ 721060SN/A} 731060SN/A 741060SN/Atemplate <class Impl> 751060SN/Avoid 761755SN/AFullO3CPU<Impl>::TickEvent::process() 771060SN/A{ 781060SN/A cpu->tick(); 791060SN/A} 801060SN/A 811060SN/Atemplate <class Impl> 821060SN/Aconst char * 831755SN/AFullO3CPU<Impl>::TickEvent::description() 841060SN/A{ 851755SN/A return "FullO3CPU tick event"; 861060SN/A} 871060SN/A 881060SN/Atemplate <class Impl> 892292SN/AFullO3CPU<Impl>::FullO3CPU(Params *params) 902733Sktlim@umich.edu : BaseO3CPU(params), 911060SN/A tickEvent(this), 922292SN/A removeInstsThisCycle(false), 931060SN/A fetch(params), 941060SN/A decode(params), 951060SN/A rename(params), 961060SN/A iew(params), 971060SN/A commit(params), 981060SN/A 992292SN/A regFile(params->numPhysIntRegs, params->numPhysFloatRegs), 1001060SN/A 1012292SN/A freeList(params->numberOfThreads,//number of activeThreads 1022292SN/A TheISA::NumIntRegs, params->numPhysIntRegs, 1032292SN/A TheISA::NumFloatRegs, params->numPhysFloatRegs), 1041060SN/A 1052292SN/A rob(params->numROBEntries, params->squashWidth, 1062292SN/A params->smtROBPolicy, params->smtROBThreshold, 1072292SN/A params->numberOfThreads), 1081060SN/A 1092292SN/A scoreboard(params->numberOfThreads,//number of activeThreads 1102292SN/A TheISA::NumIntRegs, params->numPhysIntRegs, 1112292SN/A TheISA::NumFloatRegs, params->numPhysFloatRegs, 1122292SN/A TheISA::NumMiscRegs * number_of_threads, 1132292SN/A TheISA::ZeroReg), 1141060SN/A 1151060SN/A // For now just have these time buffers be pretty big. 1162325SN/A // @todo: Make these time buffer sizes parameters or derived 1172325SN/A // from latencies 1181061SN/A timeBuffer(5, 5), 1191061SN/A fetchQueue(5, 5), 1201061SN/A decodeQueue(5, 5), 1211061SN/A renameQueue(5, 5), 1221061SN/A iewQueue(5, 5), 1232325SN/A activityRec(NumStages, 10, params->activity), 1241060SN/A 1251060SN/A globalSeqNum(1), 1261060SN/A 1271858SN/A#if FULL_SYSTEM 1282292SN/A system(params->system), 1291060SN/A physmem(system->physmem), 1301060SN/A#endif // FULL_SYSTEM 1312292SN/A mem(params->mem), 1322316SN/A switchCount(0), 1332316SN/A deferRegistration(params->deferRegistration), 1342316SN/A numThreads(number_of_threads) 1351060SN/A{ 1361060SN/A _status = Idle; 1371681SN/A 1382733Sktlim@umich.edu checker = NULL; 1392733Sktlim@umich.edu 1402794Sktlim@umich.edu if (params->checker) { 1412733Sktlim@umich.edu#if USE_CHECKER 1422316SN/A BaseCPU *temp_checker = params->checker; 1432316SN/A checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker); 1442316SN/A checker->setMemory(mem); 1452316SN/A#if FULL_SYSTEM 1462316SN/A checker->setSystem(params->system); 1472316SN/A#endif 1482794Sktlim@umich.edu#else 1492794Sktlim@umich.edu panic("Checker enabled but not compiled in!"); 1502794Sktlim@umich.edu#endif // USE_CHECKER 1512316SN/A } 1522316SN/A 1531858SN/A#if !FULL_SYSTEM 1542292SN/A thread.resize(number_of_threads); 1552292SN/A tids.resize(number_of_threads); 1561681SN/A#endif 1571681SN/A 1582325SN/A // The stages also need their CPU pointer setup. However this 1592325SN/A // must be done at the upper level CPU because they have pointers 1602325SN/A // to the upper level CPU, and not this FullO3CPU. 1611060SN/A 1622292SN/A // Set up Pointers to the activeThreads list for each stage 1632292SN/A fetch.setActiveThreads(&activeThreads); 1642292SN/A decode.setActiveThreads(&activeThreads); 1652292SN/A rename.setActiveThreads(&activeThreads); 1662292SN/A iew.setActiveThreads(&activeThreads); 1672292SN/A commit.setActiveThreads(&activeThreads); 1681060SN/A 1691060SN/A // Give each of the stages the time buffer they will use. 1701060SN/A fetch.setTimeBuffer(&timeBuffer); 1711060SN/A decode.setTimeBuffer(&timeBuffer); 1721060SN/A rename.setTimeBuffer(&timeBuffer); 1731060SN/A iew.setTimeBuffer(&timeBuffer); 1741060SN/A commit.setTimeBuffer(&timeBuffer); 1751060SN/A 1761060SN/A // Also setup each of the stages' queues. 1771060SN/A fetch.setFetchQueue(&fetchQueue); 1781060SN/A decode.setFetchQueue(&fetchQueue); 1792292SN/A commit.setFetchQueue(&fetchQueue); 1801060SN/A decode.setDecodeQueue(&decodeQueue); 1811060SN/A rename.setDecodeQueue(&decodeQueue); 1821060SN/A rename.setRenameQueue(&renameQueue); 1831060SN/A iew.setRenameQueue(&renameQueue); 1841060SN/A iew.setIEWQueue(&iewQueue); 1851060SN/A commit.setIEWQueue(&iewQueue); 1861060SN/A commit.setRenameQueue(&renameQueue); 1871060SN/A 1882316SN/A commit.setFetchStage(&fetch); 1892292SN/A commit.setIEWStage(&iew); 1902292SN/A rename.setIEWStage(&iew); 1912292SN/A rename.setCommitStage(&commit); 1922292SN/A 1932292SN/A#if !FULL_SYSTEM 1942307SN/A int active_threads = params->workload.size(); 1952292SN/A#else 1962307SN/A int active_threads = 1; 1972292SN/A#endif 1982292SN/A 1992316SN/A //Make Sure That this a Valid Architeture 2002292SN/A assert(params->numPhysIntRegs >= numThreads * TheISA::NumIntRegs); 2012292SN/A assert(params->numPhysFloatRegs >= numThreads * TheISA::NumFloatRegs); 2022292SN/A 2032292SN/A rename.setScoreboard(&scoreboard); 2042292SN/A iew.setScoreboard(&scoreboard); 2052292SN/A 2061060SN/A // Setup the rename map for whichever stages need it. 2072292SN/A PhysRegIndex lreg_idx = 0; 2082292SN/A PhysRegIndex freg_idx = params->numPhysIntRegs; //Index to 1 after int regs 2091060SN/A 2102292SN/A for (int tid=0; tid < numThreads; tid++) { 2112307SN/A bool bindRegs = (tid <= active_threads - 1); 2122292SN/A 2132292SN/A commitRenameMap[tid].init(TheISA::NumIntRegs, 2142292SN/A params->numPhysIntRegs, 2152325SN/A lreg_idx, //Index for Logical. Regs 2162292SN/A 2172292SN/A TheISA::NumFloatRegs, 2182292SN/A params->numPhysFloatRegs, 2192325SN/A freg_idx, //Index for Float Regs 2202292SN/A 2212292SN/A TheISA::NumMiscRegs, 2222292SN/A 2232292SN/A TheISA::ZeroReg, 2242292SN/A TheISA::ZeroReg, 2252292SN/A 2262292SN/A tid, 2272292SN/A false); 2282292SN/A 2292292SN/A renameMap[tid].init(TheISA::NumIntRegs, 2302292SN/A params->numPhysIntRegs, 2312325SN/A lreg_idx, //Index for Logical. Regs 2322292SN/A 2332292SN/A TheISA::NumFloatRegs, 2342292SN/A params->numPhysFloatRegs, 2352325SN/A freg_idx, //Index for Float Regs 2362292SN/A 2372292SN/A TheISA::NumMiscRegs, 2382292SN/A 2392292SN/A TheISA::ZeroReg, 2402292SN/A TheISA::ZeroReg, 2412292SN/A 2422292SN/A tid, 2432292SN/A bindRegs); 2442292SN/A } 2452292SN/A 2462292SN/A rename.setRenameMap(renameMap); 2472292SN/A commit.setRenameMap(commitRenameMap); 2482292SN/A 2492292SN/A // Give renameMap & rename stage access to the freeList; 2502292SN/A for (int i=0; i < numThreads; i++) { 2512292SN/A renameMap[i].setFreeList(&freeList); 2522292SN/A } 2531060SN/A rename.setFreeList(&freeList); 2542292SN/A 2551060SN/A // Setup the ROB for whichever stages need it. 2561060SN/A commit.setROB(&rob); 2572292SN/A 2582292SN/A lastRunningCycle = curTick; 2592292SN/A 2602292SN/A contextSwitch = false; 2611060SN/A} 2621060SN/A 2631060SN/Atemplate <class Impl> 2641755SN/AFullO3CPU<Impl>::~FullO3CPU() 2651060SN/A{ 2661060SN/A} 2671060SN/A 2681060SN/Atemplate <class Impl> 2691060SN/Avoid 2701755SN/AFullO3CPU<Impl>::fullCPURegStats() 2711062SN/A{ 2722733Sktlim@umich.edu BaseO3CPU::regStats(); 2732292SN/A 2742733Sktlim@umich.edu // Register any of the O3CPU's stats here. 2752292SN/A timesIdled 2762292SN/A .name(name() + ".timesIdled") 2772292SN/A .desc("Number of times that the entire CPU went into an idle state and" 2782292SN/A " unscheduled itself") 2792292SN/A .prereq(timesIdled); 2802292SN/A 2812292SN/A idleCycles 2822292SN/A .name(name() + ".idleCycles") 2832292SN/A .desc("Total number of cycles that the CPU has spent unscheduled due " 2842292SN/A "to idling") 2852292SN/A .prereq(idleCycles); 2862292SN/A 2872292SN/A // Number of Instructions simulated 2882292SN/A // -------------------------------- 2892292SN/A // Should probably be in Base CPU but need templated 2902292SN/A // MaxThreads so put in here instead 2912292SN/A committedInsts 2922292SN/A .init(numThreads) 2932292SN/A .name(name() + ".committedInsts") 2942292SN/A .desc("Number of Instructions Simulated"); 2952292SN/A 2962292SN/A totalCommittedInsts 2972292SN/A .name(name() + ".committedInsts_total") 2982292SN/A .desc("Number of Instructions Simulated"); 2992292SN/A 3002292SN/A cpi 3012292SN/A .name(name() + ".cpi") 3022292SN/A .desc("CPI: Cycles Per Instruction") 3032292SN/A .precision(6); 3042292SN/A cpi = simTicks / committedInsts; 3052292SN/A 3062292SN/A totalCpi 3072292SN/A .name(name() + ".cpi_total") 3082292SN/A .desc("CPI: Total CPI of All Threads") 3092292SN/A .precision(6); 3102292SN/A totalCpi = simTicks / totalCommittedInsts; 3112292SN/A 3122292SN/A ipc 3132292SN/A .name(name() + ".ipc") 3142292SN/A .desc("IPC: Instructions Per Cycle") 3152292SN/A .precision(6); 3162292SN/A ipc = committedInsts / simTicks; 3172292SN/A 3182292SN/A totalIpc 3192292SN/A .name(name() + ".ipc_total") 3202292SN/A .desc("IPC: Total IPC of All Threads") 3212292SN/A .precision(6); 3222292SN/A totalIpc = totalCommittedInsts / simTicks; 3232292SN/A 3241062SN/A} 3251062SN/A 3261062SN/Atemplate <class Impl> 3271062SN/Avoid 3281755SN/AFullO3CPU<Impl>::tick() 3291060SN/A{ 3302733Sktlim@umich.edu DPRINTF(O3CPU, "\n\nFullO3CPU: Ticking main, FullO3CPU.\n"); 3311060SN/A 3322292SN/A ++numCycles; 3332292SN/A 3342325SN/A// activity = false; 3352292SN/A 3362292SN/A //Tick each of the stages 3371060SN/A fetch.tick(); 3381060SN/A 3391060SN/A decode.tick(); 3401060SN/A 3411060SN/A rename.tick(); 3421060SN/A 3431060SN/A iew.tick(); 3441060SN/A 3451060SN/A commit.tick(); 3461060SN/A 3472292SN/A#if !FULL_SYSTEM 3482292SN/A doContextSwitch(); 3492292SN/A#endif 3502292SN/A 3512292SN/A // Now advance the time buffers 3521060SN/A timeBuffer.advance(); 3531060SN/A 3541060SN/A fetchQueue.advance(); 3551060SN/A decodeQueue.advance(); 3561060SN/A renameQueue.advance(); 3571060SN/A iewQueue.advance(); 3581060SN/A 3592325SN/A activityRec.advance(); 3602292SN/A 3612292SN/A if (removeInstsThisCycle) { 3622292SN/A cleanUpRemovedInsts(); 3632292SN/A } 3642292SN/A 3652325SN/A if (!tickEvent.scheduled()) { 3662325SN/A if (_status == SwitchedOut) { 3672325SN/A // increment stat 3682325SN/A lastRunningCycle = curTick; 3692325SN/A } else if (!activityRec.active()) { 3702325SN/A lastRunningCycle = curTick; 3712325SN/A timesIdled++; 3722325SN/A } else { 3732325SN/A tickEvent.schedule(curTick + cycles(1)); 3742325SN/A } 3752292SN/A } 3762292SN/A 3772292SN/A#if !FULL_SYSTEM 3782292SN/A updateThreadPriority(); 3792292SN/A#endif 3802292SN/A 3811060SN/A} 3821060SN/A 3831060SN/Atemplate <class Impl> 3841060SN/Avoid 3851755SN/AFullO3CPU<Impl>::init() 3861060SN/A{ 3872307SN/A if (!deferRegistration) { 3882680Sktlim@umich.edu registerThreadContexts(); 3892292SN/A } 3901060SN/A 3912292SN/A // Set inSyscall so that the CPU doesn't squash when initially 3922292SN/A // setting up registers. 3932292SN/A for (int i = 0; i < number_of_threads; ++i) 3942292SN/A thread[i]->inSyscall = true; 3952292SN/A 3962292SN/A for (int tid=0; tid < number_of_threads; tid++) { 3971858SN/A#if FULL_SYSTEM 3982680Sktlim@umich.edu ThreadContext *src_tc = threadContexts[tid]; 3991681SN/A#else 4002680Sktlim@umich.edu ThreadContext *src_tc = thread[tid]->getTC(); 4011681SN/A#endif 4022292SN/A // Threads start in the Suspended State 4032680Sktlim@umich.edu if (src_tc->status() != ThreadContext::Suspended) { 4042292SN/A continue; 4051060SN/A } 4061060SN/A 4072292SN/A#if FULL_SYSTEM 4082680Sktlim@umich.edu TheISA::initCPU(src_tc, src_tc->readCpuId()); 4092292SN/A#endif 4102292SN/A } 4112292SN/A 4122292SN/A // Clear inSyscall. 4132292SN/A for (int i = 0; i < number_of_threads; ++i) 4142292SN/A thread[i]->inSyscall = false; 4152292SN/A 4162316SN/A // Initialize stages. 4172292SN/A fetch.initStage(); 4182292SN/A iew.initStage(); 4192292SN/A rename.initStage(); 4202292SN/A commit.initStage(); 4212292SN/A 4222292SN/A commit.setThreads(thread); 4232292SN/A} 4242292SN/A 4252292SN/Atemplate <class Impl> 4262292SN/Avoid 4272292SN/AFullO3CPU<Impl>::insertThread(unsigned tid) 4282292SN/A{ 4292733Sktlim@umich.edu DPRINTF(O3CPU,"[tid:%i] Initializing thread data"); 4302292SN/A // Will change now that the PC and thread state is internal to the CPU 4312683Sktlim@umich.edu // and not in the ThreadContext. 4322292SN/A#if 0 4332292SN/A#if FULL_SYSTEM 4342680Sktlim@umich.edu ThreadContext *src_tc = system->threadContexts[tid]; 4352292SN/A#else 4362683Sktlim@umich.edu ThreadContext *src_tc = thread[tid]; 4372292SN/A#endif 4382292SN/A 4392292SN/A //Bind Int Regs to Rename Map 4402292SN/A for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) { 4412292SN/A PhysRegIndex phys_reg = freeList.getIntReg(); 4422292SN/A 4432292SN/A renameMap[tid].setEntry(ireg,phys_reg); 4442292SN/A scoreboard.setReg(phys_reg); 4452292SN/A } 4462292SN/A 4472292SN/A //Bind Float Regs to Rename Map 4482292SN/A for (int freg = 0; freg < TheISA::NumFloatRegs; freg++) { 4492292SN/A PhysRegIndex phys_reg = freeList.getFloatReg(); 4502292SN/A 4512292SN/A renameMap[tid].setEntry(freg,phys_reg); 4522292SN/A scoreboard.setReg(phys_reg); 4532292SN/A } 4542292SN/A 4552292SN/A //Copy Thread Data Into RegFile 4562680Sktlim@umich.edu this->copyFromTC(tid); 4572292SN/A 4582292SN/A //Set PC/NPC 4592680Sktlim@umich.edu regFile.pc[tid] = src_tc->readPC(); 4602680Sktlim@umich.edu regFile.npc[tid] = src_tc->readNextPC(); 4612292SN/A 4622680Sktlim@umich.edu src_tc->setStatus(ThreadContext::Active); 4632292SN/A 4642292SN/A activateContext(tid,1); 4652292SN/A 4662292SN/A //Reset ROB/IQ/LSQ Entries 4672292SN/A commit.rob->resetEntries(); 4682292SN/A iew.resetEntries(); 4692292SN/A#endif 4702292SN/A} 4712292SN/A 4722292SN/Atemplate <class Impl> 4732292SN/Avoid 4742292SN/AFullO3CPU<Impl>::removeThread(unsigned tid) 4752292SN/A{ 4762733Sktlim@umich.edu DPRINTF(O3CPU,"[tid:%i] Removing thread data"); 4772292SN/A#if 0 4782292SN/A //Unbind Int Regs from Rename Map 4792292SN/A for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) { 4802292SN/A PhysRegIndex phys_reg = renameMap[tid].lookup(ireg); 4812292SN/A 4822292SN/A scoreboard.unsetReg(phys_reg); 4832292SN/A freeList.addReg(phys_reg); 4842292SN/A } 4852292SN/A 4862292SN/A //Unbind Float Regs from Rename Map 4872292SN/A for (int freg = 0; freg < TheISA::NumFloatRegs; freg++) { 4882292SN/A PhysRegIndex phys_reg = renameMap[tid].lookup(freg); 4892292SN/A 4902292SN/A scoreboard.unsetReg(phys_reg); 4912292SN/A freeList.addReg(phys_reg); 4922292SN/A } 4932292SN/A 4942292SN/A //Copy Thread Data From RegFile 4952292SN/A /* Fix Me: 4962292SN/A * Do we really need to do this if we are removing a thread 4972292SN/A * in the sense that it's finished (exiting)? If the thread is just 4982292SN/A * being suspended we might... 4992292SN/A */ 5002680Sktlim@umich.edu// this->copyToTC(tid); 5012292SN/A 5022292SN/A //Squash Throughout Pipeline 5032292SN/A fetch.squash(0,tid); 5042292SN/A decode.squash(tid); 5052292SN/A rename.squash(tid); 5062292SN/A 5072292SN/A assert(iew.ldstQueue.getCount(tid) == 0); 5082292SN/A 5092292SN/A //Reset ROB/IQ/LSQ Entries 5102292SN/A if (activeThreads.size() >= 1) { 5112292SN/A commit.rob->resetEntries(); 5122292SN/A iew.resetEntries(); 5132292SN/A } 5142292SN/A#endif 5152292SN/A} 5162292SN/A 5172292SN/A 5182292SN/Atemplate <class Impl> 5192292SN/Avoid 5202292SN/AFullO3CPU<Impl>::activateWhenReady(int tid) 5212292SN/A{ 5222733Sktlim@umich.edu DPRINTF(O3CPU,"[tid:%i]: Checking if resources are available for incoming" 5232292SN/A "(e.g. PhysRegs/ROB/IQ/LSQ) \n", 5242292SN/A tid); 5252292SN/A 5262292SN/A bool ready = true; 5272292SN/A 5282292SN/A if (freeList.numFreeIntRegs() >= TheISA::NumIntRegs) { 5292733Sktlim@umich.edu DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough " 5302292SN/A "Phys. Int. Regs.\n", 5312292SN/A tid); 5322292SN/A ready = false; 5332292SN/A } else if (freeList.numFreeFloatRegs() >= TheISA::NumFloatRegs) { 5342733Sktlim@umich.edu DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough " 5352292SN/A "Phys. Float. Regs.\n", 5362292SN/A tid); 5372292SN/A ready = false; 5382292SN/A } else if (commit.rob->numFreeEntries() >= 5392292SN/A commit.rob->entryAmount(activeThreads.size() + 1)) { 5402733Sktlim@umich.edu DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough " 5412292SN/A "ROB entries.\n", 5422292SN/A tid); 5432292SN/A ready = false; 5442292SN/A } else if (iew.instQueue.numFreeEntries() >= 5452292SN/A iew.instQueue.entryAmount(activeThreads.size() + 1)) { 5462733Sktlim@umich.edu DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough " 5472292SN/A "IQ entries.\n", 5482292SN/A tid); 5492292SN/A ready = false; 5502292SN/A } else if (iew.ldstQueue.numFreeEntries() >= 5512292SN/A iew.ldstQueue.entryAmount(activeThreads.size() + 1)) { 5522733Sktlim@umich.edu DPRINTF(O3CPU,"[tid:%i] Suspending thread due to not enough " 5532292SN/A "LSQ entries.\n", 5542292SN/A tid); 5552292SN/A ready = false; 5562292SN/A } 5572292SN/A 5582292SN/A if (ready) { 5592292SN/A insertThread(tid); 5602292SN/A 5612292SN/A contextSwitch = false; 5622292SN/A 5632292SN/A cpuWaitList.remove(tid); 5642292SN/A } else { 5652292SN/A suspendContext(tid); 5662292SN/A 5672292SN/A //blocks fetch 5682292SN/A contextSwitch = true; 5692292SN/A 5702292SN/A //do waitlist 5712292SN/A cpuWaitList.push_back(tid); 5721060SN/A } 5731060SN/A} 5741060SN/A 5751060SN/Atemplate <class Impl> 5761060SN/Avoid 5772292SN/AFullO3CPU<Impl>::activateContext(int tid, int delay) 5781060SN/A{ 5791060SN/A // Needs to set each stage to running as well. 5802292SN/A list<unsigned>::iterator isActive = find( 5812292SN/A activeThreads.begin(), activeThreads.end(), tid); 5822292SN/A 5832292SN/A if (isActive == activeThreads.end()) { 5842292SN/A //May Need to Re-code this if the delay variable is the 5852292SN/A //delay needed for thread to activate 5862733Sktlim@umich.edu DPRINTF(O3CPU, "Adding Thread %i to active threads list\n", 5872292SN/A tid); 5882292SN/A 5892292SN/A activeThreads.push_back(tid); 5902292SN/A } 5912292SN/A 5922307SN/A assert(_status == Idle || _status == SwitchedOut); 5931060SN/A 5941060SN/A scheduleTickEvent(delay); 5951060SN/A 5962292SN/A // Be sure to signal that there's some activity so the CPU doesn't 5972292SN/A // deschedule itself. 5982325SN/A activityRec.activity(); 5992292SN/A fetch.wakeFromQuiesce(); 6002292SN/A 6011060SN/A _status = Running; 6021060SN/A} 6031060SN/A 6041060SN/Atemplate <class Impl> 6051060SN/Avoid 6062292SN/AFullO3CPU<Impl>::suspendContext(int tid) 6071060SN/A{ 6082733Sktlim@umich.edu DPRINTF(O3CPU,"[tid: %i]: Suspended ...\n", tid); 6092292SN/A unscheduleTickEvent(); 6102292SN/A _status = Idle; 6112292SN/A/* 6122292SN/A //Remove From Active List, if Active 6132292SN/A list<unsigned>::iterator isActive = find( 6142292SN/A activeThreads.begin(), activeThreads.end(), tid); 6152292SN/A 6162292SN/A if (isActive != activeThreads.end()) { 6172733Sktlim@umich.edu DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n", 6182292SN/A tid); 6192292SN/A activeThreads.erase(isActive); 6202292SN/A } 6212292SN/A*/ 6221060SN/A} 6231060SN/A 6241060SN/Atemplate <class Impl> 6251060SN/Avoid 6262292SN/AFullO3CPU<Impl>::deallocateContext(int tid) 6271060SN/A{ 6282733Sktlim@umich.edu DPRINTF(O3CPU,"[tid:%i]: Deallocating ...", tid); 6292292SN/A/* 6302292SN/A //Remove From Active List, if Active 6312292SN/A list<unsigned>::iterator isActive = find( 6322292SN/A activeThreads.begin(), activeThreads.end(), tid); 6332292SN/A 6342292SN/A if (isActive != activeThreads.end()) { 6352733Sktlim@umich.edu DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n", 6362292SN/A tid); 6372292SN/A activeThreads.erase(isActive); 6382292SN/A 6392292SN/A removeThread(tid); 6402292SN/A } 6412292SN/A*/ 6421060SN/A} 6431060SN/A 6441060SN/Atemplate <class Impl> 6451060SN/Avoid 6462292SN/AFullO3CPU<Impl>::haltContext(int tid) 6471060SN/A{ 6482733Sktlim@umich.edu DPRINTF(O3CPU,"[tid:%i]: Halted ...", tid); 6492292SN/A/* 6502292SN/A //Remove From Active List, if Active 6512292SN/A list<unsigned>::iterator isActive = find( 6522292SN/A activeThreads.begin(), activeThreads.end(), tid); 6532292SN/A 6542292SN/A if (isActive != activeThreads.end()) { 6552733Sktlim@umich.edu DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n", 6562292SN/A tid); 6572292SN/A activeThreads.erase(isActive); 6582292SN/A 6592292SN/A removeThread(tid); 6602292SN/A } 6612292SN/A*/ 6621060SN/A} 6631060SN/A 6641060SN/Atemplate <class Impl> 6651060SN/Avoid 6662316SN/AFullO3CPU<Impl>::switchOut(Sampler *_sampler) 6671060SN/A{ 6682316SN/A sampler = _sampler; 6692316SN/A switchCount = 0; 6702307SN/A fetch.switchOut(); 6712307SN/A decode.switchOut(); 6722307SN/A rename.switchOut(); 6732307SN/A iew.switchOut(); 6742307SN/A commit.switchOut(); 6752325SN/A 6762325SN/A // Wake the CPU and record activity so everything can drain out if 6772325SN/A // the CPU is currently idle. 6782325SN/A wakeCPU(); 6792325SN/A activityRec.activity(); 6802316SN/A} 6812310SN/A 6822316SN/Atemplate <class Impl> 6832316SN/Avoid 6842316SN/AFullO3CPU<Impl>::signalSwitched() 6852316SN/A{ 6862325SN/A if (++switchCount == NumStages) { 6872316SN/A fetch.doSwitchOut(); 6882316SN/A rename.doSwitchOut(); 6892316SN/A commit.doSwitchOut(); 6902316SN/A instList.clear(); 6912316SN/A while (!removeList.empty()) { 6922316SN/A removeList.pop(); 6932316SN/A } 6942316SN/A 6952794Sktlim@umich.edu#if USE_CHECKER 6962316SN/A if (checker) 6972316SN/A checker->switchOut(sampler); 6982794Sktlim@umich.edu#endif 6992316SN/A 7002316SN/A if (tickEvent.scheduled()) 7012316SN/A tickEvent.squash(); 7022316SN/A sampler->signalSwitched(); 7032316SN/A _status = SwitchedOut; 7042310SN/A } 7052316SN/A assert(switchCount <= 5); 7061060SN/A} 7071060SN/A 7081060SN/Atemplate <class Impl> 7091060SN/Avoid 7101755SN/AFullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU) 7111060SN/A{ 7122325SN/A // Flush out any old data from the time buffers. 7132325SN/A for (int i = 0; i < 10; ++i) { 7142307SN/A timeBuffer.advance(); 7152307SN/A fetchQueue.advance(); 7162307SN/A decodeQueue.advance(); 7172307SN/A renameQueue.advance(); 7182307SN/A iewQueue.advance(); 7192307SN/A } 7202307SN/A 7212325SN/A activityRec.reset(); 7222307SN/A 7231060SN/A BaseCPU::takeOverFrom(oldCPU); 7241060SN/A 7252307SN/A fetch.takeOverFrom(); 7262307SN/A decode.takeOverFrom(); 7272307SN/A rename.takeOverFrom(); 7282307SN/A iew.takeOverFrom(); 7292307SN/A commit.takeOverFrom(); 7302307SN/A 7311060SN/A assert(!tickEvent.scheduled()); 7321060SN/A 7332325SN/A // @todo: Figure out how to properly select the tid to put onto 7342325SN/A // the active threads list. 7352307SN/A int tid = 0; 7362307SN/A 7372307SN/A list<unsigned>::iterator isActive = find( 7382307SN/A activeThreads.begin(), activeThreads.end(), tid); 7392307SN/A 7402307SN/A if (isActive == activeThreads.end()) { 7412325SN/A //May Need to Re-code this if the delay variable is the delay 7422325SN/A //needed for thread to activate 7432733Sktlim@umich.edu DPRINTF(O3CPU, "Adding Thread %i to active threads list\n", 7442307SN/A tid); 7452307SN/A 7462307SN/A activeThreads.push_back(tid); 7472307SN/A } 7482307SN/A 7492325SN/A // Set all statuses to active, schedule the CPU's tick event. 7502307SN/A // @todo: Fix up statuses so this is handled properly 7512680Sktlim@umich.edu for (int i = 0; i < threadContexts.size(); ++i) { 7522680Sktlim@umich.edu ThreadContext *tc = threadContexts[i]; 7532680Sktlim@umich.edu if (tc->status() == ThreadContext::Active && _status != Running) { 7541681SN/A _status = Running; 7551681SN/A tickEvent.schedule(curTick); 7561681SN/A } 7571060SN/A } 7582307SN/A if (!tickEvent.scheduled()) 7592307SN/A tickEvent.schedule(curTick); 7601060SN/A} 7611060SN/A 7621060SN/Atemplate <class Impl> 7631060SN/Auint64_t 7641755SN/AFullO3CPU<Impl>::readIntReg(int reg_idx) 7651060SN/A{ 7661060SN/A return regFile.readIntReg(reg_idx); 7671060SN/A} 7681060SN/A 7691060SN/Atemplate <class Impl> 7702455SN/AFloatReg 7712455SN/AFullO3CPU<Impl>::readFloatReg(int reg_idx, int width) 7721060SN/A{ 7732455SN/A return regFile.readFloatReg(reg_idx, width); 7741060SN/A} 7751060SN/A 7761060SN/Atemplate <class Impl> 7772455SN/AFloatReg 7782455SN/AFullO3CPU<Impl>::readFloatReg(int reg_idx) 7791060SN/A{ 7802455SN/A return regFile.readFloatReg(reg_idx); 7811060SN/A} 7821060SN/A 7831060SN/Atemplate <class Impl> 7842455SN/AFloatRegBits 7852455SN/AFullO3CPU<Impl>::readFloatRegBits(int reg_idx, int width) 7861060SN/A{ 7872455SN/A return regFile.readFloatRegBits(reg_idx, width); 7882455SN/A} 7892455SN/A 7902455SN/Atemplate <class Impl> 7912455SN/AFloatRegBits 7922455SN/AFullO3CPU<Impl>::readFloatRegBits(int reg_idx) 7932455SN/A{ 7942455SN/A return regFile.readFloatRegBits(reg_idx); 7951060SN/A} 7961060SN/A 7971060SN/Atemplate <class Impl> 7981060SN/Avoid 7991755SN/AFullO3CPU<Impl>::setIntReg(int reg_idx, uint64_t val) 8001060SN/A{ 8011060SN/A regFile.setIntReg(reg_idx, val); 8021060SN/A} 8031060SN/A 8041060SN/Atemplate <class Impl> 8051060SN/Avoid 8062455SN/AFullO3CPU<Impl>::setFloatReg(int reg_idx, FloatReg val, int width) 8071060SN/A{ 8082455SN/A regFile.setFloatReg(reg_idx, val, width); 8091060SN/A} 8101060SN/A 8111060SN/Atemplate <class Impl> 8121060SN/Avoid 8132455SN/AFullO3CPU<Impl>::setFloatReg(int reg_idx, FloatReg val) 8141060SN/A{ 8152455SN/A regFile.setFloatReg(reg_idx, val); 8161060SN/A} 8171060SN/A 8181060SN/Atemplate <class Impl> 8191060SN/Avoid 8202455SN/AFullO3CPU<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val, int width) 8211060SN/A{ 8222455SN/A regFile.setFloatRegBits(reg_idx, val, width); 8232455SN/A} 8242455SN/A 8252455SN/Atemplate <class Impl> 8262455SN/Avoid 8272455SN/AFullO3CPU<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val) 8282455SN/A{ 8292455SN/A regFile.setFloatRegBits(reg_idx, val); 8301060SN/A} 8311060SN/A 8321060SN/Atemplate <class Impl> 8331060SN/Auint64_t 8342292SN/AFullO3CPU<Impl>::readArchIntReg(int reg_idx, unsigned tid) 8351060SN/A{ 8362292SN/A PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx); 8372292SN/A 8382292SN/A return regFile.readIntReg(phys_reg); 8392292SN/A} 8402292SN/A 8412292SN/Atemplate <class Impl> 8422292SN/Afloat 8432292SN/AFullO3CPU<Impl>::readArchFloatRegSingle(int reg_idx, unsigned tid) 8442292SN/A{ 8452307SN/A int idx = reg_idx + TheISA::FP_Base_DepTag; 8462307SN/A PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); 8472292SN/A 8482669Sktlim@umich.edu return regFile.readFloatReg(phys_reg); 8492292SN/A} 8502292SN/A 8512292SN/Atemplate <class Impl> 8522292SN/Adouble 8532292SN/AFullO3CPU<Impl>::readArchFloatRegDouble(int reg_idx, unsigned tid) 8542292SN/A{ 8552307SN/A int idx = reg_idx + TheISA::FP_Base_DepTag; 8562307SN/A PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); 8572292SN/A 8582669Sktlim@umich.edu return regFile.readFloatReg(phys_reg, 64); 8592292SN/A} 8602292SN/A 8612292SN/Atemplate <class Impl> 8622292SN/Auint64_t 8632292SN/AFullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, unsigned tid) 8642292SN/A{ 8652307SN/A int idx = reg_idx + TheISA::FP_Base_DepTag; 8662307SN/A PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); 8672292SN/A 8682669Sktlim@umich.edu return regFile.readFloatRegBits(phys_reg); 8691060SN/A} 8701060SN/A 8711060SN/Atemplate <class Impl> 8721060SN/Avoid 8732292SN/AFullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, unsigned tid) 8741060SN/A{ 8752292SN/A PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx); 8762292SN/A 8772292SN/A regFile.setIntReg(phys_reg, val); 8781060SN/A} 8791060SN/A 8801060SN/Atemplate <class Impl> 8811060SN/Avoid 8822292SN/AFullO3CPU<Impl>::setArchFloatRegSingle(int reg_idx, float val, unsigned tid) 8831060SN/A{ 8842292SN/A PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx); 8852292SN/A 8862669Sktlim@umich.edu regFile.setFloatReg(phys_reg, val); 8871060SN/A} 8881060SN/A 8891060SN/Atemplate <class Impl> 8901060SN/Avoid 8912292SN/AFullO3CPU<Impl>::setArchFloatRegDouble(int reg_idx, double val, unsigned tid) 8921060SN/A{ 8932292SN/A PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx); 8942292SN/A 8952669Sktlim@umich.edu regFile.setFloatReg(phys_reg, val, 64); 8961060SN/A} 8971060SN/A 8981060SN/Atemplate <class Impl> 8991060SN/Avoid 9002292SN/AFullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, unsigned tid) 9011060SN/A{ 9022292SN/A PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx); 9031060SN/A 9042669Sktlim@umich.edu regFile.setFloatRegBits(phys_reg, val); 9052292SN/A} 9062292SN/A 9072292SN/Atemplate <class Impl> 9082292SN/Auint64_t 9092292SN/AFullO3CPU<Impl>::readPC(unsigned tid) 9102292SN/A{ 9112292SN/A return commit.readPC(tid); 9121060SN/A} 9131060SN/A 9141060SN/Atemplate <class Impl> 9151060SN/Avoid 9162292SN/AFullO3CPU<Impl>::setPC(Addr new_PC,unsigned tid) 9171060SN/A{ 9182292SN/A commit.setPC(new_PC, tid); 9192292SN/A} 9201060SN/A 9212292SN/Atemplate <class Impl> 9222292SN/Auint64_t 9232292SN/AFullO3CPU<Impl>::readNextPC(unsigned tid) 9242292SN/A{ 9252292SN/A return commit.readNextPC(tid); 9262292SN/A} 9271060SN/A 9282292SN/Atemplate <class Impl> 9292292SN/Avoid 9302292SN/AFullO3CPU<Impl>::setNextPC(uint64_t val,unsigned tid) 9312292SN/A{ 9322292SN/A commit.setNextPC(val, tid); 9332292SN/A} 9341060SN/A 9352756Sksewell@umich.edu#if THE_ISA != ALPHA_ISA 9362756Sksewell@umich.edutemplate <class Impl> 9372756Sksewell@umich.eduuint64_t 9382756Sksewell@umich.eduFullO3CPU<Impl>::readNextNPC(unsigned tid) 9392756Sksewell@umich.edu{ 9402756Sksewell@umich.edu return commit.readNextNPC(tid); 9412756Sksewell@umich.edu} 9422756Sksewell@umich.edu 9432756Sksewell@umich.edutemplate <class Impl> 9442756Sksewell@umich.eduvoid 9452756Sksewell@umich.eduFullO3CPU<Impl>::setNextNNPC(uint64_t val,unsigned tid) 9462756Sksewell@umich.edu{ 9472756Sksewell@umich.edu commit.setNextNPC(val, tid); 9482756Sksewell@umich.edu} 9492756Sksewell@umich.edu#endif 9502756Sksewell@umich.edu 9512292SN/Atemplate <class Impl> 9522292SN/Atypename FullO3CPU<Impl>::ListIt 9532292SN/AFullO3CPU<Impl>::addInst(DynInstPtr &inst) 9542292SN/A{ 9552292SN/A instList.push_back(inst); 9561060SN/A 9572292SN/A return --(instList.end()); 9582292SN/A} 9591060SN/A 9602292SN/Atemplate <class Impl> 9612292SN/Avoid 9622292SN/AFullO3CPU<Impl>::instDone(unsigned tid) 9632292SN/A{ 9642292SN/A // Keep an instruction count. 9652292SN/A thread[tid]->numInst++; 9662292SN/A thread[tid]->numInsts++; 9672292SN/A committedInsts[tid]++; 9682292SN/A totalCommittedInsts++; 9692292SN/A 9702292SN/A // Check for instruction-count-based events. 9712292SN/A comInstEventQueue[tid]->serviceEvents(thread[tid]->numInst); 9722292SN/A} 9732292SN/A 9742292SN/Atemplate <class Impl> 9752292SN/Avoid 9762292SN/AFullO3CPU<Impl>::addToRemoveList(DynInstPtr &inst) 9772292SN/A{ 9782292SN/A removeInstsThisCycle = true; 9792292SN/A 9802292SN/A removeList.push(inst->getInstListIt()); 9811060SN/A} 9821060SN/A 9831060SN/Atemplate <class Impl> 9841060SN/Avoid 9851755SN/AFullO3CPU<Impl>::removeFrontInst(DynInstPtr &inst) 9861060SN/A{ 9872733Sktlim@umich.edu DPRINTF(O3CPU, "Removing committed instruction [tid:%i] PC %#x " 9882292SN/A "[sn:%lli]\n", 9892303SN/A inst->threadNumber, inst->readPC(), inst->seqNum); 9901060SN/A 9912292SN/A removeInstsThisCycle = true; 9921060SN/A 9931060SN/A // Remove the front instruction. 9942292SN/A removeList.push(inst->getInstListIt()); 9951060SN/A} 9961060SN/A 9971060SN/Atemplate <class Impl> 9981060SN/Avoid 9992292SN/AFullO3CPU<Impl>::removeInstsNotInROB(unsigned tid) 10001060SN/A{ 10012733Sktlim@umich.edu DPRINTF(O3CPU, "Thread %i: Deleting instructions from instruction" 10022292SN/A " list.\n", tid); 10031060SN/A 10042292SN/A ListIt end_it; 10051060SN/A 10062292SN/A bool rob_empty = false; 10072292SN/A 10082292SN/A if (instList.empty()) { 10092292SN/A return; 10102292SN/A } else if (rob.isEmpty(/*tid*/)) { 10112733Sktlim@umich.edu DPRINTF(O3CPU, "ROB is empty, squashing all insts.\n"); 10122292SN/A end_it = instList.begin(); 10132292SN/A rob_empty = true; 10142292SN/A } else { 10152292SN/A end_it = (rob.readTailInst(tid))->getInstListIt(); 10162733Sktlim@umich.edu DPRINTF(O3CPU, "ROB is not empty, squashing insts not in ROB.\n"); 10172292SN/A } 10182292SN/A 10192292SN/A removeInstsThisCycle = true; 10202292SN/A 10212292SN/A ListIt inst_it = instList.end(); 10222292SN/A 10232292SN/A inst_it--; 10242292SN/A 10252292SN/A // Walk through the instruction list, removing any instructions 10262292SN/A // that were inserted after the given instruction iterator, end_it. 10272292SN/A while (inst_it != end_it) { 10282292SN/A assert(!instList.empty()); 10292292SN/A 10302292SN/A squashInstIt(inst_it, tid); 10312292SN/A 10322292SN/A inst_it--; 10332292SN/A } 10342292SN/A 10352292SN/A // If the ROB was empty, then we actually need to remove the first 10362292SN/A // instruction as well. 10372292SN/A if (rob_empty) { 10382292SN/A squashInstIt(inst_it, tid); 10392292SN/A } 10401060SN/A} 10411060SN/A 10421060SN/Atemplate <class Impl> 10431060SN/Avoid 10442292SN/AFullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num, 10452292SN/A unsigned tid) 10461062SN/A{ 10472292SN/A assert(!instList.empty()); 10482292SN/A 10492292SN/A removeInstsThisCycle = true; 10502292SN/A 10512292SN/A ListIt inst_iter = instList.end(); 10522292SN/A 10532292SN/A inst_iter--; 10542292SN/A 10552733Sktlim@umich.edu DPRINTF(O3CPU, "Deleting instructions from instruction " 10562292SN/A "list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n", 10572292SN/A tid, seq_num, (*inst_iter)->seqNum); 10581062SN/A 10592292SN/A while ((*inst_iter)->seqNum > seq_num) { 10601062SN/A 10612292SN/A bool break_loop = (inst_iter == instList.begin()); 10621062SN/A 10632292SN/A squashInstIt(inst_iter, tid); 10641062SN/A 10652292SN/A inst_iter--; 10661062SN/A 10672292SN/A if (break_loop) 10682292SN/A break; 10692292SN/A } 10702292SN/A} 10712292SN/A 10722292SN/Atemplate <class Impl> 10732292SN/Ainline void 10742292SN/AFullO3CPU<Impl>::squashInstIt(const ListIt &instIt, const unsigned &tid) 10752292SN/A{ 10762292SN/A if ((*instIt)->threadNumber == tid) { 10772733Sktlim@umich.edu DPRINTF(O3CPU, "Squashing instruction, " 10782292SN/A "[tid:%i] [sn:%lli] PC %#x\n", 10792292SN/A (*instIt)->threadNumber, 10802292SN/A (*instIt)->seqNum, 10812292SN/A (*instIt)->readPC()); 10821062SN/A 10831062SN/A // Mark it as squashed. 10842292SN/A (*instIt)->setSquashed(); 10852292SN/A 10862325SN/A // @todo: Formulate a consistent method for deleting 10872325SN/A // instructions from the instruction list 10882292SN/A // Remove the instruction from the list. 10892292SN/A removeList.push(instIt); 10902292SN/A } 10912292SN/A} 10922292SN/A 10932292SN/Atemplate <class Impl> 10942292SN/Avoid 10952292SN/AFullO3CPU<Impl>::cleanUpRemovedInsts() 10962292SN/A{ 10972292SN/A while (!removeList.empty()) { 10982733Sktlim@umich.edu DPRINTF(O3CPU, "Removing instruction, " 10992292SN/A "[tid:%i] [sn:%lli] PC %#x\n", 11002292SN/A (*removeList.front())->threadNumber, 11012292SN/A (*removeList.front())->seqNum, 11022292SN/A (*removeList.front())->readPC()); 11032292SN/A 11042292SN/A instList.erase(removeList.front()); 11052292SN/A 11062292SN/A removeList.pop(); 11071062SN/A } 11081062SN/A 11092292SN/A removeInstsThisCycle = false; 11101062SN/A} 11112325SN/A/* 11121062SN/Atemplate <class Impl> 11131062SN/Avoid 11141755SN/AFullO3CPU<Impl>::removeAllInsts() 11151060SN/A{ 11161060SN/A instList.clear(); 11171060SN/A} 11182325SN/A*/ 11191060SN/Atemplate <class Impl> 11201060SN/Avoid 11211755SN/AFullO3CPU<Impl>::dumpInsts() 11221060SN/A{ 11231060SN/A int num = 0; 11241060SN/A 11252292SN/A ListIt inst_list_it = instList.begin(); 11262292SN/A 11272292SN/A cprintf("Dumping Instruction List\n"); 11282292SN/A 11292292SN/A while (inst_list_it != instList.end()) { 11302292SN/A cprintf("Instruction:%i\nPC:%#x\n[tid:%i]\n[sn:%lli]\nIssued:%i\n" 11312292SN/A "Squashed:%i\n\n", 11322292SN/A num, (*inst_list_it)->readPC(), (*inst_list_it)->threadNumber, 11332292SN/A (*inst_list_it)->seqNum, (*inst_list_it)->isIssued(), 11342292SN/A (*inst_list_it)->isSquashed()); 11351060SN/A inst_list_it++; 11361060SN/A ++num; 11371060SN/A } 11381060SN/A} 11392325SN/A/* 11401060SN/Atemplate <class Impl> 11411060SN/Avoid 11421755SN/AFullO3CPU<Impl>::wakeDependents(DynInstPtr &inst) 11431060SN/A{ 11441060SN/A iew.wakeDependents(inst); 11451060SN/A} 11462325SN/A*/ 11472292SN/Atemplate <class Impl> 11482292SN/Avoid 11492292SN/AFullO3CPU<Impl>::wakeCPU() 11502292SN/A{ 11512325SN/A if (activityRec.active() || tickEvent.scheduled()) { 11522325SN/A DPRINTF(Activity, "CPU already running.\n"); 11532292SN/A return; 11542292SN/A } 11552292SN/A 11562325SN/A DPRINTF(Activity, "Waking up CPU\n"); 11572325SN/A 11582325SN/A idleCycles += (curTick - 1) - lastRunningCycle; 11592292SN/A 11602292SN/A tickEvent.schedule(curTick); 11612292SN/A} 11622292SN/A 11632292SN/Atemplate <class Impl> 11642292SN/Aint 11652292SN/AFullO3CPU<Impl>::getFreeTid() 11662292SN/A{ 11672292SN/A for (int i=0; i < numThreads; i++) { 11682292SN/A if (!tids[i]) { 11692292SN/A tids[i] = true; 11702292SN/A return i; 11712292SN/A } 11722292SN/A } 11732292SN/A 11742292SN/A return -1; 11752292SN/A} 11762292SN/A 11772292SN/Atemplate <class Impl> 11782292SN/Avoid 11792292SN/AFullO3CPU<Impl>::doContextSwitch() 11802292SN/A{ 11812292SN/A if (contextSwitch) { 11822292SN/A 11832292SN/A //ADD CODE TO DEACTIVE THREAD HERE (???) 11842292SN/A 11852292SN/A for (int tid=0; tid < cpuWaitList.size(); tid++) { 11862292SN/A activateWhenReady(tid); 11872292SN/A } 11882292SN/A 11892292SN/A if (cpuWaitList.size() == 0) 11902292SN/A contextSwitch = true; 11912292SN/A } 11922292SN/A} 11932292SN/A 11942292SN/Atemplate <class Impl> 11952292SN/Avoid 11962292SN/AFullO3CPU<Impl>::updateThreadPriority() 11972292SN/A{ 11982292SN/A if (activeThreads.size() > 1) 11992292SN/A { 12002292SN/A //DEFAULT TO ROUND ROBIN SCHEME 12012292SN/A //e.g. Move highest priority to end of thread list 12022292SN/A list<unsigned>::iterator list_begin = activeThreads.begin(); 12032292SN/A list<unsigned>::iterator list_end = activeThreads.end(); 12042292SN/A 12052292SN/A unsigned high_thread = *list_begin; 12062292SN/A 12072292SN/A activeThreads.erase(list_begin); 12082292SN/A 12092292SN/A activeThreads.push_back(high_thread); 12102292SN/A } 12112292SN/A} 12121060SN/A 12131755SN/A// Forward declaration of FullO3CPU. 12141755SN/Atemplate class FullO3CPU<AlphaSimpleImpl>; 1215