cpu.cc revision 13500
12810Srdreslin@umich.edu/*
211375Sandreas.hansson@arm.com * Copyright (c) 2011-2012, 2014, 2016, 2017 ARM Limited
311051Sandreas.hansson@arm.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
411051Sandreas.hansson@arm.com * All rights reserved
511051Sandreas.hansson@arm.com *
611051Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
711051Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
811051Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
911051Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
1011051Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
1111051Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
1211051Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
1311051Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
1411051Sandreas.hansson@arm.com *
1511051Sandreas.hansson@arm.com * Copyright (c) 2004-2006 The Regents of The University of Michigan
162810Srdreslin@umich.edu * Copyright (c) 2011 Regents of the University of California
172810Srdreslin@umich.edu * All rights reserved.
182810Srdreslin@umich.edu *
192810Srdreslin@umich.edu * Redistribution and use in source and binary forms, with or without
202810Srdreslin@umich.edu * modification, are permitted provided that the following conditions are
212810Srdreslin@umich.edu * met: redistributions of source code must retain the above copyright
222810Srdreslin@umich.edu * notice, this list of conditions and the following disclaimer;
232810Srdreslin@umich.edu * redistributions in binary form must reproduce the above copyright
242810Srdreslin@umich.edu * notice, this list of conditions and the following disclaimer in the
252810Srdreslin@umich.edu * documentation and/or other materials provided with the distribution;
262810Srdreslin@umich.edu * neither the name of the copyright holders nor the names of its
272810Srdreslin@umich.edu * contributors may be used to endorse or promote products derived from
282810Srdreslin@umich.edu * this software without specific prior written permission.
292810Srdreslin@umich.edu *
302810Srdreslin@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
312810Srdreslin@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
322810Srdreslin@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
332810Srdreslin@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
342810Srdreslin@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
352810Srdreslin@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
362810Srdreslin@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
372810Srdreslin@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
382810Srdreslin@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
392810Srdreslin@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
402810Srdreslin@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
412810Srdreslin@umich.edu *
4211051Sandreas.hansson@arm.com * Authors: Kevin Lim
4311051Sandreas.hansson@arm.com *          Korey Sewell
442810Srdreslin@umich.edu *          Rick Strong
4511051Sandreas.hansson@arm.com */
4611051Sandreas.hansson@arm.com
472810Srdreslin@umich.edu#include "cpu/o3/cpu.hh"
482810Srdreslin@umich.edu
492810Srdreslin@umich.edu#include "arch/generic/traits.hh"
502810Srdreslin@umich.edu#include "arch/kernel_stats.hh"
5111051Sandreas.hansson@arm.com#include "config/the_isa.hh"
522810Srdreslin@umich.edu#include "cpu/activity.hh"
532810Srdreslin@umich.edu#include "cpu/checker/cpu.hh"
5411051Sandreas.hansson@arm.com#include "cpu/checker/thread_context.hh"
552810Srdreslin@umich.edu#include "cpu/o3/isa_specific.hh"
5611051Sandreas.hansson@arm.com#include "cpu/o3/thread_context.hh"
5711051Sandreas.hansson@arm.com#include "cpu/quiesce_event.hh"
5811051Sandreas.hansson@arm.com#include "cpu/simple_thread.hh"
5911051Sandreas.hansson@arm.com#include "cpu/thread_context.hh"
6011051Sandreas.hansson@arm.com#include "debug/Activity.hh"
6111288Ssteve.reinhardt@amd.com#include "debug/Drain.hh"
6211051Sandreas.hansson@arm.com#include "debug/O3CPU.hh"
6311051Sandreas.hansson@arm.com#include "debug/Quiesce.hh"
6411051Sandreas.hansson@arm.com#include "enums/MemoryMode.hh"
6511051Sandreas.hansson@arm.com#include "sim/core.hh"
6611051Sandreas.hansson@arm.com#include "sim/full_system.hh"
6711053Sandreas.hansson@arm.com#include "sim/process.hh"
6811053Sandreas.hansson@arm.com#include "sim/stat_control.hh"
6911051Sandreas.hansson@arm.com#include "sim/system.hh"
7011051Sandreas.hansson@arm.com
7111051Sandreas.hansson@arm.com#if THE_ISA == ALPHA_ISA
7211197Sandreas.hansson@arm.com#include "arch/alpha/osfpal.hh"
7311197Sandreas.hansson@arm.com#include "debug/Activity.hh"
7411199Sandreas.hansson@arm.com
7511197Sandreas.hansson@arm.com#endif
7612084Sspwilson2@wisc.edu
7712084Sspwilson2@wisc.edustruct BaseCPUParams;
7811197Sandreas.hansson@arm.com
7911051Sandreas.hansson@arm.comusing namespace TheISA;
8011051Sandreas.hansson@arm.comusing namespace std;
8111051Sandreas.hansson@arm.com
8211051Sandreas.hansson@arm.comBaseO3CPU::BaseO3CPU(BaseCPUParams *params)
8311051Sandreas.hansson@arm.com    : BaseCPU(params)
8411051Sandreas.hansson@arm.com{
8511051Sandreas.hansson@arm.com}
8611051Sandreas.hansson@arm.com
8711051Sandreas.hansson@arm.comvoid
8811051Sandreas.hansson@arm.comBaseO3CPU::regStats()
8911051Sandreas.hansson@arm.com{
9011051Sandreas.hansson@arm.com    BaseCPU::regStats();
9111051Sandreas.hansson@arm.com}
9211051Sandreas.hansson@arm.com
9311051Sandreas.hansson@arm.comtemplate<class Impl>
9411051Sandreas.hansson@arm.combool
9511051Sandreas.hansson@arm.comFullO3CPU<Impl>::IcachePort::recvTimingResp(PacketPtr pkt)
9611051Sandreas.hansson@arm.com{
9711051Sandreas.hansson@arm.com    DPRINTF(O3CPU, "Fetch unit received timing\n");
9811051Sandreas.hansson@arm.com    // We shouldn't ever get a cacheable block in Modified state
9911051Sandreas.hansson@arm.com    assert(pkt->req->isUncacheable() ||
10011051Sandreas.hansson@arm.com           !(pkt->cacheResponding() && !pkt->hasSharers()));
10111051Sandreas.hansson@arm.com    fetch->processCacheCompletion(pkt);
10211051Sandreas.hansson@arm.com
10311051Sandreas.hansson@arm.com    return true;
10411051Sandreas.hansson@arm.com}
10511051Sandreas.hansson@arm.com
10611051Sandreas.hansson@arm.comtemplate<class Impl>
10711051Sandreas.hansson@arm.comvoid
10811051Sandreas.hansson@arm.comFullO3CPU<Impl>::IcachePort::recvReqRetry()
10911051Sandreas.hansson@arm.com{
11011051Sandreas.hansson@arm.com    fetch->recvReqRetry();
11111051Sandreas.hansson@arm.com}
11211051Sandreas.hansson@arm.com
11311051Sandreas.hansson@arm.comtemplate <class Impl>
11411051Sandreas.hansson@arm.combool
11511051Sandreas.hansson@arm.comFullO3CPU<Impl>::DcachePort::recvTimingResp(PacketPtr pkt)
11611051Sandreas.hansson@arm.com{
11711051Sandreas.hansson@arm.com    return lsq->recvTimingResp(pkt);
11811051Sandreas.hansson@arm.com}
11911051Sandreas.hansson@arm.com
12011051Sandreas.hansson@arm.comtemplate <class Impl>
12111051Sandreas.hansson@arm.comvoid
12211051Sandreas.hansson@arm.comFullO3CPU<Impl>::DcachePort::recvTimingSnoopReq(PacketPtr pkt)
12311051Sandreas.hansson@arm.com{
12411051Sandreas.hansson@arm.com    for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
12511051Sandreas.hansson@arm.com        if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
12611051Sandreas.hansson@arm.com            cpu->wakeup(tid);
12711051Sandreas.hansson@arm.com        }
12811051Sandreas.hansson@arm.com    }
12911051Sandreas.hansson@arm.com    lsq->recvTimingSnoopReq(pkt);
13011051Sandreas.hansson@arm.com}
13111051Sandreas.hansson@arm.com
13211051Sandreas.hansson@arm.comtemplate <class Impl>
13311051Sandreas.hansson@arm.comvoid
13411051Sandreas.hansson@arm.comFullO3CPU<Impl>::DcachePort::recvReqRetry()
13511051Sandreas.hansson@arm.com{
13611051Sandreas.hansson@arm.com    lsq->recvReqRetry();
13711051Sandreas.hansson@arm.com}
13811051Sandreas.hansson@arm.com
13911051Sandreas.hansson@arm.comtemplate <class Impl>
14011051Sandreas.hansson@arm.comFullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
14111051Sandreas.hansson@arm.com    : BaseO3CPU(params),
14211051Sandreas.hansson@arm.com      itb(params->itb),
14311051Sandreas.hansson@arm.com      dtb(params->dtb),
14411051Sandreas.hansson@arm.com      tickEvent([this]{ tick(); }, "FullO3CPU tick",
14511051Sandreas.hansson@arm.com                false, Event::CPU_Tick_Pri),
14611051Sandreas.hansson@arm.com#ifndef NDEBUG
14711051Sandreas.hansson@arm.com      instcount(0),
14811051Sandreas.hansson@arm.com#endif
14911051Sandreas.hansson@arm.com      removeInstsThisCycle(false),
15011601Sandreas.hansson@arm.com      fetch(this, params),
15111601Sandreas.hansson@arm.com      decode(this, params),
15211051Sandreas.hansson@arm.com      rename(this, params),
15311051Sandreas.hansson@arm.com      iew(this, params),
15411051Sandreas.hansson@arm.com      commit(this, params),
15511051Sandreas.hansson@arm.com
15611051Sandreas.hansson@arm.com      /* It is mandatory that all SMT threads use the same renaming mode as
15711051Sandreas.hansson@arm.com       * they are sharing registers and rename */
15811051Sandreas.hansson@arm.com      vecMode(initRenameMode<TheISA::ISA>::mode(params->isa[0])),
15911051Sandreas.hansson@arm.com      regFile(params->numPhysIntRegs,
16011051Sandreas.hansson@arm.com              params->numPhysFloatRegs,
16111051Sandreas.hansson@arm.com              params->numPhysVecRegs,
16211284Sandreas.hansson@arm.com              params->numPhysCCRegs,
16311051Sandreas.hansson@arm.com              vecMode),
16411051Sandreas.hansson@arm.com
16511051Sandreas.hansson@arm.com      freeList(name() + ".freelist", &regFile),
16611051Sandreas.hansson@arm.com
16711051Sandreas.hansson@arm.com      rob(this, params),
16811051Sandreas.hansson@arm.com
16911051Sandreas.hansson@arm.com      scoreboard(name() + ".scoreboard",
17011284Sandreas.hansson@arm.com                 regFile.totalNumPhysRegs()),
17111284Sandreas.hansson@arm.com
17211284Sandreas.hansson@arm.com      isa(numThreads, NULL),
17311284Sandreas.hansson@arm.com
17411051Sandreas.hansson@arm.com      icachePort(&fetch, this),
17511284Sandreas.hansson@arm.com      dcachePort(&iew.ldstQueue, this),
17611051Sandreas.hansson@arm.com
17711051Sandreas.hansson@arm.com      timeBuffer(params->backComSize, params->forwardComSize),
17811051Sandreas.hansson@arm.com      fetchQueue(params->backComSize, params->forwardComSize),
17911284Sandreas.hansson@arm.com      decodeQueue(params->backComSize, params->forwardComSize),
18011284Sandreas.hansson@arm.com      renameQueue(params->backComSize, params->forwardComSize),
18111284Sandreas.hansson@arm.com      iewQueue(params->backComSize, params->forwardComSize),
18211284Sandreas.hansson@arm.com      activityRec(name(), NumStages,
18311051Sandreas.hansson@arm.com                  params->backComSize + params->forwardComSize,
18411744Snikos.nikoleris@arm.com                  params->activity),
18511051Sandreas.hansson@arm.com
18611051Sandreas.hansson@arm.com      globalSeqNum(1),
18711051Sandreas.hansson@arm.com      system(params->system),
18811051Sandreas.hansson@arm.com      lastRunningCycle(curCycle())
18911286Sandreas.hansson@arm.com{
19011286Sandreas.hansson@arm.com    if (!params->switched_out) {
19111286Sandreas.hansson@arm.com        _status = Running;
19211051Sandreas.hansson@arm.com    } else {
19311286Sandreas.hansson@arm.com        _status = SwitchedOut;
19411600Sandreas.hansson@arm.com    }
19511600Sandreas.hansson@arm.com
19611051Sandreas.hansson@arm.com    if (params->checker) {
19711051Sandreas.hansson@arm.com        BaseCPU *temp_checker = params->checker;
19811051Sandreas.hansson@arm.com        checker = dynamic_cast<Checker<Impl> *>(temp_checker);
19911284Sandreas.hansson@arm.com        checker->setIcachePort(&icachePort);
20011051Sandreas.hansson@arm.com        checker->setSystem(params->system);
20111051Sandreas.hansson@arm.com    } else {
20211051Sandreas.hansson@arm.com        checker = NULL;
20311602Sandreas.hansson@arm.com    }
20411051Sandreas.hansson@arm.com
20511051Sandreas.hansson@arm.com    if (!FullSystem) {
20611284Sandreas.hansson@arm.com        thread.resize(numThreads);
20711051Sandreas.hansson@arm.com        tids.resize(numThreads);
20811284Sandreas.hansson@arm.com    }
20911602Sandreas.hansson@arm.com
21011051Sandreas.hansson@arm.com    // The stages also need their CPU pointer setup.  However this
21111051Sandreas.hansson@arm.com    // must be done at the upper level CPU because they have pointers
21211284Sandreas.hansson@arm.com    // to the upper level CPU, and not this FullO3CPU.
21311051Sandreas.hansson@arm.com
21411284Sandreas.hansson@arm.com    // Set up Pointers to the activeThreads list for each stage
21511284Sandreas.hansson@arm.com    fetch.setActiveThreads(&activeThreads);
21611284Sandreas.hansson@arm.com    decode.setActiveThreads(&activeThreads);
21711051Sandreas.hansson@arm.com    rename.setActiveThreads(&activeThreads);
21811051Sandreas.hansson@arm.com    iew.setActiveThreads(&activeThreads);
21911051Sandreas.hansson@arm.com    commit.setActiveThreads(&activeThreads);
22011284Sandreas.hansson@arm.com
22111284Sandreas.hansson@arm.com    // Give each of the stages the time buffer they will use.
22211284Sandreas.hansson@arm.com    fetch.setTimeBuffer(&timeBuffer);
22311284Sandreas.hansson@arm.com    decode.setTimeBuffer(&timeBuffer);
22411051Sandreas.hansson@arm.com    rename.setTimeBuffer(&timeBuffer);
22511051Sandreas.hansson@arm.com    iew.setTimeBuffer(&timeBuffer);
22611051Sandreas.hansson@arm.com    commit.setTimeBuffer(&timeBuffer);
22711284Sandreas.hansson@arm.com
22811284Sandreas.hansson@arm.com    // Also setup each of the stages' queues.
22911284Sandreas.hansson@arm.com    fetch.setFetchQueue(&fetchQueue);
23011197Sandreas.hansson@arm.com    decode.setFetchQueue(&fetchQueue);
23111601Sandreas.hansson@arm.com    commit.setFetchQueue(&fetchQueue);
23211601Sandreas.hansson@arm.com    decode.setDecodeQueue(&decodeQueue);
23311601Sandreas.hansson@arm.com    rename.setDecodeQueue(&decodeQueue);
23411601Sandreas.hansson@arm.com    rename.setRenameQueue(&renameQueue);
23511601Sandreas.hansson@arm.com    iew.setRenameQueue(&renameQueue);
23611601Sandreas.hansson@arm.com    iew.setIEWQueue(&iewQueue);
23711601Sandreas.hansson@arm.com    commit.setIEWQueue(&iewQueue);
23811601Sandreas.hansson@arm.com    commit.setRenameQueue(&renameQueue);
23911197Sandreas.hansson@arm.com
24011601Sandreas.hansson@arm.com    commit.setIEWStage(&iew);
24111601Sandreas.hansson@arm.com    rename.setIEWStage(&iew);
24211601Sandreas.hansson@arm.com    rename.setCommitStage(&commit);
24311601Sandreas.hansson@arm.com
24411601Sandreas.hansson@arm.com    ThreadID active_threads;
24511601Sandreas.hansson@arm.com    if (FullSystem) {
24611601Sandreas.hansson@arm.com        active_threads = 1;
24711051Sandreas.hansson@arm.com    } else {
24811051Sandreas.hansson@arm.com        active_threads = params->workload.size();
24911051Sandreas.hansson@arm.com
25011051Sandreas.hansson@arm.com        if (active_threads > Impl::MaxThreads) {
25111051Sandreas.hansson@arm.com            panic("Workload Size too large. Increase the 'MaxThreads' "
25211284Sandreas.hansson@arm.com                  "constant in your O3CPU impl. file (e.g. o3/alpha/impl.hh) "
25311284Sandreas.hansson@arm.com                  "or edit your workload size.");
25411051Sandreas.hansson@arm.com        }
25511051Sandreas.hansson@arm.com    }
25611051Sandreas.hansson@arm.com
25711051Sandreas.hansson@arm.com    //Make Sure That this a Valid Architeture
25811284Sandreas.hansson@arm.com    assert(params->numPhysIntRegs   >= numThreads * TheISA::NumIntRegs);
25911051Sandreas.hansson@arm.com    assert(params->numPhysFloatRegs >= numThreads * TheISA::NumFloatRegs);
26011051Sandreas.hansson@arm.com    assert(params->numPhysVecRegs >= numThreads * TheISA::NumVecRegs);
26111602Sandreas.hansson@arm.com    assert(params->numPhysCCRegs >= numThreads * TheISA::NumCCRegs);
26211602Sandreas.hansson@arm.com
26311602Sandreas.hansson@arm.com    rename.setScoreboard(&scoreboard);
26411602Sandreas.hansson@arm.com    iew.setScoreboard(&scoreboard);
26511602Sandreas.hansson@arm.com
26611602Sandreas.hansson@arm.com    // Setup the rename map for whichever stages need it.
26711602Sandreas.hansson@arm.com    for (ThreadID tid = 0; tid < numThreads; tid++) {
26811602Sandreas.hansson@arm.com        isa[tid] = params->isa[tid];
26911602Sandreas.hansson@arm.com        assert(initRenameMode<TheISA::ISA>::equals(isa[tid], isa[0]));
27011602Sandreas.hansson@arm.com
27111602Sandreas.hansson@arm.com        // Only Alpha has an FP zero register, so for other ISAs we
27211051Sandreas.hansson@arm.com        // use an invalid FP register index to avoid special treatment
27311602Sandreas.hansson@arm.com        // of any valid FP reg.
27411197Sandreas.hansson@arm.com        RegIndex invalidFPReg = TheISA::NumFloatRegs + 1;
27511744Snikos.nikoleris@arm.com        RegIndex fpZeroReg =
27611744Snikos.nikoleris@arm.com            (THE_ISA == ALPHA_ISA) ? TheISA::ZeroReg : invalidFPReg;
27711051Sandreas.hansson@arm.com
27811051Sandreas.hansson@arm.com        commitRenameMap[tid].init(&regFile, TheISA::ZeroReg, fpZeroReg,
27911051Sandreas.hansson@arm.com                                  &freeList,
28011051Sandreas.hansson@arm.com                                  vecMode);
28111051Sandreas.hansson@arm.com
28211051Sandreas.hansson@arm.com        renameMap[tid].init(&regFile, TheISA::ZeroReg, fpZeroReg,
28311051Sandreas.hansson@arm.com                            &freeList, vecMode);
28411051Sandreas.hansson@arm.com    }
28511051Sandreas.hansson@arm.com
28611051Sandreas.hansson@arm.com    // Initialize rename map to assign physical registers to the
28711051Sandreas.hansson@arm.com    // architectural registers for active threads only.
28811051Sandreas.hansson@arm.com    for (ThreadID tid = 0; tid < active_threads; tid++) {
28911051Sandreas.hansson@arm.com        for (RegIndex ridx = 0; ridx < TheISA::NumIntRegs; ++ridx) {
29011051Sandreas.hansson@arm.com            // Note that we can't use the rename() method because we don't
29111051Sandreas.hansson@arm.com            // want special treatment for the zero register at this point
29211051Sandreas.hansson@arm.com            PhysRegIdPtr phys_reg = freeList.getIntReg();
29311051Sandreas.hansson@arm.com            renameMap[tid].setEntry(RegId(IntRegClass, ridx), phys_reg);
29411051Sandreas.hansson@arm.com            commitRenameMap[tid].setEntry(RegId(IntRegClass, ridx), phys_reg);
29511051Sandreas.hansson@arm.com        }
29611051Sandreas.hansson@arm.com
29711744Snikos.nikoleris@arm.com        for (RegIndex ridx = 0; ridx < TheISA::NumFloatRegs; ++ridx) {
29811051Sandreas.hansson@arm.com            PhysRegIdPtr phys_reg = freeList.getFloatReg();
29911051Sandreas.hansson@arm.com            renameMap[tid].setEntry(RegId(FloatRegClass, ridx), phys_reg);
30011744Snikos.nikoleris@arm.com            commitRenameMap[tid].setEntry(
30111051Sandreas.hansson@arm.com                    RegId(FloatRegClass, ridx), phys_reg);
30211051Sandreas.hansson@arm.com        }
30311051Sandreas.hansson@arm.com
30411051Sandreas.hansson@arm.com        /* Here we need two 'interfaces' the 'whole register' and the
30511199Sandreas.hansson@arm.com         * 'register element'. At any point only one of them will be
30611051Sandreas.hansson@arm.com         * active. */
30711051Sandreas.hansson@arm.com        if (vecMode == Enums::Full) {
30811051Sandreas.hansson@arm.com            /* Initialize the full-vector interface */
30911867Snikos.nikoleris@arm.com            for (RegIndex ridx = 0; ridx < TheISA::NumVecRegs; ++ridx) {
31011051Sandreas.hansson@arm.com                RegId rid = RegId(VecRegClass, ridx);
31111051Sandreas.hansson@arm.com                PhysRegIdPtr phys_reg = freeList.getVecReg();
31211484Snikos.nikoleris@arm.com                renameMap[tid].setEntry(rid, phys_reg);
31311051Sandreas.hansson@arm.com                commitRenameMap[tid].setEntry(rid, phys_reg);
31411051Sandreas.hansson@arm.com            }
31511051Sandreas.hansson@arm.com        } else {
31611051Sandreas.hansson@arm.com            /* Initialize the vector-element interface */
31711051Sandreas.hansson@arm.com            for (RegIndex ridx = 0; ridx < TheISA::NumVecRegs; ++ridx) {
31811051Sandreas.hansson@arm.com                for (ElemIndex ldx = 0; ldx < TheISA::NumVecElemPerVecReg;
31911051Sandreas.hansson@arm.com                        ++ldx) {
32011870Snikos.nikoleris@arm.com                    RegId lrid = RegId(VecElemClass, ridx, ldx);
32111051Sandreas.hansson@arm.com                    PhysRegIdPtr phys_elem = freeList.getVecElem();
32211744Snikos.nikoleris@arm.com                    renameMap[tid].setEntry(lrid, phys_elem);
32311051Sandreas.hansson@arm.com                    commitRenameMap[tid].setEntry(lrid, phys_elem);
32411051Sandreas.hansson@arm.com                }
32511051Sandreas.hansson@arm.com            }
32611199Sandreas.hansson@arm.com        }
32711051Sandreas.hansson@arm.com
32811051Sandreas.hansson@arm.com        for (RegIndex ridx = 0; ridx < TheISA::NumCCRegs; ++ridx) {
32911051Sandreas.hansson@arm.com            PhysRegIdPtr phys_reg = freeList.getCCReg();
33011051Sandreas.hansson@arm.com            renameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg);
33111051Sandreas.hansson@arm.com            commitRenameMap[tid].setEntry(RegId(CCRegClass, ridx), phys_reg);
33211051Sandreas.hansson@arm.com        }
33311051Sandreas.hansson@arm.com    }
33411051Sandreas.hansson@arm.com
33511375Sandreas.hansson@arm.com    rename.setRenameMap(renameMap);
33611375Sandreas.hansson@arm.com    commit.setRenameMap(commitRenameMap);
33711375Sandreas.hansson@arm.com    rename.setFreeList(&freeList);
33811199Sandreas.hansson@arm.com
33911199Sandreas.hansson@arm.com    // Setup the ROB for whichever stages need it.
34011199Sandreas.hansson@arm.com    commit.setROB(&rob);
34111199Sandreas.hansson@arm.com
34211199Sandreas.hansson@arm.com    lastActivatedCycle = 0;
34311199Sandreas.hansson@arm.com#if 0
34411199Sandreas.hansson@arm.com    // Give renameMap & rename stage access to the freeList;
34511199Sandreas.hansson@arm.com    for (ThreadID tid = 0; tid < numThreads; tid++)
34611199Sandreas.hansson@arm.com        globalSeqNum[tid] = 1;
34711199Sandreas.hansson@arm.com#endif
34811199Sandreas.hansson@arm.com
34911199Sandreas.hansson@arm.com    DPRINTF(O3CPU, "Creating O3CPU object.\n");
35011199Sandreas.hansson@arm.com
35111199Sandreas.hansson@arm.com    // Setup any thread state.
35211199Sandreas.hansson@arm.com    this->thread.resize(this->numThreads);
35311199Sandreas.hansson@arm.com
35411199Sandreas.hansson@arm.com    for (ThreadID tid = 0; tid < this->numThreads; ++tid) {
35511199Sandreas.hansson@arm.com        if (FullSystem) {
35611199Sandreas.hansson@arm.com            // SMT is not supported in FS mode yet.
35711199Sandreas.hansson@arm.com            assert(this->numThreads == 1);
35811375Sandreas.hansson@arm.com            this->thread[tid] = new Thread(this, 0, NULL);
35911199Sandreas.hansson@arm.com        } else {
36011199Sandreas.hansson@arm.com            if (tid < params->workload.size()) {
36111051Sandreas.hansson@arm.com                DPRINTF(O3CPU, "Workload[%i] process is %#x",
36211051Sandreas.hansson@arm.com                        tid, this->thread[tid]);
36311051Sandreas.hansson@arm.com                this->thread[tid] = new typename FullO3CPU<Impl>::Thread(
36411051Sandreas.hansson@arm.com                        (typename Impl::O3CPU *)(this),
36511051Sandreas.hansson@arm.com                        tid, params->workload[tid]);
36611199Sandreas.hansson@arm.com
36711051Sandreas.hansson@arm.com                //usedTids[tid] = true;
36811199Sandreas.hansson@arm.com                //threadMap[tid] = tid;
36911199Sandreas.hansson@arm.com            } else {
37011199Sandreas.hansson@arm.com                //Allocate Empty thread so M5 can use later
37111199Sandreas.hansson@arm.com                //when scheduling threads to CPU
37211199Sandreas.hansson@arm.com                Process* dummy_proc = NULL;
37311199Sandreas.hansson@arm.com
37411199Sandreas.hansson@arm.com                this->thread[tid] = new typename FullO3CPU<Impl>::Thread(
37511199Sandreas.hansson@arm.com                        (typename Impl::O3CPU *)(this),
37611199Sandreas.hansson@arm.com                        tid, dummy_proc);
37711199Sandreas.hansson@arm.com                //usedTids[tid] = false;
37811199Sandreas.hansson@arm.com            }
37911199Sandreas.hansson@arm.com        }
38011484Snikos.nikoleris@arm.com
38111051Sandreas.hansson@arm.com        ThreadContext *tc;
38211051Sandreas.hansson@arm.com
38311484Snikos.nikoleris@arm.com        // Setup the TC that will serve as the interface to the threads/CPU.
38411051Sandreas.hansson@arm.com        O3ThreadContext<Impl> *o3_tc = new O3ThreadContext<Impl>;
38511051Sandreas.hansson@arm.com
38611051Sandreas.hansson@arm.com        tc = o3_tc;
38711051Sandreas.hansson@arm.com
38811051Sandreas.hansson@arm.com        // If we're using a checker, then the TC should be the
38911051Sandreas.hansson@arm.com        // CheckerThreadContext.
39011051Sandreas.hansson@arm.com        if (params->checker) {
39111051Sandreas.hansson@arm.com            tc = new CheckerThreadContext<O3ThreadContext<Impl> >(
39211051Sandreas.hansson@arm.com                o3_tc, this->checker);
39311051Sandreas.hansson@arm.com        }
39411051Sandreas.hansson@arm.com
39511199Sandreas.hansson@arm.com        o3_tc->cpu = (typename Impl::O3CPU *)(this);
39611199Sandreas.hansson@arm.com        assert(o3_tc->cpu);
39711199Sandreas.hansson@arm.com        o3_tc->thread = this->thread[tid];
39811199Sandreas.hansson@arm.com
39911199Sandreas.hansson@arm.com        // Setup quiesce event.
40011284Sandreas.hansson@arm.com        this->thread[tid]->quiesceEvent = new EndQuiesceEvent(tc);
40111284Sandreas.hansson@arm.com
40211284Sandreas.hansson@arm.com        // Give the thread the TC.
40311284Sandreas.hansson@arm.com        this->thread[tid]->tc = tc;
40411051Sandreas.hansson@arm.com
40511051Sandreas.hansson@arm.com        // Add the TC to the CPU's list of TC's.
40611051Sandreas.hansson@arm.com        this->threadContexts.push_back(tc);
40711051Sandreas.hansson@arm.com    }
40811051Sandreas.hansson@arm.com
40911051Sandreas.hansson@arm.com    // FullO3CPU always requires an interrupt controller.
41011051Sandreas.hansson@arm.com    if (!params->switched_out && interrupts.empty()) {
41111051Sandreas.hansson@arm.com        fatal("FullO3CPU %s has no interrupt controller.\n"
41211051Sandreas.hansson@arm.com              "Ensure createInterruptController() is called.\n", name());
41311484Snikos.nikoleris@arm.com    }
41411051Sandreas.hansson@arm.com
41511051Sandreas.hansson@arm.com    for (ThreadID tid = 0; tid < this->numThreads; tid++)
41611051Sandreas.hansson@arm.com        this->thread[tid]->setFuncExeInst(0);
41711051Sandreas.hansson@arm.com}
41811051Sandreas.hansson@arm.com
41911051Sandreas.hansson@arm.comtemplate <class Impl>
42011051Sandreas.hansson@arm.comFullO3CPU<Impl>::~FullO3CPU()
42111051Sandreas.hansson@arm.com{
42211051Sandreas.hansson@arm.com}
42311051Sandreas.hansson@arm.com
42411051Sandreas.hansson@arm.comtemplate <class Impl>
42511601Sandreas.hansson@arm.comvoid
42611601Sandreas.hansson@arm.comFullO3CPU<Impl>::regProbePoints()
42711051Sandreas.hansson@arm.com{
42811051Sandreas.hansson@arm.com    BaseCPU::regProbePoints();
42911601Sandreas.hansson@arm.com
43011601Sandreas.hansson@arm.com    ppInstAccessComplete = new ProbePointArg<PacketPtr>(getProbeManager(), "InstAccessComplete");
43111601Sandreas.hansson@arm.com    ppDataAccessComplete = new ProbePointArg<std::pair<DynInstPtr, PacketPtr> >(getProbeManager(), "DataAccessComplete");
43211051Sandreas.hansson@arm.com
43311051Sandreas.hansson@arm.com    fetch.regProbePoints();
43411051Sandreas.hansson@arm.com    rename.regProbePoints();
43511484Snikos.nikoleris@arm.com    iew.regProbePoints();
43611284Sandreas.hansson@arm.com    commit.regProbePoints();
43711051Sandreas.hansson@arm.com}
43811051Sandreas.hansson@arm.com
43911051Sandreas.hansson@arm.comtemplate <class Impl>
44011484Snikos.nikoleris@arm.comvoid
44111051Sandreas.hansson@arm.comFullO3CPU<Impl>::regStats()
44211051Sandreas.hansson@arm.com{
44311051Sandreas.hansson@arm.com    BaseO3CPU::regStats();
44411051Sandreas.hansson@arm.com
44511051Sandreas.hansson@arm.com    // Register any of the O3CPU's stats here.
44611051Sandreas.hansson@arm.com    timesIdled
44711051Sandreas.hansson@arm.com        .name(name() + ".timesIdled")
44811051Sandreas.hansson@arm.com        .desc("Number of times that the entire CPU went into an idle state and"
44911051Sandreas.hansson@arm.com              " unscheduled itself")
45011601Sandreas.hansson@arm.com        .prereq(timesIdled);
45111601Sandreas.hansson@arm.com
45211601Sandreas.hansson@arm.com    idleCycles
45311601Sandreas.hansson@arm.com        .name(name() + ".idleCycles")
45411601Sandreas.hansson@arm.com        .desc("Total number of cycles that the CPU has spent unscheduled due "
45511601Sandreas.hansson@arm.com              "to idling")
45611601Sandreas.hansson@arm.com        .prereq(idleCycles);
45711601Sandreas.hansson@arm.com
45811601Sandreas.hansson@arm.com    quiesceCycles
45911601Sandreas.hansson@arm.com        .name(name() + ".quiesceCycles")
46011601Sandreas.hansson@arm.com        .desc("Total number of cycles that CPU has spent quiesced or waiting "
46111601Sandreas.hansson@arm.com              "for an interrupt")
46211051Sandreas.hansson@arm.com        .prereq(quiesceCycles);
46311051Sandreas.hansson@arm.com
46411051Sandreas.hansson@arm.com    // Number of Instructions simulated
46511051Sandreas.hansson@arm.com    // --------------------------------
46611051Sandreas.hansson@arm.com    // Should probably be in Base CPU but need templated
46711051Sandreas.hansson@arm.com    // MaxThreads so put in here instead
46811051Sandreas.hansson@arm.com    committedInsts
46911051Sandreas.hansson@arm.com        .init(numThreads)
47011051Sandreas.hansson@arm.com        .name(name() + ".committedInsts")
47111051Sandreas.hansson@arm.com        .desc("Number of Instructions Simulated")
47211051Sandreas.hansson@arm.com        .flags(Stats::total);
47311051Sandreas.hansson@arm.com
47411051Sandreas.hansson@arm.com    committedOps
47511051Sandreas.hansson@arm.com        .init(numThreads)
47611051Sandreas.hansson@arm.com        .name(name() + ".committedOps")
47711199Sandreas.hansson@arm.com        .desc("Number of Ops (including micro ops) Simulated")
47811199Sandreas.hansson@arm.com        .flags(Stats::total);
47911199Sandreas.hansson@arm.com
48011199Sandreas.hansson@arm.com    cpi
48111199Sandreas.hansson@arm.com        .name(name() + ".cpi")
48211051Sandreas.hansson@arm.com        .desc("CPI: Cycles Per Instruction")
48311199Sandreas.hansson@arm.com        .precision(6);
48411051Sandreas.hansson@arm.com    cpi = numCycles / committedInsts;
48511051Sandreas.hansson@arm.com
48611051Sandreas.hansson@arm.com    totalCpi
48711051Sandreas.hansson@arm.com        .name(name() + ".cpi_total")
48811051Sandreas.hansson@arm.com        .desc("CPI: Total CPI of All Threads")
48911051Sandreas.hansson@arm.com        .precision(6);
49011051Sandreas.hansson@arm.com    totalCpi = numCycles / sum(committedInsts);
49111051Sandreas.hansson@arm.com
49211051Sandreas.hansson@arm.com    ipc
49311051Sandreas.hansson@arm.com        .name(name() + ".ipc")
49411051Sandreas.hansson@arm.com        .desc("IPC: Instructions Per Cycle")
49511051Sandreas.hansson@arm.com        .precision(6);
49611051Sandreas.hansson@arm.com    ipc =  committedInsts / numCycles;
49711051Sandreas.hansson@arm.com
49811051Sandreas.hansson@arm.com    totalIpc
49911051Sandreas.hansson@arm.com        .name(name() + ".ipc_total")
50011051Sandreas.hansson@arm.com        .desc("IPC: Total IPC of All Threads")
50111130Sali.jafri@arm.com        .precision(6);
50211130Sali.jafri@arm.com    totalIpc =  sum(committedInsts) / numCycles;
50311130Sali.jafri@arm.com
50411130Sali.jafri@arm.com    this->fetch.regStats();
50511130Sali.jafri@arm.com    this->decode.regStats();
50611130Sali.jafri@arm.com    this->rename.regStats();
50711130Sali.jafri@arm.com    this->iew.regStats();
50811130Sali.jafri@arm.com    this->commit.regStats();
50911130Sali.jafri@arm.com    this->rob.regStats();
51011199Sandreas.hansson@arm.com
51111130Sali.jafri@arm.com    intRegfileReads
51211130Sali.jafri@arm.com        .name(name() + ".int_regfile_reads")
51311130Sali.jafri@arm.com        .desc("number of integer regfile reads")
51411130Sali.jafri@arm.com        .prereq(intRegfileReads);
51511130Sali.jafri@arm.com
51611130Sali.jafri@arm.com    intRegfileWrites
51711130Sali.jafri@arm.com        .name(name() + ".int_regfile_writes")
51811130Sali.jafri@arm.com        .desc("number of integer regfile writes")
51911130Sali.jafri@arm.com        .prereq(intRegfileWrites);
52011130Sali.jafri@arm.com
52111130Sali.jafri@arm.com    fpRegfileReads
52211130Sali.jafri@arm.com        .name(name() + ".fp_regfile_reads")
52311130Sali.jafri@arm.com        .desc("number of floating regfile reads")
52411130Sali.jafri@arm.com        .prereq(fpRegfileReads);
52511130Sali.jafri@arm.com
52611130Sali.jafri@arm.com    fpRegfileWrites
52711130Sali.jafri@arm.com        .name(name() + ".fp_regfile_writes")
52811130Sali.jafri@arm.com        .desc("number of floating regfile writes")
52911130Sali.jafri@arm.com        .prereq(fpRegfileWrites);
53011130Sali.jafri@arm.com
53111130Sali.jafri@arm.com    vecRegfileReads
53211130Sali.jafri@arm.com        .name(name() + ".vec_regfile_reads")
53311130Sali.jafri@arm.com        .desc("number of vector regfile reads")
53411051Sandreas.hansson@arm.com        .prereq(vecRegfileReads);
53511051Sandreas.hansson@arm.com
53611051Sandreas.hansson@arm.com    vecRegfileWrites
53711051Sandreas.hansson@arm.com        .name(name() + ".vec_regfile_writes")
53811744Snikos.nikoleris@arm.com        .desc("number of vector regfile writes")
53911051Sandreas.hansson@arm.com        .prereq(vecRegfileWrites);
54011051Sandreas.hansson@arm.com
54111051Sandreas.hansson@arm.com    ccRegfileReads
54211051Sandreas.hansson@arm.com        .name(name() + ".cc_regfile_reads")
54311276Sandreas.hansson@arm.com        .desc("number of cc regfile reads")
54411276Sandreas.hansson@arm.com        .prereq(ccRegfileReads);
54511276Sandreas.hansson@arm.com
54611276Sandreas.hansson@arm.com    ccRegfileWrites
54711276Sandreas.hansson@arm.com        .name(name() + ".cc_regfile_writes")
54811276Sandreas.hansson@arm.com        .desc("number of cc regfile writes")
54911276Sandreas.hansson@arm.com        .prereq(ccRegfileWrites);
55011276Sandreas.hansson@arm.com
55111276Sandreas.hansson@arm.com    miscRegfileReads
55211051Sandreas.hansson@arm.com        .name(name() + ".misc_regfile_reads")
55311276Sandreas.hansson@arm.com        .desc("number of misc regfile reads")
55411276Sandreas.hansson@arm.com        .prereq(miscRegfileReads);
55511276Sandreas.hansson@arm.com
55611276Sandreas.hansson@arm.com    miscRegfileWrites
55711276Sandreas.hansson@arm.com        .name(name() + ".misc_regfile_writes")
55811051Sandreas.hansson@arm.com        .desc("number of misc regfile writes")
55911051Sandreas.hansson@arm.com        .prereq(miscRegfileWrites);
56011051Sandreas.hansson@arm.com}
56111051Sandreas.hansson@arm.com
56211051Sandreas.hansson@arm.comtemplate <class Impl>
56311051Sandreas.hansson@arm.comvoid
56411051Sandreas.hansson@arm.comFullO3CPU<Impl>::tick()
56511051Sandreas.hansson@arm.com{
56611051Sandreas.hansson@arm.com    DPRINTF(O3CPU, "\n\nFullO3CPU: Ticking main, FullO3CPU.\n");
56711051Sandreas.hansson@arm.com    assert(!switchedOut());
56811051Sandreas.hansson@arm.com    assert(drainState() != DrainState::Drained);
56911051Sandreas.hansson@arm.com
57011051Sandreas.hansson@arm.com    ++numCycles;
57111051Sandreas.hansson@arm.com    updateCycleCounters(BaseCPU::CPU_STATE_ON);
57211051Sandreas.hansson@arm.com
57311051Sandreas.hansson@arm.com//    activity = false;
57411051Sandreas.hansson@arm.com
57511051Sandreas.hansson@arm.com    //Tick each of the stages
57611051Sandreas.hansson@arm.com    fetch.tick();
57711051Sandreas.hansson@arm.com
57811051Sandreas.hansson@arm.com    decode.tick();
57911051Sandreas.hansson@arm.com
58011051Sandreas.hansson@arm.com    rename.tick();
58111051Sandreas.hansson@arm.com
58211051Sandreas.hansson@arm.com    iew.tick();
58311051Sandreas.hansson@arm.com
58411051Sandreas.hansson@arm.com    commit.tick();
58511051Sandreas.hansson@arm.com
58611830Sbaz21@cam.ac.uk    // Now advance the time buffers
58711051Sandreas.hansson@arm.com    timeBuffer.advance();
58811051Sandreas.hansson@arm.com
58911051Sandreas.hansson@arm.com    fetchQueue.advance();
59011051Sandreas.hansson@arm.com    decodeQueue.advance();
59111051Sandreas.hansson@arm.com    renameQueue.advance();
59211051Sandreas.hansson@arm.com    iewQueue.advance();
59311051Sandreas.hansson@arm.com
59411051Sandreas.hansson@arm.com    activityRec.advance();
59511051Sandreas.hansson@arm.com
59611051Sandreas.hansson@arm.com    if (removeInstsThisCycle) {
59711051Sandreas.hansson@arm.com        cleanUpRemovedInsts();
59811051Sandreas.hansson@arm.com    }
59911051Sandreas.hansson@arm.com
60011284Sandreas.hansson@arm.com    if (!tickEvent.scheduled()) {
60111051Sandreas.hansson@arm.com        if (_status == SwitchedOut) {
60211284Sandreas.hansson@arm.com            DPRINTF(O3CPU, "Switched out!\n");
60311284Sandreas.hansson@arm.com            // increment stat
60411744Snikos.nikoleris@arm.com            lastRunningCycle = curCycle();
60511744Snikos.nikoleris@arm.com        } else if (!activityRec.active() || _status == Idle) {
60611051Sandreas.hansson@arm.com            DPRINTF(O3CPU, "Idle!\n");
60711284Sandreas.hansson@arm.com            lastRunningCycle = curCycle();
60811284Sandreas.hansson@arm.com            timesIdled++;
60911284Sandreas.hansson@arm.com        } else {
61011284Sandreas.hansson@arm.com            schedule(tickEvent, clockEdge(Cycles(1)));
61111284Sandreas.hansson@arm.com            DPRINTF(O3CPU, "Scheduling next tick!\n");
61211334Sandreas.hansson@arm.com        }
61311284Sandreas.hansson@arm.com    }
61411334Sandreas.hansson@arm.com
61511334Sandreas.hansson@arm.com    if (!FullSystem)
61611334Sandreas.hansson@arm.com        updateThreadPriority();
61711334Sandreas.hansson@arm.com
61811284Sandreas.hansson@arm.com    tryDrain();
61911334Sandreas.hansson@arm.com}
62011334Sandreas.hansson@arm.com
62111334Sandreas.hansson@arm.comtemplate <class Impl>
62211334Sandreas.hansson@arm.comvoid
62311334Sandreas.hansson@arm.comFullO3CPU<Impl>::init()
62411334Sandreas.hansson@arm.com{
62511051Sandreas.hansson@arm.com    BaseCPU::init();
62611334Sandreas.hansson@arm.com
62711334Sandreas.hansson@arm.com    for (ThreadID tid = 0; tid < numThreads; ++tid) {
62811334Sandreas.hansson@arm.com        // Set noSquashFromTC so that the CPU doesn't squash when initially
62911334Sandreas.hansson@arm.com        // setting up registers.
63011051Sandreas.hansson@arm.com        thread[tid]->noSquashFromTC = true;
63111334Sandreas.hansson@arm.com        // Initialise the ThreadContext's memory proxies
63211334Sandreas.hansson@arm.com        thread[tid]->initMemProxies(thread[tid]->getTC());
63311334Sandreas.hansson@arm.com    }
63411051Sandreas.hansson@arm.com
63511334Sandreas.hansson@arm.com    if (FullSystem && !params()->switched_out) {
63611334Sandreas.hansson@arm.com        for (ThreadID tid = 0; tid < numThreads; tid++) {
63711334Sandreas.hansson@arm.com            ThreadContext *src_tc = threadContexts[tid];
63811334Sandreas.hansson@arm.com            TheISA::initCPU(src_tc, src_tc->contextId());
63911334Sandreas.hansson@arm.com        }
64011334Sandreas.hansson@arm.com    }
64111334Sandreas.hansson@arm.com
64211051Sandreas.hansson@arm.com    // Clear noSquashFromTC.
64311334Sandreas.hansson@arm.com    for (int tid = 0; tid < numThreads; ++tid)
64411334Sandreas.hansson@arm.com        thread[tid]->noSquashFromTC = false;
64511334Sandreas.hansson@arm.com
64611334Sandreas.hansson@arm.com    commit.setThreads(thread);
64711334Sandreas.hansson@arm.com}
64811334Sandreas.hansson@arm.com
64911334Sandreas.hansson@arm.comtemplate <class Impl>
65011334Sandreas.hansson@arm.comvoid
65111051Sandreas.hansson@arm.comFullO3CPU<Impl>::startup()
65211284Sandreas.hansson@arm.com{
65311284Sandreas.hansson@arm.com    BaseCPU::startup();
65411190Sandreas.hansson@arm.com    for (int tid = 0; tid < numThreads; ++tid)
65511051Sandreas.hansson@arm.com        isa[tid]->startup(threadContexts[tid]);
65611334Sandreas.hansson@arm.com
65711334Sandreas.hansson@arm.com    fetch.startupStage();
65811334Sandreas.hansson@arm.com    decode.startupStage();
65911334Sandreas.hansson@arm.com    iew.startupStage();
66011334Sandreas.hansson@arm.com    rename.startupStage();
66111051Sandreas.hansson@arm.com    commit.startupStage();
66211051Sandreas.hansson@arm.com}
66311051Sandreas.hansson@arm.com
66411051Sandreas.hansson@arm.comtemplate <class Impl>
66511051Sandreas.hansson@arm.comvoid
66611051Sandreas.hansson@arm.comFullO3CPU<Impl>::activateThread(ThreadID tid)
66711051Sandreas.hansson@arm.com{
66811051Sandreas.hansson@arm.com    list<ThreadID>::iterator isActive =
66911051Sandreas.hansson@arm.com        std::find(activeThreads.begin(), activeThreads.end(), tid);
67011051Sandreas.hansson@arm.com
67111484Snikos.nikoleris@arm.com    DPRINTF(O3CPU, "[tid:%i]: Calling activate thread.\n", tid);
67211051Sandreas.hansson@arm.com    assert(!switchedOut());
67311051Sandreas.hansson@arm.com
67411051Sandreas.hansson@arm.com    if (isActive == activeThreads.end()) {
67511051Sandreas.hansson@arm.com        DPRINTF(O3CPU, "[tid:%i]: Adding to active threads list\n",
67611051Sandreas.hansson@arm.com                tid);
67711051Sandreas.hansson@arm.com
67811051Sandreas.hansson@arm.com        activeThreads.push_back(tid);
67911051Sandreas.hansson@arm.com    }
68011051Sandreas.hansson@arm.com}
68111051Sandreas.hansson@arm.com
68211051Sandreas.hansson@arm.comtemplate <class Impl>
68311051Sandreas.hansson@arm.comvoid
68411051Sandreas.hansson@arm.comFullO3CPU<Impl>::deactivateThread(ThreadID tid)
68511051Sandreas.hansson@arm.com{
68611051Sandreas.hansson@arm.com    //Remove From Active List, if Active
68711051Sandreas.hansson@arm.com    list<ThreadID>::iterator thread_it =
68811051Sandreas.hansson@arm.com        std::find(activeThreads.begin(), activeThreads.end(), tid);
68911051Sandreas.hansson@arm.com
69011051Sandreas.hansson@arm.com    DPRINTF(O3CPU, "[tid:%i]: Calling deactivate thread.\n", tid);
69111051Sandreas.hansson@arm.com    assert(!switchedOut());
69211051Sandreas.hansson@arm.com
69311051Sandreas.hansson@arm.com    if (thread_it != activeThreads.end()) {
69411051Sandreas.hansson@arm.com        DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
69511051Sandreas.hansson@arm.com                tid);
69611051Sandreas.hansson@arm.com        activeThreads.erase(thread_it);
69711051Sandreas.hansson@arm.com    }
69811051Sandreas.hansson@arm.com
69911051Sandreas.hansson@arm.com    fetch.deactivateThread(tid);
70011051Sandreas.hansson@arm.com    commit.deactivateThread(tid);
70111051Sandreas.hansson@arm.com}
70211051Sandreas.hansson@arm.com
70311051Sandreas.hansson@arm.comtemplate <class Impl>
70411051Sandreas.hansson@arm.comCounter
70511051Sandreas.hansson@arm.comFullO3CPU<Impl>::totalInsts() const
70611051Sandreas.hansson@arm.com{
70711483Snikos.nikoleris@arm.com    Counter total(0);
70811483Snikos.nikoleris@arm.com
70911051Sandreas.hansson@arm.com    ThreadID size = thread.size();
71011051Sandreas.hansson@arm.com    for (ThreadID i = 0; i < size; i++)
71111051Sandreas.hansson@arm.com        total += thread[i]->numInst;
71211051Sandreas.hansson@arm.com
71311051Sandreas.hansson@arm.com    return total;
71411051Sandreas.hansson@arm.com}
71511051Sandreas.hansson@arm.com
71611051Sandreas.hansson@arm.comtemplate <class Impl>
71711051Sandreas.hansson@arm.comCounter
71811051Sandreas.hansson@arm.comFullO3CPU<Impl>::totalOps() const
71911051Sandreas.hansson@arm.com{
72011051Sandreas.hansson@arm.com    Counter total(0);
72111051Sandreas.hansson@arm.com
72211051Sandreas.hansson@arm.com    ThreadID size = thread.size();
72311051Sandreas.hansson@arm.com    for (ThreadID i = 0; i < size; i++)
72411051Sandreas.hansson@arm.com        total += thread[i]->numOp;
72511051Sandreas.hansson@arm.com
72611051Sandreas.hansson@arm.com    return total;
72711194Sali.jafri@arm.com}
72811051Sandreas.hansson@arm.com
72911744Snikos.nikoleris@arm.comtemplate <class Impl>
73011744Snikos.nikoleris@arm.comvoid
73111199Sandreas.hansson@arm.comFullO3CPU<Impl>::activateContext(ThreadID tid)
73211190Sandreas.hansson@arm.com{
73311190Sandreas.hansson@arm.com    assert(!switchedOut());
73411190Sandreas.hansson@arm.com
73511190Sandreas.hansson@arm.com    // Needs to set each stage to running as well.
73611190Sandreas.hansson@arm.com    activateThread(tid);
73711051Sandreas.hansson@arm.com
73811051Sandreas.hansson@arm.com    // We don't want to wake the CPU if it is drained. In that case,
73911051Sandreas.hansson@arm.com    // we just want to flag the thread as active and schedule the tick
74011051Sandreas.hansson@arm.com    // event from drainResume() instead.
74111892Snikos.nikoleris@arm.com    if (drainState() == DrainState::Drained)
74211051Sandreas.hansson@arm.com        return;
74311051Sandreas.hansson@arm.com
74411051Sandreas.hansson@arm.com    // If we are time 0 or if the last activation time is in the past,
74511051Sandreas.hansson@arm.com    // schedule the next tick and wake up the fetch unit
74611051Sandreas.hansson@arm.com    if (lastActivatedCycle == 0 || lastActivatedCycle < curTick()) {
74711051Sandreas.hansson@arm.com        scheduleTickEvent(Cycles(0));
74811051Sandreas.hansson@arm.com
74911051Sandreas.hansson@arm.com        // Be sure to signal that there's some activity so the CPU doesn't
75011051Sandreas.hansson@arm.com        // deschedule itself.
75111051Sandreas.hansson@arm.com        activityRec.activity();
75211051Sandreas.hansson@arm.com        fetch.wakeFromQuiesce();
75311051Sandreas.hansson@arm.com
75411051Sandreas.hansson@arm.com        Cycles cycles(curCycle() - lastRunningCycle);
75511051Sandreas.hansson@arm.com        // @todo: This is an oddity that is only here to match the stats
75611051Sandreas.hansson@arm.com        if (cycles != 0)
75711051Sandreas.hansson@arm.com            --cycles;
75811051Sandreas.hansson@arm.com        quiesceCycles += cycles;
75911051Sandreas.hansson@arm.com
76011051Sandreas.hansson@arm.com        lastActivatedCycle = curTick();
76111051Sandreas.hansson@arm.com
76211051Sandreas.hansson@arm.com        _status = Running;
76311051Sandreas.hansson@arm.com
76411051Sandreas.hansson@arm.com        BaseCPU::activateContext(tid);
76511051Sandreas.hansson@arm.com    }
76611051Sandreas.hansson@arm.com}
76711051Sandreas.hansson@arm.com
76811051Sandreas.hansson@arm.comtemplate <class Impl>
76911051Sandreas.hansson@arm.comvoid
77011051Sandreas.hansson@arm.comFullO3CPU<Impl>::suspendContext(ThreadID tid)
77111051Sandreas.hansson@arm.com{
77211051Sandreas.hansson@arm.com    DPRINTF(O3CPU,"[tid: %i]: Suspending Thread Context.\n", tid);
77311051Sandreas.hansson@arm.com    assert(!switchedOut());
77411051Sandreas.hansson@arm.com
77511051Sandreas.hansson@arm.com    deactivateThread(tid);
77611051Sandreas.hansson@arm.com
77711051Sandreas.hansson@arm.com    // If this was the last thread then unschedule the tick event.
77811051Sandreas.hansson@arm.com    if (activeThreads.size() == 0) {
77911051Sandreas.hansson@arm.com        unscheduleTickEvent();
78011051Sandreas.hansson@arm.com        lastRunningCycle = curCycle();
78111286Sandreas.hansson@arm.com        _status = Idle;
78211051Sandreas.hansson@arm.com    }
78311051Sandreas.hansson@arm.com
78411194Sali.jafri@arm.com    DPRINTF(Quiesce, "Suspending Context\n");
78511051Sandreas.hansson@arm.com
78611051Sandreas.hansson@arm.com    BaseCPU::suspendContext(tid);
78711051Sandreas.hansson@arm.com}
78811051Sandreas.hansson@arm.com
78911051Sandreas.hansson@arm.comtemplate <class Impl>
79011051Sandreas.hansson@arm.comvoid
79111051Sandreas.hansson@arm.comFullO3CPU<Impl>::haltContext(ThreadID tid)
79211051Sandreas.hansson@arm.com{
79311051Sandreas.hansson@arm.com    //For now, this is the same as deallocate
79411051Sandreas.hansson@arm.com    DPRINTF(O3CPU,"[tid:%i]: Halt Context called. Deallocating", tid);
79511051Sandreas.hansson@arm.com    assert(!switchedOut());
79611051Sandreas.hansson@arm.com
79711051Sandreas.hansson@arm.com    deactivateThread(tid);
79811051Sandreas.hansson@arm.com    removeThread(tid);
79911051Sandreas.hansson@arm.com
80011199Sandreas.hansson@arm.com    updateCycleCounters(BaseCPU::CPU_STATE_SLEEP);
80111199Sandreas.hansson@arm.com}
80211199Sandreas.hansson@arm.com
80311051Sandreas.hansson@arm.comtemplate <class Impl>
80411190Sandreas.hansson@arm.comvoid
80511051Sandreas.hansson@arm.comFullO3CPU<Impl>::insertThread(ThreadID tid)
80611744Snikos.nikoleris@arm.com{
80711744Snikos.nikoleris@arm.com    DPRINTF(O3CPU,"[tid:%i] Initializing thread into CPU");
80811051Sandreas.hansson@arm.com    // Will change now that the PC and thread state is internal to the CPU
80911051Sandreas.hansson@arm.com    // and not in the ThreadContext.
81011051Sandreas.hansson@arm.com    ThreadContext *src_tc;
81111051Sandreas.hansson@arm.com    if (FullSystem)
81211051Sandreas.hansson@arm.com        src_tc = system->threadContexts[tid];
81311051Sandreas.hansson@arm.com    else
81411051Sandreas.hansson@arm.com        src_tc = tcBase(tid);
81511051Sandreas.hansson@arm.com
81611051Sandreas.hansson@arm.com    //Bind Int Regs to Rename Map
81711051Sandreas.hansson@arm.com
81811197Sandreas.hansson@arm.com    for (RegId reg_id(IntRegClass, 0); reg_id.index() < TheISA::NumIntRegs;
81911197Sandreas.hansson@arm.com         reg_id.index()++) {
82011051Sandreas.hansson@arm.com        PhysRegIdPtr phys_reg = freeList.getIntReg();
82111051Sandreas.hansson@arm.com        renameMap[tid].setEntry(reg_id, phys_reg);
82211051Sandreas.hansson@arm.com        scoreboard.setReg(phys_reg);
82311051Sandreas.hansson@arm.com    }
82411051Sandreas.hansson@arm.com
82511051Sandreas.hansson@arm.com    //Bind Float Regs to Rename Map
82611051Sandreas.hansson@arm.com    for (RegId reg_id(FloatRegClass, 0); reg_id.index() < TheISA::NumFloatRegs;
82711051Sandreas.hansson@arm.com         reg_id.index()++) {
82811051Sandreas.hansson@arm.com        PhysRegIdPtr phys_reg = freeList.getFloatReg();
82911051Sandreas.hansson@arm.com        renameMap[tid].setEntry(reg_id, phys_reg);
83011483Snikos.nikoleris@arm.com        scoreboard.setReg(phys_reg);
83111483Snikos.nikoleris@arm.com    }
83211051Sandreas.hansson@arm.com
83311051Sandreas.hansson@arm.com    //Bind condition-code Regs to Rename Map
83411483Snikos.nikoleris@arm.com    for (RegId reg_id(CCRegClass, 0); reg_id.index() < TheISA::NumCCRegs;
83511483Snikos.nikoleris@arm.com         reg_id.index()++) {
83611051Sandreas.hansson@arm.com        PhysRegIdPtr phys_reg = freeList.getCCReg();
83711051Sandreas.hansson@arm.com        renameMap[tid].setEntry(reg_id, phys_reg);
83811051Sandreas.hansson@arm.com        scoreboard.setReg(phys_reg);
83911051Sandreas.hansson@arm.com    }
84011051Sandreas.hansson@arm.com
84111051Sandreas.hansson@arm.com    //Copy Thread Data Into RegFile
84211051Sandreas.hansson@arm.com    //this->copyFromTC(tid);
84311051Sandreas.hansson@arm.com
84411051Sandreas.hansson@arm.com    //Set PC/NPC/NNPC
84511051Sandreas.hansson@arm.com    pcState(src_tc->pcState(), tid);
84611051Sandreas.hansson@arm.com
84711051Sandreas.hansson@arm.com    src_tc->setStatus(ThreadContext::Active);
84811051Sandreas.hansson@arm.com
84911051Sandreas.hansson@arm.com    activateContext(tid);
85011051Sandreas.hansson@arm.com
85111199Sandreas.hansson@arm.com    //Reset ROB/IQ/LSQ Entries
85211051Sandreas.hansson@arm.com    commit.rob->resetEntries();
85311051Sandreas.hansson@arm.com    iew.resetEntries();
85411051Sandreas.hansson@arm.com}
85511051Sandreas.hansson@arm.com
85611051Sandreas.hansson@arm.comtemplate <class Impl>
85711051Sandreas.hansson@arm.comvoid
85811051Sandreas.hansson@arm.comFullO3CPU<Impl>::removeThread(ThreadID tid)
85911051Sandreas.hansson@arm.com{
86011051Sandreas.hansson@arm.com    DPRINTF(O3CPU,"[tid:%i] Removing thread context from CPU.\n", tid);
86111051Sandreas.hansson@arm.com
86211051Sandreas.hansson@arm.com    // Copy Thread Data From RegFile
86311051Sandreas.hansson@arm.com    // If thread is suspended, it might be re-allocated
86411051Sandreas.hansson@arm.com    // this->copyToTC(tid);
86511051Sandreas.hansson@arm.com
86611051Sandreas.hansson@arm.com
86711051Sandreas.hansson@arm.com    // @todo: 2-27-2008: Fix how we free up rename mappings
86811051Sandreas.hansson@arm.com    // here to alleviate the case for double-freeing registers
86911051Sandreas.hansson@arm.com    // in SMT workloads.
87011051Sandreas.hansson@arm.com
87111051Sandreas.hansson@arm.com    // Unbind Int Regs from Rename Map
87211051Sandreas.hansson@arm.com    for (RegId reg_id(IntRegClass, 0); reg_id.index() < TheISA::NumIntRegs;
87311051Sandreas.hansson@arm.com         reg_id.index()++) {
87411051Sandreas.hansson@arm.com        PhysRegIdPtr phys_reg = renameMap[tid].lookup(reg_id);
87511051Sandreas.hansson@arm.com        scoreboard.unsetReg(phys_reg);
87611284Sandreas.hansson@arm.com        freeList.addReg(phys_reg);
87711051Sandreas.hansson@arm.com    }
87811051Sandreas.hansson@arm.com
87911051Sandreas.hansson@arm.com    // Unbind Float Regs from Rename Map
88011051Sandreas.hansson@arm.com    for (RegId reg_id(FloatRegClass, 0); reg_id.index() < TheISA::NumFloatRegs;
88111051Sandreas.hansson@arm.com         reg_id.index()++) {
88211051Sandreas.hansson@arm.com        PhysRegIdPtr phys_reg = renameMap[tid].lookup(reg_id);
88311051Sandreas.hansson@arm.com        scoreboard.unsetReg(phys_reg);
88411051Sandreas.hansson@arm.com        freeList.addReg(phys_reg);
88511051Sandreas.hansson@arm.com    }
88611051Sandreas.hansson@arm.com
88711051Sandreas.hansson@arm.com    // Unbind condition-code Regs from Rename Map
88811051Sandreas.hansson@arm.com    for (RegId reg_id(CCRegClass, 0); reg_id.index() < TheISA::NumCCRegs;
88911051Sandreas.hansson@arm.com         reg_id.index()++) {
89011051Sandreas.hansson@arm.com        PhysRegIdPtr phys_reg = renameMap[tid].lookup(reg_id);
89111051Sandreas.hansson@arm.com        scoreboard.unsetReg(phys_reg);
89211051Sandreas.hansson@arm.com        freeList.addReg(phys_reg);
89311051Sandreas.hansson@arm.com    }
89411051Sandreas.hansson@arm.com
89511051Sandreas.hansson@arm.com    // Squash Throughout Pipeline
89611051Sandreas.hansson@arm.com    DynInstPtr inst = commit.rob->readHeadInst(tid);
89711051Sandreas.hansson@arm.com    InstSeqNum squash_seq_num = inst->seqNum;
89811051Sandreas.hansson@arm.com    fetch.squash(0, squash_seq_num, inst, tid);
89911051Sandreas.hansson@arm.com    decode.squash(tid);
90011051Sandreas.hansson@arm.com    rename.squash(squash_seq_num, tid);
90111452Sandreas.hansson@arm.com    iew.squash(tid);
90211452Sandreas.hansson@arm.com    iew.ldstQueue.squash(squash_seq_num, tid);
90311051Sandreas.hansson@arm.com    commit.rob->squash(squash_seq_num, tid);
90411452Sandreas.hansson@arm.com
90511452Sandreas.hansson@arm.com
90611452Sandreas.hansson@arm.com    assert(iew.instQueue.getCount(tid) == 0);
90711051Sandreas.hansson@arm.com    assert(iew.ldstQueue.getCount(tid) == 0);
90811051Sandreas.hansson@arm.com
90911452Sandreas.hansson@arm.com    // Reset ROB/IQ/LSQ Entries
91011745Sandreas.hansson@arm.com
91111745Sandreas.hansson@arm.com    // Commented out for now.  This should be possible to do by
91211452Sandreas.hansson@arm.com    // telling all the pipeline stages to drain first, and then
91311452Sandreas.hansson@arm.com    // checking until the drain completes.  Once the pipeline is
91411452Sandreas.hansson@arm.com    // drained, call resetEntries(). - 10-09-06 ktlim
91511051Sandreas.hansson@arm.com/*
91611051Sandreas.hansson@arm.com    if (activeThreads.size() >= 1) {
91711051Sandreas.hansson@arm.com        commit.rob->resetEntries();
91811051Sandreas.hansson@arm.com        iew.resetEntries();
91911051Sandreas.hansson@arm.com    }
92011051Sandreas.hansson@arm.com*/
92111051Sandreas.hansson@arm.com}
92211051Sandreas.hansson@arm.com
92311051Sandreas.hansson@arm.comtemplate <class Impl>
92411051Sandreas.hansson@arm.comFault
92511747Snikos.nikoleris@arm.comFullO3CPU<Impl>::hwrei(ThreadID tid)
92611747Snikos.nikoleris@arm.com{
92711747Snikos.nikoleris@arm.com#if THE_ISA == ALPHA_ISA
92811747Snikos.nikoleris@arm.com    // Need to clear the lock flag upon returning from an interrupt.
92911747Snikos.nikoleris@arm.com    this->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG, false, tid);
93011747Snikos.nikoleris@arm.com
93111747Snikos.nikoleris@arm.com    this->thread[tid]->kernelStats->hwrei();
93211284Sandreas.hansson@arm.com
93311284Sandreas.hansson@arm.com    // FIXME: XXX check for interrupts? XXX
93411284Sandreas.hansson@arm.com#endif
93511051Sandreas.hansson@arm.com    return NoFault;
93611051Sandreas.hansson@arm.com}
93711051Sandreas.hansson@arm.com
93811051Sandreas.hansson@arm.comtemplate <class Impl>
93911051Sandreas.hansson@arm.combool
94011051Sandreas.hansson@arm.comFullO3CPU<Impl>::simPalCheck(int palFunc, ThreadID tid)
94111051Sandreas.hansson@arm.com{
94211051Sandreas.hansson@arm.com#if THE_ISA == ALPHA_ISA
94311051Sandreas.hansson@arm.com    if (this->thread[tid]->kernelStats)
94411051Sandreas.hansson@arm.com        this->thread[tid]->kernelStats->callpal(palFunc,
94511051Sandreas.hansson@arm.com                                                this->threadContexts[tid]);
94611284Sandreas.hansson@arm.com
94711051Sandreas.hansson@arm.com    switch (palFunc) {
94811051Sandreas.hansson@arm.com      case PAL::halt:
94911051Sandreas.hansson@arm.com        halt();
95011051Sandreas.hansson@arm.com        if (--System::numSystemsRunning == 0)
95111284Sandreas.hansson@arm.com            exitSimLoop("all cpus halted");
95211284Sandreas.hansson@arm.com        break;
95311284Sandreas.hansson@arm.com
95411602Sandreas.hansson@arm.com      case PAL::bpt:
95511051Sandreas.hansson@arm.com      case PAL::bugchk:
95611051Sandreas.hansson@arm.com        if (this->system->breakpoint())
95711051Sandreas.hansson@arm.com            return false;
95811284Sandreas.hansson@arm.com        break;
95911284Sandreas.hansson@arm.com    }
96011744Snikos.nikoleris@arm.com#endif
96111744Snikos.nikoleris@arm.com    return true;
96211051Sandreas.hansson@arm.com}
96311051Sandreas.hansson@arm.com
96411051Sandreas.hansson@arm.comtemplate <class Impl>
96511892Snikos.nikoleris@arm.comFault
96611051Sandreas.hansson@arm.comFullO3CPU<Impl>::getInterrupts()
96711051Sandreas.hansson@arm.com{
96811744Snikos.nikoleris@arm.com    // Check if there are any outstanding interrupts
96911744Snikos.nikoleris@arm.com    return this->interrupts[0]->getInterrupt(this->threadContexts[0]);
97011051Sandreas.hansson@arm.com}
97111051Sandreas.hansson@arm.com
97211051Sandreas.hansson@arm.comtemplate <class Impl>
97311051Sandreas.hansson@arm.comvoid
97411051Sandreas.hansson@arm.comFullO3CPU<Impl>::processInterrupts(const Fault &interrupt)
97511051Sandreas.hansson@arm.com{
97611051Sandreas.hansson@arm.com    // Check for interrupts here.  For now can copy the code that
97711051Sandreas.hansson@arm.com    // exists within isa_fullsys_traits.hh.  Also assume that thread 0
97811051Sandreas.hansson@arm.com    // is the one that handles the interrupts.
97911051Sandreas.hansson@arm.com    // @todo: Possibly consolidate the interrupt checking code.
98011051Sandreas.hansson@arm.com    // @todo: Allow other threads to handle interrupts.
98111051Sandreas.hansson@arm.com
98211051Sandreas.hansson@arm.com    assert(interrupt != NoFault);
98311051Sandreas.hansson@arm.com    this->interrupts[0]->updateIntrInfo(this->threadContexts[0]);
98411051Sandreas.hansson@arm.com
98511051Sandreas.hansson@arm.com    DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name());
98611333Sandreas.hansson@arm.com    this->trap(interrupt, 0, nullptr);
98711333Sandreas.hansson@arm.com}
98811284Sandreas.hansson@arm.com
98911744Snikos.nikoleris@arm.comtemplate <class Impl>
99011744Snikos.nikoleris@arm.comvoid
99111333Sandreas.hansson@arm.comFullO3CPU<Impl>::trap(const Fault &fault, ThreadID tid,
99211333Sandreas.hansson@arm.com                      const StaticInstPtr &inst)
99311333Sandreas.hansson@arm.com{
99411333Sandreas.hansson@arm.com    // Pass the thread's TC into the invoke method.
99511334Sandreas.hansson@arm.com    fault->invoke(this->threadContexts[tid], inst);
99611334Sandreas.hansson@arm.com}
99711051Sandreas.hansson@arm.com
99811051Sandreas.hansson@arm.comtemplate <class Impl>
99911051Sandreas.hansson@arm.comvoid
100011051Sandreas.hansson@arm.comFullO3CPU<Impl>::syscall(int64_t callnum, ThreadID tid, Fault *fault)
100111051Sandreas.hansson@arm.com{
100211051Sandreas.hansson@arm.com    DPRINTF(O3CPU, "[tid:%i] Executing syscall().\n\n", tid);
100311051Sandreas.hansson@arm.com
100411051Sandreas.hansson@arm.com    DPRINTF(Activity,"Activity: syscall() called.\n");
100511484Snikos.nikoleris@arm.com
100611051Sandreas.hansson@arm.com    // Temporarily increase this by one to account for the syscall
100711051Sandreas.hansson@arm.com    // instruction.
100811051Sandreas.hansson@arm.com    ++(this->thread[tid]->funcExeInst);
100911051Sandreas.hansson@arm.com
101011051Sandreas.hansson@arm.com    // Execute the actual syscall.
101111130Sali.jafri@arm.com    this->thread[tid]->syscall(callnum, fault);
101211051Sandreas.hansson@arm.com
101311051Sandreas.hansson@arm.com    // Decrease funcExeInst by one as the normal commit will handle
101411051Sandreas.hansson@arm.com    // incrementing it.
101511051Sandreas.hansson@arm.com    --(this->thread[tid]->funcExeInst);
101611452Sandreas.hansson@arm.com}
101711452Sandreas.hansson@arm.com
101811452Sandreas.hansson@arm.comtemplate <class Impl>
101911452Sandreas.hansson@arm.comvoid
102011452Sandreas.hansson@arm.comFullO3CPU<Impl>::serializeThread(CheckpointOut &cp, ThreadID tid) const
102111452Sandreas.hansson@arm.com{
102211452Sandreas.hansson@arm.com    thread[tid]->serialize(cp);
102311452Sandreas.hansson@arm.com}
102411452Sandreas.hansson@arm.com
102511452Sandreas.hansson@arm.comtemplate <class Impl>
102611051Sandreas.hansson@arm.comvoid
102711484Snikos.nikoleris@arm.comFullO3CPU<Impl>::unserializeThread(CheckpointIn &cp, ThreadID tid)
102811051Sandreas.hansson@arm.com{
102911051Sandreas.hansson@arm.com    thread[tid]->unserialize(cp);
103011051Sandreas.hansson@arm.com}
103111051Sandreas.hansson@arm.com
103211051Sandreas.hansson@arm.comtemplate <class Impl>
103311051Sandreas.hansson@arm.comDrainState
103411051Sandreas.hansson@arm.comFullO3CPU<Impl>::drain()
103511744Snikos.nikoleris@arm.com{
103611744Snikos.nikoleris@arm.com    // Deschedule any power gating event (if any)
103711051Sandreas.hansson@arm.com    deschedulePowerGatingEvent();
103811051Sandreas.hansson@arm.com
103911051Sandreas.hansson@arm.com    // If the CPU isn't doing anything, then return immediately.
104011051Sandreas.hansson@arm.com    if (switchedOut())
104111051Sandreas.hansson@arm.com        return DrainState::Drained;
104211051Sandreas.hansson@arm.com
104311051Sandreas.hansson@arm.com    DPRINTF(Drain, "Draining...\n");
104411452Sandreas.hansson@arm.com
104511452Sandreas.hansson@arm.com    // We only need to signal a drain to the commit stage as this
104611051Sandreas.hansson@arm.com    // initiates squashing controls the draining. Once the commit
104711744Snikos.nikoleris@arm.com    // stage commits an instruction where it is safe to stop, it'll
104811744Snikos.nikoleris@arm.com    // squash the rest of the instructions in the pipeline and force
104911051Sandreas.hansson@arm.com    // the fetch stage to stall. The pipeline will be drained once all
105011051Sandreas.hansson@arm.com    // in-flight instructions have retired.
105111051Sandreas.hansson@arm.com    commit.drain();
105211051Sandreas.hansson@arm.com
105311051Sandreas.hansson@arm.com    // Wake the CPU and record activity so everything can drain out if
105411051Sandreas.hansson@arm.com    // the CPU was not able to immediately drain.
105511051Sandreas.hansson@arm.com    if (!isDrained())  {
105611051Sandreas.hansson@arm.com        // If a thread is suspended, wake it up so it can be drained
105711051Sandreas.hansson@arm.com        for (auto t : threadContexts) {
105811051Sandreas.hansson@arm.com            if (t->status() == ThreadContext::Suspended){
105911051Sandreas.hansson@arm.com                DPRINTF(Drain, "Currently suspended so activate %i \n",
106011051Sandreas.hansson@arm.com                        t->threadId());
106111051Sandreas.hansson@arm.com                t->activate();
106211051Sandreas.hansson@arm.com                // As the thread is now active, change the power state as well
106311051Sandreas.hansson@arm.com                activateContext(t->threadId());
106411051Sandreas.hansson@arm.com            }
106511197Sandreas.hansson@arm.com        }
106611197Sandreas.hansson@arm.com
106711452Sandreas.hansson@arm.com        wakeCPU();
106811452Sandreas.hansson@arm.com        activityRec.activity();
106911601Sandreas.hansson@arm.com
107011051Sandreas.hansson@arm.com        DPRINTF(Drain, "CPU not drained\n");
107111051Sandreas.hansson@arm.com
107211051Sandreas.hansson@arm.com        return DrainState::Draining;
107311051Sandreas.hansson@arm.com    } else {
107411197Sandreas.hansson@arm.com        DPRINTF(Drain, "CPU is already drained\n");
107511197Sandreas.hansson@arm.com        if (tickEvent.scheduled())
107611601Sandreas.hansson@arm.com            deschedule(tickEvent);
107711601Sandreas.hansson@arm.com
107811051Sandreas.hansson@arm.com        // Flush out any old data from the time buffers.  In
107911051Sandreas.hansson@arm.com        // particular, there might be some data in flight from the
108011051Sandreas.hansson@arm.com        // fetch stage that isn't visible in any of the CPU buffers we
108111051Sandreas.hansson@arm.com        // test in isDrained().
108211051Sandreas.hansson@arm.com        for (int i = 0; i < timeBuffer.getSize(); ++i) {
108311051Sandreas.hansson@arm.com            timeBuffer.advance();
108411051Sandreas.hansson@arm.com            fetchQueue.advance();
108511051Sandreas.hansson@arm.com            decodeQueue.advance();
108611452Sandreas.hansson@arm.com            renameQueue.advance();
108711452Sandreas.hansson@arm.com            iewQueue.advance();
108811452Sandreas.hansson@arm.com        }
108911452Sandreas.hansson@arm.com
109011051Sandreas.hansson@arm.com        drainSanityCheck();
109111051Sandreas.hansson@arm.com        return DrainState::Drained;
109211051Sandreas.hansson@arm.com    }
109311051Sandreas.hansson@arm.com}
109411051Sandreas.hansson@arm.com
109511051Sandreas.hansson@arm.comtemplate <class Impl>
109611051Sandreas.hansson@arm.combool
109711051Sandreas.hansson@arm.comFullO3CPU<Impl>::tryDrain()
109811051Sandreas.hansson@arm.com{
109911051Sandreas.hansson@arm.com    if (drainState() != DrainState::Draining || !isDrained())
110011051Sandreas.hansson@arm.com        return false;
110111051Sandreas.hansson@arm.com
110211051Sandreas.hansson@arm.com    if (tickEvent.scheduled())
110311197Sandreas.hansson@arm.com        deschedule(tickEvent);
110411130Sali.jafri@arm.com
110511051Sandreas.hansson@arm.com    DPRINTF(Drain, "CPU done draining, processing drain event\n");
110611197Sandreas.hansson@arm.com    signalDrainDone();
110711197Sandreas.hansson@arm.com
110811197Sandreas.hansson@arm.com    return true;
110911197Sandreas.hansson@arm.com}
111011197Sandreas.hansson@arm.com
111111197Sandreas.hansson@arm.comtemplate <class Impl>
111211197Sandreas.hansson@arm.comvoid
111311197Sandreas.hansson@arm.comFullO3CPU<Impl>::drainSanityCheck() const
111411197Sandreas.hansson@arm.com{
111511197Sandreas.hansson@arm.com    assert(isDrained());
111611197Sandreas.hansson@arm.com    fetch.drainSanityCheck();
111711197Sandreas.hansson@arm.com    decode.drainSanityCheck();
111811197Sandreas.hansson@arm.com    rename.drainSanityCheck();
111911197Sandreas.hansson@arm.com    iew.drainSanityCheck();
112011197Sandreas.hansson@arm.com    commit.drainSanityCheck();
112111197Sandreas.hansson@arm.com}
112211197Sandreas.hansson@arm.com
112311197Sandreas.hansson@arm.comtemplate <class Impl>
112411197Sandreas.hansson@arm.combool
112511197Sandreas.hansson@arm.comFullO3CPU<Impl>::isDrained() const
112611199Sandreas.hansson@arm.com{
112711199Sandreas.hansson@arm.com    bool drained(true);
112811867Snikos.nikoleris@arm.com
112911197Sandreas.hansson@arm.com    if (!instList.empty() || !removeList.empty()) {
113011197Sandreas.hansson@arm.com        DPRINTF(Drain, "Main CPU structures not drained.\n");
113111051Sandreas.hansson@arm.com        drained = false;
113211051Sandreas.hansson@arm.com    }
113311051Sandreas.hansson@arm.com
113411051Sandreas.hansson@arm.com    if (!fetch.isDrained()) {
113511051Sandreas.hansson@arm.com        DPRINTF(Drain, "Fetch not drained.\n");
113611051Sandreas.hansson@arm.com        drained = false;
113711051Sandreas.hansson@arm.com    }
113811051Sandreas.hansson@arm.com
113911051Sandreas.hansson@arm.com    if (!decode.isDrained()) {
114011051Sandreas.hansson@arm.com        DPRINTF(Drain, "Decode not drained.\n");
114111051Sandreas.hansson@arm.com        drained = false;
114211051Sandreas.hansson@arm.com    }
114311051Sandreas.hansson@arm.com
114411051Sandreas.hansson@arm.com    if (!rename.isDrained()) {
114511051Sandreas.hansson@arm.com        DPRINTF(Drain, "Rename not drained.\n");
114611051Sandreas.hansson@arm.com        drained = false;
114711051Sandreas.hansson@arm.com    }
114811051Sandreas.hansson@arm.com
114911051Sandreas.hansson@arm.com    if (!iew.isDrained()) {
115011051Sandreas.hansson@arm.com        DPRINTF(Drain, "IEW not drained.\n");
115111051Sandreas.hansson@arm.com        drained = false;
115211051Sandreas.hansson@arm.com    }
115311892Snikos.nikoleris@arm.com
115411051Sandreas.hansson@arm.com    if (!commit.isDrained()) {
115511051Sandreas.hansson@arm.com        DPRINTF(Drain, "Commit not drained.\n");
115611051Sandreas.hansson@arm.com        drained = false;
115711051Sandreas.hansson@arm.com    }
115811051Sandreas.hansson@arm.com
115911051Sandreas.hansson@arm.com    return drained;
116011051Sandreas.hansson@arm.com}
116111051Sandreas.hansson@arm.com
116211051Sandreas.hansson@arm.comtemplate <class Impl>
116311051Sandreas.hansson@arm.comvoid
116411051Sandreas.hansson@arm.comFullO3CPU<Impl>::commitDrained(ThreadID tid)
116511051Sandreas.hansson@arm.com{
116611051Sandreas.hansson@arm.com    fetch.drainStall(tid);
116711051Sandreas.hansson@arm.com}
116811051Sandreas.hansson@arm.com
116911051Sandreas.hansson@arm.comtemplate <class Impl>
117011051Sandreas.hansson@arm.comvoid
117111051Sandreas.hansson@arm.comFullO3CPU<Impl>::drainResume()
117211284Sandreas.hansson@arm.com{
117311284Sandreas.hansson@arm.com    if (switchedOut())
117411051Sandreas.hansson@arm.com        return;
117511051Sandreas.hansson@arm.com
117611284Sandreas.hansson@arm.com    DPRINTF(Drain, "Resuming...\n");
117711051Sandreas.hansson@arm.com    verifyMemoryMode();
117811051Sandreas.hansson@arm.com
117911051Sandreas.hansson@arm.com    fetch.drainResume();
118011051Sandreas.hansson@arm.com    commit.drainResume();
118111051Sandreas.hansson@arm.com
118211051Sandreas.hansson@arm.com    _status = Idle;
118311051Sandreas.hansson@arm.com    for (ThreadID i = 0; i < thread.size(); i++) {
118411744Snikos.nikoleris@arm.com        if (thread[i]->status() == ThreadContext::Active) {
118511051Sandreas.hansson@arm.com            DPRINTF(Drain, "Activating thread: %i\n", i);
118611051Sandreas.hansson@arm.com            activateThread(i);
118711051Sandreas.hansson@arm.com            _status = Running;
118811051Sandreas.hansson@arm.com        }
118911051Sandreas.hansson@arm.com    }
119011051Sandreas.hansson@arm.com
119111051Sandreas.hansson@arm.com    assert(!tickEvent.scheduled());
119211051Sandreas.hansson@arm.com    if (_status == Running)
119311051Sandreas.hansson@arm.com        schedule(tickEvent, nextCycle());
119411051Sandreas.hansson@arm.com
119511051Sandreas.hansson@arm.com    // Reschedule any power gating event (if any)
119611051Sandreas.hansson@arm.com    schedulePowerGatingEvent();
119711051Sandreas.hansson@arm.com}
119811485Snikos.nikoleris@arm.com
119911051Sandreas.hansson@arm.comtemplate <class Impl>
120011051Sandreas.hansson@arm.comvoid
120111051Sandreas.hansson@arm.comFullO3CPU<Impl>::switchOut()
120211051Sandreas.hansson@arm.com{
120311051Sandreas.hansson@arm.com    DPRINTF(O3CPU, "Switching out\n");
120411051Sandreas.hansson@arm.com    BaseCPU::switchOut();
120511051Sandreas.hansson@arm.com
120611051Sandreas.hansson@arm.com    activityRec.reset();
120711051Sandreas.hansson@arm.com
120811051Sandreas.hansson@arm.com    _status = SwitchedOut;
120911051Sandreas.hansson@arm.com
121011051Sandreas.hansson@arm.com    if (checker)
121111051Sandreas.hansson@arm.com        checker->switchOut();
121211051Sandreas.hansson@arm.com}
121311051Sandreas.hansson@arm.com
121411051Sandreas.hansson@arm.comtemplate <class Impl>
121511375Sandreas.hansson@arm.comvoid
121611375Sandreas.hansson@arm.comFullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
121711375Sandreas.hansson@arm.com{
121811375Sandreas.hansson@arm.com    BaseCPU::takeOverFrom(oldCPU);
121911375Sandreas.hansson@arm.com
122011453Sandreas.hansson@arm.com    fetch.takeOverFrom();
122111453Sandreas.hansson@arm.com    decode.takeOverFrom();
122211375Sandreas.hansson@arm.com    rename.takeOverFrom();
122311453Sandreas.hansson@arm.com    iew.takeOverFrom();
122411375Sandreas.hansson@arm.com    commit.takeOverFrom();
122511375Sandreas.hansson@arm.com
122611375Sandreas.hansson@arm.com    assert(!tickEvent.scheduled());
122711051Sandreas.hansson@arm.com
122811051Sandreas.hansson@arm.com    FullO3CPU<Impl> *oldO3CPU = dynamic_cast<FullO3CPU<Impl>*>(oldCPU);
122911051Sandreas.hansson@arm.com    if (oldO3CPU)
123011051Sandreas.hansson@arm.com        globalSeqNum = oldO3CPU->globalSeqNum;
123111051Sandreas.hansson@arm.com
123211051Sandreas.hansson@arm.com    lastRunningCycle = curCycle();
123311051Sandreas.hansson@arm.com    _status = Idle;
123411051Sandreas.hansson@arm.com}
123511051Sandreas.hansson@arm.com
123611051Sandreas.hansson@arm.comtemplate <class Impl>
123711051Sandreas.hansson@arm.comvoid
123811051Sandreas.hansson@arm.comFullO3CPU<Impl>::verifyMemoryMode() const
123911744Snikos.nikoleris@arm.com{
124011744Snikos.nikoleris@arm.com    if (!system->isTimingMode()) {
124111051Sandreas.hansson@arm.com        fatal("The O3 CPU requires the memory system to be in "
124211051Sandreas.hansson@arm.com              "'timing' mode.\n");
124311744Snikos.nikoleris@arm.com    }
124411744Snikos.nikoleris@arm.com}
124511051Sandreas.hansson@arm.com
124611375Sandreas.hansson@arm.comtemplate <class Impl>
124711375Sandreas.hansson@arm.comTheISA::MiscReg
124811375Sandreas.hansson@arm.comFullO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, ThreadID tid) const
124911375Sandreas.hansson@arm.com{
125011375Sandreas.hansson@arm.com    return this->isa[tid]->readMiscRegNoEffect(misc_reg);
125111375Sandreas.hansson@arm.com}
125211375Sandreas.hansson@arm.com
125311375Sandreas.hansson@arm.comtemplate <class Impl>
125411375Sandreas.hansson@arm.comTheISA::MiscReg
125511375Sandreas.hansson@arm.comFullO3CPU<Impl>::readMiscReg(int misc_reg, ThreadID tid)
125611453Sandreas.hansson@arm.com{
125711375Sandreas.hansson@arm.com    miscRegfileReads++;
125811051Sandreas.hansson@arm.com    return this->isa[tid]->readMiscReg(misc_reg, tcBase(tid));
125911051Sandreas.hansson@arm.com}
126011051Sandreas.hansson@arm.com
126111051Sandreas.hansson@arm.comtemplate <class Impl>
126211484Snikos.nikoleris@arm.comvoid
126311051Sandreas.hansson@arm.comFullO3CPU<Impl>::setMiscRegNoEffect(int misc_reg,
126411051Sandreas.hansson@arm.com        const TheISA::MiscReg &val, ThreadID tid)
126511051Sandreas.hansson@arm.com{
126611051Sandreas.hansson@arm.com    this->isa[tid]->setMiscRegNoEffect(misc_reg, val);
126711051Sandreas.hansson@arm.com}
126811051Sandreas.hansson@arm.com
126911051Sandreas.hansson@arm.comtemplate <class Impl>
127011051Sandreas.hansson@arm.comvoid
127111051Sandreas.hansson@arm.comFullO3CPU<Impl>::setMiscReg(int misc_reg,
127211051Sandreas.hansson@arm.com        const TheISA::MiscReg &val, ThreadID tid)
127311051Sandreas.hansson@arm.com{
127411051Sandreas.hansson@arm.com    miscRegfileWrites++;
127511051Sandreas.hansson@arm.com    this->isa[tid]->setMiscReg(misc_reg, val, tcBase(tid));
127611051Sandreas.hansson@arm.com}
127711051Sandreas.hansson@arm.com
127811051Sandreas.hansson@arm.comtemplate <class Impl>
127911051Sandreas.hansson@arm.comuint64_t
128011375Sandreas.hansson@arm.comFullO3CPU<Impl>::readIntReg(PhysRegIdPtr phys_reg)
128111375Sandreas.hansson@arm.com{
128211375Sandreas.hansson@arm.com    intRegfileReads++;
128311375Sandreas.hansson@arm.com    return regFile.readIntReg(phys_reg);
128411375Sandreas.hansson@arm.com}
128511375Sandreas.hansson@arm.com
128611284Sandreas.hansson@arm.comtemplate <class Impl>
128711284Sandreas.hansson@arm.comFloatRegBits
128811284Sandreas.hansson@arm.comFullO3CPU<Impl>::readFloatRegBits(PhysRegIdPtr phys_reg)
128911284Sandreas.hansson@arm.com{
129011177Sandreas.hansson@arm.com    fpRegfileReads++;
129111177Sandreas.hansson@arm.com    return regFile.readFloatRegBits(phys_reg);
129211051Sandreas.hansson@arm.com}
129311051Sandreas.hansson@arm.com
129411051Sandreas.hansson@arm.comtemplate <class Impl>
129511177Sandreas.hansson@arm.comauto
129611177Sandreas.hansson@arm.comFullO3CPU<Impl>::readVecReg(PhysRegIdPtr phys_reg) const
129711051Sandreas.hansson@arm.com        -> const VecRegContainer&
129811051Sandreas.hansson@arm.com{
129911051Sandreas.hansson@arm.com    vecRegfileReads++;
130011051Sandreas.hansson@arm.com    return regFile.readVecReg(phys_reg);
130111741Snikos.nikoleris@arm.com}
130211484Snikos.nikoleris@arm.com
130311051Sandreas.hansson@arm.comtemplate <class Impl>
130411051Sandreas.hansson@arm.comauto
130511051Sandreas.hansson@arm.comFullO3CPU<Impl>::getWritableVecReg(PhysRegIdPtr phys_reg)
130611051Sandreas.hansson@arm.com        -> VecRegContainer&
130711136Sandreas.hansson@arm.com{
130811051Sandreas.hansson@arm.com    vecRegfileWrites++;
130911051Sandreas.hansson@arm.com    return regFile.getWritableVecReg(phys_reg);
131011051Sandreas.hansson@arm.com}
131111051Sandreas.hansson@arm.com
131211601Sandreas.hansson@arm.comtemplate <class Impl>
131311742Snikos.nikoleris@arm.comauto
131411742Snikos.nikoleris@arm.comFullO3CPU<Impl>::readVecElem(PhysRegIdPtr phys_reg) const -> const VecElem&
131511742Snikos.nikoleris@arm.com{
131611742Snikos.nikoleris@arm.com    vecRegfileReads++;
131711051Sandreas.hansson@arm.com    return regFile.readVecElem(phys_reg);
131811051Sandreas.hansson@arm.com}
131911051Sandreas.hansson@arm.com
132011051Sandreas.hansson@arm.comtemplate <class Impl>
132111051Sandreas.hansson@arm.comCCReg
132211051Sandreas.hansson@arm.comFullO3CPU<Impl>::readCCReg(PhysRegIdPtr phys_reg)
132311051Sandreas.hansson@arm.com{
132411051Sandreas.hansson@arm.com    ccRegfileReads++;
132511483Snikos.nikoleris@arm.com    return regFile.readCCReg(phys_reg);
132611483Snikos.nikoleris@arm.com}
132711483Snikos.nikoleris@arm.com
132811483Snikos.nikoleris@arm.comtemplate <class Impl>
132911051Sandreas.hansson@arm.comvoid
133011051Sandreas.hansson@arm.comFullO3CPU<Impl>::setIntReg(PhysRegIdPtr phys_reg, uint64_t val)
133111051Sandreas.hansson@arm.com{
133211051Sandreas.hansson@arm.com    intRegfileWrites++;
133311051Sandreas.hansson@arm.com    regFile.setIntReg(phys_reg, val);
133411601Sandreas.hansson@arm.com}
133511601Sandreas.hansson@arm.com
133611601Sandreas.hansson@arm.comtemplate <class Impl>
133711601Sandreas.hansson@arm.comvoid
133811051Sandreas.hansson@arm.comFullO3CPU<Impl>::setFloatRegBits(PhysRegIdPtr phys_reg, FloatRegBits val)
133911051Sandreas.hansson@arm.com{
134011051Sandreas.hansson@arm.com    fpRegfileWrites++;
134111051Sandreas.hansson@arm.com    regFile.setFloatRegBits(phys_reg, val);
134211051Sandreas.hansson@arm.com}
134311051Sandreas.hansson@arm.com
134411051Sandreas.hansson@arm.comtemplate <class Impl>
134511051Sandreas.hansson@arm.comvoid
134611284Sandreas.hansson@arm.comFullO3CPU<Impl>::setVecReg(PhysRegIdPtr phys_reg, const VecRegContainer& val)
134711284Sandreas.hansson@arm.com{
134811284Sandreas.hansson@arm.com    vecRegfileWrites++;
134911051Sandreas.hansson@arm.com    regFile.setVecReg(phys_reg, val);
135011741Snikos.nikoleris@arm.com}
135111742Snikos.nikoleris@arm.com
135211484Snikos.nikoleris@arm.comtemplate <class Impl>
135311051Sandreas.hansson@arm.comvoid
135411051Sandreas.hansson@arm.comFullO3CPU<Impl>::setVecElem(PhysRegIdPtr phys_reg, const VecElem& val)
135511051Sandreas.hansson@arm.com{
135611051Sandreas.hansson@arm.com    vecRegfileWrites++;
135711136Sandreas.hansson@arm.com    regFile.setVecElem(phys_reg, val);
135811051Sandreas.hansson@arm.com}
135911051Sandreas.hansson@arm.com
136011051Sandreas.hansson@arm.comtemplate <class Impl>
136111601Sandreas.hansson@arm.comvoid
136211051Sandreas.hansson@arm.comFullO3CPU<Impl>::setCCReg(PhysRegIdPtr phys_reg, CCReg val)
136311051Sandreas.hansson@arm.com{
136411051Sandreas.hansson@arm.com    ccRegfileWrites++;
136511051Sandreas.hansson@arm.com    regFile.setCCReg(phys_reg, val);
136611051Sandreas.hansson@arm.com}
136711051Sandreas.hansson@arm.com
136811051Sandreas.hansson@arm.comtemplate <class Impl>
136911051Sandreas.hansson@arm.comuint64_t
137011051Sandreas.hansson@arm.comFullO3CPU<Impl>::readArchIntReg(int reg_idx, ThreadID tid)
137111051Sandreas.hansson@arm.com{
137211051Sandreas.hansson@arm.com    intRegfileReads++;
137311051Sandreas.hansson@arm.com    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
137411051Sandreas.hansson@arm.com            RegId(IntRegClass, reg_idx));
137511051Sandreas.hansson@arm.com
137611051Sandreas.hansson@arm.com    return regFile.readIntReg(phys_reg);
137711051Sandreas.hansson@arm.com}
137811051Sandreas.hansson@arm.com
137911051Sandreas.hansson@arm.comtemplate <class Impl>
138011051Sandreas.hansson@arm.comuint64_t
138111742Snikos.nikoleris@arm.comFullO3CPU<Impl>::readArchFloatRegBits(int reg_idx, ThreadID tid)
138211051Sandreas.hansson@arm.com{
138311051Sandreas.hansson@arm.com    fpRegfileReads++;
138411051Sandreas.hansson@arm.com    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
138511051Sandreas.hansson@arm.com        RegId(FloatRegClass, reg_idx));
138611051Sandreas.hansson@arm.com
138711051Sandreas.hansson@arm.com    return regFile.readFloatRegBits(phys_reg);
138811051Sandreas.hansson@arm.com}
138911051Sandreas.hansson@arm.com
139011051Sandreas.hansson@arm.comtemplate <class Impl>
139111051Sandreas.hansson@arm.comauto
139211051Sandreas.hansson@arm.comFullO3CPU<Impl>::readArchVecReg(int reg_idx, ThreadID tid) const
139311051Sandreas.hansson@arm.com        -> const VecRegContainer&
139411750Snikos.nikoleris@arm.com{
139511750Snikos.nikoleris@arm.com    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
139611750Snikos.nikoleris@arm.com                RegId(VecRegClass, reg_idx));
139711750Snikos.nikoleris@arm.com    return readVecReg(phys_reg);
139811750Snikos.nikoleris@arm.com}
139911750Snikos.nikoleris@arm.com
140011750Snikos.nikoleris@arm.comtemplate <class Impl>
140111750Snikos.nikoleris@arm.comauto
140211750Snikos.nikoleris@arm.comFullO3CPU<Impl>::getWritableArchVecReg(int reg_idx, ThreadID tid)
140311750Snikos.nikoleris@arm.com        -> VecRegContainer&
140411750Snikos.nikoleris@arm.com{
140511051Sandreas.hansson@arm.com    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
140611051Sandreas.hansson@arm.com                RegId(VecRegClass, reg_idx));
140711051Sandreas.hansson@arm.com    return getWritableVecReg(phys_reg);
140811051Sandreas.hansson@arm.com}
140911051Sandreas.hansson@arm.com
141011051Sandreas.hansson@arm.comtemplate <class Impl>
141111051Sandreas.hansson@arm.comauto
141211051Sandreas.hansson@arm.comFullO3CPU<Impl>::readArchVecElem(const RegIndex& reg_idx, const ElemIndex& ldx,
141311051Sandreas.hansson@arm.com                                 ThreadID tid) const -> const VecElem&
141411051Sandreas.hansson@arm.com{
141511051Sandreas.hansson@arm.com    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
141611051Sandreas.hansson@arm.com                                RegId(VecRegClass, reg_idx, ldx));
141711051Sandreas.hansson@arm.com    return readVecElem(phys_reg);
141811051Sandreas.hansson@arm.com}
141911051Sandreas.hansson@arm.com
142011051Sandreas.hansson@arm.comtemplate <class Impl>
142111051Sandreas.hansson@arm.comCCReg
142211051Sandreas.hansson@arm.comFullO3CPU<Impl>::readArchCCReg(int reg_idx, ThreadID tid)
142311136Sandreas.hansson@arm.com{
142411051Sandreas.hansson@arm.com    ccRegfileReads++;
142511051Sandreas.hansson@arm.com    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
142611051Sandreas.hansson@arm.com        RegId(CCRegClass, reg_idx));
142711051Sandreas.hansson@arm.com
142811744Snikos.nikoleris@arm.com    return regFile.readCCReg(phys_reg);
142911744Snikos.nikoleris@arm.com}
143011051Sandreas.hansson@arm.com
143111051Sandreas.hansson@arm.comtemplate <class Impl>
143211051Sandreas.hansson@arm.comvoid
143311194Sali.jafri@arm.comFullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, ThreadID tid)
143411051Sandreas.hansson@arm.com{
143511051Sandreas.hansson@arm.com    intRegfileWrites++;
143611051Sandreas.hansson@arm.com    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
143711051Sandreas.hansson@arm.com            RegId(IntRegClass, reg_idx));
143811051Sandreas.hansson@arm.com
143911051Sandreas.hansson@arm.com    regFile.setIntReg(phys_reg, val);
144011051Sandreas.hansson@arm.com}
144111051Sandreas.hansson@arm.com
144211051Sandreas.hansson@arm.comtemplate <class Impl>
144311051Sandreas.hansson@arm.comvoid
144411051Sandreas.hansson@arm.comFullO3CPU<Impl>::setArchFloatRegBits(int reg_idx, uint64_t val, ThreadID tid)
144511051Sandreas.hansson@arm.com{
144611051Sandreas.hansson@arm.com    fpRegfileWrites++;
144711051Sandreas.hansson@arm.com    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
144811051Sandreas.hansson@arm.com            RegId(FloatRegClass, reg_idx));
144911749Snikos.nikoleris@arm.com
145011749Snikos.nikoleris@arm.com    regFile.setFloatRegBits(phys_reg, val);
145111749Snikos.nikoleris@arm.com}
145211749Snikos.nikoleris@arm.com
145311749Snikos.nikoleris@arm.comtemplate <class Impl>
145411749Snikos.nikoleris@arm.comvoid
145511749Snikos.nikoleris@arm.comFullO3CPU<Impl>::setArchVecReg(int reg_idx, const VecRegContainer& val,
145611749Snikos.nikoleris@arm.com                               ThreadID tid)
145711749Snikos.nikoleris@arm.com{
145811749Snikos.nikoleris@arm.com    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
145911749Snikos.nikoleris@arm.com                RegId(VecRegClass, reg_idx));
146011749Snikos.nikoleris@arm.com    setVecReg(phys_reg, val);
146111051Sandreas.hansson@arm.com}
146211051Sandreas.hansson@arm.com
146311051Sandreas.hansson@arm.comtemplate <class Impl>
146411051Sandreas.hansson@arm.comvoid
146511742Snikos.nikoleris@arm.comFullO3CPU<Impl>::setArchVecElem(const RegIndex& reg_idx, const ElemIndex& ldx,
146611051Sandreas.hansson@arm.com                                const VecElem& val, ThreadID tid)
146711051Sandreas.hansson@arm.com{
146811051Sandreas.hansson@arm.com    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
146911601Sandreas.hansson@arm.com                RegId(VecRegClass, reg_idx, ldx));
147011601Sandreas.hansson@arm.com    setVecElem(phys_reg, val);
147111051Sandreas.hansson@arm.com}
147211051Sandreas.hansson@arm.com
147311051Sandreas.hansson@arm.comtemplate <class Impl>
147411051Sandreas.hansson@arm.comvoid
147511136Sandreas.hansson@arm.comFullO3CPU<Impl>::setArchCCReg(int reg_idx, CCReg val, ThreadID tid)
147611197Sandreas.hansson@arm.com{
147711051Sandreas.hansson@arm.com    ccRegfileWrites++;
147811051Sandreas.hansson@arm.com    PhysRegIdPtr phys_reg = commitRenameMap[tid].lookup(
147911051Sandreas.hansson@arm.com            RegId(CCRegClass, reg_idx));
148011051Sandreas.hansson@arm.com
148111051Sandreas.hansson@arm.com    regFile.setCCReg(phys_reg, val);
148211051Sandreas.hansson@arm.com}
148311051Sandreas.hansson@arm.com
148411051Sandreas.hansson@arm.comtemplate <class Impl>
148511051Sandreas.hansson@arm.comTheISA::PCState
148611051Sandreas.hansson@arm.comFullO3CPU<Impl>::pcState(ThreadID tid)
148711051Sandreas.hansson@arm.com{
148811375Sandreas.hansson@arm.com    return commit.pcState(tid);
148911051Sandreas.hansson@arm.com}
149011051Sandreas.hansson@arm.com
149111375Sandreas.hansson@arm.comtemplate <class Impl>
149211375Sandreas.hansson@arm.comvoid
149311375Sandreas.hansson@arm.comFullO3CPU<Impl>::pcState(const TheISA::PCState &val, ThreadID tid)
149411051Sandreas.hansson@arm.com{
149511051Sandreas.hansson@arm.com    commit.pcState(val, tid);
149611051Sandreas.hansson@arm.com}
149711051Sandreas.hansson@arm.com
149811375Sandreas.hansson@arm.comtemplate <class Impl>
149911051Sandreas.hansson@arm.comAddr
150011051Sandreas.hansson@arm.comFullO3CPU<Impl>::instAddr(ThreadID tid)
150111051Sandreas.hansson@arm.com{
150211051Sandreas.hansson@arm.com    return commit.instAddr(tid);
150311051Sandreas.hansson@arm.com}
150411051Sandreas.hansson@arm.com
150511051Sandreas.hansson@arm.comtemplate <class Impl>
150611051Sandreas.hansson@arm.comAddr
150711051Sandreas.hansson@arm.comFullO3CPU<Impl>::nextInstAddr(ThreadID tid)
150811051Sandreas.hansson@arm.com{
150911051Sandreas.hansson@arm.com    return commit.nextInstAddr(tid);
151011051Sandreas.hansson@arm.com}
151111051Sandreas.hansson@arm.com
151211051Sandreas.hansson@arm.comtemplate <class Impl>
151311051Sandreas.hansson@arm.comMicroPC
151411051Sandreas.hansson@arm.comFullO3CPU<Impl>::microPC(ThreadID tid)
151511051Sandreas.hansson@arm.com{
151611051Sandreas.hansson@arm.com    return commit.microPC(tid);
151711199Sandreas.hansson@arm.com}
151811051Sandreas.hansson@arm.com
151911051Sandreas.hansson@arm.comtemplate <class Impl>
152011051Sandreas.hansson@arm.comvoid
152111051Sandreas.hansson@arm.comFullO3CPU<Impl>::squashFromTC(ThreadID tid)
152211051Sandreas.hansson@arm.com{
152311051Sandreas.hansson@arm.com    this->thread[tid]->noSquashFromTC = true;
152411051Sandreas.hansson@arm.com    this->commit.generateTCEvent(tid);
152511051Sandreas.hansson@arm.com}
152611051Sandreas.hansson@arm.com
152711051Sandreas.hansson@arm.comtemplate <class Impl>
152811051Sandreas.hansson@arm.comtypename FullO3CPU<Impl>::ListIt
152911051Sandreas.hansson@arm.comFullO3CPU<Impl>::addInst(const DynInstPtr &inst)
153011051Sandreas.hansson@arm.com{
153111051Sandreas.hansson@arm.com    instList.push_back(inst);
153211867Snikos.nikoleris@arm.com
153311051Sandreas.hansson@arm.com    return --(instList.end());
153411051Sandreas.hansson@arm.com}
153511744Snikos.nikoleris@arm.com
153611051Sandreas.hansson@arm.comtemplate <class Impl>
153711051Sandreas.hansson@arm.comvoid
153811051Sandreas.hansson@arm.comFullO3CPU<Impl>::instDone(ThreadID tid, const DynInstPtr &inst)
153911051Sandreas.hansson@arm.com{
154011051Sandreas.hansson@arm.com    // Keep an instruction count.
154111051Sandreas.hansson@arm.com    if (!inst->isMicroop() || inst->isLastMicroop()) {
154211199Sandreas.hansson@arm.com        thread[tid]->numInst++;
154311199Sandreas.hansson@arm.com        thread[tid]->numInsts++;
154411199Sandreas.hansson@arm.com        committedInsts[tid]++;
154511051Sandreas.hansson@arm.com        system->totalNumInsts++;
154611051Sandreas.hansson@arm.com
154711051Sandreas.hansson@arm.com        // Check for instruction-count-based events.
154811199Sandreas.hansson@arm.com        comInstEventQueue[tid]->serviceEvents(thread[tid]->numInst);
154911199Sandreas.hansson@arm.com        system->instEventQueue.serviceEvents(system->totalNumInsts);
155011051Sandreas.hansson@arm.com    }
155111199Sandreas.hansson@arm.com    thread[tid]->numOp++;
155211051Sandreas.hansson@arm.com    thread[tid]->numOps++;
155311199Sandreas.hansson@arm.com    committedOps[tid]++;
155411051Sandreas.hansson@arm.com
155511051Sandreas.hansson@arm.com    probeInstCommit(inst->staticInst);
155611051Sandreas.hansson@arm.com}
155711199Sandreas.hansson@arm.com
155811199Sandreas.hansson@arm.comtemplate <class Impl>
155911199Sandreas.hansson@arm.comvoid
156011199Sandreas.hansson@arm.comFullO3CPU<Impl>::removeFrontInst(const DynInstPtr &inst)
156111744Snikos.nikoleris@arm.com{
156211744Snikos.nikoleris@arm.com    DPRINTF(O3CPU, "Removing committed instruction [tid:%i] PC %s "
156311199Sandreas.hansson@arm.com            "[sn:%lli]\n",
156411051Sandreas.hansson@arm.com            inst->threadNumber, inst->pcState(), inst->seqNum);
156511051Sandreas.hansson@arm.com
156611051Sandreas.hansson@arm.com    removeInstsThisCycle = true;
156711051Sandreas.hansson@arm.com
156811051Sandreas.hansson@arm.com    // Remove the front instruction.
156911284Sandreas.hansson@arm.com    removeList.push(inst->getInstListIt());
157011284Sandreas.hansson@arm.com}
157111051Sandreas.hansson@arm.com
157211051Sandreas.hansson@arm.comtemplate <class Impl>
157311199Sandreas.hansson@arm.comvoid
157411199Sandreas.hansson@arm.comFullO3CPU<Impl>::removeInstsNotInROB(ThreadID tid)
157511051Sandreas.hansson@arm.com{
157611199Sandreas.hansson@arm.com    DPRINTF(O3CPU, "Thread %i: Deleting instructions from instruction"
157711199Sandreas.hansson@arm.com            " list.\n", tid);
157811199Sandreas.hansson@arm.com
157911199Sandreas.hansson@arm.com    ListIt end_it;
158011051Sandreas.hansson@arm.com
158111051Sandreas.hansson@arm.com    bool rob_empty = false;
158211051Sandreas.hansson@arm.com
158311051Sandreas.hansson@arm.com    if (instList.empty()) {
158411051Sandreas.hansson@arm.com        return;
158511199Sandreas.hansson@arm.com    } else if (rob.isEmpty(tid)) {
158611051Sandreas.hansson@arm.com        DPRINTF(O3CPU, "ROB is empty, squashing all insts.\n");
158711051Sandreas.hansson@arm.com        end_it = instList.begin();
158811051Sandreas.hansson@arm.com        rob_empty = true;
158911051Sandreas.hansson@arm.com    } else {
159011051Sandreas.hansson@arm.com        end_it = (rob.readTailInst(tid))->getInstListIt();
159111051Sandreas.hansson@arm.com        DPRINTF(O3CPU, "ROB is not empty, squashing insts not in ROB.\n");
159211051Sandreas.hansson@arm.com    }
159311051Sandreas.hansson@arm.com
159411051Sandreas.hansson@arm.com    removeInstsThisCycle = true;
159511051Sandreas.hansson@arm.com
159611051Sandreas.hansson@arm.com    ListIt inst_it = instList.end();
159711051Sandreas.hansson@arm.com
159811051Sandreas.hansson@arm.com    inst_it--;
159911051Sandreas.hansson@arm.com
160011744Snikos.nikoleris@arm.com    // Walk through the instruction list, removing any instructions
160111051Sandreas.hansson@arm.com    // that were inserted after the given instruction iterator, end_it.
160211051Sandreas.hansson@arm.com    while (inst_it != end_it) {
160311051Sandreas.hansson@arm.com        assert(!instList.empty());
160411051Sandreas.hansson@arm.com
160511051Sandreas.hansson@arm.com        squashInstIt(inst_it, tid);
160611051Sandreas.hansson@arm.com
160711051Sandreas.hansson@arm.com        inst_it--;
160811051Sandreas.hansson@arm.com    }
160911051Sandreas.hansson@arm.com
161011051Sandreas.hansson@arm.com    // If the ROB was empty, then we actually need to remove the first
161111051Sandreas.hansson@arm.com    // instruction as well.
161211051Sandreas.hansson@arm.com    if (rob_empty) {
161311051Sandreas.hansson@arm.com        squashInstIt(inst_it, tid);
161411051Sandreas.hansson@arm.com    }
161511051Sandreas.hansson@arm.com}
161611051Sandreas.hansson@arm.com
161711051Sandreas.hansson@arm.comtemplate <class Impl>
161811051Sandreas.hansson@arm.comvoid
161911051Sandreas.hansson@arm.comFullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid)
162011051Sandreas.hansson@arm.com{
162111051Sandreas.hansson@arm.com    assert(!instList.empty());
162211051Sandreas.hansson@arm.com
162311051Sandreas.hansson@arm.com    removeInstsThisCycle = true;
162411051Sandreas.hansson@arm.com
162511051Sandreas.hansson@arm.com    ListIt inst_iter = instList.end();
162611051Sandreas.hansson@arm.com
162711051Sandreas.hansson@arm.com    inst_iter--;
162811051Sandreas.hansson@arm.com
162911051Sandreas.hansson@arm.com    DPRINTF(O3CPU, "Deleting instructions from instruction "
163011051Sandreas.hansson@arm.com            "list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n",
163111051Sandreas.hansson@arm.com            tid, seq_num, (*inst_iter)->seqNum);
163211051Sandreas.hansson@arm.com
163311051Sandreas.hansson@arm.com    while ((*inst_iter)->seqNum > seq_num) {
163411051Sandreas.hansson@arm.com
163511051Sandreas.hansson@arm.com        bool break_loop = (inst_iter == instList.begin());
163611051Sandreas.hansson@arm.com
163711865Snikos.nikoleris@arm.com        squashInstIt(inst_iter, tid);
163811865Snikos.nikoleris@arm.com
163911865Snikos.nikoleris@arm.com        inst_iter--;
164011051Sandreas.hansson@arm.com
164111051Sandreas.hansson@arm.com        if (break_loop)
164211051Sandreas.hansson@arm.com            break;
164311051Sandreas.hansson@arm.com    }
164411051Sandreas.hansson@arm.com}
164511051Sandreas.hansson@arm.com
164611051Sandreas.hansson@arm.comtemplate <class Impl>
164711051Sandreas.hansson@arm.cominline void
164811051Sandreas.hansson@arm.comFullO3CPU<Impl>::squashInstIt(const ListIt &instIt, ThreadID tid)
164911051Sandreas.hansson@arm.com{
165011051Sandreas.hansson@arm.com    if ((*instIt)->threadNumber == tid) {
165111051Sandreas.hansson@arm.com        DPRINTF(O3CPU, "Squashing instruction, "
165211051Sandreas.hansson@arm.com                "[tid:%i] [sn:%lli] PC %s\n",
165311051Sandreas.hansson@arm.com                (*instIt)->threadNumber,
165411051Sandreas.hansson@arm.com                (*instIt)->seqNum,
165511051Sandreas.hansson@arm.com                (*instIt)->pcState());
165611051Sandreas.hansson@arm.com
165711051Sandreas.hansson@arm.com        // Mark it as squashed.
165811051Sandreas.hansson@arm.com        (*instIt)->setSquashed();
165911051Sandreas.hansson@arm.com
166011051Sandreas.hansson@arm.com        // @todo: Formulate a consistent method for deleting
166111867Snikos.nikoleris@arm.com        // instructions from the instruction list
166211051Sandreas.hansson@arm.com        // Remove the instruction from the list.
166311051Sandreas.hansson@arm.com        removeList.push(instIt);
166411051Sandreas.hansson@arm.com    }
166511051Sandreas.hansson@arm.com}
166611051Sandreas.hansson@arm.com
166711051Sandreas.hansson@arm.comtemplate <class Impl>
166811051Sandreas.hansson@arm.comvoid
166911051Sandreas.hansson@arm.comFullO3CPU<Impl>::cleanUpRemovedInsts()
167011051Sandreas.hansson@arm.com{
167111051Sandreas.hansson@arm.com    while (!removeList.empty()) {
167211484Snikos.nikoleris@arm.com        DPRINTF(O3CPU, "Removing instruction, "
167311051Sandreas.hansson@arm.com                "[tid:%i] [sn:%lli] PC %s\n",
167411051Sandreas.hansson@arm.com                (*removeList.front())->threadNumber,
167511051Sandreas.hansson@arm.com                (*removeList.front())->seqNum,
167611051Sandreas.hansson@arm.com                (*removeList.front())->pcState());
167711051Sandreas.hansson@arm.com
167811051Sandreas.hansson@arm.com        instList.erase(removeList.front());
167911051Sandreas.hansson@arm.com
168011051Sandreas.hansson@arm.com        removeList.pop();
168111051Sandreas.hansson@arm.com    }
168211051Sandreas.hansson@arm.com
168311284Sandreas.hansson@arm.com    removeInstsThisCycle = false;
168411051Sandreas.hansson@arm.com}
168511051Sandreas.hansson@arm.com/*
168611484Snikos.nikoleris@arm.comtemplate <class Impl>
168711051Sandreas.hansson@arm.comvoid
168811483Snikos.nikoleris@arm.comFullO3CPU<Impl>::removeAllInsts()
168911483Snikos.nikoleris@arm.com{
169011051Sandreas.hansson@arm.com    instList.clear();
169111051Sandreas.hansson@arm.com}
169211051Sandreas.hansson@arm.com*/
169311436SRekai.GonzalezAlberquilla@arm.comtemplate <class Impl>
169411436SRekai.GonzalezAlberquilla@arm.comvoid
169511436SRekai.GonzalezAlberquilla@arm.comFullO3CPU<Impl>::dumpInsts()
169611051Sandreas.hansson@arm.com{
169711051Sandreas.hansson@arm.com    int num = 0;
169811199Sandreas.hansson@arm.com
169911051Sandreas.hansson@arm.com    ListIt inst_list_it = instList.begin();
170011051Sandreas.hansson@arm.com
170111051Sandreas.hansson@arm.com    cprintf("Dumping Instruction List\n");
170211051Sandreas.hansson@arm.com
170311051Sandreas.hansson@arm.com    while (inst_list_it != instList.end()) {
170411051Sandreas.hansson@arm.com        cprintf("Instruction:%i\nPC:%#x\n[tid:%i]\n[sn:%lli]\nIssued:%i\n"
170511051Sandreas.hansson@arm.com                "Squashed:%i\n\n",
170611051Sandreas.hansson@arm.com                num, (*inst_list_it)->instAddr(), (*inst_list_it)->threadNumber,
170711051Sandreas.hansson@arm.com                (*inst_list_it)->seqNum, (*inst_list_it)->isIssued(),
170811051Sandreas.hansson@arm.com                (*inst_list_it)->isSquashed());
170911051Sandreas.hansson@arm.com        inst_list_it++;
171011197Sandreas.hansson@arm.com        ++num;
171111197Sandreas.hansson@arm.com    }
171211197Sandreas.hansson@arm.com}
171311197Sandreas.hansson@arm.com/*
171411197Sandreas.hansson@arm.comtemplate <class Impl>
171511197Sandreas.hansson@arm.comvoid
171611197Sandreas.hansson@arm.comFullO3CPU<Impl>::wakeDependents(const DynInstPtr &inst)
171711051Sandreas.hansson@arm.com{
171811051Sandreas.hansson@arm.com    iew.wakeDependents(inst);
171911051Sandreas.hansson@arm.com}
172011051Sandreas.hansson@arm.com*/
172111051Sandreas.hansson@arm.comtemplate <class Impl>
172211051Sandreas.hansson@arm.comvoid
172311051Sandreas.hansson@arm.comFullO3CPU<Impl>::wakeCPU()
172411197Sandreas.hansson@arm.com{
172511197Sandreas.hansson@arm.com    if (activityRec.active() || tickEvent.scheduled()) {
172611051Sandreas.hansson@arm.com        DPRINTF(Activity, "CPU already running.\n");
172711051Sandreas.hansson@arm.com        return;
172811051Sandreas.hansson@arm.com    }
172911051Sandreas.hansson@arm.com
173011051Sandreas.hansson@arm.com    DPRINTF(Activity, "Waking up CPU\n");
173111051Sandreas.hansson@arm.com
173211051Sandreas.hansson@arm.com    Cycles cycles(curCycle() - lastRunningCycle);
173311051Sandreas.hansson@arm.com    // @todo: This is an oddity that is only here to match the stats
173411375Sandreas.hansson@arm.com    if (cycles > 1) {
173511892Snikos.nikoleris@arm.com        --cycles;
173611375Sandreas.hansson@arm.com        idleCycles += cycles;
173711051Sandreas.hansson@arm.com        numCycles += cycles;
173811484Snikos.nikoleris@arm.com    }
173911051Sandreas.hansson@arm.com
174011051Sandreas.hansson@arm.com    schedule(tickEvent, clockEdge());
174111051Sandreas.hansson@arm.com}
174211051Sandreas.hansson@arm.com
174311051Sandreas.hansson@arm.comtemplate <class Impl>
174411601Sandreas.hansson@arm.comvoid
174511051Sandreas.hansson@arm.comFullO3CPU<Impl>::wakeup(ThreadID tid)
174611051Sandreas.hansson@arm.com{
174711197Sandreas.hansson@arm.com    if (this->thread[tid]->status() != ThreadContext::Suspended)
174811197Sandreas.hansson@arm.com        return;
174911484Snikos.nikoleris@arm.com
175011197Sandreas.hansson@arm.com    this->wakeCPU();
175111484Snikos.nikoleris@arm.com
175211197Sandreas.hansson@arm.com    DPRINTF(Quiesce, "Suspended Processor woken\n");
175311197Sandreas.hansson@arm.com    this->threadContexts[tid]->activate();
175411197Sandreas.hansson@arm.com}
175511051Sandreas.hansson@arm.com
175611051Sandreas.hansson@arm.comtemplate <class Impl>
175711051Sandreas.hansson@arm.comThreadID
175811051Sandreas.hansson@arm.comFullO3CPU<Impl>::getFreeTid()
175911051Sandreas.hansson@arm.com{
176011051Sandreas.hansson@arm.com    for (ThreadID tid = 0; tid < numThreads; tid++) {
176111051Sandreas.hansson@arm.com        if (!tids[tid]) {
176211051Sandreas.hansson@arm.com            tids[tid] = true;
176311051Sandreas.hansson@arm.com            return tid;
176411051Sandreas.hansson@arm.com        }
176511051Sandreas.hansson@arm.com    }
176611051Sandreas.hansson@arm.com
176711051Sandreas.hansson@arm.com    return InvalidThreadID;
176811051Sandreas.hansson@arm.com}
176911051Sandreas.hansson@arm.com
177011051Sandreas.hansson@arm.comtemplate <class Impl>
177111051Sandreas.hansson@arm.comvoid
177211051Sandreas.hansson@arm.comFullO3CPU<Impl>::updateThreadPriority()
177311051Sandreas.hansson@arm.com{
177411051Sandreas.hansson@arm.com    if (activeThreads.size() > 1) {
177511051Sandreas.hansson@arm.com        //DEFAULT TO ROUND ROBIN SCHEME
177611051Sandreas.hansson@arm.com        //e.g. Move highest priority to end of thread list
177711051Sandreas.hansson@arm.com        list<ThreadID>::iterator list_begin = activeThreads.begin();
177811051Sandreas.hansson@arm.com
177911051Sandreas.hansson@arm.com        unsigned high_thread = *list_begin;
178011051Sandreas.hansson@arm.com
178111137Sandreas.hansson@arm.com        activeThreads.erase(list_begin);
178211137Sandreas.hansson@arm.com
178311601Sandreas.hansson@arm.com        activeThreads.push_back(high_thread);
178411137Sandreas.hansson@arm.com    }
178511284Sandreas.hansson@arm.com}
178611137Sandreas.hansson@arm.com
178711137Sandreas.hansson@arm.com// Forward declaration of FullO3CPU.
178811284Sandreas.hansson@arm.comtemplate class FullO3CPU<O3CPUImpl>;
178911284Sandreas.hansson@arm.com