base.cc revision 12109
12SN/A/*
211147Smitch.hayenga@arm.com * Copyright (c) 2010-2012,2015 ARM Limited
39920Syasuko.eckert@amd.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
47338SAli.Saidi@ARM.com * All rights reserved
57338SAli.Saidi@ARM.com *
67338SAli.Saidi@ARM.com * The license below extends only to copyright in the software and shall
77338SAli.Saidi@ARM.com * not be construed as granting a license to any other intellectual
87338SAli.Saidi@ARM.com * property including but not limited to intellectual property relating
97338SAli.Saidi@ARM.com * to a hardware implementation of the functionality of the software
107338SAli.Saidi@ARM.com * licensed hereunder.  You may use the software subject to the license
117338SAli.Saidi@ARM.com * terms below provided that you ensure that this notice is replicated
127338SAli.Saidi@ARM.com * unmodified and in its entirety in all distributions of the software,
137338SAli.Saidi@ARM.com * modified or unmodified, in source code or in binary form.
147338SAli.Saidi@ARM.com *
151762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
162SN/A * All rights reserved.
172SN/A *
182SN/A * Redistribution and use in source and binary forms, with or without
192SN/A * modification, are permitted provided that the following conditions are
202SN/A * met: redistributions of source code must retain the above copyright
212SN/A * notice, this list of conditions and the following disclaimer;
222SN/A * redistributions in binary form must reproduce the above copyright
232SN/A * notice, this list of conditions and the following disclaimer in the
242SN/A * documentation and/or other materials provided with the distribution;
252SN/A * neither the name of the copyright holders nor the names of its
262SN/A * contributors may be used to endorse or promote products derived from
272SN/A * this software without specific prior written permission.
282SN/A *
292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
302SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
312SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
322SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
332SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
342SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
352SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
362SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
372SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
382SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
392SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
402665Ssaidi@eecs.umich.edu *
412665Ssaidi@eecs.umich.edu * Authors: Steve Reinhardt
422SN/A */
432SN/A
4411793Sbrandon.potter@amd.com#include "cpu/simple/base.hh"
4511793Sbrandon.potter@amd.com
468779Sgblack@eecs.umich.edu#include "arch/kernel_stats.hh"
478779Sgblack@eecs.umich.edu#include "arch/stacktrace.hh"
488779Sgblack@eecs.umich.edu#include "arch/tlb.hh"
492439SN/A#include "arch/utility.hh"
508779Sgblack@eecs.umich.edu#include "arch/vtophys.hh"
516216Snate@binkert.org#include "base/cp_annotate.hh"
52146SN/A#include "base/cprintf.hh"
53146SN/A#include "base/inifile.hh"
5411793Sbrandon.potter@amd.com#include "base/loader/symtab.hh"
55146SN/A#include "base/misc.hh"
56146SN/A#include "base/pollevent.hh"
57146SN/A#include "base/trace.hh"
586216Snate@binkert.org#include "base/types.hh"
596658Snate@binkert.org#include "config/the_isa.hh"
601717SN/A#include "cpu/base.hh"
618887Sgeoffrey.blake@arm.com#include "cpu/checker/cpu.hh"
628887Sgeoffrey.blake@arm.com#include "cpu/checker/thread_context.hh"
63146SN/A#include "cpu/exetrace.hh"
6410061Sandreas@sandberg.pp.se#include "cpu/pred/bpred_unit.hh"
651977SN/A#include "cpu/profile.hh"
6611147Smitch.hayenga@arm.com#include "cpu/simple/exec_context.hh"
672683Sktlim@umich.edu#include "cpu/simple_thread.hh"
681717SN/A#include "cpu/smt.hh"
69146SN/A#include "cpu/static_inst.hh"
702683Sktlim@umich.edu#include "cpu/thread_context.hh"
718232Snate@binkert.org#include "debug/Decode.hh"
728232Snate@binkert.org#include "debug/Fetch.hh"
738232Snate@binkert.org#include "debug/Quiesce.hh"
748779Sgblack@eecs.umich.edu#include "mem/mem_object.hh"
753348Sbinkertn@umich.edu#include "mem/packet.hh"
766105Ssteve.reinhardt@amd.com#include "mem/request.hh"
776216Snate@binkert.org#include "params/BaseSimpleCPU.hh"
782036SN/A#include "sim/byteswap.hh"
79146SN/A#include "sim/debug.hh"
808817Sgblack@eecs.umich.edu#include "sim/faults.hh"
818793Sgblack@eecs.umich.edu#include "sim/full_system.hh"
8256SN/A#include "sim/sim_events.hh"
8356SN/A#include "sim/sim_object.hh"
84695SN/A#include "sim/stats.hh"
852901Ssaidi@eecs.umich.edu#include "sim/system.hh"
862SN/A
872SN/Ausing namespace std;
882449SN/Ausing namespace TheISA;
891355SN/A
905529Snate@binkert.orgBaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p)
9110061Sandreas@sandberg.pp.se    : BaseCPU(p),
9211147Smitch.hayenga@arm.com      curThread(0),
9310061Sandreas@sandberg.pp.se      branchPred(p->branchPred),
9411147Smitch.hayenga@arm.com      traceData(NULL),
9511147Smitch.hayenga@arm.com      inst(),
9611147Smitch.hayenga@arm.com      _status(Idle)
97224SN/A{
9811147Smitch.hayenga@arm.com    SimpleThread *thread;
992SN/A
10011147Smitch.hayenga@arm.com    for (unsigned i = 0; i < numThreads; i++) {
10111147Smitch.hayenga@arm.com        if (FullSystem) {
10211147Smitch.hayenga@arm.com            thread = new SimpleThread(this, i, p->system,
10311147Smitch.hayenga@arm.com                                      p->itb, p->dtb, p->isa[i]);
10411147Smitch.hayenga@arm.com        } else {
10511147Smitch.hayenga@arm.com            thread = new SimpleThread(this, i, p->system, p->workload[i],
10611147Smitch.hayenga@arm.com                                      p->itb, p->dtb, p->isa[i]);
10711147Smitch.hayenga@arm.com        }
10811147Smitch.hayenga@arm.com        threadInfo.push_back(new SimpleExecContext(this, thread));
10911147Smitch.hayenga@arm.com        ThreadContext *tc = thread->getTC();
11011147Smitch.hayenga@arm.com        threadContexts.push_back(tc);
11111147Smitch.hayenga@arm.com    }
1122SN/A
1138733Sgeoffrey.blake@arm.com    if (p->checker) {
11411147Smitch.hayenga@arm.com        if (numThreads != 1)
11511147Smitch.hayenga@arm.com            fatal("Checker currently does not support SMT");
11611147Smitch.hayenga@arm.com
1178733Sgeoffrey.blake@arm.com        BaseCPU *temp_checker = p->checker;
1188733Sgeoffrey.blake@arm.com        checker = dynamic_cast<CheckerCPU *>(temp_checker);
1198733Sgeoffrey.blake@arm.com        checker->setSystem(p->system);
1208733Sgeoffrey.blake@arm.com        // Manipulate thread context
12111147Smitch.hayenga@arm.com        ThreadContext *cpu_tc = threadContexts[0];
12211147Smitch.hayenga@arm.com        threadContexts[0] = new CheckerThreadContext<ThreadContext>(cpu_tc, this->checker);
1238733Sgeoffrey.blake@arm.com    } else {
1248733Sgeoffrey.blake@arm.com        checker = NULL;
1258733Sgeoffrey.blake@arm.com    }
12611147Smitch.hayenga@arm.com}
1278733Sgeoffrey.blake@arm.com
12811147Smitch.hayenga@arm.comvoid
12911147Smitch.hayenga@arm.comBaseSimpleCPU::init()
13011147Smitch.hayenga@arm.com{
13111147Smitch.hayenga@arm.com    BaseCPU::init();
1322SN/A
13311147Smitch.hayenga@arm.com    for (auto tc : threadContexts) {
13411147Smitch.hayenga@arm.com        // Initialise the ThreadContext's memory proxies
13511147Smitch.hayenga@arm.com        tc->initMemProxies(tc);
1364377Sgblack@eecs.umich.edu
13711147Smitch.hayenga@arm.com        if (FullSystem && !params()->switched_out) {
13811147Smitch.hayenga@arm.com            // initialize CPU, including PC
13911147Smitch.hayenga@arm.com            TheISA::initCPU(tc, tc->contextId());
14011147Smitch.hayenga@arm.com        }
14111147Smitch.hayenga@arm.com    }
14211147Smitch.hayenga@arm.com}
1435169Ssaidi@eecs.umich.edu
14411147Smitch.hayenga@arm.comvoid
14511147Smitch.hayenga@arm.comBaseSimpleCPU::checkPcEventQueue()
14611147Smitch.hayenga@arm.com{
14711147Smitch.hayenga@arm.com    Addr oldpc, pc = threadInfo[curThread]->thread->instAddr();
14811147Smitch.hayenga@arm.com    do {
14911147Smitch.hayenga@arm.com        oldpc = pc;
15011147Smitch.hayenga@arm.com        system->pcEventQueue.service(threadContexts[curThread]);
15111147Smitch.hayenga@arm.com        pc = threadInfo[curThread]->thread->instAddr();
15211147Smitch.hayenga@arm.com    } while (oldpc != pc);
15311147Smitch.hayenga@arm.com}
15411147Smitch.hayenga@arm.com
15511147Smitch.hayenga@arm.comvoid
15611147Smitch.hayenga@arm.comBaseSimpleCPU::swapActiveThread()
15711147Smitch.hayenga@arm.com{
15811147Smitch.hayenga@arm.com    if (numThreads > 1) {
15911147Smitch.hayenga@arm.com        if ((!curStaticInst || !curStaticInst->isDelayedCommit()) &&
16011147Smitch.hayenga@arm.com             !threadInfo[curThread]->stayAtPC) {
16111147Smitch.hayenga@arm.com            // Swap active threads
16211147Smitch.hayenga@arm.com            if (!activeThreads.empty()) {
16311147Smitch.hayenga@arm.com                curThread = activeThreads.front();
16411147Smitch.hayenga@arm.com                activeThreads.pop_front();
16511147Smitch.hayenga@arm.com                activeThreads.push_back(curThread);
16611147Smitch.hayenga@arm.com            }
16711147Smitch.hayenga@arm.com        }
16811147Smitch.hayenga@arm.com    }
16911147Smitch.hayenga@arm.com}
17011147Smitch.hayenga@arm.com
17111147Smitch.hayenga@arm.comvoid
17211147Smitch.hayenga@arm.comBaseSimpleCPU::countInst()
17311147Smitch.hayenga@arm.com{
17411147Smitch.hayenga@arm.com    SimpleExecContext& t_info = *threadInfo[curThread];
17511147Smitch.hayenga@arm.com
17611147Smitch.hayenga@arm.com    if (!curStaticInst->isMicroop() || curStaticInst->isLastMicroop()) {
17711147Smitch.hayenga@arm.com        t_info.numInst++;
17811147Smitch.hayenga@arm.com        t_info.numInsts++;
17911147Smitch.hayenga@arm.com    }
18011147Smitch.hayenga@arm.com    t_info.numOp++;
18111147Smitch.hayenga@arm.com    t_info.numOps++;
18211147Smitch.hayenga@arm.com
18311147Smitch.hayenga@arm.com    system->totalNumInsts++;
18411147Smitch.hayenga@arm.com    t_info.thread->funcExeInst++;
18511147Smitch.hayenga@arm.com}
18611147Smitch.hayenga@arm.com
18711147Smitch.hayenga@arm.comCounter
18811147Smitch.hayenga@arm.comBaseSimpleCPU::totalInsts() const
18911147Smitch.hayenga@arm.com{
19011147Smitch.hayenga@arm.com    Counter total_inst = 0;
19111147Smitch.hayenga@arm.com    for (auto& t_info : threadInfo) {
19211147Smitch.hayenga@arm.com        total_inst += t_info->numInst;
19311147Smitch.hayenga@arm.com    }
19411147Smitch.hayenga@arm.com
19511147Smitch.hayenga@arm.com    return total_inst;
19611147Smitch.hayenga@arm.com}
19711147Smitch.hayenga@arm.com
19811147Smitch.hayenga@arm.comCounter
19911147Smitch.hayenga@arm.comBaseSimpleCPU::totalOps() const
20011147Smitch.hayenga@arm.com{
20111147Smitch.hayenga@arm.com    Counter total_op = 0;
20211147Smitch.hayenga@arm.com    for (auto& t_info : threadInfo) {
20311147Smitch.hayenga@arm.com        total_op += t_info->numOp;
20411147Smitch.hayenga@arm.com    }
20511147Smitch.hayenga@arm.com
20611147Smitch.hayenga@arm.com    return total_op;
2072SN/A}
2082SN/A
2092623SN/ABaseSimpleCPU::~BaseSimpleCPU()
2102SN/A{
2112SN/A}
2122SN/A
213180SN/Avoid
2148737Skoansin.tan@gmail.comBaseSimpleCPU::haltContext(ThreadID thread_num)
215393SN/A{
216393SN/A    // for now, these are equivalent
217393SN/A    suspendContext(thread_num);
218393SN/A}
219384SN/A
220189SN/A
221189SN/Avoid
2222623SN/ABaseSimpleCPU::regStats()
2232SN/A{
224729SN/A    using namespace Stats;
225334SN/A
2262SN/A    BaseCPU::regStats();
2272SN/A
22811147Smitch.hayenga@arm.com    for (ThreadID tid = 0; tid < numThreads; tid++) {
22911147Smitch.hayenga@arm.com        SimpleExecContext& t_info = *threadInfo[tid];
2308834Satgutier@umich.edu
23111147Smitch.hayenga@arm.com        std::string thread_str = name();
23211147Smitch.hayenga@arm.com        if (numThreads > 1)
23311147Smitch.hayenga@arm.com            thread_str += ".thread" + std::to_string(tid);
2342SN/A
23511147Smitch.hayenga@arm.com        t_info.numInsts
23611147Smitch.hayenga@arm.com            .name(thread_str + ".committedInsts")
23711147Smitch.hayenga@arm.com            .desc("Number of instructions committed")
23811147Smitch.hayenga@arm.com            ;
2397897Shestness@cs.utexas.edu
24011147Smitch.hayenga@arm.com        t_info.numOps
24111147Smitch.hayenga@arm.com            .name(thread_str + ".committedOps")
24211147Smitch.hayenga@arm.com            .desc("Number of ops (including micro ops) committed")
24311147Smitch.hayenga@arm.com            ;
2447897Shestness@cs.utexas.edu
24511147Smitch.hayenga@arm.com        t_info.numIntAluAccesses
24611147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_alu_accesses")
24711147Smitch.hayenga@arm.com            .desc("Number of integer alu accesses")
24811147Smitch.hayenga@arm.com            ;
2497897Shestness@cs.utexas.edu
25011147Smitch.hayenga@arm.com        t_info.numFpAluAccesses
25111147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_alu_accesses")
25211147Smitch.hayenga@arm.com            .desc("Number of float alu accesses")
25311147Smitch.hayenga@arm.com            ;
2547897Shestness@cs.utexas.edu
25511147Smitch.hayenga@arm.com        t_info.numCallsReturns
25611147Smitch.hayenga@arm.com            .name(thread_str + ".num_func_calls")
25711147Smitch.hayenga@arm.com            .desc("number of times a function call or return occured")
25811147Smitch.hayenga@arm.com            ;
2597897Shestness@cs.utexas.edu
26011147Smitch.hayenga@arm.com        t_info.numCondCtrlInsts
26111147Smitch.hayenga@arm.com            .name(thread_str + ".num_conditional_control_insts")
26211147Smitch.hayenga@arm.com            .desc("number of instructions that are conditional controls")
26311147Smitch.hayenga@arm.com            ;
2647897Shestness@cs.utexas.edu
26511147Smitch.hayenga@arm.com        t_info.numIntInsts
26611147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_insts")
26711147Smitch.hayenga@arm.com            .desc("number of integer instructions")
26811147Smitch.hayenga@arm.com            ;
2697897Shestness@cs.utexas.edu
27011147Smitch.hayenga@arm.com        t_info.numFpInsts
27111147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_insts")
27211147Smitch.hayenga@arm.com            .desc("number of float instructions")
27311147Smitch.hayenga@arm.com            ;
2747897Shestness@cs.utexas.edu
27511147Smitch.hayenga@arm.com        t_info.numIntRegReads
27611147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_register_reads")
27711147Smitch.hayenga@arm.com            .desc("number of times the integer registers were read")
27811147Smitch.hayenga@arm.com            ;
2797897Shestness@cs.utexas.edu
28011147Smitch.hayenga@arm.com        t_info.numIntRegWrites
28111147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_register_writes")
28211147Smitch.hayenga@arm.com            .desc("number of times the integer registers were written")
28311147Smitch.hayenga@arm.com            ;
2847897Shestness@cs.utexas.edu
28511147Smitch.hayenga@arm.com        t_info.numFpRegReads
28611147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_register_reads")
28711147Smitch.hayenga@arm.com            .desc("number of times the floating registers were read")
28811147Smitch.hayenga@arm.com            ;
2899920Syasuko.eckert@amd.com
29011147Smitch.hayenga@arm.com        t_info.numFpRegWrites
29111147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_register_writes")
29211147Smitch.hayenga@arm.com            .desc("number of times the floating registers were written")
29311147Smitch.hayenga@arm.com            ;
2949920Syasuko.eckert@amd.com
29512109SRekai.GonzalezAlberquilla@arm.com        t_info.numVecRegReads
29612109SRekai.GonzalezAlberquilla@arm.com            .name(thread_str + ".num_vec_register_reads")
29712109SRekai.GonzalezAlberquilla@arm.com            .desc("number of times the vector registers were read")
29812109SRekai.GonzalezAlberquilla@arm.com            ;
29912109SRekai.GonzalezAlberquilla@arm.com
30012109SRekai.GonzalezAlberquilla@arm.com        t_info.numVecRegWrites
30112109SRekai.GonzalezAlberquilla@arm.com            .name(thread_str + ".num_vec_register_writes")
30212109SRekai.GonzalezAlberquilla@arm.com            .desc("number of times the vector registers were written")
30312109SRekai.GonzalezAlberquilla@arm.com            ;
30412109SRekai.GonzalezAlberquilla@arm.com
30511147Smitch.hayenga@arm.com        t_info.numCCRegReads
30611147Smitch.hayenga@arm.com            .name(thread_str + ".num_cc_register_reads")
30711147Smitch.hayenga@arm.com            .desc("number of times the CC registers were read")
30811147Smitch.hayenga@arm.com            .flags(nozero)
30911147Smitch.hayenga@arm.com            ;
3107897Shestness@cs.utexas.edu
31111147Smitch.hayenga@arm.com        t_info.numCCRegWrites
31211147Smitch.hayenga@arm.com            .name(thread_str + ".num_cc_register_writes")
31311147Smitch.hayenga@arm.com            .desc("number of times the CC registers were written")
31411147Smitch.hayenga@arm.com            .flags(nozero)
31511147Smitch.hayenga@arm.com            ;
3167897Shestness@cs.utexas.edu
31711147Smitch.hayenga@arm.com        t_info.numMemRefs
31811147Smitch.hayenga@arm.com            .name(thread_str + ".num_mem_refs")
31911147Smitch.hayenga@arm.com            .desc("number of memory refs")
32011147Smitch.hayenga@arm.com            ;
3212SN/A
32211147Smitch.hayenga@arm.com        t_info.numStoreInsts
32311147Smitch.hayenga@arm.com            .name(thread_str + ".num_store_insts")
32411147Smitch.hayenga@arm.com            .desc("Number of store instructions")
32511147Smitch.hayenga@arm.com            ;
3261001SN/A
32711147Smitch.hayenga@arm.com        t_info.numLoadInsts
32811147Smitch.hayenga@arm.com            .name(thread_str + ".num_load_insts")
32911147Smitch.hayenga@arm.com            .desc("Number of load instructions")
33011147Smitch.hayenga@arm.com            ;
3312SN/A
33211147Smitch.hayenga@arm.com        t_info.notIdleFraction
33311147Smitch.hayenga@arm.com            .name(thread_str + ".not_idle_fraction")
33411147Smitch.hayenga@arm.com            .desc("Percentage of non-idle cycles")
33511147Smitch.hayenga@arm.com            ;
3367897Shestness@cs.utexas.edu
33711147Smitch.hayenga@arm.com        t_info.idleFraction
33811147Smitch.hayenga@arm.com            .name(thread_str + ".idle_fraction")
33911147Smitch.hayenga@arm.com            .desc("Percentage of idle cycles")
34011147Smitch.hayenga@arm.com            ;
3417897Shestness@cs.utexas.edu
34211147Smitch.hayenga@arm.com        t_info.numBusyCycles
34311147Smitch.hayenga@arm.com            .name(thread_str + ".num_busy_cycles")
34411147Smitch.hayenga@arm.com            .desc("Number of busy cycles")
34511147Smitch.hayenga@arm.com            ;
3462SN/A
34711147Smitch.hayenga@arm.com        t_info.numIdleCycles
34811147Smitch.hayenga@arm.com            .name(thread_str + ".num_idle_cycles")
34911147Smitch.hayenga@arm.com            .desc("Number of idle cycles")
35011147Smitch.hayenga@arm.com            ;
3512SN/A
35211147Smitch.hayenga@arm.com        t_info.icacheStallCycles
35311147Smitch.hayenga@arm.com            .name(thread_str + ".icache_stall_cycles")
35411147Smitch.hayenga@arm.com            .desc("ICache total stall cycles")
35511147Smitch.hayenga@arm.com            .prereq(t_info.icacheStallCycles)
35611147Smitch.hayenga@arm.com            ;
35711147Smitch.hayenga@arm.com
35811147Smitch.hayenga@arm.com        t_info.dcacheStallCycles
35911147Smitch.hayenga@arm.com            .name(thread_str + ".dcache_stall_cycles")
36011147Smitch.hayenga@arm.com            .desc("DCache total stall cycles")
36111147Smitch.hayenga@arm.com            .prereq(t_info.dcacheStallCycles)
36211147Smitch.hayenga@arm.com            ;
36311147Smitch.hayenga@arm.com
36411147Smitch.hayenga@arm.com        t_info.statExecutedInstType
36511147Smitch.hayenga@arm.com            .init(Enums::Num_OpClass)
36611147Smitch.hayenga@arm.com            .name(thread_str + ".op_class")
36711147Smitch.hayenga@arm.com            .desc("Class of executed instruction")
36811147Smitch.hayenga@arm.com            .flags(total | pdf | dist)
36911147Smitch.hayenga@arm.com            ;
37011147Smitch.hayenga@arm.com
37111147Smitch.hayenga@arm.com        for (unsigned i = 0; i < Num_OpClasses; ++i) {
37211147Smitch.hayenga@arm.com            t_info.statExecutedInstType.subname(i, Enums::OpClassStrings[i]);
37311147Smitch.hayenga@arm.com        }
37411147Smitch.hayenga@arm.com
37511147Smitch.hayenga@arm.com        t_info.idleFraction = constant(1.0) - t_info.notIdleFraction;
37611147Smitch.hayenga@arm.com        t_info.numIdleCycles = t_info.idleFraction * numCycles;
37711147Smitch.hayenga@arm.com        t_info.numBusyCycles = t_info.notIdleFraction * numCycles;
37811147Smitch.hayenga@arm.com
37911147Smitch.hayenga@arm.com        t_info.numBranches
38011147Smitch.hayenga@arm.com            .name(thread_str + ".Branches")
38111147Smitch.hayenga@arm.com            .desc("Number of branches fetched")
38211147Smitch.hayenga@arm.com            .prereq(t_info.numBranches);
38311147Smitch.hayenga@arm.com
38411147Smitch.hayenga@arm.com        t_info.numPredictedBranches
38511147Smitch.hayenga@arm.com            .name(thread_str + ".predictedBranches")
38611147Smitch.hayenga@arm.com            .desc("Number of branches predicted as taken")
38711147Smitch.hayenga@arm.com            .prereq(t_info.numPredictedBranches);
38811147Smitch.hayenga@arm.com
38911147Smitch.hayenga@arm.com        t_info.numBranchMispred
39011147Smitch.hayenga@arm.com            .name(thread_str + ".BranchMispred")
39111147Smitch.hayenga@arm.com            .desc("Number of branch mispredictions")
39211147Smitch.hayenga@arm.com            .prereq(t_info.numBranchMispred);
39310193SCurtis.Dunham@arm.com    }
3942SN/A}
3952SN/A
3962SN/Avoid
3972623SN/ABaseSimpleCPU::resetStats()
398334SN/A{
39911147Smitch.hayenga@arm.com    for (auto &thread_info : threadInfo) {
40011147Smitch.hayenga@arm.com        thread_info->notIdleFraction = (_status != Idle);
40111147Smitch.hayenga@arm.com    }
402334SN/A}
403334SN/A
404334SN/Avoid
40510905Sandreas.sandberg@arm.comBaseSimpleCPU::serializeThread(CheckpointOut &cp, ThreadID tid) const
4062SN/A{
4079448SAndreas.Sandberg@ARM.com    assert(_status == Idle || _status == Running);
4089448SAndreas.Sandberg@ARM.com
40911147Smitch.hayenga@arm.com    threadInfo[tid]->thread->serialize(cp);
4102SN/A}
4112SN/A
4122SN/Avoid
41310905Sandreas.sandberg@arm.comBaseSimpleCPU::unserializeThread(CheckpointIn &cp, ThreadID tid)
4142SN/A{
41511147Smitch.hayenga@arm.com    threadInfo[tid]->thread->unserialize(cp);
4162SN/A}
4172SN/A
4182SN/Avoid
4196221Snate@binkert.orgchange_thread_state(ThreadID tid, int activate, int priority)
4202SN/A{
4212SN/A}
4222SN/A
4232SN/AAddr
4242623SN/ABaseSimpleCPU::dbg_vtophys(Addr addr)
4252SN/A{
42611147Smitch.hayenga@arm.com    return vtophys(threadContexts[curThread], addr);
4272SN/A}
4282SN/A
4292SN/Avoid
43011151Smitch.hayenga@arm.comBaseSimpleCPU::wakeup(ThreadID tid)
4312SN/A{
43211151Smitch.hayenga@arm.com    getCpuAddrMonitor(tid)->gotWakeup = true;
43311151Smitch.hayenga@arm.com
43411151Smitch.hayenga@arm.com    if (threadInfo[tid]->thread->status() == ThreadContext::Suspended) {
43511151Smitch.hayenga@arm.com        DPRINTF(Quiesce,"[tid:%d] Suspended Processor awoke\n", tid);
43611151Smitch.hayenga@arm.com        threadInfo[tid]->thread->activate();
43711147Smitch.hayenga@arm.com    }
4382SN/A}
4392SN/A
4402SN/Avoid
4412623SN/ABaseSimpleCPU::checkForInterrupts()
4422SN/A{
44311147Smitch.hayenga@arm.com    SimpleExecContext&t_info = *threadInfo[curThread];
44411147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
44511147Smitch.hayenga@arm.com    ThreadContext* tc = thread->getTC();
44611147Smitch.hayenga@arm.com
4475704Snate@binkert.org    if (checkInterrupts(tc)) {
44811150Smitch.hayenga@arm.com        Fault interrupt = interrupts[curThread]->getInterrupt(tc);
4492SN/A
4503520Sgblack@eecs.umich.edu        if (interrupt != NoFault) {
45111147Smitch.hayenga@arm.com            t_info.fetchOffset = 0;
45211150Smitch.hayenga@arm.com            interrupts[curThread]->updateIntrInfo(tc);
4533520Sgblack@eecs.umich.edu            interrupt->invoke(tc);
4549023Sgblack@eecs.umich.edu            thread->decoder.reset();
4552SN/A        }
4562SN/A    }
4572623SN/A}
4582SN/A
4592623SN/A
4605894Sgblack@eecs.umich.eduvoid
4612662Sstever@eecs.umich.eduBaseSimpleCPU::setupFetchRequest(Request *req)
4622623SN/A{
46311147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
46411147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
46511147Smitch.hayenga@arm.com
4667720Sgblack@eecs.umich.edu    Addr instAddr = thread->instAddr();
4674495Sacolyte@umich.edu
4682623SN/A    // set up memory request for instruction fetch
4697720Sgblack@eecs.umich.edu    DPRINTF(Fetch, "Fetch: PC:%08p\n", instAddr);
4702623SN/A
47111147Smitch.hayenga@arm.com    Addr fetchPC = (instAddr & PCMask) + t_info.fetchOffset;
4728832SAli.Saidi@ARM.com    req->setVirt(0, fetchPC, sizeof(MachInst), Request::INST_FETCH, instMasterId(),
4738832SAli.Saidi@ARM.com            instAddr);
4742623SN/A}
4752623SN/A
4762623SN/A
4772623SN/Avoid
4782623SN/ABaseSimpleCPU::preExecute()
4792623SN/A{
48011147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
48111147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
48211147Smitch.hayenga@arm.com
4832SN/A    // maintain $r0 semantics
4842683Sktlim@umich.edu    thread->setIntReg(ZeroReg, 0);
4852427SN/A#if THE_ISA == ALPHA_ISA
4862683Sktlim@umich.edu    thread->setFloatReg(ZeroReg, 0.0);
4872427SN/A#endif // ALPHA_ISA
4882SN/A
4892623SN/A    // check for instruction-count-based events
49011147Smitch.hayenga@arm.com    comInstEventQueue[curThread]->serviceEvents(t_info.numInst);
4917897Shestness@cs.utexas.edu    system->instEventQueue.serviceEvents(system->totalNumInsts);
4922SN/A
4932623SN/A    // decode the instruction
4942623SN/A    inst = gtoh(inst);
4954377Sgblack@eecs.umich.edu
4967720Sgblack@eecs.umich.edu    TheISA::PCState pcState = thread->pcState();
4974377Sgblack@eecs.umich.edu
4987720Sgblack@eecs.umich.edu    if (isRomMicroPC(pcState.microPC())) {
49911147Smitch.hayenga@arm.com        t_info.stayAtPC = false;
5007720Sgblack@eecs.umich.edu        curStaticInst = microcodeRom.fetchMicroop(pcState.microPC(),
5017720Sgblack@eecs.umich.edu                                                  curMacroStaticInst);
5025665Sgblack@eecs.umich.edu    } else if (!curMacroStaticInst) {
5035665Sgblack@eecs.umich.edu        //We're not in the middle of a macro instruction
5044181Sgblack@eecs.umich.edu        StaticInstPtr instPtr = NULL;
5054181Sgblack@eecs.umich.edu
5069023Sgblack@eecs.umich.edu        TheISA::Decoder *decoder = &(thread->decoder);
5079023Sgblack@eecs.umich.edu
5084181Sgblack@eecs.umich.edu        //Predecode, ie bundle up an ExtMachInst
5094182Sgblack@eecs.umich.edu        //If more fetch data is needed, pass it in.
51011147Smitch.hayenga@arm.com        Addr fetchPC = (pcState.instAddr() & PCMask) + t_info.fetchOffset;
51111321Ssteve.reinhardt@amd.com        //if (decoder->needMoreBytes())
5129023Sgblack@eecs.umich.edu            decoder->moreBytes(pcState, fetchPC, inst);
5134593Sgblack@eecs.umich.edu        //else
5149023Sgblack@eecs.umich.edu        //    decoder->process();
5154377Sgblack@eecs.umich.edu
5169023Sgblack@eecs.umich.edu        //Decode an instruction if one is ready. Otherwise, we'll have to
5174377Sgblack@eecs.umich.edu        //fetch beyond the MachInst at the current pc.
5189023Sgblack@eecs.umich.edu        instPtr = decoder->decode(pcState);
5199023Sgblack@eecs.umich.edu        if (instPtr) {
52011147Smitch.hayenga@arm.com            t_info.stayAtPC = false;
5217720Sgblack@eecs.umich.edu            thread->pcState(pcState);
5224377Sgblack@eecs.umich.edu        } else {
52311147Smitch.hayenga@arm.com            t_info.stayAtPC = true;
52411147Smitch.hayenga@arm.com            t_info.fetchOffset += sizeof(MachInst);
5254377Sgblack@eecs.umich.edu        }
5264181Sgblack@eecs.umich.edu
5274181Sgblack@eecs.umich.edu        //If we decoded an instruction and it's microcoded, start pulling
5284181Sgblack@eecs.umich.edu        //out micro ops
5294539Sgblack@eecs.umich.edu        if (instPtr && instPtr->isMacroop()) {
5303276Sgblack@eecs.umich.edu            curMacroStaticInst = instPtr;
53111147Smitch.hayenga@arm.com            curStaticInst =
53211147Smitch.hayenga@arm.com                curMacroStaticInst->fetchMicroop(pcState.microPC());
5333280Sgblack@eecs.umich.edu        } else {
5343280Sgblack@eecs.umich.edu            curStaticInst = instPtr;
5353276Sgblack@eecs.umich.edu        }
5363276Sgblack@eecs.umich.edu    } else {
5373276Sgblack@eecs.umich.edu        //Read the next micro op from the macro op
5387720Sgblack@eecs.umich.edu        curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC());
5393276Sgblack@eecs.umich.edu    }
5403276Sgblack@eecs.umich.edu
5414181Sgblack@eecs.umich.edu    //If we decoded an instruction this "tick", record information about it.
5428955Sgblack@eecs.umich.edu    if (curStaticInst) {
5434522Ssaidi@eecs.umich.edu#if TRACING_ON
54411147Smitch.hayenga@arm.com        traceData = tracer->getInstRecord(curTick(), thread->getTC(),
5457720Sgblack@eecs.umich.edu                curStaticInst, thread->pcState(), curMacroStaticInst);
5462470SN/A
5478955Sgblack@eecs.umich.edu        DPRINTF(Decode,"Decode: Decoded %s instruction: %#x\n",
5484181Sgblack@eecs.umich.edu                curStaticInst->getName(), curStaticInst->machInst);
5494522Ssaidi@eecs.umich.edu#endif // TRACING_ON
5504181Sgblack@eecs.umich.edu    }
55110061Sandreas@sandberg.pp.se
55211147Smitch.hayenga@arm.com    if (branchPred && curStaticInst &&
55311147Smitch.hayenga@arm.com        curStaticInst->isControl()) {
55410061Sandreas@sandberg.pp.se        // Use a fake sequence number since we only have one
55510061Sandreas@sandberg.pp.se        // instruction in flight at the same time.
55610061Sandreas@sandberg.pp.se        const InstSeqNum cur_sn(0);
55711147Smitch.hayenga@arm.com        t_info.predPC = thread->pcState();
55810061Sandreas@sandberg.pp.se        const bool predict_taken(
55911147Smitch.hayenga@arm.com            branchPred->predict(curStaticInst, cur_sn, t_info.predPC,
56011147Smitch.hayenga@arm.com                                curThread));
56110061Sandreas@sandberg.pp.se
56210061Sandreas@sandberg.pp.se        if (predict_taken)
56311147Smitch.hayenga@arm.com            ++t_info.numPredictedBranches;
56410061Sandreas@sandberg.pp.se    }
5652623SN/A}
5662623SN/A
5672623SN/Avoid
5682623SN/ABaseSimpleCPU::postExecute()
5692623SN/A{
57011147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
57111147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
57211147Smitch.hayenga@arm.com
5737720Sgblack@eecs.umich.edu    assert(curStaticInst);
5747720Sgblack@eecs.umich.edu
57511147Smitch.hayenga@arm.com    TheISA::PCState pc = threadContexts[curThread]->pcState();
5767720Sgblack@eecs.umich.edu    Addr instAddr = pc.instAddr();
5778780Sgblack@eecs.umich.edu    if (FullSystem && thread->profile) {
57811147Smitch.hayenga@arm.com        bool usermode = TheISA::inUserMode(threadContexts[curThread]);
5797720Sgblack@eecs.umich.edu        thread->profilePC = usermode ? 1 : instAddr;
58011147Smitch.hayenga@arm.com        ProfileNode *node = thread->profile->consume(threadContexts[curThread],
58111147Smitch.hayenga@arm.com                                                     curStaticInst);
5822623SN/A        if (node)
5832683Sktlim@umich.edu            thread->profileNode = node;
5842623SN/A    }
5852SN/A
5862623SN/A    if (curStaticInst->isMemRef()) {
58711147Smitch.hayenga@arm.com        t_info.numMemRefs++;
5882SN/A    }
5892SN/A
5902623SN/A    if (curStaticInst->isLoad()) {
59111147Smitch.hayenga@arm.com        ++t_info.numLoad;
59211147Smitch.hayenga@arm.com        comLoadEventQueue[curThread]->serviceEvents(t_info.numLoad);
5932623SN/A    }
5942SN/A
5955953Ssaidi@eecs.umich.edu    if (CPA::available()) {
59611147Smitch.hayenga@arm.com        CPA::cpa()->swAutoBegin(threadContexts[curThread], pc.nextInstAddr());
5975953Ssaidi@eecs.umich.edu    }
5985953Ssaidi@eecs.umich.edu
59910061Sandreas@sandberg.pp.se    if (curStaticInst->isControl()) {
60011147Smitch.hayenga@arm.com        ++t_info.numBranches;
60110061Sandreas@sandberg.pp.se    }
60210061Sandreas@sandberg.pp.se
6037897Shestness@cs.utexas.edu    /* Power model statistics */
6047897Shestness@cs.utexas.edu    //integer alu accesses
6057897Shestness@cs.utexas.edu    if (curStaticInst->isInteger()){
60611147Smitch.hayenga@arm.com        t_info.numIntAluAccesses++;
60711147Smitch.hayenga@arm.com        t_info.numIntInsts++;
6087897Shestness@cs.utexas.edu    }
6097897Shestness@cs.utexas.edu
6107897Shestness@cs.utexas.edu    //float alu accesses
6117897Shestness@cs.utexas.edu    if (curStaticInst->isFloating()){
61211147Smitch.hayenga@arm.com        t_info.numFpAluAccesses++;
61311147Smitch.hayenga@arm.com        t_info.numFpInsts++;
6147897Shestness@cs.utexas.edu    }
61511147Smitch.hayenga@arm.com
6167897Shestness@cs.utexas.edu    //number of function calls/returns to get window accesses
6177897Shestness@cs.utexas.edu    if (curStaticInst->isCall() || curStaticInst->isReturn()){
61811147Smitch.hayenga@arm.com        t_info.numCallsReturns++;
6197897Shestness@cs.utexas.edu    }
62011147Smitch.hayenga@arm.com
6217897Shestness@cs.utexas.edu    //the number of branch predictions that will be made
6227897Shestness@cs.utexas.edu    if (curStaticInst->isCondCtrl()){
62311147Smitch.hayenga@arm.com        t_info.numCondCtrlInsts++;
6247897Shestness@cs.utexas.edu    }
62511147Smitch.hayenga@arm.com
6267897Shestness@cs.utexas.edu    //result bus acceses
6277897Shestness@cs.utexas.edu    if (curStaticInst->isLoad()){
62811147Smitch.hayenga@arm.com        t_info.numLoadInsts++;
6297897Shestness@cs.utexas.edu    }
63011147Smitch.hayenga@arm.com
6317897Shestness@cs.utexas.edu    if (curStaticInst->isStore()){
63211147Smitch.hayenga@arm.com        t_info.numStoreInsts++;
6337897Shestness@cs.utexas.edu    }
6347897Shestness@cs.utexas.edu    /* End power model statistics */
6357897Shestness@cs.utexas.edu
63611147Smitch.hayenga@arm.com    t_info.statExecutedInstType[curStaticInst->opClass()]++;
63710193SCurtis.Dunham@arm.com
6388780Sgblack@eecs.umich.edu    if (FullSystem)
6398780Sgblack@eecs.umich.edu        traceFunctions(instAddr);
6402644Sstever@eecs.umich.edu
6412644Sstever@eecs.umich.edu    if (traceData) {
6424046Sbinkertn@umich.edu        traceData->dump();
6434046Sbinkertn@umich.edu        delete traceData;
6444046Sbinkertn@umich.edu        traceData = NULL;
6452644Sstever@eecs.umich.edu    }
64610464SAndreas.Sandberg@ARM.com
64710464SAndreas.Sandberg@ARM.com    // Call CPU instruction commit probes
64810464SAndreas.Sandberg@ARM.com    probeInstCommit(curStaticInst);
6492623SN/A}
6502SN/A
6512623SN/Avoid
65210379Sandreas.hansson@arm.comBaseSimpleCPU::advancePC(const Fault &fault)
6532623SN/A{
65411147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
65511147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
65611147Smitch.hayenga@arm.com
65710061Sandreas@sandberg.pp.se    const bool branching(thread->pcState().branching());
65810061Sandreas@sandberg.pp.se
6594377Sgblack@eecs.umich.edu    //Since we're moving to a new pc, zero out the offset
66011147Smitch.hayenga@arm.com    t_info.fetchOffset = 0;
6612090SN/A    if (fault != NoFault) {
6623905Ssaidi@eecs.umich.edu        curMacroStaticInst = StaticInst::nullStaticInstPtr;
66311147Smitch.hayenga@arm.com        fault->invoke(threadContexts[curThread], curStaticInst);
6649023Sgblack@eecs.umich.edu        thread->decoder.reset();
6654377Sgblack@eecs.umich.edu    } else {
6667720Sgblack@eecs.umich.edu        if (curStaticInst) {
6677720Sgblack@eecs.umich.edu            if (curStaticInst->isLastMicroop())
6687720Sgblack@eecs.umich.edu                curMacroStaticInst = StaticInst::nullStaticInstPtr;
6697720Sgblack@eecs.umich.edu            TheISA::PCState pcState = thread->pcState();
6707720Sgblack@eecs.umich.edu            TheISA::advancePC(pcState, curStaticInst);
6717720Sgblack@eecs.umich.edu            thread->pcState(pcState);
6723276Sgblack@eecs.umich.edu        }
6732SN/A    }
67410061Sandreas@sandberg.pp.se
67510061Sandreas@sandberg.pp.se    if (branchPred && curStaticInst && curStaticInst->isControl()) {
67610061Sandreas@sandberg.pp.se        // Use a fake sequence number since we only have one
67710061Sandreas@sandberg.pp.se        // instruction in flight at the same time.
67810061Sandreas@sandberg.pp.se        const InstSeqNum cur_sn(0);
67910061Sandreas@sandberg.pp.se
68011147Smitch.hayenga@arm.com        if (t_info.predPC == thread->pcState()) {
68110061Sandreas@sandberg.pp.se            // Correctly predicted branch
68211147Smitch.hayenga@arm.com            branchPred->update(cur_sn, curThread);
68310061Sandreas@sandberg.pp.se        } else {
68410061Sandreas@sandberg.pp.se            // Mis-predicted branch
68511147Smitch.hayenga@arm.com            branchPred->squash(cur_sn, thread->pcState(), branching, curThread);
68611147Smitch.hayenga@arm.com            ++t_info.numBranchMispred;
68710061Sandreas@sandberg.pp.se        }
68810061Sandreas@sandberg.pp.se    }
6892SN/A}
6902SN/A
6919461Snilay@cs.wisc.eduvoid
6929461Snilay@cs.wisc.eduBaseSimpleCPU::startup()
6939461Snilay@cs.wisc.edu{
6949461Snilay@cs.wisc.edu    BaseCPU::startup();
69511147Smitch.hayenga@arm.com    for (auto& t_info : threadInfo)
69611147Smitch.hayenga@arm.com        t_info->thread->startup();
6979461Snilay@cs.wisc.edu}
698