cpu.cc revision 2356
13900Ssaidi@eecs.umich.edu/* 22632Sstever@eecs.umich.edu * Copyright (c) 2004-2006 The Regents of The University of Michigan 32632Sstever@eecs.umich.edu * All rights reserved. 42632Sstever@eecs.umich.edu * 52632Sstever@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 62632Sstever@eecs.umich.edu * modification, are permitted provided that the following conditions are 72632Sstever@eecs.umich.edu * met: redistributions of source code must retain the above copyright 82632Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 92632Sstever@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 102632Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 112632Sstever@eecs.umich.edu * documentation and/or other materials provided with the distribution; 122632Sstever@eecs.umich.edu * neither the name of the copyright holders nor the names of its 132632Sstever@eecs.umich.edu * contributors may be used to endorse or promote products derived from 142632Sstever@eecs.umich.edu * this software without specific prior written permission. 152632Sstever@eecs.umich.edu * 162632Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172632Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182632Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192632Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202632Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212632Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222632Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232632Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242632Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252632Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262632Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272632Sstever@eecs.umich.edu */ 282632Sstever@eecs.umich.edu 292632Sstever@eecs.umich.edu#include "config/full_system.hh" 302632Sstever@eecs.umich.edu 312022SN/A#if FULL_SYSTEM 322022SN/A#include "cpu/quiesce_event.hh" 332022SN/A#include "sim/system.hh" 342022SN/A#else 352022SN/A#include "sim/process.hh" 362469SN/A#endif 372469SN/A 382469SN/A#include "cpu/activity.hh" 392469SN/A#include "cpu/checker/cpu.hh" 407741Sgblack@eecs.umich.edu#include "cpu/cpu_exec_context.hh" 412516SN/A#include "cpu/exec_context.hh" 422944Sgblack@eecs.umich.edu#include "cpu/o3/alpha_dyn_inst.hh" 432482SN/A#include "cpu/o3/alpha_impl.hh" 447741Sgblack@eecs.umich.edu#include "cpu/o3/cpu.hh" 453056Sgblack@eecs.umich.edu 462469SN/A#include "sim/root.hh" 477741Sgblack@eecs.umich.edu#include "sim/stat_control.hh" 485091Sgblack@eecs.umich.edu 497720Sgblack@eecs.umich.eduusing namespace std; 507720Sgblack@eecs.umich.edu 517720Sgblack@eecs.umich.eduBaseFullCPU::BaseFullCPU(Params *params) 527720Sgblack@eecs.umich.edu : BaseCPU(params), cpu_id(0) 535091Sgblack@eecs.umich.edu{ 547741Sgblack@eecs.umich.edu} 555091Sgblack@eecs.umich.edu 565091Sgblack@eecs.umich.eduvoid 577720Sgblack@eecs.umich.eduBaseFullCPU::regStats() 587720Sgblack@eecs.umich.edu{ 597720Sgblack@eecs.umich.edu BaseCPU::regStats(); 607720Sgblack@eecs.umich.edu} 615091Sgblack@eecs.umich.edu 623056Sgblack@eecs.umich.edutemplate <class Impl> 633056Sgblack@eecs.umich.eduFullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c) 645091Sgblack@eecs.umich.edu : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c) 655091Sgblack@eecs.umich.edu{ 663056Sgblack@eecs.umich.edu} 672482SN/A 687741Sgblack@eecs.umich.edutemplate <class Impl> 693598Sgblack@eecs.umich.eduvoid 703598Sgblack@eecs.umich.eduFullO3CPU<Impl>::TickEvent::process() 717741Sgblack@eecs.umich.edu{ 725091Sgblack@eecs.umich.edu cpu->tick(); 737720Sgblack@eecs.umich.edu} 747720Sgblack@eecs.umich.edu 757720Sgblack@eecs.umich.edutemplate <class Impl> 767720Sgblack@eecs.umich.educonst char * 775091Sgblack@eecs.umich.eduFullO3CPU<Impl>::TickEvent::description() 787741Sgblack@eecs.umich.edu{ 795091Sgblack@eecs.umich.edu return "FullO3CPU tick event"; 805091Sgblack@eecs.umich.edu} 817720Sgblack@eecs.umich.edu 827720Sgblack@eecs.umich.edutemplate <class Impl> 837720Sgblack@eecs.umich.eduFullO3CPU<Impl>::FullO3CPU(Params *params) 847720Sgblack@eecs.umich.edu : BaseFullCPU(params), 855091Sgblack@eecs.umich.edu tickEvent(this), 865091Sgblack@eecs.umich.edu removeInstsThisCycle(false), 873598Sgblack@eecs.umich.edu fetch(params), 882516SN/A decode(params), 892516SN/A rename(params), 902516SN/A iew(params), 912516SN/A commit(params), 922482SN/A 935091Sgblack@eecs.umich.edu regFile(params->numPhysIntRegs, params->numPhysFloatRegs), 945091Sgblack@eecs.umich.edu 955091Sgblack@eecs.umich.edu freeList(params->numberOfThreads,//number of activeThreads 965091Sgblack@eecs.umich.edu TheISA::NumIntRegs, params->numPhysIntRegs, 975091Sgblack@eecs.umich.edu TheISA::NumFloatRegs, params->numPhysFloatRegs), 985091Sgblack@eecs.umich.edu 992469SN/A rob(params->numROBEntries, params->squashWidth, 1002482SN/A params->smtROBPolicy, params->smtROBThreshold, 1017741Sgblack@eecs.umich.edu params->numberOfThreads), 1023042Sgblack@eecs.umich.edu 1037741Sgblack@eecs.umich.edu scoreboard(params->numberOfThreads,//number of activeThreads 1044004Sgblack@eecs.umich.edu TheISA::NumIntRegs, params->numPhysIntRegs, 1054004Sgblack@eecs.umich.edu TheISA::NumFloatRegs, params->numPhysFloatRegs, 1067741Sgblack@eecs.umich.edu TheISA::NumMiscRegs * number_of_threads, 1075091Sgblack@eecs.umich.edu TheISA::ZeroReg), 1087720Sgblack@eecs.umich.edu 1097720Sgblack@eecs.umich.edu // For now just have these time buffers be pretty big. 1107720Sgblack@eecs.umich.edu // @todo: Make these time buffer sizes parameters or derived 1117720Sgblack@eecs.umich.edu // from latencies 1125091Sgblack@eecs.umich.edu timeBuffer(params->backComSize, params->forwardComSize), 1137741Sgblack@eecs.umich.edu fetchQueue(params->backComSize, params->forwardComSize), 1145091Sgblack@eecs.umich.edu decodeQueue(params->backComSize, params->forwardComSize), 1155091Sgblack@eecs.umich.edu renameQueue(params->backComSize, params->forwardComSize), 1167720Sgblack@eecs.umich.edu iewQueue(params->backComSize, params->forwardComSize), 1177720Sgblack@eecs.umich.edu activityRec(NumStages, 1187720Sgblack@eecs.umich.edu params->backComSize + params->forwardComSize, 1197720Sgblack@eecs.umich.edu params->activity), 1205091Sgblack@eecs.umich.edu 1214004Sgblack@eecs.umich.edu globalSeqNum(1), 1225091Sgblack@eecs.umich.edu 1235091Sgblack@eecs.umich.edu#if FULL_SYSTEM 1245091Sgblack@eecs.umich.edu system(params->system), 1255091Sgblack@eecs.umich.edu memCtrl(system->memctrl), 1265091Sgblack@eecs.umich.edu physmem(system->physmem), 1275091Sgblack@eecs.umich.edu mem(params->mem), 1285091Sgblack@eecs.umich.edu#else 1295091Sgblack@eecs.umich.edu// pTable(params->pTable), 1304004Sgblack@eecs.umich.edu mem(params->workload[0]->getMemory()), 1314004Sgblack@eecs.umich.edu#endif // FULL_SYSTEM 1324004Sgblack@eecs.umich.edu switchCount(0), 1337741Sgblack@eecs.umich.edu icacheInterface(params->icacheInterface), 1344004Sgblack@eecs.umich.edu dcacheInterface(params->dcacheInterface), 1354004Sgblack@eecs.umich.edu deferRegistration(params->deferRegistration), 1367741Sgblack@eecs.umich.edu numThreads(number_of_threads) 1375091Sgblack@eecs.umich.edu{ 1387720Sgblack@eecs.umich.edu _status = Idle; 1397720Sgblack@eecs.umich.edu 1407720Sgblack@eecs.umich.edu if (params->checker) { 1417720Sgblack@eecs.umich.edu BaseCPU *temp_checker = params->checker; 1425091Sgblack@eecs.umich.edu checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker); 1437741Sgblack@eecs.umich.edu checker->setMemory(mem); 1445091Sgblack@eecs.umich.edu#if FULL_SYSTEM 1455091Sgblack@eecs.umich.edu checker->setSystem(params->system); 1467720Sgblack@eecs.umich.edu#endif 1477720Sgblack@eecs.umich.edu } else { 1487720Sgblack@eecs.umich.edu checker = NULL; 1497720Sgblack@eecs.umich.edu } 1505091Sgblack@eecs.umich.edu 1515091Sgblack@eecs.umich.edu#if !FULL_SYSTEM 1525091Sgblack@eecs.umich.edu thread.resize(number_of_threads); 1534004Sgblack@eecs.umich.edu tids.resize(number_of_threads); 1544004Sgblack@eecs.umich.edu#endif 1552469SN/A 1562944Sgblack@eecs.umich.edu // The stages also need their CPU pointer setup. However this 1577720Sgblack@eecs.umich.edu // must be done at the upper level CPU because they have pointers 1583928Ssaidi@eecs.umich.edu // to the upper level CPU, and not this FullO3CPU. 1597720Sgblack@eecs.umich.edu 1603928Ssaidi@eecs.umich.edu // Set up Pointers to the activeThreads list for each stage 1617720Sgblack@eecs.umich.edu fetch.setActiveThreads(&activeThreads); 1627720Sgblack@eecs.umich.edu decode.setActiveThreads(&activeThreads); 1637720Sgblack@eecs.umich.edu rename.setActiveThreads(&activeThreads); 1642469SN/A iew.setActiveThreads(&activeThreads); 1652469SN/A commit.setActiveThreads(&activeThreads); 1662482SN/A 1672482SN/A // Give each of the stages the time buffer they will use. 1682974Sgblack@eecs.umich.edu fetch.setTimeBuffer(&timeBuffer); 1692974Sgblack@eecs.umich.edu decode.setTimeBuffer(&timeBuffer); 1702974Sgblack@eecs.umich.edu rename.setTimeBuffer(&timeBuffer); 1712526SN/A iew.setTimeBuffer(&timeBuffer); 1722974Sgblack@eecs.umich.edu commit.setTimeBuffer(&timeBuffer); 1732974Sgblack@eecs.umich.edu 1742974Sgblack@eecs.umich.edu // Also setup each of the stages' queues. 1752646Ssaidi@eecs.umich.edu fetch.setFetchQueue(&fetchQueue); 1762974Sgblack@eecs.umich.edu decode.setFetchQueue(&fetchQueue); 1772469SN/A commit.setFetchQueue(&fetchQueue); 1782516SN/A decode.setDecodeQueue(&decodeQueue); 1792646Ssaidi@eecs.umich.edu rename.setDecodeQueue(&decodeQueue); 1802482SN/A rename.setRenameQueue(&renameQueue); 1812469SN/A iew.setRenameQueue(&renameQueue); 1823931Ssaidi@eecs.umich.edu iew.setIEWQueue(&iewQueue); 1833900Ssaidi@eecs.umich.edu commit.setIEWQueue(&iewQueue); 1842482SN/A commit.setRenameQueue(&renameQueue); 1852954Sgblack@eecs.umich.edu 1862469SN/A commit.setIEWStage(&iew); 1877741Sgblack@eecs.umich.edu rename.setIEWStage(&iew); 1887741Sgblack@eecs.umich.edu rename.setCommitStage(&commit); 1897741Sgblack@eecs.umich.edu 1907741Sgblack@eecs.umich.edu#if !FULL_SYSTEM 1912482SN/A int active_threads = params->workload.size(); 1922469SN/A#else 1937741Sgblack@eecs.umich.edu int active_threads = 1; 1947741Sgblack@eecs.umich.edu#endif 1957741Sgblack@eecs.umich.edu 1962646Ssaidi@eecs.umich.edu //Make Sure That this a Valid Architeture 1977741Sgblack@eecs.umich.edu assert(params->numPhysIntRegs >= numThreads * TheISA::NumIntRegs); 1982482SN/A assert(params->numPhysFloatRegs >= numThreads * TheISA::NumFloatRegs); 1992482SN/A 2002482SN/A rename.setScoreboard(&scoreboard); 2012482SN/A iew.setScoreboard(&scoreboard); 2027741Sgblack@eecs.umich.edu 2032469SN/A // Setup the rename map for whichever stages need it. 2047741Sgblack@eecs.umich.edu PhysRegIndex lreg_idx = 0; 2057741Sgblack@eecs.umich.edu PhysRegIndex freg_idx = params->numPhysIntRegs; //Index to 1 after int regs 2067741Sgblack@eecs.umich.edu 2077741Sgblack@eecs.umich.edu for (int tid=0; tid < numThreads; tid++) { 2087741Sgblack@eecs.umich.edu bool bindRegs = (tid <= active_threads - 1); 2092482SN/A 2107741Sgblack@eecs.umich.edu commitRenameMap[tid].init(TheISA::NumIntRegs, 2117741Sgblack@eecs.umich.edu params->numPhysIntRegs, 2123929Ssaidi@eecs.umich.edu lreg_idx, //Index for Logical. Regs 2137741Sgblack@eecs.umich.edu 2142482SN/A TheISA::NumFloatRegs, 2152526SN/A params->numPhysFloatRegs, 2162469SN/A freg_idx, //Index for Float Regs 2172482SN/A 2182469SN/A TheISA::NumMiscRegs, 2195093Sgblack@eecs.umich.edu 2205093Sgblack@eecs.umich.edu TheISA::ZeroReg, 2215093Sgblack@eecs.umich.edu TheISA::ZeroReg, 2222482SN/A 2232482SN/A tid, 2242482SN/A false); 2252469SN/A 2265093Sgblack@eecs.umich.edu renameMap[tid].init(TheISA::NumIntRegs, 2275093Sgblack@eecs.umich.edu params->numPhysIntRegs, 2285093Sgblack@eecs.umich.edu lreg_idx, //Index for Logical. Regs 2292482SN/A 2302482SN/A TheISA::NumFloatRegs, 2312482SN/A params->numPhysFloatRegs, 2322469SN/A freg_idx, //Index for Float Regs 2335093Sgblack@eecs.umich.edu 2345093Sgblack@eecs.umich.edu TheISA::NumMiscRegs, 2355093Sgblack@eecs.umich.edu 2363765Sgblack@eecs.umich.edu TheISA::ZeroReg, 2372615SN/A TheISA::ZeroReg, 2382615SN/A 2393765Sgblack@eecs.umich.edu tid, 2403765Sgblack@eecs.umich.edu bindRegs); 2412615SN/A } 2423931Ssaidi@eecs.umich.edu 2433765Sgblack@eecs.umich.edu rename.setRenameMap(renameMap); 2442469SN/A commit.setRenameMap(commitRenameMap); 2455093Sgblack@eecs.umich.edu 2465093Sgblack@eecs.umich.edu // Give renameMap & rename stage access to the freeList; 2475093Sgblack@eecs.umich.edu for (int i=0; i < numThreads; i++) { 2483765Sgblack@eecs.umich.edu renameMap[i].setFreeList(&freeList); 2497741Sgblack@eecs.umich.edu } 2507741Sgblack@eecs.umich.edu rename.setFreeList(&freeList); 2517741Sgblack@eecs.umich.edu 2527741Sgblack@eecs.umich.edu // Setup the page table for whichever stages need it. 2535093Sgblack@eecs.umich.edu#if !FULL_SYSTEM 2546639Svince@csl.cornell.edu// fetch.setPageTable(pTable); 2556639Svince@csl.cornell.edu// iew.setPageTable(pTable); 2565093Sgblack@eecs.umich.edu#endif 2577741Sgblack@eecs.umich.edu 2587741Sgblack@eecs.umich.edu // Setup the ROB for whichever stages need it. 2597741Sgblack@eecs.umich.edu commit.setROB(&rob); 2605093Sgblack@eecs.umich.edu 2615093Sgblack@eecs.umich.edu lastRunningCycle = curTick; 2627741Sgblack@eecs.umich.edu 2637741Sgblack@eecs.umich.edu contextSwitch = false; 2647741Sgblack@eecs.umich.edu} 2657741Sgblack@eecs.umich.edu 2665093Sgblack@eecs.umich.edutemplate <class Impl> 2675093Sgblack@eecs.umich.eduFullO3CPU<Impl>::~FullO3CPU() 2685093Sgblack@eecs.umich.edu{ 2695093Sgblack@eecs.umich.edu} 2705093Sgblack@eecs.umich.edu 2717741Sgblack@eecs.umich.edutemplate <class Impl> 2727741Sgblack@eecs.umich.eduvoid 2737741Sgblack@eecs.umich.eduFullO3CPU<Impl>::fullCPURegStats() 2745093Sgblack@eecs.umich.edu{ 2755093Sgblack@eecs.umich.edu BaseFullCPU::regStats(); 2765093Sgblack@eecs.umich.edu 2777741Sgblack@eecs.umich.edu // Register any of the FullCPU's stats here. 2787741Sgblack@eecs.umich.edu timesIdled 2797741Sgblack@eecs.umich.edu .name(name() + ".timesIdled") 2807741Sgblack@eecs.umich.edu .desc("Number of times that the entire CPU went into an idle state and" 2815093Sgblack@eecs.umich.edu " unscheduled itself") 2825093Sgblack@eecs.umich.edu .prereq(timesIdled); 2832469SN/A 2845093Sgblack@eecs.umich.edu idleCycles 2855093Sgblack@eecs.umich.edu .name(name() + ".idleCycles") 2865093Sgblack@eecs.umich.edu .desc("Total number of cycles that the CPU has spent unscheduled due " 2875093Sgblack@eecs.umich.edu "to idling") 2885093Sgblack@eecs.umich.edu .prereq(idleCycles); 2895093Sgblack@eecs.umich.edu 2902469SN/A // Number of Instructions simulated 2915093Sgblack@eecs.umich.edu // -------------------------------- 2925093Sgblack@eecs.umich.edu // Should probably be in Base CPU but need templated 2935093Sgblack@eecs.umich.edu // MaxThreads so put in here instead 2945093Sgblack@eecs.umich.edu committedInsts 2955093Sgblack@eecs.umich.edu .init(numThreads) 2965093Sgblack@eecs.umich.edu .name(name() + ".committedInsts") 2972469SN/A .desc("Number of Instructions Simulated"); 2985093Sgblack@eecs.umich.edu 2995093Sgblack@eecs.umich.edu totalCommittedInsts 3005093Sgblack@eecs.umich.edu .name(name() + ".committedInsts_total") 3015093Sgblack@eecs.umich.edu .desc("Number of Instructions Simulated"); 3027741Sgblack@eecs.umich.edu 3037741Sgblack@eecs.umich.edu cpi 3045093Sgblack@eecs.umich.edu .name(name() + ".cpi") 3052469SN/A .desc("CPI: Cycles Per Instruction") 3065093Sgblack@eecs.umich.edu .precision(6); 3075093Sgblack@eecs.umich.edu cpi = simTicks / committedInsts; 3085093Sgblack@eecs.umich.edu 3095093Sgblack@eecs.umich.edu totalCpi 3107741Sgblack@eecs.umich.edu .name(name() + ".cpi_total") 3117741Sgblack@eecs.umich.edu .desc("CPI: Total CPI of All Threads") 3125093Sgblack@eecs.umich.edu .precision(6); 3132469SN/A totalCpi = simTicks / totalCommittedInsts; 3145093Sgblack@eecs.umich.edu 3154237Sgblack@eecs.umich.edu ipc 3167741Sgblack@eecs.umich.edu .name(name() + ".ipc") 3175093Sgblack@eecs.umich.edu .desc("IPC: Instructions Per Cycle") 3187741Sgblack@eecs.umich.edu .precision(6); 3195093Sgblack@eecs.umich.edu ipc = committedInsts / simTicks; 3205093Sgblack@eecs.umich.edu 3217741Sgblack@eecs.umich.edu totalIpc 3225093Sgblack@eecs.umich.edu .name(name() + ".ipc_total") 3235093Sgblack@eecs.umich.edu .desc("IPC: Total IPC of All Threads") 3245093Sgblack@eecs.umich.edu .precision(6); 3257741Sgblack@eecs.umich.edu totalIpc = totalCommittedInsts / simTicks; 3265093Sgblack@eecs.umich.edu 3275093Sgblack@eecs.umich.edu} 3282526SN/A 3292526SN/Atemplate <class Impl> 3302526SN/Avoid 3312526SN/AFullO3CPU<Impl>::tick() 3322526SN/A{ 3332526SN/A DPRINTF(FullCPU, "\n\nFullCPU: Ticking main, FullO3CPU.\n"); 3342469SN/A 3352526SN/A ++numCycles; 3362526SN/A 3372526SN/A// activity = false; 3382526SN/A 3392526SN/A //Tick each of the stages 3402526SN/A fetch.tick(); 3412526SN/A 3422526SN/A decode.tick(); 3432954Sgblack@eecs.umich.edu 3443929Ssaidi@eecs.umich.edu rename.tick(); 3457741Sgblack@eecs.umich.edu 3463587Sgblack@eecs.umich.edu iew.tick(); 3473587Sgblack@eecs.umich.edu 3485094Sgblack@eecs.umich.edu commit.tick(); 3493587Sgblack@eecs.umich.edu 3507720Sgblack@eecs.umich.edu#if !FULL_SYSTEM 3517741Sgblack@eecs.umich.edu doContextSwitch(); 3527720Sgblack@eecs.umich.edu#endif 3533587Sgblack@eecs.umich.edu 3547720Sgblack@eecs.umich.edu // Now advance the time buffers 3557720Sgblack@eecs.umich.edu timeBuffer.advance(); 3563587Sgblack@eecs.umich.edu 3577741Sgblack@eecs.umich.edu fetchQueue.advance(); 3583587Sgblack@eecs.umich.edu decodeQueue.advance(); 3593587Sgblack@eecs.umich.edu renameQueue.advance(); 3607741Sgblack@eecs.umich.edu iewQueue.advance(); 3613587Sgblack@eecs.umich.edu 3624040Ssaidi@eecs.umich.edu activityRec.advance(); 3634040Ssaidi@eecs.umich.edu 3642954Sgblack@eecs.umich.edu if (removeInstsThisCycle) { 3653587Sgblack@eecs.umich.edu cleanUpRemovedInsts(); 3665094Sgblack@eecs.umich.edu } 3677741Sgblack@eecs.umich.edu 3683587Sgblack@eecs.umich.edu if (!tickEvent.scheduled()) { 3694010Ssaidi@eecs.umich.edu if (_status == SwitchedOut) { 3704010Ssaidi@eecs.umich.edu // increment stat 3714010Ssaidi@eecs.umich.edu lastRunningCycle = curTick; 3724010Ssaidi@eecs.umich.edu } else if (!activityRec.active()) { 3732954Sgblack@eecs.umich.edu lastRunningCycle = curTick; 3747741Sgblack@eecs.umich.edu timesIdled++; 3753587Sgblack@eecs.umich.edu } else { 3763823Ssaidi@eecs.umich.edu tickEvent.schedule(curTick + cycles(1)); 3775094Sgblack@eecs.umich.edu } 3783823Ssaidi@eecs.umich.edu } 3793598Sgblack@eecs.umich.edu 3807741Sgblack@eecs.umich.edu#if !FULL_SYSTEM 3813598Sgblack@eecs.umich.edu updateThreadPriority(); 3823598Sgblack@eecs.umich.edu#endif 3833598Sgblack@eecs.umich.edu 3843598Sgblack@eecs.umich.edu} 3857741Sgblack@eecs.umich.edu 3867741Sgblack@eecs.umich.edutemplate <class Impl> 3877741Sgblack@eecs.umich.eduvoid 3882954Sgblack@eecs.umich.eduFullO3CPU<Impl>::init() 3893587Sgblack@eecs.umich.edu{ 3903587Sgblack@eecs.umich.edu if (!deferRegistration) { 3915094Sgblack@eecs.umich.edu registerExecContexts(); 3927741Sgblack@eecs.umich.edu } 3933587Sgblack@eecs.umich.edu 3947741Sgblack@eecs.umich.edu // Set inSyscall so that the CPU doesn't squash when initially 3953587Sgblack@eecs.umich.edu // setting up registers. 3963587Sgblack@eecs.umich.edu for (int i = 0; i < number_of_threads; ++i) 3977741Sgblack@eecs.umich.edu thread[i]->inSyscall = true; 3983823Ssaidi@eecs.umich.edu 3993587Sgblack@eecs.umich.edu for (int tid=0; tid < number_of_threads; tid++) { 4003587Sgblack@eecs.umich.edu#if FULL_SYSTEM 4015094Sgblack@eecs.umich.edu ExecContext *src_xc = execContexts[tid]; 4025094Sgblack@eecs.umich.edu#else 4035094Sgblack@eecs.umich.edu ExecContext *src_xc = thread[tid]->getXCProxy(); 4045094Sgblack@eecs.umich.edu#endif 4053823Ssaidi@eecs.umich.edu // Threads start in the Suspended State 4063587Sgblack@eecs.umich.edu if (src_xc->status() != ExecContext::Suspended) { 4073587Sgblack@eecs.umich.edu continue; 4083587Sgblack@eecs.umich.edu } 4093587Sgblack@eecs.umich.edu 4103587Sgblack@eecs.umich.edu#if FULL_SYSTEM 4113587Sgblack@eecs.umich.edu TheISA::initCPU(src_xc, src_xc->readCpuId()); 4123587Sgblack@eecs.umich.edu#endif 4133587Sgblack@eecs.umich.edu } 4143587Sgblack@eecs.umich.edu 4153587Sgblack@eecs.umich.edu // Clear inSyscall. 4167741Sgblack@eecs.umich.edu for (int i = 0; i < number_of_threads; ++i) 4173587Sgblack@eecs.umich.edu thread[i]->inSyscall = false; 4187741Sgblack@eecs.umich.edu 4193587Sgblack@eecs.umich.edu // Initialize stages. 4202526SN/A fetch.initStage(); 4217741Sgblack@eecs.umich.edu iew.initStage(); 4227741Sgblack@eecs.umich.edu rename.initStage(); 4233909Ssaidi@eecs.umich.edu commit.initStage(); 4242526SN/A 4253909Ssaidi@eecs.umich.edu commit.setThreads(thread); 4262526SN/A} 4272526SN/A 4282526SN/Atemplate <class Impl> 4292469SN/Avoid 4307085Sgblack@eecs.umich.eduFullO3CPU<Impl>::insertThread(unsigned tid) 4317085Sgblack@eecs.umich.edu{ 4327085Sgblack@eecs.umich.edu DPRINTF(FullCPU,"[tid:%i] Initializing thread data"); 4337741Sgblack@eecs.umich.edu // Will change now that the PC and thread state is internal to the CPU 4347085Sgblack@eecs.umich.edu // and not in the CPUExecContext. 4357085Sgblack@eecs.umich.edu#if 0 4367085Sgblack@eecs.umich.edu#if FULL_SYSTEM 4377085Sgblack@eecs.umich.edu ExecContext *src_xc = system->execContexts[tid]; 4387085Sgblack@eecs.umich.edu#else 4397741Sgblack@eecs.umich.edu CPUExecContext *src_xc = thread[tid]; 4407085Sgblack@eecs.umich.edu#endif 4417085Sgblack@eecs.umich.edu 4427085Sgblack@eecs.umich.edu //Bind Int Regs to Rename Map 4437085Sgblack@eecs.umich.edu for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) { 4447085Sgblack@eecs.umich.edu PhysRegIndex phys_reg = freeList.getIntReg(); 4457741Sgblack@eecs.umich.edu 4467085Sgblack@eecs.umich.edu renameMap[tid].setEntry(ireg,phys_reg); 4477085Sgblack@eecs.umich.edu scoreboard.setReg(phys_reg); 4487085Sgblack@eecs.umich.edu } 4497085Sgblack@eecs.umich.edu 4507085Sgblack@eecs.umich.edu //Bind Float Regs to Rename Map 4517741Sgblack@eecs.umich.edu for (int freg = 0; freg < TheISA::NumFloatRegs; freg++) { 4527085Sgblack@eecs.umich.edu PhysRegIndex phys_reg = freeList.getFloatReg(); 4537085Sgblack@eecs.umich.edu 4547085Sgblack@eecs.umich.edu renameMap[tid].setEntry(freg,phys_reg); 4557085Sgblack@eecs.umich.edu scoreboard.setReg(phys_reg); 4567085Sgblack@eecs.umich.edu } 4572526SN/A 4582526SN/A //Copy Thread Data Into RegFile 4592526SN/A this->copyFromXC(tid); 4607741Sgblack@eecs.umich.edu 4612591SN/A //Set PC/NPC 4622591SN/A regFile.pc[tid] = src_xc->readPC(); 4632591SN/A regFile.npc[tid] = src_xc->readNextPC(); 4642526SN/A 4652526SN/A src_xc->setStatus(ExecContext::Active); 4667741Sgblack@eecs.umich.edu 4672591SN/A activateContext(tid,1); 4682591SN/A 4692591SN/A //Reset ROB/IQ/LSQ Entries 4702526SN/A commit.rob->resetEntries(); 4712224SN/A iew.resetEntries(); 4722526SN/A#endif 4732526SN/A} 4747741Sgblack@eecs.umich.edu 4757741Sgblack@eecs.umich.edutemplate <class Impl> 4767741Sgblack@eecs.umich.eduvoid 4777741Sgblack@eecs.umich.eduFullO3CPU<Impl>::removeThread(unsigned tid) 4782526SN/A{ 4793941Ssaidi@eecs.umich.edu DPRINTF(FullCPU,"[tid:%i] Removing thread data"); 4802526SN/A#if 0 4812526SN/A //Unbind Int Regs from Rename Map 4822615SN/A for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) { 4832615SN/A PhysRegIndex phys_reg = renameMap[tid].lookup(ireg); 4842615SN/A 4852615SN/A scoreboard.unsetReg(phys_reg); 4862615SN/A freeList.addReg(phys_reg); 4872615SN/A } 4882526SN/A 4893587Sgblack@eecs.umich.edu //Unbind Float Regs from Rename Map 4903929Ssaidi@eecs.umich.edu for (int freg = 0; freg < TheISA::NumFloatRegs; freg++) { 4917741Sgblack@eecs.umich.edu PhysRegIndex phys_reg = renameMap[tid].lookup(freg); 4923587Sgblack@eecs.umich.edu 4937784SAli.Saidi@ARM.com scoreboard.unsetReg(phys_reg); 4947784SAli.Saidi@ARM.com freeList.addReg(phys_reg); 4957741Sgblack@eecs.umich.edu } 4963587Sgblack@eecs.umich.edu 4977741Sgblack@eecs.umich.edu //Copy Thread Data From RegFile 4983587Sgblack@eecs.umich.edu /* Fix Me: 4993587Sgblack@eecs.umich.edu * Do we really need to do this if we are removing a thread 5005094Sgblack@eecs.umich.edu * in the sense that it's finished (exiting)? If the thread is just 5017741Sgblack@eecs.umich.edu * being suspended we might... 5023587Sgblack@eecs.umich.edu */ 5037741Sgblack@eecs.umich.edu// this->copyToXC(tid); 5043587Sgblack@eecs.umich.edu 5053587Sgblack@eecs.umich.edu //Squash Throughout Pipeline 5063587Sgblack@eecs.umich.edu fetch.squash(0,tid); 5073587Sgblack@eecs.umich.edu decode.squash(tid); 5083587Sgblack@eecs.umich.edu rename.squash(tid); 5093587Sgblack@eecs.umich.edu 5103823Ssaidi@eecs.umich.edu assert(iew.ldstQueue.getCount(tid) == 0); 5113587Sgblack@eecs.umich.edu 5127741Sgblack@eecs.umich.edu //Reset ROB/IQ/LSQ Entries 5133587Sgblack@eecs.umich.edu if (activeThreads.size() >= 1) { 5143823Ssaidi@eecs.umich.edu commit.rob->resetEntries(); 5153587Sgblack@eecs.umich.edu iew.resetEntries(); 5163823Ssaidi@eecs.umich.edu } 5173598Sgblack@eecs.umich.edu#endif 5183598Sgblack@eecs.umich.edu} 5193598Sgblack@eecs.umich.edu 5207741Sgblack@eecs.umich.edu 5217741Sgblack@eecs.umich.edutemplate <class Impl> 5227741Sgblack@eecs.umich.eduvoid 5233587Sgblack@eecs.umich.eduFullO3CPU<Impl>::activateWhenReady(int tid) 5242526SN/A{ 5253417Sgblack@eecs.umich.edu DPRINTF(FullCPU,"[tid:%i]: Checking if resources are available for incoming" 5263417Sgblack@eecs.umich.edu "(e.g. PhysRegs/ROB/IQ/LSQ) \n", 5273417Sgblack@eecs.umich.edu tid); 5283417Sgblack@eecs.umich.edu 5297741Sgblack@eecs.umich.edu bool ready = true; 5303417Sgblack@eecs.umich.edu 5313417Sgblack@eecs.umich.edu if (freeList.numFreeIntRegs() >= TheISA::NumIntRegs) { 5323417Sgblack@eecs.umich.edu DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough " 5333417Sgblack@eecs.umich.edu "Phys. Int. Regs.\n", 5343598Sgblack@eecs.umich.edu tid); 5353417Sgblack@eecs.umich.edu ready = false; 5363417Sgblack@eecs.umich.edu } else if (freeList.numFreeFloatRegs() >= TheISA::NumFloatRegs) { 5373417Sgblack@eecs.umich.edu DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough " 5387741Sgblack@eecs.umich.edu "Phys. Float. Regs.\n", 5393417Sgblack@eecs.umich.edu tid); 5403417Sgblack@eecs.umich.edu ready = false; 5413417Sgblack@eecs.umich.edu } else if (commit.rob->numFreeEntries() >= 5423928Ssaidi@eecs.umich.edu commit.rob->entryAmount(activeThreads.size() + 1)) { 5437741Sgblack@eecs.umich.edu DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough " 5443928Ssaidi@eecs.umich.edu "ROB entries.\n", 5453417Sgblack@eecs.umich.edu tid); 5462526SN/A ready = false; 5473587Sgblack@eecs.umich.edu } else if (iew.instQueue.numFreeEntries() >= 5485094Sgblack@eecs.umich.edu iew.instQueue.entryAmount(activeThreads.size() + 1)) { 5495094Sgblack@eecs.umich.edu DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough " 5505094Sgblack@eecs.umich.edu "IQ entries.\n", 5515094Sgblack@eecs.umich.edu tid); 5525094Sgblack@eecs.umich.edu ready = false; 5535094Sgblack@eecs.umich.edu } else if (iew.ldstQueue.numFreeEntries() >= 5545094Sgblack@eecs.umich.edu iew.ldstQueue.entryAmount(activeThreads.size() + 1)) { 5555094Sgblack@eecs.umich.edu DPRINTF(FullCPU,"[tid:%i] Suspending thread due to not enough " 5563823Ssaidi@eecs.umich.edu "LSQ entries.\n", 5573587Sgblack@eecs.umich.edu tid); 5583587Sgblack@eecs.umich.edu ready = false; 5593587Sgblack@eecs.umich.edu } 5607741Sgblack@eecs.umich.edu 5613587Sgblack@eecs.umich.edu if (ready) { 5623587Sgblack@eecs.umich.edu insertThread(tid); 5633587Sgblack@eecs.umich.edu 5643587Sgblack@eecs.umich.edu contextSwitch = false; 5653587Sgblack@eecs.umich.edu 5663587Sgblack@eecs.umich.edu cpuWaitList.remove(tid); 5673587Sgblack@eecs.umich.edu } else { 5683587Sgblack@eecs.umich.edu suspendContext(tid); 5693587Sgblack@eecs.umich.edu 5703587Sgblack@eecs.umich.edu //blocks fetch 5713587Sgblack@eecs.umich.edu contextSwitch = true; 5727741Sgblack@eecs.umich.edu 5733587Sgblack@eecs.umich.edu //do waitlist 5747741Sgblack@eecs.umich.edu cpuWaitList.push_back(tid); 5753587Sgblack@eecs.umich.edu } 5763587Sgblack@eecs.umich.edu} 5773587Sgblack@eecs.umich.edu 5783587Sgblack@eecs.umich.edutemplate <class Impl> 5797741Sgblack@eecs.umich.eduvoid 5803587Sgblack@eecs.umich.eduFullO3CPU<Impl>::activateContext(int tid, int delay) 5813587Sgblack@eecs.umich.edu{ 5823587Sgblack@eecs.umich.edu // Needs to set each stage to running as well. 5835094Sgblack@eecs.umich.edu list<unsigned>::iterator isActive = find( 5845094Sgblack@eecs.umich.edu activeThreads.begin(), activeThreads.end(), tid); 5857741Sgblack@eecs.umich.edu 5863587Sgblack@eecs.umich.edu if (isActive == activeThreads.end()) { 5877741Sgblack@eecs.umich.edu //May Need to Re-code this if the delay variable is the 5883587Sgblack@eecs.umich.edu //delay needed for thread to activate 5897741Sgblack@eecs.umich.edu DPRINTF(FullCPU, "Adding Thread %i to active threads list\n", 5903823Ssaidi@eecs.umich.edu tid); 5913587Sgblack@eecs.umich.edu 5922954Sgblack@eecs.umich.edu activeThreads.push_back(tid); 5934008Ssaidi@eecs.umich.edu } 5945095Sgblack@eecs.umich.edu 5955095Sgblack@eecs.umich.edu assert(_status == Idle || _status == SwitchedOut); 5963995Sgblack@eecs.umich.edu 5975095Sgblack@eecs.umich.edu scheduleTickEvent(delay); 5985095Sgblack@eecs.umich.edu 5993995Sgblack@eecs.umich.edu // Be sure to signal that there's some activity so the CPU doesn't 6005095Sgblack@eecs.umich.edu // deschedule itself. 6015095Sgblack@eecs.umich.edu activityRec.activity(); 6023995Sgblack@eecs.umich.edu if (thread[tid]->quiesceEvent && thread[tid]->quiesceEvent->scheduled()) 6033918Ssaidi@eecs.umich.edu thread[tid]->quiesceEvent->deschedule(); 6043918Ssaidi@eecs.umich.edu 6053995Sgblack@eecs.umich.edu fetch.wakeFromQuiesce(); 6063279Sgblack@eecs.umich.edu 6072963Sgblack@eecs.umich.edu _status = Running; 6083995Sgblack@eecs.umich.edu} 6093279Sgblack@eecs.umich.edu 6104008Ssaidi@eecs.umich.edutemplate <class Impl> 6113995Sgblack@eecs.umich.eduvoid 6123279Sgblack@eecs.umich.eduFullO3CPU<Impl>::suspendContext(int tid) 6132963Sgblack@eecs.umich.edu{ 6143995Sgblack@eecs.umich.edu DPRINTF(FullCPU,"[tid: %i]: Suspended ...\n", tid); 6153279Sgblack@eecs.umich.edu unscheduleTickEvent(); 6162963Sgblack@eecs.umich.edu _status = Idle; 6173995Sgblack@eecs.umich.edu/* 6183279Sgblack@eecs.umich.edu //Remove From Active List, if Active 6193995Sgblack@eecs.umich.edu list<unsigned>::iterator isActive = find( 6205095Sgblack@eecs.umich.edu activeThreads.begin(), activeThreads.end(), tid); 6215095Sgblack@eecs.umich.edu 6223995Sgblack@eecs.umich.edu if (isActive != activeThreads.end()) { 6235095Sgblack@eecs.umich.edu DPRINTF(FullCPU,"[tid:%i]: Removing from active threads list\n", 6245095Sgblack@eecs.umich.edu tid); 6253995Sgblack@eecs.umich.edu activeThreads.erase(isActive); 6265095Sgblack@eecs.umich.edu } 6273279Sgblack@eecs.umich.edu*/ 6283995Sgblack@eecs.umich.edu} 6295095Sgblack@eecs.umich.edu 6303279Sgblack@eecs.umich.edutemplate <class Impl> 6313995Sgblack@eecs.umich.eduvoid 6323995Sgblack@eecs.umich.eduFullO3CPU<Impl>::deallocateContext(int tid) 6333995Sgblack@eecs.umich.edu{ 6343995Sgblack@eecs.umich.edu DPRINTF(FullCPU,"[tid:%i]: Deallocating ...", tid); 6352963Sgblack@eecs.umich.edu/* 6364008Ssaidi@eecs.umich.edu //Remove From Active List, if Active 6374008Ssaidi@eecs.umich.edu list<unsigned>::iterator isActive = find( 6384008Ssaidi@eecs.umich.edu activeThreads.begin(), activeThreads.end(), tid); 6394008Ssaidi@eecs.umich.edu 6402963Sgblack@eecs.umich.edu if (isActive != activeThreads.end()) { 6412963Sgblack@eecs.umich.edu DPRINTF(FullCPU,"[tid:%i]: Removing from active threads list\n", 6424008Ssaidi@eecs.umich.edu tid); 6434008Ssaidi@eecs.umich.edu activeThreads.erase(isActive); 6444008Ssaidi@eecs.umich.edu 6454008Ssaidi@eecs.umich.edu removeThread(tid); 6462963Sgblack@eecs.umich.edu } 6473995Sgblack@eecs.umich.edu*/ 6483941Ssaidi@eecs.umich.edu} 6492963Sgblack@eecs.umich.edu 6502954Sgblack@eecs.umich.edutemplate <class Impl> 6513992Sgblack@eecs.umich.eduvoid 6524008Ssaidi@eecs.umich.eduFullO3CPU<Impl>::haltContext(int tid) 6534204Sgblack@eecs.umich.edu{ 6547741Sgblack@eecs.umich.edu DPRINTF(FullCPU,"[tid:%i]: Halted ...", tid); 6554204Sgblack@eecs.umich.edu/* 6564204Sgblack@eecs.umich.edu //Remove From Active List, if Active 6574204Sgblack@eecs.umich.edu list<unsigned>::iterator isActive = find( 6584204Sgblack@eecs.umich.edu activeThreads.begin(), activeThreads.end(), tid); 6594204Sgblack@eecs.umich.edu 6607741Sgblack@eecs.umich.edu if (isActive != activeThreads.end()) { 6614204Sgblack@eecs.umich.edu DPRINTF(FullCPU,"[tid:%i]: Removing from active threads list\n", 6624204Sgblack@eecs.umich.edu tid); 6634204Sgblack@eecs.umich.edu activeThreads.erase(isActive); 6644204Sgblack@eecs.umich.edu 6654204Sgblack@eecs.umich.edu removeThread(tid); 6664204Sgblack@eecs.umich.edu } 6677741Sgblack@eecs.umich.edu*/ 6684204Sgblack@eecs.umich.edu} 6694204Sgblack@eecs.umich.edu 6704204Sgblack@eecs.umich.edutemplate <class Impl> 6714204Sgblack@eecs.umich.eduvoid 6724204Sgblack@eecs.umich.eduFullO3CPU<Impl>::switchOut(Sampler *_sampler) 6737741Sgblack@eecs.umich.edu{ 6744204Sgblack@eecs.umich.edu sampler = _sampler; 6754204Sgblack@eecs.umich.edu switchCount = 0; 6764204Sgblack@eecs.umich.edu fetch.switchOut(); 6774204Sgblack@eecs.umich.edu decode.switchOut(); 6784204Sgblack@eecs.umich.edu rename.switchOut(); 6794204Sgblack@eecs.umich.edu iew.switchOut(); 6807741Sgblack@eecs.umich.edu commit.switchOut(); 6814204Sgblack@eecs.umich.edu 6824204Sgblack@eecs.umich.edu // Wake the CPU and record activity so everything can drain out if 6834204Sgblack@eecs.umich.edu // the CPU is currently idle. 6844204Sgblack@eecs.umich.edu wakeCPU(); 6854204Sgblack@eecs.umich.edu activityRec.activity(); 6867741Sgblack@eecs.umich.edu} 6874204Sgblack@eecs.umich.edu 6884204Sgblack@eecs.umich.edutemplate <class Impl> 6894204Sgblack@eecs.umich.eduvoid 6904204Sgblack@eecs.umich.eduFullO3CPU<Impl>::signalSwitched() 6914204Sgblack@eecs.umich.edu{ 6924204Sgblack@eecs.umich.edu if (++switchCount == NumStages) { 6937741Sgblack@eecs.umich.edu fetch.doSwitchOut(); 6944204Sgblack@eecs.umich.edu rename.doSwitchOut(); 6954204Sgblack@eecs.umich.edu commit.doSwitchOut(); 6964204Sgblack@eecs.umich.edu instList.clear(); 6974204Sgblack@eecs.umich.edu while (!removeList.empty()) { 6984204Sgblack@eecs.umich.edu removeList.pop(); 6997741Sgblack@eecs.umich.edu } 7004204Sgblack@eecs.umich.edu 7014204Sgblack@eecs.umich.edu if (checker) 7024204Sgblack@eecs.umich.edu checker->switchOut(sampler); 7034204Sgblack@eecs.umich.edu 7044204Sgblack@eecs.umich.edu if (tickEvent.scheduled()) 7053992Sgblack@eecs.umich.edu tickEvent.squash(); 7063992Sgblack@eecs.umich.edu sampler->signalSwitched(); 7077741Sgblack@eecs.umich.edu _status = SwitchedOut; 7083992Sgblack@eecs.umich.edu } 7097741Sgblack@eecs.umich.edu assert(switchCount <= 5); 7103992Sgblack@eecs.umich.edu} 7117741Sgblack@eecs.umich.edu 7123992Sgblack@eecs.umich.edutemplate <class Impl> 7133992Sgblack@eecs.umich.eduvoid 7143992Sgblack@eecs.umich.eduFullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU) 7153992Sgblack@eecs.umich.edu{ 7167741Sgblack@eecs.umich.edu // Flush out any old data from the time buffers. 7173992Sgblack@eecs.umich.edu for (int i = 0; i < timeBuffer.getSize(); ++i) { 7183992Sgblack@eecs.umich.edu timeBuffer.advance(); 7193992Sgblack@eecs.umich.edu fetchQueue.advance(); 7203992Sgblack@eecs.umich.edu decodeQueue.advance(); 7213992Sgblack@eecs.umich.edu renameQueue.advance(); 7227741Sgblack@eecs.umich.edu iewQueue.advance(); 7233992Sgblack@eecs.umich.edu } 7247741Sgblack@eecs.umich.edu 7253992Sgblack@eecs.umich.edu activityRec.reset(); 7267741Sgblack@eecs.umich.edu 7273992Sgblack@eecs.umich.edu BaseCPU::takeOverFrom(oldCPU); 7283992Sgblack@eecs.umich.edu 7293992Sgblack@eecs.umich.edu fetch.takeOverFrom(); 7303992Sgblack@eecs.umich.edu decode.takeOverFrom(); 7317741Sgblack@eecs.umich.edu rename.takeOverFrom(); 7323992Sgblack@eecs.umich.edu iew.takeOverFrom(); 7333992Sgblack@eecs.umich.edu commit.takeOverFrom(); 7343992Sgblack@eecs.umich.edu 7353995Sgblack@eecs.umich.edu assert(!tickEvent.scheduled()); 7363997Ssaidi@eecs.umich.edu 7373992Sgblack@eecs.umich.edu // @todo: Figure out how to properly select the tid to put onto 7387741Sgblack@eecs.umich.edu // the active threads list. 7393992Sgblack@eecs.umich.edu int tid = 0; 7407741Sgblack@eecs.umich.edu 7413992Sgblack@eecs.umich.edu list<unsigned>::iterator isActive = find( 7427741Sgblack@eecs.umich.edu activeThreads.begin(), activeThreads.end(), tid); 7433992Sgblack@eecs.umich.edu 7443992Sgblack@eecs.umich.edu if (isActive == activeThreads.end()) { 7457741Sgblack@eecs.umich.edu //May Need to Re-code this if the delay variable is the delay 7463992Sgblack@eecs.umich.edu //needed for thread to activate 7473992Sgblack@eecs.umich.edu DPRINTF(FullCPU, "Adding Thread %i to active threads list\n", 7483992Sgblack@eecs.umich.edu tid); 7493997Ssaidi@eecs.umich.edu 7503992Sgblack@eecs.umich.edu activeThreads.push_back(tid); 7517741Sgblack@eecs.umich.edu } 7523992Sgblack@eecs.umich.edu 7537741Sgblack@eecs.umich.edu // Set all statuses to active, schedule the CPU's tick event. 7543992Sgblack@eecs.umich.edu // @todo: Fix up statuses so this is handled properly 7557741Sgblack@eecs.umich.edu for (int i = 0; i < execContexts.size(); ++i) { 7563992Sgblack@eecs.umich.edu ExecContext *xc = execContexts[i]; 7573992Sgblack@eecs.umich.edu if (xc->status() == ExecContext::Active && _status != Running) { 7587741Sgblack@eecs.umich.edu _status = Running; 7593992Sgblack@eecs.umich.edu tickEvent.schedule(curTick); 7603992Sgblack@eecs.umich.edu } 7613992Sgblack@eecs.umich.edu } 7623997Ssaidi@eecs.umich.edu if (!tickEvent.scheduled()) 7634204Sgblack@eecs.umich.edu tickEvent.schedule(curTick); 7647741Sgblack@eecs.umich.edu} 7654204Sgblack@eecs.umich.edu 7664204Sgblack@eecs.umich.edutemplate <class Impl> 7674204Sgblack@eecs.umich.eduvoid 7684204Sgblack@eecs.umich.eduFullO3CPU<Impl>::serialize(std::ostream &os) 7694204Sgblack@eecs.umich.edu{ 7707741Sgblack@eecs.umich.edu BaseCPU::serialize(os); 7714204Sgblack@eecs.umich.edu nameOut(os, csprintf("%s.tickEvent", name())); 7724204Sgblack@eecs.umich.edu tickEvent.serialize(os); 7734204Sgblack@eecs.umich.edu 7744204Sgblack@eecs.umich.edu // Use SimpleThread's ability to checkpoint to make it easier to 7754204Sgblack@eecs.umich.edu // write out the registers. Also make this static so it doesn't 7764204Sgblack@eecs.umich.edu // get instantiated multiple times (causes a panic in statistics). 7777741Sgblack@eecs.umich.edu static CPUExecContext temp; 7784204Sgblack@eecs.umich.edu 7794204Sgblack@eecs.umich.edu for (int i = 0; i < thread.size(); i++) { 7804204Sgblack@eecs.umich.edu nameOut(os, csprintf("%s.xc.%i", name(), i)); 7814204Sgblack@eecs.umich.edu temp.copyXC(thread[i]->getXCProxy()); 7824204Sgblack@eecs.umich.edu temp.serialize(os); 7837741Sgblack@eecs.umich.edu } 7844204Sgblack@eecs.umich.edu} 7854204Sgblack@eecs.umich.edu 7864204Sgblack@eecs.umich.edutemplate <class Impl> 7874204Sgblack@eecs.umich.eduvoid 7884204Sgblack@eecs.umich.eduFullO3CPU<Impl>::unserialize(Checkpoint *cp, const std::string §ion) 7894204Sgblack@eecs.umich.edu{ 7907741Sgblack@eecs.umich.edu BaseCPU::unserialize(cp, section); 7914204Sgblack@eecs.umich.edu tickEvent.unserialize(cp, csprintf("%s.tickEvent", section)); 7924204Sgblack@eecs.umich.edu 7934204Sgblack@eecs.umich.edu // Use SimpleThread's ability to checkpoint to make it easier to 7944204Sgblack@eecs.umich.edu // read in the registers. Also make this static so it doesn't 7954204Sgblack@eecs.umich.edu // get instantiated multiple times (causes a panic in statistics). 7967741Sgblack@eecs.umich.edu static CPUExecContext temp; 7974204Sgblack@eecs.umich.edu 7984204Sgblack@eecs.umich.edu for (int i = 0; i < thread.size(); i++) { 7994204Sgblack@eecs.umich.edu temp.copyXC(thread[i]->getXCProxy()); 8004204Sgblack@eecs.umich.edu temp.unserialize(cp, csprintf("%s.xc.%i", section, i)); 8014204Sgblack@eecs.umich.edu thread[i]->getXCProxy()->copyArchRegs(temp.getProxy()); 8024204Sgblack@eecs.umich.edu } 8037741Sgblack@eecs.umich.edu} 8044204Sgblack@eecs.umich.edu 8054204Sgblack@eecs.umich.edutemplate <class Impl> 8064204Sgblack@eecs.umich.eduuint64_t 8074204Sgblack@eecs.umich.eduFullO3CPU<Impl>::readIntReg(int reg_idx) 8084204Sgblack@eecs.umich.edu{ 8097741Sgblack@eecs.umich.edu return regFile.readIntReg(reg_idx); 8104204Sgblack@eecs.umich.edu} 8114204Sgblack@eecs.umich.edu 8124204Sgblack@eecs.umich.edutemplate <class Impl> 8134204Sgblack@eecs.umich.edufloat 8144204Sgblack@eecs.umich.eduFullO3CPU<Impl>::readFloatRegSingle(int reg_idx) 8154204Sgblack@eecs.umich.edu{ 8167741Sgblack@eecs.umich.edu return regFile.readFloatRegSingle(reg_idx); 8174204Sgblack@eecs.umich.edu} 8184204Sgblack@eecs.umich.edu 8194204Sgblack@eecs.umich.edutemplate <class Impl> 8204204Sgblack@eecs.umich.edudouble 8214204Sgblack@eecs.umich.eduFullO3CPU<Impl>::readFloatRegDouble(int reg_idx) 8227741Sgblack@eecs.umich.edu{ 8234204Sgblack@eecs.umich.edu return regFile.readFloatRegDouble(reg_idx); 8244204Sgblack@eecs.umich.edu} 8254204Sgblack@eecs.umich.edu 8264204Sgblack@eecs.umich.edutemplate <class Impl> 8274204Sgblack@eecs.umich.eduuint64_t 8284204Sgblack@eecs.umich.eduFullO3CPU<Impl>::readFloatRegInt(int reg_idx) 8297741Sgblack@eecs.umich.edu{ 8304204Sgblack@eecs.umich.edu return regFile.readFloatRegInt(reg_idx); 8314204Sgblack@eecs.umich.edu} 8324204Sgblack@eecs.umich.edu 8334204Sgblack@eecs.umich.edutemplate <class Impl> 8344204Sgblack@eecs.umich.eduvoid 8357741Sgblack@eecs.umich.eduFullO3CPU<Impl>::setIntReg(int reg_idx, uint64_t val) 8364204Sgblack@eecs.umich.edu{ 8374204Sgblack@eecs.umich.edu regFile.setIntReg(reg_idx, val); 8384204Sgblack@eecs.umich.edu} 8394204Sgblack@eecs.umich.edu 8404204Sgblack@eecs.umich.edutemplate <class Impl> 8414204Sgblack@eecs.umich.eduvoid 8427741Sgblack@eecs.umich.eduFullO3CPU<Impl>::setFloatRegSingle(int reg_idx, float val) 8434204Sgblack@eecs.umich.edu{ 8444204Sgblack@eecs.umich.edu regFile.setFloatRegSingle(reg_idx, val); 8454204Sgblack@eecs.umich.edu} 8464204Sgblack@eecs.umich.edu 8474204Sgblack@eecs.umich.edutemplate <class Impl> 8487741Sgblack@eecs.umich.eduvoid 8494204Sgblack@eecs.umich.eduFullO3CPU<Impl>::setFloatRegDouble(int reg_idx, double val) 8504204Sgblack@eecs.umich.edu{ 8514204Sgblack@eecs.umich.edu regFile.setFloatRegDouble(reg_idx, val); 8524204Sgblack@eecs.umich.edu} 8534204Sgblack@eecs.umich.edu 8544204Sgblack@eecs.umich.edutemplate <class Impl> 8557741Sgblack@eecs.umich.eduvoid 8564204Sgblack@eecs.umich.eduFullO3CPU<Impl>::setFloatRegInt(int reg_idx, uint64_t val) 8574204Sgblack@eecs.umich.edu{ 8584204Sgblack@eecs.umich.edu regFile.setFloatRegInt(reg_idx, val); 8594204Sgblack@eecs.umich.edu} 8604204Sgblack@eecs.umich.edu 8617741Sgblack@eecs.umich.edutemplate <class Impl> 8624204Sgblack@eecs.umich.eduuint64_t 8634204Sgblack@eecs.umich.eduFullO3CPU<Impl>::readArchIntReg(int reg_idx, unsigned tid) 8644204Sgblack@eecs.umich.edu{ 8654204Sgblack@eecs.umich.edu PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx); 8664204Sgblack@eecs.umich.edu 8673992Sgblack@eecs.umich.edu return regFile.readIntReg(phys_reg); 8683992Sgblack@eecs.umich.edu} 8693992Sgblack@eecs.umich.edu 8707741Sgblack@eecs.umich.edutemplate <class Impl> 8717741Sgblack@eecs.umich.edufloat 8722954Sgblack@eecs.umich.eduFullO3CPU<Impl>::readArchFloatRegSingle(int reg_idx, unsigned tid) 8733941Ssaidi@eecs.umich.edu{ 8743941Ssaidi@eecs.umich.edu int idx = reg_idx + TheISA::FP_Base_DepTag; 8753941Ssaidi@eecs.umich.edu PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); 8763941Ssaidi@eecs.umich.edu 8773941Ssaidi@eecs.umich.edu return regFile.readFloatRegSingle(phys_reg); 8783941Ssaidi@eecs.umich.edu} 8793941Ssaidi@eecs.umich.edu 8803941Ssaidi@eecs.umich.edutemplate <class Impl> 8813941Ssaidi@eecs.umich.edudouble 8823941Ssaidi@eecs.umich.eduFullO3CPU<Impl>::readArchFloatRegDouble(int reg_idx, unsigned tid) 8833941Ssaidi@eecs.umich.edu{ 8843941Ssaidi@eecs.umich.edu int idx = reg_idx + TheISA::FP_Base_DepTag; 8853941Ssaidi@eecs.umich.edu PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); 8863941Ssaidi@eecs.umich.edu 8873941Ssaidi@eecs.umich.edu return regFile.readFloatRegDouble(phys_reg); 8883042Sgblack@eecs.umich.edu} 8892963Sgblack@eecs.umich.edu 8903042Sgblack@eecs.umich.edutemplate <class Impl> 8912963Sgblack@eecs.umich.eduuint64_t 8922963Sgblack@eecs.umich.eduFullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, unsigned tid) 8933941Ssaidi@eecs.umich.edu{ 8942963Sgblack@eecs.umich.edu int idx = reg_idx + TheISA::FP_Base_DepTag; 8952963Sgblack@eecs.umich.edu PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); 8963042Sgblack@eecs.umich.edu 8972963Sgblack@eecs.umich.edu return regFile.readFloatRegInt(phys_reg); 8982963Sgblack@eecs.umich.edu} 8993941Ssaidi@eecs.umich.edu 9003941Ssaidi@eecs.umich.edutemplate <class Impl> 9013941Ssaidi@eecs.umich.eduvoid 9023941Ssaidi@eecs.umich.eduFullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, unsigned tid) 9033941Ssaidi@eecs.umich.edu{ 9043941Ssaidi@eecs.umich.edu PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx); 9053941Ssaidi@eecs.umich.edu 9063941Ssaidi@eecs.umich.edu regFile.setIntReg(phys_reg, val); 9073941Ssaidi@eecs.umich.edu} 9083941Ssaidi@eecs.umich.edu 9093941Ssaidi@eecs.umich.edutemplate <class Impl> 9103941Ssaidi@eecs.umich.eduvoid 9113941Ssaidi@eecs.umich.eduFullO3CPU<Impl>::setArchFloatRegSingle(int reg_idx, float val, unsigned tid) 9123941Ssaidi@eecs.umich.edu{ 9133941Ssaidi@eecs.umich.edu int idx = reg_idx + TheISA::FP_Base_DepTag; 9142954Sgblack@eecs.umich.edu PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); 9152954Sgblack@eecs.umich.edu 9162954Sgblack@eecs.umich.edu regFile.setFloatRegSingle(phys_reg, val); 9172954Sgblack@eecs.umich.edu} 9182963Sgblack@eecs.umich.edu 9193057Sgblack@eecs.umich.edutemplate <class Impl> 9203057Sgblack@eecs.umich.eduvoid 9217741Sgblack@eecs.umich.eduFullO3CPU<Impl>::setArchFloatRegDouble(int reg_idx, double val, unsigned tid) 9227741Sgblack@eecs.umich.edu{ 9237741Sgblack@eecs.umich.edu int idx = reg_idx + TheISA::FP_Base_DepTag; 9247741Sgblack@eecs.umich.edu PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); 9257741Sgblack@eecs.umich.edu 9267741Sgblack@eecs.umich.edu regFile.setFloatRegDouble(phys_reg, val); 9277741Sgblack@eecs.umich.edu} 9287741Sgblack@eecs.umich.edu 9297741Sgblack@eecs.umich.edutemplate <class Impl> 9307741Sgblack@eecs.umich.eduvoid 9317741Sgblack@eecs.umich.eduFullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, unsigned tid) 9327741Sgblack@eecs.umich.edu{ 9337741Sgblack@eecs.umich.edu int idx = reg_idx + TheISA::FP_Base_DepTag; 9347741Sgblack@eecs.umich.edu PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); 9357741Sgblack@eecs.umich.edu 9367741Sgblack@eecs.umich.edu regFile.setFloatRegInt(phys_reg, val); 9377741Sgblack@eecs.umich.edu} 9387741Sgblack@eecs.umich.edu 9397741Sgblack@eecs.umich.edutemplate <class Impl> 9407741Sgblack@eecs.umich.eduuint64_t 9413057Sgblack@eecs.umich.eduFullO3CPU<Impl>::readPC(unsigned tid) 9422963Sgblack@eecs.umich.edu{ 9432954Sgblack@eecs.umich.edu return commit.readPC(tid); 9443941Ssaidi@eecs.umich.edu} 9453941Ssaidi@eecs.umich.edu 9463941Ssaidi@eecs.umich.edutemplate <class Impl> 9473941Ssaidi@eecs.umich.eduvoid 9483941Ssaidi@eecs.umich.eduFullO3CPU<Impl>::setPC(Addr new_PC,unsigned tid) 9493941Ssaidi@eecs.umich.edu{ 9503941Ssaidi@eecs.umich.edu commit.setPC(new_PC, tid); 9513941Ssaidi@eecs.umich.edu} 9523941Ssaidi@eecs.umich.edu 9533941Ssaidi@eecs.umich.edutemplate <class Impl> 9544008Ssaidi@eecs.umich.eduuint64_t 9554008Ssaidi@eecs.umich.eduFullO3CPU<Impl>::readNextPC(unsigned tid) 9563941Ssaidi@eecs.umich.edu{ 9573941Ssaidi@eecs.umich.edu return commit.readNextPC(tid); 9583941Ssaidi@eecs.umich.edu} 9593941Ssaidi@eecs.umich.edu 9604008Ssaidi@eecs.umich.edutemplate <class Impl> 9612963Sgblack@eecs.umich.eduvoid 9622963Sgblack@eecs.umich.eduFullO3CPU<Impl>::setNextPC(uint64_t val,unsigned tid) 9634008Ssaidi@eecs.umich.edu{ 9643279Sgblack@eecs.umich.edu commit.setNextPC(val, tid); 9652963Sgblack@eecs.umich.edu} 9663941Ssaidi@eecs.umich.edu 9673941Ssaidi@eecs.umich.edutemplate <class Impl> 9684008Ssaidi@eecs.umich.edutypename FullO3CPU<Impl>::ListIt 9692963Sgblack@eecs.umich.eduFullO3CPU<Impl>::addInst(DynInstPtr &inst) 9702963Sgblack@eecs.umich.edu{ 9714008Ssaidi@eecs.umich.edu instList.push_back(inst); 9723279Sgblack@eecs.umich.edu 9732963Sgblack@eecs.umich.edu return --(instList.end()); 9743941Ssaidi@eecs.umich.edu} 9753941Ssaidi@eecs.umich.edu 9763941Ssaidi@eecs.umich.edutemplate <class Impl> 9773941Ssaidi@eecs.umich.eduvoid 9783941Ssaidi@eecs.umich.eduFullO3CPU<Impl>::instDone(unsigned tid) 9793941Ssaidi@eecs.umich.edu{ 9803941Ssaidi@eecs.umich.edu // Keep an instruction count. 9813941Ssaidi@eecs.umich.edu thread[tid]->numInst++; 9824008Ssaidi@eecs.umich.edu thread[tid]->numInsts++; 9834008Ssaidi@eecs.umich.edu committedInsts[tid]++; 9843941Ssaidi@eecs.umich.edu totalCommittedInsts++; 9853941Ssaidi@eecs.umich.edu 9864008Ssaidi@eecs.umich.edu // Check for instruction-count-based events. 9874008Ssaidi@eecs.umich.edu comInstEventQueue[tid]->serviceEvents(thread[tid]->numInst); 9883941Ssaidi@eecs.umich.edu} 9893941Ssaidi@eecs.umich.edu 9903941Ssaidi@eecs.umich.edutemplate <class Impl> 9913941Ssaidi@eecs.umich.eduvoid 9924008Ssaidi@eecs.umich.eduFullO3CPU<Impl>::addToRemoveList(DynInstPtr &inst) 9934008Ssaidi@eecs.umich.edu{ 9942954Sgblack@eecs.umich.edu removeInstsThisCycle = true; 9953941Ssaidi@eecs.umich.edu 9962954Sgblack@eecs.umich.edu removeList.push(inst->getInstListIt()); 9974090Ssaidi@eecs.umich.edu} 9984090Ssaidi@eecs.umich.edu 9994096Sgblack@eecs.umich.edutemplate <class Impl> 10004113Sgblack@eecs.umich.eduvoid 10014113Sgblack@eecs.umich.eduFullO3CPU<Impl>::removeFrontInst(DynInstPtr &inst) 10024113Sgblack@eecs.umich.edu{ 10034113Sgblack@eecs.umich.edu DPRINTF(FullCPU, "FullCPU: Removing committed instruction [tid:%i] PC %#x " 10044113Sgblack@eecs.umich.edu "[sn:%lli]\n", 10054113Sgblack@eecs.umich.edu inst->threadNumber, inst->readPC(), inst->seqNum); 10064113Sgblack@eecs.umich.edu 10074113Sgblack@eecs.umich.edu removeInstsThisCycle = true; 10084113Sgblack@eecs.umich.edu 10094113Sgblack@eecs.umich.edu // Remove the front instruction. 10107720Sgblack@eecs.umich.edu removeList.push(inst->getInstListIt()); 10117720Sgblack@eecs.umich.edu} 10124113Sgblack@eecs.umich.edu 10134113Sgblack@eecs.umich.edutemplate <class Impl> 10144096Sgblack@eecs.umich.eduvoid 10154096Sgblack@eecs.umich.eduFullO3CPU<Impl>::removeInstsNotInROB(unsigned tid) 10164090Ssaidi@eecs.umich.edu{ 10172526SN/A DPRINTF(FullCPU, "FullCPU: Thread %i: Deleting instructions from instruction" 10182526SN/A " list.\n", tid); 10197741Sgblack@eecs.umich.edu 10202526SN/A ListIt end_it; 10217741Sgblack@eecs.umich.edu 10227720Sgblack@eecs.umich.edu bool rob_empty = false; 10233928Ssaidi@eecs.umich.edu 10247720Sgblack@eecs.umich.edu if (instList.empty()) { 10253928Ssaidi@eecs.umich.edu return; 10267720Sgblack@eecs.umich.edu } else if (rob.isEmpty(/*tid*/)) { 10277720Sgblack@eecs.umich.edu DPRINTF(FullCPU, "FullCPU: ROB is empty, squashing all insts.\n"); 10287720Sgblack@eecs.umich.edu end_it = instList.begin(); 10292526SN/A rob_empty = true; 10302526SN/A } else { 10312526SN/A end_it = (rob.readTailInst(tid))->getInstListIt(); 10322526SN/A DPRINTF(FullCPU, "FullCPU: ROB is not empty, squashing insts not in ROB.\n"); 10337741Sgblack@eecs.umich.edu } 10347741Sgblack@eecs.umich.edu 10357741Sgblack@eecs.umich.edu removeInstsThisCycle = true; 10367741Sgblack@eecs.umich.edu 10377741Sgblack@eecs.umich.edu ListIt inst_it = instList.end(); 10383909Ssaidi@eecs.umich.edu 10392561SN/A inst_it--; 10403909Ssaidi@eecs.umich.edu 10417741Sgblack@eecs.umich.edu // Walk through the instruction list, removing any instructions 10423765Sgblack@eecs.umich.edu // that were inserted after the given instruction iterator, end_it. 10437741Sgblack@eecs.umich.edu while (inst_it != end_it) { 10447720Sgblack@eecs.umich.edu assert(!instList.empty()); 10457720Sgblack@eecs.umich.edu 10467720Sgblack@eecs.umich.edu squashInstIt(inst_it, tid); 10473417Sgblack@eecs.umich.edu 10482561SN/A inst_it--; 10492561SN/A } 10502561SN/A 10512561SN/A // If the ROB was empty, then we actually need to remove the first 10522526SN/A // instruction as well. 10532526SN/A if (rob_empty) { 10542526SN/A squashInstIt(inst_it, tid); 10552526SN/A } 10567741Sgblack@eecs.umich.edu} 10572561SN/A 10582561SN/Atemplate <class Impl> 10593531Sgblack@eecs.umich.eduvoid 10602561SN/AFullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num, 10614828Sgblack@eecs.umich.edu unsigned tid) 10622526SN/A{ 10637741Sgblack@eecs.umich.edu assert(!instList.empty()); 10642561SN/A 10652561SN/A removeInstsThisCycle = true; 10663531Sgblack@eecs.umich.edu 10672526SN/A ListIt inst_iter = instList.end(); 10684828Sgblack@eecs.umich.edu 10692526SN/A inst_iter--; 10704090Ssaidi@eecs.umich.edu 10714090Ssaidi@eecs.umich.edu DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction " 10722526SN/A "list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n", 10737741Sgblack@eecs.umich.edu tid, seq_num, (*inst_iter)->seqNum); 10747741Sgblack@eecs.umich.edu 10753909Ssaidi@eecs.umich.edu while ((*inst_iter)->seqNum > seq_num) { 10762526SN/A 10773909Ssaidi@eecs.umich.edu bool break_loop = (inst_iter == instList.begin()); 10787741Sgblack@eecs.umich.edu 10792526SN/A squashInstIt(inst_iter, tid); 10807741Sgblack@eecs.umich.edu 10812526SN/A inst_iter--; 10823765Sgblack@eecs.umich.edu 10832561SN/A if (break_loop) 10842561SN/A break; 10852526SN/A } 10862526SN/A} 10872526SN/A 10887741Sgblack@eecs.umich.edutemplate <class Impl> 10897741Sgblack@eecs.umich.eduinline void 10903909Ssaidi@eecs.umich.eduFullO3CPU<Impl>::squashInstIt(const ListIt &instIt, const unsigned &tid) 10912526SN/A{ 10923909Ssaidi@eecs.umich.edu if ((*instIt)->threadNumber == tid) { 10937741Sgblack@eecs.umich.edu DPRINTF(FullCPU, "FullCPU: Squashing instruction, " 10943417Sgblack@eecs.umich.edu "[tid:%i] [sn:%lli] PC %#x\n", 10953765Sgblack@eecs.umich.edu (*instIt)->threadNumber, 10962561SN/A (*instIt)->seqNum, 10972561SN/A (*instIt)->readPC()); 10982526SN/A 10992526SN/A // Mark it as squashed. 11002526SN/A (*instIt)->setSquashed(); 11012526SN/A 11022646Ssaidi@eecs.umich.edu // @todo: Formulate a consistent method for deleting 11032646Ssaidi@eecs.umich.edu // instructions from the instruction list 11042646Ssaidi@eecs.umich.edu // Remove the instruction from the list. 11052646Ssaidi@eecs.umich.edu removeList.push(instIt); 11062646Ssaidi@eecs.umich.edu } 11073825Ssaidi@eecs.umich.edu} 11087720Sgblack@eecs.umich.edu 11097720Sgblack@eecs.umich.edutemplate <class Impl> 11107720Sgblack@eecs.umich.eduvoid 11117720Sgblack@eecs.umich.eduFullO3CPU<Impl>::cleanUpRemovedInsts() 11122526SN/A{ 11135094Sgblack@eecs.umich.edu while (!removeList.empty()) { 11142938Sgblack@eecs.umich.edu DPRINTF(FullCPU, "FullCPU: Removing instruction, " 11152646Ssaidi@eecs.umich.edu "[tid:%i] [sn:%lli] PC %#x\n", 11162646Ssaidi@eecs.umich.edu (*removeList.front())->threadNumber, 11172646Ssaidi@eecs.umich.edu (*removeList.front())->seqNum, 11182646Ssaidi@eecs.umich.edu (*removeList.front())->readPC()); 11192646Ssaidi@eecs.umich.edu 11203826Ssaidi@eecs.umich.edu instList.erase(removeList.front()); 11217720Sgblack@eecs.umich.edu 11227720Sgblack@eecs.umich.edu removeList.pop(); 11237720Sgblack@eecs.umich.edu } 11247720Sgblack@eecs.umich.edu 11252526SN/A removeInstsThisCycle = false; 11265094Sgblack@eecs.umich.edu} 11272526SN/A/* 11282526SN/Atemplate <class Impl> 11292469SN/Avoid 11302469SN/AFullO3CPU<Impl>::removeAllInsts() 11312526SN/A{ 11323272Sgblack@eecs.umich.edu instList.clear(); 11333272Sgblack@eecs.umich.edu} 11343272Sgblack@eecs.umich.edu*/ 11353835Sgblack@eecs.umich.edutemplate <class Impl> 11364115Ssaidi@eecs.umich.eduvoid 11374115Ssaidi@eecs.umich.eduFullO3CPU<Impl>::dumpInsts() 11383272Sgblack@eecs.umich.edu{ 11392526SN/A int num = 0; 11402526SN/A 11413272Sgblack@eecs.umich.edu ListIt inst_list_it = instList.begin(); 11423272Sgblack@eecs.umich.edu 11433272Sgblack@eecs.umich.edu cprintf("Dumping Instruction List\n"); 11444224Sgblack@eecs.umich.edu 11457741Sgblack@eecs.umich.edu while (inst_list_it != instList.end()) { 11467741Sgblack@eecs.umich.edu cprintf("Instruction:%i\nPC:%#x\n[tid:%i]\n[sn:%lli]\nIssued:%i\n" 11477741Sgblack@eecs.umich.edu "Squashed:%i\n\n", 11487741Sgblack@eecs.umich.edu num, (*inst_list_it)->readPC(), (*inst_list_it)->threadNumber, 11494256Sgblack@eecs.umich.edu (*inst_list_it)->seqNum, (*inst_list_it)->isIssued(), 11504256Sgblack@eecs.umich.edu (*inst_list_it)->isSquashed()); 11514256Sgblack@eecs.umich.edu inst_list_it++; 11524256Sgblack@eecs.umich.edu ++num; 11534224Sgblack@eecs.umich.edu } 11542526SN/A} 11552526SN/A/* 11563272Sgblack@eecs.umich.edutemplate <class Impl> 11573272Sgblack@eecs.umich.eduvoid 11583272Sgblack@eecs.umich.eduFullO3CPU<Impl>::wakeDependents(DynInstPtr &inst) 11593272Sgblack@eecs.umich.edu{ 11602526SN/A iew.wakeDependents(inst); 11614040Ssaidi@eecs.umich.edu} 11624040Ssaidi@eecs.umich.edu*/ 11634040Ssaidi@eecs.umich.edutemplate <class Impl> 11644040Ssaidi@eecs.umich.eduvoid 11654040Ssaidi@eecs.umich.eduFullO3CPU<Impl>::wakeCPU() 11663272Sgblack@eecs.umich.edu{ 11674040Ssaidi@eecs.umich.edu if (activityRec.active() || tickEvent.scheduled()) { 11684040Ssaidi@eecs.umich.edu DPRINTF(Activity, "CPU already running.\n"); 11694040Ssaidi@eecs.umich.edu return; 11704040Ssaidi@eecs.umich.edu } 11714040Ssaidi@eecs.umich.edu 11723810Sgblack@eecs.umich.edu DPRINTF(Activity, "Waking up CPU\n"); 11735096Sgblack@eecs.umich.edu 11745096Sgblack@eecs.umich.edu idleCycles += (curTick - 1) - lastRunningCycle; 11755096Sgblack@eecs.umich.edu 11763856Ssaidi@eecs.umich.edu tickEvent.schedule(curTick); 11777741Sgblack@eecs.umich.edu} 11783926Ssaidi@eecs.umich.edu 11794040Ssaidi@eecs.umich.edutemplate <class Impl> 11805096Sgblack@eecs.umich.eduint 11817741Sgblack@eecs.umich.eduFullO3CPU<Impl>::getFreeTid() 11823926Ssaidi@eecs.umich.edu{ 11834040Ssaidi@eecs.umich.edu for (int i=0; i < numThreads; i++) { 11845096Sgblack@eecs.umich.edu if (!tids[i]) { 11857741Sgblack@eecs.umich.edu tids[i] = true; 11863856Ssaidi@eecs.umich.edu return i; 11874040Ssaidi@eecs.umich.edu } 11885096Sgblack@eecs.umich.edu } 11897741Sgblack@eecs.umich.edu 11903856Ssaidi@eecs.umich.edu return -1; 11914040Ssaidi@eecs.umich.edu} 11925096Sgblack@eecs.umich.edu 11937741Sgblack@eecs.umich.edutemplate <class Impl> 11944040Ssaidi@eecs.umich.eduvoid 11954040Ssaidi@eecs.umich.eduFullO3CPU<Impl>::doContextSwitch() 11965096Sgblack@eecs.umich.edu{ 11977741Sgblack@eecs.umich.edu if (contextSwitch) { 11984040Ssaidi@eecs.umich.edu 11994040Ssaidi@eecs.umich.edu //ADD CODE TO DEACTIVE THREAD HERE (???) 12005096Sgblack@eecs.umich.edu 12017741Sgblack@eecs.umich.edu for (int tid=0; tid < cpuWaitList.size(); tid++) { 12024040Ssaidi@eecs.umich.edu activateWhenReady(tid); 12034040Ssaidi@eecs.umich.edu } 12045096Sgblack@eecs.umich.edu 12057741Sgblack@eecs.umich.edu if (cpuWaitList.size() == 0) 12064040Ssaidi@eecs.umich.edu contextSwitch = true; 12074040Ssaidi@eecs.umich.edu } 12085096Sgblack@eecs.umich.edu} 12097741Sgblack@eecs.umich.edu 12103856Ssaidi@eecs.umich.edutemplate <class Impl> 12114040Ssaidi@eecs.umich.eduvoid 12125096Sgblack@eecs.umich.eduFullO3CPU<Impl>::updateThreadPriority() 12137741Sgblack@eecs.umich.edu{ 12143856Ssaidi@eecs.umich.edu if (activeThreads.size() > 1) 12154040Ssaidi@eecs.umich.edu { 12165096Sgblack@eecs.umich.edu //DEFAULT TO ROUND ROBIN SCHEME 12177741Sgblack@eecs.umich.edu //e.g. Move highest priority to end of thread list 12183901Ssaidi@eecs.umich.edu list<unsigned>::iterator list_begin = activeThreads.begin(); 12194040Ssaidi@eecs.umich.edu list<unsigned>::iterator list_end = activeThreads.end(); 12205096Sgblack@eecs.umich.edu 12217741Sgblack@eecs.umich.edu unsigned high_thread = *list_begin; 12223926Ssaidi@eecs.umich.edu 12234040Ssaidi@eecs.umich.edu activeThreads.erase(list_begin); 12245096Sgblack@eecs.umich.edu 12257741Sgblack@eecs.umich.edu activeThreads.push_back(high_thread); 12264040Ssaidi@eecs.umich.edu } 12274040Ssaidi@eecs.umich.edu} 12285096Sgblack@eecs.umich.edu 12297741Sgblack@eecs.umich.edu// Forward declaration of FullO3CPU. 12304040Ssaidi@eecs.umich.edutemplate class FullO3CPU<AlphaSimpleImpl>; 12314040Ssaidi@eecs.umich.edu