base.cc revision 11722
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
448779Sgblack@eecs.umich.edu#include "arch/kernel_stats.hh"
458779Sgblack@eecs.umich.edu#include "arch/stacktrace.hh"
468779Sgblack@eecs.umich.edu#include "arch/tlb.hh"
472439SN/A#include "arch/utility.hh"
488779Sgblack@eecs.umich.edu#include "arch/vtophys.hh"
498229Snate@binkert.org#include "base/loader/symtab.hh"
506216Snate@binkert.org#include "base/cp_annotate.hh"
51146SN/A#include "base/cprintf.hh"
52146SN/A#include "base/inifile.hh"
53146SN/A#include "base/misc.hh"
54146SN/A#include "base/pollevent.hh"
55146SN/A#include "base/trace.hh"
566216Snate@binkert.org#include "base/types.hh"
576658Snate@binkert.org#include "config/the_isa.hh"
588229Snate@binkert.org#include "cpu/simple/base.hh"
591717SN/A#include "cpu/base.hh"
608887Sgeoffrey.blake@arm.com#include "cpu/checker/cpu.hh"
618887Sgeoffrey.blake@arm.com#include "cpu/checker/thread_context.hh"
62146SN/A#include "cpu/exetrace.hh"
6310061Sandreas@sandberg.pp.se#include "cpu/pred/bpred_unit.hh"
641977SN/A#include "cpu/profile.hh"
6511147Smitch.hayenga@arm.com#include "cpu/simple/exec_context.hh"
662683Sktlim@umich.edu#include "cpu/simple_thread.hh"
671717SN/A#include "cpu/smt.hh"
68146SN/A#include "cpu/static_inst.hh"
692683Sktlim@umich.edu#include "cpu/thread_context.hh"
708232Snate@binkert.org#include "debug/Decode.hh"
718232Snate@binkert.org#include "debug/Fetch.hh"
728232Snate@binkert.org#include "debug/Quiesce.hh"
738779Sgblack@eecs.umich.edu#include "mem/mem_object.hh"
743348Sbinkertn@umich.edu#include "mem/packet.hh"
756105Ssteve.reinhardt@amd.com#include "mem/request.hh"
766216Snate@binkert.org#include "params/BaseSimpleCPU.hh"
772036SN/A#include "sim/byteswap.hh"
78146SN/A#include "sim/debug.hh"
798817Sgblack@eecs.umich.edu#include "sim/faults.hh"
808793Sgblack@eecs.umich.edu#include "sim/full_system.hh"
8156SN/A#include "sim/sim_events.hh"
8256SN/A#include "sim/sim_object.hh"
83695SN/A#include "sim/stats.hh"
842901Ssaidi@eecs.umich.edu#include "sim/system.hh"
852SN/A
862SN/Ausing namespace std;
872449SN/Ausing namespace TheISA;
881355SN/A
895529Snate@binkert.orgBaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p)
9010061Sandreas@sandberg.pp.se    : BaseCPU(p),
9111147Smitch.hayenga@arm.com      curThread(0),
9210061Sandreas@sandberg.pp.se      branchPred(p->branchPred),
9311147Smitch.hayenga@arm.com      traceData(NULL),
9411147Smitch.hayenga@arm.com      inst(),
9511147Smitch.hayenga@arm.com      _status(Idle)
96224SN/A{
9711147Smitch.hayenga@arm.com    SimpleThread *thread;
982SN/A
9911147Smitch.hayenga@arm.com    for (unsigned i = 0; i < numThreads; i++) {
10011147Smitch.hayenga@arm.com        if (FullSystem) {
10111147Smitch.hayenga@arm.com            thread = new SimpleThread(this, i, p->system,
10211147Smitch.hayenga@arm.com                                      p->itb, p->dtb, p->isa[i]);
10311147Smitch.hayenga@arm.com        } else {
10411147Smitch.hayenga@arm.com            thread = new SimpleThread(this, i, p->system, p->workload[i],
10511147Smitch.hayenga@arm.com                                      p->itb, p->dtb, p->isa[i]);
10611147Smitch.hayenga@arm.com        }
10711147Smitch.hayenga@arm.com        threadInfo.push_back(new SimpleExecContext(this, thread));
10811147Smitch.hayenga@arm.com        ThreadContext *tc = thread->getTC();
10911147Smitch.hayenga@arm.com        threadContexts.push_back(tc);
11011147Smitch.hayenga@arm.com    }
1112SN/A
1128733Sgeoffrey.blake@arm.com    if (p->checker) {
11311147Smitch.hayenga@arm.com        if (numThreads != 1)
11411147Smitch.hayenga@arm.com            fatal("Checker currently does not support SMT");
11511147Smitch.hayenga@arm.com
1168733Sgeoffrey.blake@arm.com        BaseCPU *temp_checker = p->checker;
1178733Sgeoffrey.blake@arm.com        checker = dynamic_cast<CheckerCPU *>(temp_checker);
1188733Sgeoffrey.blake@arm.com        checker->setSystem(p->system);
1198733Sgeoffrey.blake@arm.com        // Manipulate thread context
12011147Smitch.hayenga@arm.com        ThreadContext *cpu_tc = threadContexts[0];
12111147Smitch.hayenga@arm.com        threadContexts[0] = new CheckerThreadContext<ThreadContext>(cpu_tc, this->checker);
1228733Sgeoffrey.blake@arm.com    } else {
1238733Sgeoffrey.blake@arm.com        checker = NULL;
1248733Sgeoffrey.blake@arm.com    }
12511147Smitch.hayenga@arm.com}
1268733Sgeoffrey.blake@arm.com
12711147Smitch.hayenga@arm.comvoid
12811147Smitch.hayenga@arm.comBaseSimpleCPU::init()
12911147Smitch.hayenga@arm.com{
13011147Smitch.hayenga@arm.com    BaseCPU::init();
1312SN/A
13211147Smitch.hayenga@arm.com    for (auto tc : threadContexts) {
13311147Smitch.hayenga@arm.com        // Initialise the ThreadContext's memory proxies
13411147Smitch.hayenga@arm.com        tc->initMemProxies(tc);
1354377Sgblack@eecs.umich.edu
13611147Smitch.hayenga@arm.com        if (FullSystem && !params()->switched_out) {
13711147Smitch.hayenga@arm.com            // initialize CPU, including PC
13811147Smitch.hayenga@arm.com            TheISA::initCPU(tc, tc->contextId());
13911147Smitch.hayenga@arm.com        }
14011147Smitch.hayenga@arm.com    }
14111147Smitch.hayenga@arm.com}
1425169Ssaidi@eecs.umich.edu
14311147Smitch.hayenga@arm.comvoid
14411147Smitch.hayenga@arm.comBaseSimpleCPU::checkPcEventQueue()
14511147Smitch.hayenga@arm.com{
14611147Smitch.hayenga@arm.com    Addr oldpc, pc = threadInfo[curThread]->thread->instAddr();
14711147Smitch.hayenga@arm.com    do {
14811147Smitch.hayenga@arm.com        oldpc = pc;
14911147Smitch.hayenga@arm.com        system->pcEventQueue.service(threadContexts[curThread]);
15011147Smitch.hayenga@arm.com        pc = threadInfo[curThread]->thread->instAddr();
15111147Smitch.hayenga@arm.com    } while (oldpc != pc);
15211147Smitch.hayenga@arm.com}
15311147Smitch.hayenga@arm.com
15411147Smitch.hayenga@arm.comvoid
15511147Smitch.hayenga@arm.comBaseSimpleCPU::swapActiveThread()
15611147Smitch.hayenga@arm.com{
15711147Smitch.hayenga@arm.com    if (numThreads > 1) {
15811147Smitch.hayenga@arm.com        if ((!curStaticInst || !curStaticInst->isDelayedCommit()) &&
15911147Smitch.hayenga@arm.com             !threadInfo[curThread]->stayAtPC) {
16011147Smitch.hayenga@arm.com            // Swap active threads
16111147Smitch.hayenga@arm.com            if (!activeThreads.empty()) {
16211147Smitch.hayenga@arm.com                curThread = activeThreads.front();
16311147Smitch.hayenga@arm.com                activeThreads.pop_front();
16411147Smitch.hayenga@arm.com                activeThreads.push_back(curThread);
16511147Smitch.hayenga@arm.com            }
16611147Smitch.hayenga@arm.com        }
16711147Smitch.hayenga@arm.com    }
16811147Smitch.hayenga@arm.com}
16911147Smitch.hayenga@arm.com
17011147Smitch.hayenga@arm.comvoid
17111147Smitch.hayenga@arm.comBaseSimpleCPU::countInst()
17211147Smitch.hayenga@arm.com{
17311147Smitch.hayenga@arm.com    SimpleExecContext& t_info = *threadInfo[curThread];
17411147Smitch.hayenga@arm.com
17511147Smitch.hayenga@arm.com    if (!curStaticInst->isMicroop() || curStaticInst->isLastMicroop()) {
17611147Smitch.hayenga@arm.com        t_info.numInst++;
17711147Smitch.hayenga@arm.com        t_info.numInsts++;
17811147Smitch.hayenga@arm.com    }
17911147Smitch.hayenga@arm.com    t_info.numOp++;
18011147Smitch.hayenga@arm.com    t_info.numOps++;
18111147Smitch.hayenga@arm.com
18211147Smitch.hayenga@arm.com    system->totalNumInsts++;
18311147Smitch.hayenga@arm.com    t_info.thread->funcExeInst++;
18411147Smitch.hayenga@arm.com}
18511147Smitch.hayenga@arm.com
18611147Smitch.hayenga@arm.comCounter
18711147Smitch.hayenga@arm.comBaseSimpleCPU::totalInsts() const
18811147Smitch.hayenga@arm.com{
18911147Smitch.hayenga@arm.com    Counter total_inst = 0;
19011147Smitch.hayenga@arm.com    for (auto& t_info : threadInfo) {
19111147Smitch.hayenga@arm.com        total_inst += t_info->numInst;
19211147Smitch.hayenga@arm.com    }
19311147Smitch.hayenga@arm.com
19411147Smitch.hayenga@arm.com    return total_inst;
19511147Smitch.hayenga@arm.com}
19611147Smitch.hayenga@arm.com
19711147Smitch.hayenga@arm.comCounter
19811147Smitch.hayenga@arm.comBaseSimpleCPU::totalOps() const
19911147Smitch.hayenga@arm.com{
20011147Smitch.hayenga@arm.com    Counter total_op = 0;
20111147Smitch.hayenga@arm.com    for (auto& t_info : threadInfo) {
20211147Smitch.hayenga@arm.com        total_op += t_info->numOp;
20311147Smitch.hayenga@arm.com    }
20411147Smitch.hayenga@arm.com
20511147Smitch.hayenga@arm.com    return total_op;
2062SN/A}
2072SN/A
2082623SN/ABaseSimpleCPU::~BaseSimpleCPU()
2092SN/A{
2102SN/A}
2112SN/A
212180SN/Avoid
2138737Skoansin.tan@gmail.comBaseSimpleCPU::haltContext(ThreadID thread_num)
214393SN/A{
215393SN/A    // for now, these are equivalent
216393SN/A    suspendContext(thread_num);
217393SN/A}
218384SN/A
219189SN/A
220189SN/Avoid
2212623SN/ABaseSimpleCPU::regStats()
2222SN/A{
223729SN/A    using namespace Stats;
224334SN/A
2252SN/A    BaseCPU::regStats();
2262SN/A
22711147Smitch.hayenga@arm.com    for (ThreadID tid = 0; tid < numThreads; tid++) {
22811147Smitch.hayenga@arm.com        SimpleExecContext& t_info = *threadInfo[tid];
2298834Satgutier@umich.edu
23011147Smitch.hayenga@arm.com        std::string thread_str = name();
23111147Smitch.hayenga@arm.com        if (numThreads > 1)
23211147Smitch.hayenga@arm.com            thread_str += ".thread" + std::to_string(tid);
2332SN/A
23411147Smitch.hayenga@arm.com        t_info.numInsts
23511147Smitch.hayenga@arm.com            .name(thread_str + ".committedInsts")
23611147Smitch.hayenga@arm.com            .desc("Number of instructions committed")
23711147Smitch.hayenga@arm.com            ;
2387897Shestness@cs.utexas.edu
23911147Smitch.hayenga@arm.com        t_info.numOps
24011147Smitch.hayenga@arm.com            .name(thread_str + ".committedOps")
24111147Smitch.hayenga@arm.com            .desc("Number of ops (including micro ops) committed")
24211147Smitch.hayenga@arm.com            ;
2437897Shestness@cs.utexas.edu
24411147Smitch.hayenga@arm.com        t_info.numIntAluAccesses
24511147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_alu_accesses")
24611147Smitch.hayenga@arm.com            .desc("Number of integer alu accesses")
24711147Smitch.hayenga@arm.com            ;
2487897Shestness@cs.utexas.edu
24911147Smitch.hayenga@arm.com        t_info.numFpAluAccesses
25011147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_alu_accesses")
25111147Smitch.hayenga@arm.com            .desc("Number of float alu accesses")
25211147Smitch.hayenga@arm.com            ;
2537897Shestness@cs.utexas.edu
25411147Smitch.hayenga@arm.com        t_info.numCallsReturns
25511147Smitch.hayenga@arm.com            .name(thread_str + ".num_func_calls")
25611147Smitch.hayenga@arm.com            .desc("number of times a function call or return occured")
25711147Smitch.hayenga@arm.com            ;
2587897Shestness@cs.utexas.edu
25911147Smitch.hayenga@arm.com        t_info.numCondCtrlInsts
26011147Smitch.hayenga@arm.com            .name(thread_str + ".num_conditional_control_insts")
26111147Smitch.hayenga@arm.com            .desc("number of instructions that are conditional controls")
26211147Smitch.hayenga@arm.com            ;
2637897Shestness@cs.utexas.edu
26411147Smitch.hayenga@arm.com        t_info.numIntInsts
26511147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_insts")
26611147Smitch.hayenga@arm.com            .desc("number of integer instructions")
26711147Smitch.hayenga@arm.com            ;
2687897Shestness@cs.utexas.edu
26911147Smitch.hayenga@arm.com        t_info.numFpInsts
27011147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_insts")
27111147Smitch.hayenga@arm.com            .desc("number of float instructions")
27211147Smitch.hayenga@arm.com            ;
2737897Shestness@cs.utexas.edu
27411147Smitch.hayenga@arm.com        t_info.numIntRegReads
27511147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_register_reads")
27611147Smitch.hayenga@arm.com            .desc("number of times the integer registers were read")
27711147Smitch.hayenga@arm.com            ;
2787897Shestness@cs.utexas.edu
27911147Smitch.hayenga@arm.com        t_info.numIntRegWrites
28011147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_register_writes")
28111147Smitch.hayenga@arm.com            .desc("number of times the integer registers were written")
28211147Smitch.hayenga@arm.com            ;
2837897Shestness@cs.utexas.edu
28411147Smitch.hayenga@arm.com        t_info.numFpRegReads
28511147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_register_reads")
28611147Smitch.hayenga@arm.com            .desc("number of times the floating registers were read")
28711147Smitch.hayenga@arm.com            ;
2889920Syasuko.eckert@amd.com
28911147Smitch.hayenga@arm.com        t_info.numFpRegWrites
29011147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_register_writes")
29111147Smitch.hayenga@arm.com            .desc("number of times the floating registers were written")
29211147Smitch.hayenga@arm.com            ;
2939920Syasuko.eckert@amd.com
29411147Smitch.hayenga@arm.com        t_info.numCCRegReads
29511147Smitch.hayenga@arm.com            .name(thread_str + ".num_cc_register_reads")
29611147Smitch.hayenga@arm.com            .desc("number of times the CC registers were read")
29711147Smitch.hayenga@arm.com            .flags(nozero)
29811147Smitch.hayenga@arm.com            ;
2997897Shestness@cs.utexas.edu
30011147Smitch.hayenga@arm.com        t_info.numCCRegWrites
30111147Smitch.hayenga@arm.com            .name(thread_str + ".num_cc_register_writes")
30211147Smitch.hayenga@arm.com            .desc("number of times the CC registers were written")
30311147Smitch.hayenga@arm.com            .flags(nozero)
30411147Smitch.hayenga@arm.com            ;
3057897Shestness@cs.utexas.edu
30611147Smitch.hayenga@arm.com        t_info.numMemRefs
30711147Smitch.hayenga@arm.com            .name(thread_str + ".num_mem_refs")
30811147Smitch.hayenga@arm.com            .desc("number of memory refs")
30911147Smitch.hayenga@arm.com            ;
3102SN/A
31111147Smitch.hayenga@arm.com        t_info.numStoreInsts
31211147Smitch.hayenga@arm.com            .name(thread_str + ".num_store_insts")
31311147Smitch.hayenga@arm.com            .desc("Number of store instructions")
31411147Smitch.hayenga@arm.com            ;
3151001SN/A
31611147Smitch.hayenga@arm.com        t_info.numLoadInsts
31711147Smitch.hayenga@arm.com            .name(thread_str + ".num_load_insts")
31811147Smitch.hayenga@arm.com            .desc("Number of load instructions")
31911147Smitch.hayenga@arm.com            ;
3202SN/A
32111147Smitch.hayenga@arm.com        t_info.notIdleFraction
32211147Smitch.hayenga@arm.com            .name(thread_str + ".not_idle_fraction")
32311147Smitch.hayenga@arm.com            .desc("Percentage of non-idle cycles")
32411147Smitch.hayenga@arm.com            ;
3257897Shestness@cs.utexas.edu
32611147Smitch.hayenga@arm.com        t_info.idleFraction
32711147Smitch.hayenga@arm.com            .name(thread_str + ".idle_fraction")
32811147Smitch.hayenga@arm.com            .desc("Percentage of idle cycles")
32911147Smitch.hayenga@arm.com            ;
3307897Shestness@cs.utexas.edu
33111147Smitch.hayenga@arm.com        t_info.numBusyCycles
33211147Smitch.hayenga@arm.com            .name(thread_str + ".num_busy_cycles")
33311147Smitch.hayenga@arm.com            .desc("Number of busy cycles")
33411147Smitch.hayenga@arm.com            ;
3352SN/A
33611147Smitch.hayenga@arm.com        t_info.numIdleCycles
33711147Smitch.hayenga@arm.com            .name(thread_str + ".num_idle_cycles")
33811147Smitch.hayenga@arm.com            .desc("Number of idle cycles")
33911147Smitch.hayenga@arm.com            ;
3402SN/A
34111147Smitch.hayenga@arm.com        t_info.icacheStallCycles
34211147Smitch.hayenga@arm.com            .name(thread_str + ".icache_stall_cycles")
34311147Smitch.hayenga@arm.com            .desc("ICache total stall cycles")
34411147Smitch.hayenga@arm.com            .prereq(t_info.icacheStallCycles)
34511147Smitch.hayenga@arm.com            ;
34611147Smitch.hayenga@arm.com
34711147Smitch.hayenga@arm.com        t_info.dcacheStallCycles
34811147Smitch.hayenga@arm.com            .name(thread_str + ".dcache_stall_cycles")
34911147Smitch.hayenga@arm.com            .desc("DCache total stall cycles")
35011147Smitch.hayenga@arm.com            .prereq(t_info.dcacheStallCycles)
35111147Smitch.hayenga@arm.com            ;
35211147Smitch.hayenga@arm.com
35311147Smitch.hayenga@arm.com        t_info.statExecutedInstType
35411147Smitch.hayenga@arm.com            .init(Enums::Num_OpClass)
35511147Smitch.hayenga@arm.com            .name(thread_str + ".op_class")
35611147Smitch.hayenga@arm.com            .desc("Class of executed instruction")
35711147Smitch.hayenga@arm.com            .flags(total | pdf | dist)
35811147Smitch.hayenga@arm.com            ;
35911147Smitch.hayenga@arm.com
36011147Smitch.hayenga@arm.com        for (unsigned i = 0; i < Num_OpClasses; ++i) {
36111147Smitch.hayenga@arm.com            t_info.statExecutedInstType.subname(i, Enums::OpClassStrings[i]);
36211147Smitch.hayenga@arm.com        }
36311147Smitch.hayenga@arm.com
36411147Smitch.hayenga@arm.com        t_info.idleFraction = constant(1.0) - t_info.notIdleFraction;
36511147Smitch.hayenga@arm.com        t_info.numIdleCycles = t_info.idleFraction * numCycles;
36611147Smitch.hayenga@arm.com        t_info.numBusyCycles = t_info.notIdleFraction * numCycles;
36711147Smitch.hayenga@arm.com
36811147Smitch.hayenga@arm.com        t_info.numBranches
36911147Smitch.hayenga@arm.com            .name(thread_str + ".Branches")
37011147Smitch.hayenga@arm.com            .desc("Number of branches fetched")
37111147Smitch.hayenga@arm.com            .prereq(t_info.numBranches);
37211147Smitch.hayenga@arm.com
37311147Smitch.hayenga@arm.com        t_info.numPredictedBranches
37411147Smitch.hayenga@arm.com            .name(thread_str + ".predictedBranches")
37511147Smitch.hayenga@arm.com            .desc("Number of branches predicted as taken")
37611147Smitch.hayenga@arm.com            .prereq(t_info.numPredictedBranches);
37711147Smitch.hayenga@arm.com
37811147Smitch.hayenga@arm.com        t_info.numBranchMispred
37911147Smitch.hayenga@arm.com            .name(thread_str + ".BranchMispred")
38011147Smitch.hayenga@arm.com            .desc("Number of branch mispredictions")
38111147Smitch.hayenga@arm.com            .prereq(t_info.numBranchMispred);
38210193SCurtis.Dunham@arm.com    }
3832SN/A}
3842SN/A
3852SN/Avoid
3862623SN/ABaseSimpleCPU::resetStats()
387334SN/A{
38811147Smitch.hayenga@arm.com    for (auto &thread_info : threadInfo) {
38911147Smitch.hayenga@arm.com        thread_info->notIdleFraction = (_status != Idle);
39011147Smitch.hayenga@arm.com    }
391334SN/A}
392334SN/A
393334SN/Avoid
39410905Sandreas.sandberg@arm.comBaseSimpleCPU::serializeThread(CheckpointOut &cp, ThreadID tid) const
3952SN/A{
3969448SAndreas.Sandberg@ARM.com    assert(_status == Idle || _status == Running);
3979448SAndreas.Sandberg@ARM.com
39811147Smitch.hayenga@arm.com    threadInfo[tid]->thread->serialize(cp);
3992SN/A}
4002SN/A
4012SN/Avoid
40210905Sandreas.sandberg@arm.comBaseSimpleCPU::unserializeThread(CheckpointIn &cp, ThreadID tid)
4032SN/A{
40411147Smitch.hayenga@arm.com    threadInfo[tid]->thread->unserialize(cp);
4052SN/A}
4062SN/A
4072SN/Avoid
4086221Snate@binkert.orgchange_thread_state(ThreadID tid, int activate, int priority)
4092SN/A{
4102SN/A}
4112SN/A
4122SN/AAddr
4132623SN/ABaseSimpleCPU::dbg_vtophys(Addr addr)
4142SN/A{
41511147Smitch.hayenga@arm.com    return vtophys(threadContexts[curThread], addr);
4162SN/A}
4172SN/A
4182SN/Avoid
41911151Smitch.hayenga@arm.comBaseSimpleCPU::wakeup(ThreadID tid)
4202SN/A{
42111151Smitch.hayenga@arm.com    getCpuAddrMonitor(tid)->gotWakeup = true;
42211151Smitch.hayenga@arm.com
42311151Smitch.hayenga@arm.com    if (threadInfo[tid]->thread->status() == ThreadContext::Suspended) {
42411151Smitch.hayenga@arm.com        DPRINTF(Quiesce,"[tid:%d] Suspended Processor awoke\n", tid);
42511151Smitch.hayenga@arm.com        threadInfo[tid]->thread->activate();
42611147Smitch.hayenga@arm.com    }
4272SN/A}
4282SN/A
4292SN/Avoid
4302623SN/ABaseSimpleCPU::checkForInterrupts()
4312SN/A{
43211147Smitch.hayenga@arm.com    SimpleExecContext&t_info = *threadInfo[curThread];
43311147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
43411147Smitch.hayenga@arm.com    ThreadContext* tc = thread->getTC();
43511147Smitch.hayenga@arm.com
4365704Snate@binkert.org    if (checkInterrupts(tc)) {
43711150Smitch.hayenga@arm.com        Fault interrupt = interrupts[curThread]->getInterrupt(tc);
4382SN/A
4393520Sgblack@eecs.umich.edu        if (interrupt != NoFault) {
44011147Smitch.hayenga@arm.com            t_info.fetchOffset = 0;
44111150Smitch.hayenga@arm.com            interrupts[curThread]->updateIntrInfo(tc);
4423520Sgblack@eecs.umich.edu            interrupt->invoke(tc);
4439023Sgblack@eecs.umich.edu            thread->decoder.reset();
4442SN/A        }
4452SN/A    }
4462623SN/A}
4472SN/A
4482623SN/A
4495894Sgblack@eecs.umich.eduvoid
4502662Sstever@eecs.umich.eduBaseSimpleCPU::setupFetchRequest(Request *req)
4512623SN/A{
45211147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
45311147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
45411147Smitch.hayenga@arm.com
4557720Sgblack@eecs.umich.edu    Addr instAddr = thread->instAddr();
4564495Sacolyte@umich.edu
4572623SN/A    // set up memory request for instruction fetch
4587720Sgblack@eecs.umich.edu    DPRINTF(Fetch, "Fetch: PC:%08p\n", instAddr);
4592623SN/A
46011147Smitch.hayenga@arm.com    Addr fetchPC = (instAddr & PCMask) + t_info.fetchOffset;
4618832SAli.Saidi@ARM.com    req->setVirt(0, fetchPC, sizeof(MachInst), Request::INST_FETCH, instMasterId(),
4628832SAli.Saidi@ARM.com            instAddr);
4632623SN/A}
4642623SN/A
4652623SN/A
4662623SN/Avoid
4672623SN/ABaseSimpleCPU::preExecute()
4682623SN/A{
46911147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
47011147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
47111147Smitch.hayenga@arm.com
4722SN/A    // maintain $r0 semantics
4732683Sktlim@umich.edu    thread->setIntReg(ZeroReg, 0);
4742427SN/A#if THE_ISA == ALPHA_ISA
4752683Sktlim@umich.edu    thread->setFloatReg(ZeroReg, 0.0);
4762427SN/A#endif // ALPHA_ISA
4772SN/A
4782623SN/A    // check for instruction-count-based events
47911147Smitch.hayenga@arm.com    comInstEventQueue[curThread]->serviceEvents(t_info.numInst);
4807897Shestness@cs.utexas.edu    system->instEventQueue.serviceEvents(system->totalNumInsts);
4812SN/A
4822623SN/A    // decode the instruction
4832623SN/A    inst = gtoh(inst);
4844377Sgblack@eecs.umich.edu
4857720Sgblack@eecs.umich.edu    TheISA::PCState pcState = thread->pcState();
4864377Sgblack@eecs.umich.edu
4877720Sgblack@eecs.umich.edu    if (isRomMicroPC(pcState.microPC())) {
48811147Smitch.hayenga@arm.com        t_info.stayAtPC = false;
4897720Sgblack@eecs.umich.edu        curStaticInst = microcodeRom.fetchMicroop(pcState.microPC(),
4907720Sgblack@eecs.umich.edu                                                  curMacroStaticInst);
4915665Sgblack@eecs.umich.edu    } else if (!curMacroStaticInst) {
4925665Sgblack@eecs.umich.edu        //We're not in the middle of a macro instruction
4934181Sgblack@eecs.umich.edu        StaticInstPtr instPtr = NULL;
4944181Sgblack@eecs.umich.edu
4959023Sgblack@eecs.umich.edu        TheISA::Decoder *decoder = &(thread->decoder);
4969023Sgblack@eecs.umich.edu
4974181Sgblack@eecs.umich.edu        //Predecode, ie bundle up an ExtMachInst
4984182Sgblack@eecs.umich.edu        //If more fetch data is needed, pass it in.
49911147Smitch.hayenga@arm.com        Addr fetchPC = (pcState.instAddr() & PCMask) + t_info.fetchOffset;
50011321Ssteve.reinhardt@amd.com        //if (decoder->needMoreBytes())
5019023Sgblack@eecs.umich.edu            decoder->moreBytes(pcState, fetchPC, inst);
5024593Sgblack@eecs.umich.edu        //else
5039023Sgblack@eecs.umich.edu        //    decoder->process();
5044377Sgblack@eecs.umich.edu
5059023Sgblack@eecs.umich.edu        //Decode an instruction if one is ready. Otherwise, we'll have to
5064377Sgblack@eecs.umich.edu        //fetch beyond the MachInst at the current pc.
5079023Sgblack@eecs.umich.edu        instPtr = decoder->decode(pcState);
5089023Sgblack@eecs.umich.edu        if (instPtr) {
50911147Smitch.hayenga@arm.com            t_info.stayAtPC = false;
5107720Sgblack@eecs.umich.edu            thread->pcState(pcState);
5114377Sgblack@eecs.umich.edu        } else {
51211147Smitch.hayenga@arm.com            t_info.stayAtPC = true;
51311147Smitch.hayenga@arm.com            t_info.fetchOffset += sizeof(MachInst);
5144377Sgblack@eecs.umich.edu        }
5154181Sgblack@eecs.umich.edu
5164181Sgblack@eecs.umich.edu        //If we decoded an instruction and it's microcoded, start pulling
5174181Sgblack@eecs.umich.edu        //out micro ops
5184539Sgblack@eecs.umich.edu        if (instPtr && instPtr->isMacroop()) {
5193276Sgblack@eecs.umich.edu            curMacroStaticInst = instPtr;
52011147Smitch.hayenga@arm.com            curStaticInst =
52111147Smitch.hayenga@arm.com                curMacroStaticInst->fetchMicroop(pcState.microPC());
5223280Sgblack@eecs.umich.edu        } else {
5233280Sgblack@eecs.umich.edu            curStaticInst = instPtr;
5243276Sgblack@eecs.umich.edu        }
5253276Sgblack@eecs.umich.edu    } else {
5263276Sgblack@eecs.umich.edu        //Read the next micro op from the macro op
5277720Sgblack@eecs.umich.edu        curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC());
5283276Sgblack@eecs.umich.edu    }
5293276Sgblack@eecs.umich.edu
5304181Sgblack@eecs.umich.edu    //If we decoded an instruction this "tick", record information about it.
5318955Sgblack@eecs.umich.edu    if (curStaticInst) {
5324522Ssaidi@eecs.umich.edu#if TRACING_ON
53311147Smitch.hayenga@arm.com        traceData = tracer->getInstRecord(curTick(), thread->getTC(),
5347720Sgblack@eecs.umich.edu                curStaticInst, thread->pcState(), curMacroStaticInst);
5352470SN/A
5368955Sgblack@eecs.umich.edu        DPRINTF(Decode,"Decode: Decoded %s instruction: %#x\n",
5374181Sgblack@eecs.umich.edu                curStaticInst->getName(), curStaticInst->machInst);
5384522Ssaidi@eecs.umich.edu#endif // TRACING_ON
5394181Sgblack@eecs.umich.edu    }
54010061Sandreas@sandberg.pp.se
54111147Smitch.hayenga@arm.com    if (branchPred && curStaticInst &&
54211147Smitch.hayenga@arm.com        curStaticInst->isControl()) {
54310061Sandreas@sandberg.pp.se        // Use a fake sequence number since we only have one
54410061Sandreas@sandberg.pp.se        // instruction in flight at the same time.
54510061Sandreas@sandberg.pp.se        const InstSeqNum cur_sn(0);
54611147Smitch.hayenga@arm.com        t_info.predPC = thread->pcState();
54710061Sandreas@sandberg.pp.se        const bool predict_taken(
54811147Smitch.hayenga@arm.com            branchPred->predict(curStaticInst, cur_sn, t_info.predPC,
54911147Smitch.hayenga@arm.com                                curThread));
55010061Sandreas@sandberg.pp.se
55110061Sandreas@sandberg.pp.se        if (predict_taken)
55211147Smitch.hayenga@arm.com            ++t_info.numPredictedBranches;
55310061Sandreas@sandberg.pp.se    }
5542623SN/A}
5552623SN/A
5562623SN/Avoid
5572623SN/ABaseSimpleCPU::postExecute()
5582623SN/A{
55911147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
56011147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
56111147Smitch.hayenga@arm.com
5627720Sgblack@eecs.umich.edu    assert(curStaticInst);
5637720Sgblack@eecs.umich.edu
56411147Smitch.hayenga@arm.com    TheISA::PCState pc = threadContexts[curThread]->pcState();
5657720Sgblack@eecs.umich.edu    Addr instAddr = pc.instAddr();
5668780Sgblack@eecs.umich.edu    if (FullSystem && thread->profile) {
56711147Smitch.hayenga@arm.com        bool usermode = TheISA::inUserMode(threadContexts[curThread]);
5687720Sgblack@eecs.umich.edu        thread->profilePC = usermode ? 1 : instAddr;
56911147Smitch.hayenga@arm.com        ProfileNode *node = thread->profile->consume(threadContexts[curThread],
57011147Smitch.hayenga@arm.com                                                     curStaticInst);
5712623SN/A        if (node)
5722683Sktlim@umich.edu            thread->profileNode = node;
5732623SN/A    }
5742SN/A
5752623SN/A    if (curStaticInst->isMemRef()) {
57611147Smitch.hayenga@arm.com        t_info.numMemRefs++;
5772SN/A    }
5782SN/A
5792623SN/A    if (curStaticInst->isLoad()) {
58011147Smitch.hayenga@arm.com        ++t_info.numLoad;
58111147Smitch.hayenga@arm.com        comLoadEventQueue[curThread]->serviceEvents(t_info.numLoad);
5822623SN/A    }
5832SN/A
5845953Ssaidi@eecs.umich.edu    if (CPA::available()) {
58511147Smitch.hayenga@arm.com        CPA::cpa()->swAutoBegin(threadContexts[curThread], pc.nextInstAddr());
5865953Ssaidi@eecs.umich.edu    }
5875953Ssaidi@eecs.umich.edu
58810061Sandreas@sandberg.pp.se    if (curStaticInst->isControl()) {
58911147Smitch.hayenga@arm.com        ++t_info.numBranches;
59010061Sandreas@sandberg.pp.se    }
59110061Sandreas@sandberg.pp.se
5927897Shestness@cs.utexas.edu    /* Power model statistics */
5937897Shestness@cs.utexas.edu    //integer alu accesses
5947897Shestness@cs.utexas.edu    if (curStaticInst->isInteger()){
59511147Smitch.hayenga@arm.com        t_info.numIntAluAccesses++;
59611147Smitch.hayenga@arm.com        t_info.numIntInsts++;
5977897Shestness@cs.utexas.edu    }
5987897Shestness@cs.utexas.edu
5997897Shestness@cs.utexas.edu    //float alu accesses
6007897Shestness@cs.utexas.edu    if (curStaticInst->isFloating()){
60111147Smitch.hayenga@arm.com        t_info.numFpAluAccesses++;
60211147Smitch.hayenga@arm.com        t_info.numFpInsts++;
6037897Shestness@cs.utexas.edu    }
60411147Smitch.hayenga@arm.com
6057897Shestness@cs.utexas.edu    //number of function calls/returns to get window accesses
6067897Shestness@cs.utexas.edu    if (curStaticInst->isCall() || curStaticInst->isReturn()){
60711147Smitch.hayenga@arm.com        t_info.numCallsReturns++;
6087897Shestness@cs.utexas.edu    }
60911147Smitch.hayenga@arm.com
6107897Shestness@cs.utexas.edu    //the number of branch predictions that will be made
6117897Shestness@cs.utexas.edu    if (curStaticInst->isCondCtrl()){
61211147Smitch.hayenga@arm.com        t_info.numCondCtrlInsts++;
6137897Shestness@cs.utexas.edu    }
61411147Smitch.hayenga@arm.com
6157897Shestness@cs.utexas.edu    //result bus acceses
6167897Shestness@cs.utexas.edu    if (curStaticInst->isLoad()){
61711147Smitch.hayenga@arm.com        t_info.numLoadInsts++;
6187897Shestness@cs.utexas.edu    }
61911147Smitch.hayenga@arm.com
6207897Shestness@cs.utexas.edu    if (curStaticInst->isStore()){
62111147Smitch.hayenga@arm.com        t_info.numStoreInsts++;
6227897Shestness@cs.utexas.edu    }
6237897Shestness@cs.utexas.edu    /* End power model statistics */
6247897Shestness@cs.utexas.edu
62511147Smitch.hayenga@arm.com    t_info.statExecutedInstType[curStaticInst->opClass()]++;
62610193SCurtis.Dunham@arm.com
6278780Sgblack@eecs.umich.edu    if (FullSystem)
6288780Sgblack@eecs.umich.edu        traceFunctions(instAddr);
6292644Sstever@eecs.umich.edu
6302644Sstever@eecs.umich.edu    if (traceData) {
6314046Sbinkertn@umich.edu        traceData->dump();
6324046Sbinkertn@umich.edu        delete traceData;
6334046Sbinkertn@umich.edu        traceData = NULL;
6342644Sstever@eecs.umich.edu    }
63510464SAndreas.Sandberg@ARM.com
63610464SAndreas.Sandberg@ARM.com    // Call CPU instruction commit probes
63710464SAndreas.Sandberg@ARM.com    probeInstCommit(curStaticInst);
6382623SN/A}
6392SN/A
6402623SN/Avoid
64110379Sandreas.hansson@arm.comBaseSimpleCPU::advancePC(const Fault &fault)
6422623SN/A{
64311147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
64411147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
64511147Smitch.hayenga@arm.com
64610061Sandreas@sandberg.pp.se    const bool branching(thread->pcState().branching());
64710061Sandreas@sandberg.pp.se
6484377Sgblack@eecs.umich.edu    //Since we're moving to a new pc, zero out the offset
64911147Smitch.hayenga@arm.com    t_info.fetchOffset = 0;
6502090SN/A    if (fault != NoFault) {
6513905Ssaidi@eecs.umich.edu        curMacroStaticInst = StaticInst::nullStaticInstPtr;
65211147Smitch.hayenga@arm.com        fault->invoke(threadContexts[curThread], curStaticInst);
6539023Sgblack@eecs.umich.edu        thread->decoder.reset();
6544377Sgblack@eecs.umich.edu    } else {
6557720Sgblack@eecs.umich.edu        if (curStaticInst) {
6567720Sgblack@eecs.umich.edu            if (curStaticInst->isLastMicroop())
6577720Sgblack@eecs.umich.edu                curMacroStaticInst = StaticInst::nullStaticInstPtr;
6587720Sgblack@eecs.umich.edu            TheISA::PCState pcState = thread->pcState();
6597720Sgblack@eecs.umich.edu            TheISA::advancePC(pcState, curStaticInst);
6607720Sgblack@eecs.umich.edu            thread->pcState(pcState);
6613276Sgblack@eecs.umich.edu        }
6622SN/A    }
66310061Sandreas@sandberg.pp.se
66410061Sandreas@sandberg.pp.se    if (branchPred && curStaticInst && curStaticInst->isControl()) {
66510061Sandreas@sandberg.pp.se        // Use a fake sequence number since we only have one
66610061Sandreas@sandberg.pp.se        // instruction in flight at the same time.
66710061Sandreas@sandberg.pp.se        const InstSeqNum cur_sn(0);
66810061Sandreas@sandberg.pp.se
66911147Smitch.hayenga@arm.com        if (t_info.predPC == thread->pcState()) {
67010061Sandreas@sandberg.pp.se            // Correctly predicted branch
67111147Smitch.hayenga@arm.com            branchPred->update(cur_sn, curThread);
67210061Sandreas@sandberg.pp.se        } else {
67310061Sandreas@sandberg.pp.se            // Mis-predicted branch
67411147Smitch.hayenga@arm.com            branchPred->squash(cur_sn, thread->pcState(), branching, curThread);
67511147Smitch.hayenga@arm.com            ++t_info.numBranchMispred;
67610061Sandreas@sandberg.pp.se        }
67710061Sandreas@sandberg.pp.se    }
6782SN/A}
6792SN/A
6809461Snilay@cs.wisc.eduvoid
6819461Snilay@cs.wisc.eduBaseSimpleCPU::startup()
6829461Snilay@cs.wisc.edu{
6839461Snilay@cs.wisc.edu    BaseCPU::startup();
68411147Smitch.hayenga@arm.com    for (auto& t_info : threadInfo)
68511147Smitch.hayenga@arm.com        t_info->thread->startup();
6869461Snilay@cs.wisc.edu}
687