base.cc revision 12372
12SN/A/*
212284Sjose.marinho@arm.com * Copyright (c) 2010-2012, 2015, 2017 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"
5512334Sgabeblack@google.com#include "base/logging.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);
21812284Sjose.marinho@arm.com    updateCycleCounters(BaseCPU::CPU_STATE_SLEEP);
219393SN/A}
220384SN/A
221189SN/A
222189SN/Avoid
2232623SN/ABaseSimpleCPU::regStats()
2242SN/A{
225729SN/A    using namespace Stats;
226334SN/A
2272SN/A    BaseCPU::regStats();
2282SN/A
22911147Smitch.hayenga@arm.com    for (ThreadID tid = 0; tid < numThreads; tid++) {
23011147Smitch.hayenga@arm.com        SimpleExecContext& t_info = *threadInfo[tid];
2318834Satgutier@umich.edu
23211147Smitch.hayenga@arm.com        std::string thread_str = name();
23311147Smitch.hayenga@arm.com        if (numThreads > 1)
23411147Smitch.hayenga@arm.com            thread_str += ".thread" + std::to_string(tid);
2352SN/A
23611147Smitch.hayenga@arm.com        t_info.numInsts
23711147Smitch.hayenga@arm.com            .name(thread_str + ".committedInsts")
23811147Smitch.hayenga@arm.com            .desc("Number of instructions committed")
23911147Smitch.hayenga@arm.com            ;
2407897Shestness@cs.utexas.edu
24111147Smitch.hayenga@arm.com        t_info.numOps
24211147Smitch.hayenga@arm.com            .name(thread_str + ".committedOps")
24311147Smitch.hayenga@arm.com            .desc("Number of ops (including micro ops) committed")
24411147Smitch.hayenga@arm.com            ;
2457897Shestness@cs.utexas.edu
24611147Smitch.hayenga@arm.com        t_info.numIntAluAccesses
24711147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_alu_accesses")
24811147Smitch.hayenga@arm.com            .desc("Number of integer alu accesses")
24911147Smitch.hayenga@arm.com            ;
2507897Shestness@cs.utexas.edu
25111147Smitch.hayenga@arm.com        t_info.numFpAluAccesses
25211147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_alu_accesses")
25311147Smitch.hayenga@arm.com            .desc("Number of float alu accesses")
25411147Smitch.hayenga@arm.com            ;
2557897Shestness@cs.utexas.edu
25612110SRekai.GonzalezAlberquilla@arm.com        t_info.numVecAluAccesses
25712110SRekai.GonzalezAlberquilla@arm.com            .name(thread_str + ".num_vec_alu_accesses")
25812110SRekai.GonzalezAlberquilla@arm.com            .desc("Number of vector alu accesses")
25912110SRekai.GonzalezAlberquilla@arm.com            ;
26012110SRekai.GonzalezAlberquilla@arm.com
26111147Smitch.hayenga@arm.com        t_info.numCallsReturns
26211147Smitch.hayenga@arm.com            .name(thread_str + ".num_func_calls")
26311147Smitch.hayenga@arm.com            .desc("number of times a function call or return occured")
26411147Smitch.hayenga@arm.com            ;
2657897Shestness@cs.utexas.edu
26611147Smitch.hayenga@arm.com        t_info.numCondCtrlInsts
26711147Smitch.hayenga@arm.com            .name(thread_str + ".num_conditional_control_insts")
26811147Smitch.hayenga@arm.com            .desc("number of instructions that are conditional controls")
26911147Smitch.hayenga@arm.com            ;
2707897Shestness@cs.utexas.edu
27111147Smitch.hayenga@arm.com        t_info.numIntInsts
27211147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_insts")
27311147Smitch.hayenga@arm.com            .desc("number of integer instructions")
27411147Smitch.hayenga@arm.com            ;
2757897Shestness@cs.utexas.edu
27611147Smitch.hayenga@arm.com        t_info.numFpInsts
27711147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_insts")
27811147Smitch.hayenga@arm.com            .desc("number of float instructions")
27911147Smitch.hayenga@arm.com            ;
2807897Shestness@cs.utexas.edu
28112110SRekai.GonzalezAlberquilla@arm.com        t_info.numVecInsts
28212110SRekai.GonzalezAlberquilla@arm.com            .name(thread_str + ".num_vec_insts")
28312110SRekai.GonzalezAlberquilla@arm.com            .desc("number of vector instructions")
28412110SRekai.GonzalezAlberquilla@arm.com            ;
28512110SRekai.GonzalezAlberquilla@arm.com
28611147Smitch.hayenga@arm.com        t_info.numIntRegReads
28711147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_register_reads")
28811147Smitch.hayenga@arm.com            .desc("number of times the integer registers were read")
28911147Smitch.hayenga@arm.com            ;
2907897Shestness@cs.utexas.edu
29111147Smitch.hayenga@arm.com        t_info.numIntRegWrites
29211147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_register_writes")
29311147Smitch.hayenga@arm.com            .desc("number of times the integer registers were written")
29411147Smitch.hayenga@arm.com            ;
2957897Shestness@cs.utexas.edu
29611147Smitch.hayenga@arm.com        t_info.numFpRegReads
29711147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_register_reads")
29811147Smitch.hayenga@arm.com            .desc("number of times the floating registers were read")
29911147Smitch.hayenga@arm.com            ;
3009920Syasuko.eckert@amd.com
30111147Smitch.hayenga@arm.com        t_info.numFpRegWrites
30211147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_register_writes")
30311147Smitch.hayenga@arm.com            .desc("number of times the floating registers were written")
30411147Smitch.hayenga@arm.com            ;
3059920Syasuko.eckert@amd.com
30612109SRekai.GonzalezAlberquilla@arm.com        t_info.numVecRegReads
30712109SRekai.GonzalezAlberquilla@arm.com            .name(thread_str + ".num_vec_register_reads")
30812109SRekai.GonzalezAlberquilla@arm.com            .desc("number of times the vector registers were read")
30912109SRekai.GonzalezAlberquilla@arm.com            ;
31012109SRekai.GonzalezAlberquilla@arm.com
31112109SRekai.GonzalezAlberquilla@arm.com        t_info.numVecRegWrites
31212109SRekai.GonzalezAlberquilla@arm.com            .name(thread_str + ".num_vec_register_writes")
31312109SRekai.GonzalezAlberquilla@arm.com            .desc("number of times the vector registers were written")
31412109SRekai.GonzalezAlberquilla@arm.com            ;
31512109SRekai.GonzalezAlberquilla@arm.com
31611147Smitch.hayenga@arm.com        t_info.numCCRegReads
31711147Smitch.hayenga@arm.com            .name(thread_str + ".num_cc_register_reads")
31811147Smitch.hayenga@arm.com            .desc("number of times the CC registers were read")
31911147Smitch.hayenga@arm.com            .flags(nozero)
32011147Smitch.hayenga@arm.com            ;
3217897Shestness@cs.utexas.edu
32211147Smitch.hayenga@arm.com        t_info.numCCRegWrites
32311147Smitch.hayenga@arm.com            .name(thread_str + ".num_cc_register_writes")
32411147Smitch.hayenga@arm.com            .desc("number of times the CC registers were written")
32511147Smitch.hayenga@arm.com            .flags(nozero)
32611147Smitch.hayenga@arm.com            ;
3277897Shestness@cs.utexas.edu
32811147Smitch.hayenga@arm.com        t_info.numMemRefs
32911147Smitch.hayenga@arm.com            .name(thread_str + ".num_mem_refs")
33011147Smitch.hayenga@arm.com            .desc("number of memory refs")
33111147Smitch.hayenga@arm.com            ;
3322SN/A
33311147Smitch.hayenga@arm.com        t_info.numStoreInsts
33411147Smitch.hayenga@arm.com            .name(thread_str + ".num_store_insts")
33511147Smitch.hayenga@arm.com            .desc("Number of store instructions")
33611147Smitch.hayenga@arm.com            ;
3371001SN/A
33811147Smitch.hayenga@arm.com        t_info.numLoadInsts
33911147Smitch.hayenga@arm.com            .name(thread_str + ".num_load_insts")
34011147Smitch.hayenga@arm.com            .desc("Number of load instructions")
34111147Smitch.hayenga@arm.com            ;
3422SN/A
34311147Smitch.hayenga@arm.com        t_info.notIdleFraction
34411147Smitch.hayenga@arm.com            .name(thread_str + ".not_idle_fraction")
34511147Smitch.hayenga@arm.com            .desc("Percentage of non-idle cycles")
34611147Smitch.hayenga@arm.com            ;
3477897Shestness@cs.utexas.edu
34811147Smitch.hayenga@arm.com        t_info.idleFraction
34911147Smitch.hayenga@arm.com            .name(thread_str + ".idle_fraction")
35011147Smitch.hayenga@arm.com            .desc("Percentage of idle cycles")
35111147Smitch.hayenga@arm.com            ;
3527897Shestness@cs.utexas.edu
35311147Smitch.hayenga@arm.com        t_info.numBusyCycles
35411147Smitch.hayenga@arm.com            .name(thread_str + ".num_busy_cycles")
35511147Smitch.hayenga@arm.com            .desc("Number of busy cycles")
35611147Smitch.hayenga@arm.com            ;
3572SN/A
35811147Smitch.hayenga@arm.com        t_info.numIdleCycles
35911147Smitch.hayenga@arm.com            .name(thread_str + ".num_idle_cycles")
36011147Smitch.hayenga@arm.com            .desc("Number of idle cycles")
36111147Smitch.hayenga@arm.com            ;
3622SN/A
36311147Smitch.hayenga@arm.com        t_info.icacheStallCycles
36411147Smitch.hayenga@arm.com            .name(thread_str + ".icache_stall_cycles")
36511147Smitch.hayenga@arm.com            .desc("ICache total stall cycles")
36611147Smitch.hayenga@arm.com            .prereq(t_info.icacheStallCycles)
36711147Smitch.hayenga@arm.com            ;
36811147Smitch.hayenga@arm.com
36911147Smitch.hayenga@arm.com        t_info.dcacheStallCycles
37011147Smitch.hayenga@arm.com            .name(thread_str + ".dcache_stall_cycles")
37111147Smitch.hayenga@arm.com            .desc("DCache total stall cycles")
37211147Smitch.hayenga@arm.com            .prereq(t_info.dcacheStallCycles)
37311147Smitch.hayenga@arm.com            ;
37411147Smitch.hayenga@arm.com
37511147Smitch.hayenga@arm.com        t_info.statExecutedInstType
37611147Smitch.hayenga@arm.com            .init(Enums::Num_OpClass)
37711147Smitch.hayenga@arm.com            .name(thread_str + ".op_class")
37811147Smitch.hayenga@arm.com            .desc("Class of executed instruction")
37911147Smitch.hayenga@arm.com            .flags(total | pdf | dist)
38011147Smitch.hayenga@arm.com            ;
38111147Smitch.hayenga@arm.com
38211147Smitch.hayenga@arm.com        for (unsigned i = 0; i < Num_OpClasses; ++i) {
38311147Smitch.hayenga@arm.com            t_info.statExecutedInstType.subname(i, Enums::OpClassStrings[i]);
38411147Smitch.hayenga@arm.com        }
38511147Smitch.hayenga@arm.com
38611147Smitch.hayenga@arm.com        t_info.idleFraction = constant(1.0) - t_info.notIdleFraction;
38711147Smitch.hayenga@arm.com        t_info.numIdleCycles = t_info.idleFraction * numCycles;
38811147Smitch.hayenga@arm.com        t_info.numBusyCycles = t_info.notIdleFraction * numCycles;
38911147Smitch.hayenga@arm.com
39011147Smitch.hayenga@arm.com        t_info.numBranches
39111147Smitch.hayenga@arm.com            .name(thread_str + ".Branches")
39211147Smitch.hayenga@arm.com            .desc("Number of branches fetched")
39311147Smitch.hayenga@arm.com            .prereq(t_info.numBranches);
39411147Smitch.hayenga@arm.com
39511147Smitch.hayenga@arm.com        t_info.numPredictedBranches
39611147Smitch.hayenga@arm.com            .name(thread_str + ".predictedBranches")
39711147Smitch.hayenga@arm.com            .desc("Number of branches predicted as taken")
39811147Smitch.hayenga@arm.com            .prereq(t_info.numPredictedBranches);
39911147Smitch.hayenga@arm.com
40011147Smitch.hayenga@arm.com        t_info.numBranchMispred
40111147Smitch.hayenga@arm.com            .name(thread_str + ".BranchMispred")
40211147Smitch.hayenga@arm.com            .desc("Number of branch mispredictions")
40311147Smitch.hayenga@arm.com            .prereq(t_info.numBranchMispred);
40410193SCurtis.Dunham@arm.com    }
4052SN/A}
4062SN/A
4072SN/Avoid
4082623SN/ABaseSimpleCPU::resetStats()
409334SN/A{
41011147Smitch.hayenga@arm.com    for (auto &thread_info : threadInfo) {
41111147Smitch.hayenga@arm.com        thread_info->notIdleFraction = (_status != Idle);
41211147Smitch.hayenga@arm.com    }
413334SN/A}
414334SN/A
415334SN/Avoid
41610905Sandreas.sandberg@arm.comBaseSimpleCPU::serializeThread(CheckpointOut &cp, ThreadID tid) const
4172SN/A{
4189448SAndreas.Sandberg@ARM.com    assert(_status == Idle || _status == Running);
4199448SAndreas.Sandberg@ARM.com
42011147Smitch.hayenga@arm.com    threadInfo[tid]->thread->serialize(cp);
4212SN/A}
4222SN/A
4232SN/Avoid
42410905Sandreas.sandberg@arm.comBaseSimpleCPU::unserializeThread(CheckpointIn &cp, ThreadID tid)
4252SN/A{
42611147Smitch.hayenga@arm.com    threadInfo[tid]->thread->unserialize(cp);
4272SN/A}
4282SN/A
4292SN/Avoid
4306221Snate@binkert.orgchange_thread_state(ThreadID tid, int activate, int priority)
4312SN/A{
4322SN/A}
4332SN/A
4342SN/AAddr
4352623SN/ABaseSimpleCPU::dbg_vtophys(Addr addr)
4362SN/A{
43711147Smitch.hayenga@arm.com    return vtophys(threadContexts[curThread], addr);
4382SN/A}
4392SN/A
4402SN/Avoid
44111151Smitch.hayenga@arm.comBaseSimpleCPU::wakeup(ThreadID tid)
4422SN/A{
44311151Smitch.hayenga@arm.com    getCpuAddrMonitor(tid)->gotWakeup = true;
44411151Smitch.hayenga@arm.com
44511151Smitch.hayenga@arm.com    if (threadInfo[tid]->thread->status() == ThreadContext::Suspended) {
44611151Smitch.hayenga@arm.com        DPRINTF(Quiesce,"[tid:%d] Suspended Processor awoke\n", tid);
44711151Smitch.hayenga@arm.com        threadInfo[tid]->thread->activate();
44811147Smitch.hayenga@arm.com    }
4492SN/A}
4502SN/A
4512SN/Avoid
4522623SN/ABaseSimpleCPU::checkForInterrupts()
4532SN/A{
45411147Smitch.hayenga@arm.com    SimpleExecContext&t_info = *threadInfo[curThread];
45511147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
45611147Smitch.hayenga@arm.com    ThreadContext* tc = thread->getTC();
45711147Smitch.hayenga@arm.com
4585704Snate@binkert.org    if (checkInterrupts(tc)) {
45911150Smitch.hayenga@arm.com        Fault interrupt = interrupts[curThread]->getInterrupt(tc);
4602SN/A
4613520Sgblack@eecs.umich.edu        if (interrupt != NoFault) {
46211147Smitch.hayenga@arm.com            t_info.fetchOffset = 0;
46311150Smitch.hayenga@arm.com            interrupts[curThread]->updateIntrInfo(tc);
4643520Sgblack@eecs.umich.edu            interrupt->invoke(tc);
4659023Sgblack@eecs.umich.edu            thread->decoder.reset();
4662SN/A        }
4672SN/A    }
4682623SN/A}
4692SN/A
4702623SN/A
4715894Sgblack@eecs.umich.eduvoid
4722662Sstever@eecs.umich.eduBaseSimpleCPU::setupFetchRequest(Request *req)
4732623SN/A{
47411147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
47511147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
47611147Smitch.hayenga@arm.com
4777720Sgblack@eecs.umich.edu    Addr instAddr = thread->instAddr();
47812372Smattdsinclair@gmail.com    Addr fetchPC = (instAddr & PCMask) + t_info.fetchOffset;
4794495Sacolyte@umich.edu
4802623SN/A    // set up memory request for instruction fetch
48112372Smattdsinclair@gmail.com    DPRINTF(Fetch, "Fetch: Inst PC:%08p, Fetch PC:%08p\n", instAddr, fetchPC);
4822623SN/A
48312372Smattdsinclair@gmail.com    req->setVirt(0, fetchPC, sizeof(MachInst), Request::INST_FETCH,
48412372Smattdsinclair@gmail.com                 instMasterId(), instAddr);
4852623SN/A}
4862623SN/A
4872623SN/A
4882623SN/Avoid
4892623SN/ABaseSimpleCPU::preExecute()
4902623SN/A{
49111147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
49211147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
49311147Smitch.hayenga@arm.com
4942SN/A    // maintain $r0 semantics
4952683Sktlim@umich.edu    thread->setIntReg(ZeroReg, 0);
4962427SN/A#if THE_ISA == ALPHA_ISA
4972683Sktlim@umich.edu    thread->setFloatReg(ZeroReg, 0.0);
4982427SN/A#endif // ALPHA_ISA
4992SN/A
5002623SN/A    // check for instruction-count-based events
50111147Smitch.hayenga@arm.com    comInstEventQueue[curThread]->serviceEvents(t_info.numInst);
5027897Shestness@cs.utexas.edu    system->instEventQueue.serviceEvents(system->totalNumInsts);
5032SN/A
5042623SN/A    // decode the instruction
5052623SN/A    inst = gtoh(inst);
5064377Sgblack@eecs.umich.edu
5077720Sgblack@eecs.umich.edu    TheISA::PCState pcState = thread->pcState();
5084377Sgblack@eecs.umich.edu
5097720Sgblack@eecs.umich.edu    if (isRomMicroPC(pcState.microPC())) {
51011147Smitch.hayenga@arm.com        t_info.stayAtPC = false;
5117720Sgblack@eecs.umich.edu        curStaticInst = microcodeRom.fetchMicroop(pcState.microPC(),
5127720Sgblack@eecs.umich.edu                                                  curMacroStaticInst);
5135665Sgblack@eecs.umich.edu    } else if (!curMacroStaticInst) {
5145665Sgblack@eecs.umich.edu        //We're not in the middle of a macro instruction
5154181Sgblack@eecs.umich.edu        StaticInstPtr instPtr = NULL;
5164181Sgblack@eecs.umich.edu
5179023Sgblack@eecs.umich.edu        TheISA::Decoder *decoder = &(thread->decoder);
5189023Sgblack@eecs.umich.edu
5194181Sgblack@eecs.umich.edu        //Predecode, ie bundle up an ExtMachInst
5204182Sgblack@eecs.umich.edu        //If more fetch data is needed, pass it in.
52111147Smitch.hayenga@arm.com        Addr fetchPC = (pcState.instAddr() & PCMask) + t_info.fetchOffset;
52211321Ssteve.reinhardt@amd.com        //if (decoder->needMoreBytes())
5239023Sgblack@eecs.umich.edu            decoder->moreBytes(pcState, fetchPC, inst);
5244593Sgblack@eecs.umich.edu        //else
5259023Sgblack@eecs.umich.edu        //    decoder->process();
5264377Sgblack@eecs.umich.edu
5279023Sgblack@eecs.umich.edu        //Decode an instruction if one is ready. Otherwise, we'll have to
5284377Sgblack@eecs.umich.edu        //fetch beyond the MachInst at the current pc.
5299023Sgblack@eecs.umich.edu        instPtr = decoder->decode(pcState);
5309023Sgblack@eecs.umich.edu        if (instPtr) {
53111147Smitch.hayenga@arm.com            t_info.stayAtPC = false;
5327720Sgblack@eecs.umich.edu            thread->pcState(pcState);
5334377Sgblack@eecs.umich.edu        } else {
53411147Smitch.hayenga@arm.com            t_info.stayAtPC = true;
53511147Smitch.hayenga@arm.com            t_info.fetchOffset += sizeof(MachInst);
5364377Sgblack@eecs.umich.edu        }
5374181Sgblack@eecs.umich.edu
5384181Sgblack@eecs.umich.edu        //If we decoded an instruction and it's microcoded, start pulling
5394181Sgblack@eecs.umich.edu        //out micro ops
5404539Sgblack@eecs.umich.edu        if (instPtr && instPtr->isMacroop()) {
5413276Sgblack@eecs.umich.edu            curMacroStaticInst = instPtr;
54211147Smitch.hayenga@arm.com            curStaticInst =
54311147Smitch.hayenga@arm.com                curMacroStaticInst->fetchMicroop(pcState.microPC());
5443280Sgblack@eecs.umich.edu        } else {
5453280Sgblack@eecs.umich.edu            curStaticInst = instPtr;
5463276Sgblack@eecs.umich.edu        }
5473276Sgblack@eecs.umich.edu    } else {
5483276Sgblack@eecs.umich.edu        //Read the next micro op from the macro op
5497720Sgblack@eecs.umich.edu        curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC());
5503276Sgblack@eecs.umich.edu    }
5513276Sgblack@eecs.umich.edu
5524181Sgblack@eecs.umich.edu    //If we decoded an instruction this "tick", record information about it.
5538955Sgblack@eecs.umich.edu    if (curStaticInst) {
5544522Ssaidi@eecs.umich.edu#if TRACING_ON
55511147Smitch.hayenga@arm.com        traceData = tracer->getInstRecord(curTick(), thread->getTC(),
5567720Sgblack@eecs.umich.edu                curStaticInst, thread->pcState(), curMacroStaticInst);
5572470SN/A
5588955Sgblack@eecs.umich.edu        DPRINTF(Decode,"Decode: Decoded %s instruction: %#x\n",
5594181Sgblack@eecs.umich.edu                curStaticInst->getName(), curStaticInst->machInst);
5604522Ssaidi@eecs.umich.edu#endif // TRACING_ON
5614181Sgblack@eecs.umich.edu    }
56210061Sandreas@sandberg.pp.se
56311147Smitch.hayenga@arm.com    if (branchPred && curStaticInst &&
56411147Smitch.hayenga@arm.com        curStaticInst->isControl()) {
56510061Sandreas@sandberg.pp.se        // Use a fake sequence number since we only have one
56610061Sandreas@sandberg.pp.se        // instruction in flight at the same time.
56710061Sandreas@sandberg.pp.se        const InstSeqNum cur_sn(0);
56811147Smitch.hayenga@arm.com        t_info.predPC = thread->pcState();
56910061Sandreas@sandberg.pp.se        const bool predict_taken(
57011147Smitch.hayenga@arm.com            branchPred->predict(curStaticInst, cur_sn, t_info.predPC,
57111147Smitch.hayenga@arm.com                                curThread));
57210061Sandreas@sandberg.pp.se
57310061Sandreas@sandberg.pp.se        if (predict_taken)
57411147Smitch.hayenga@arm.com            ++t_info.numPredictedBranches;
57510061Sandreas@sandberg.pp.se    }
5762623SN/A}
5772623SN/A
5782623SN/Avoid
5792623SN/ABaseSimpleCPU::postExecute()
5802623SN/A{
58111147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
58211147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
58311147Smitch.hayenga@arm.com
5847720Sgblack@eecs.umich.edu    assert(curStaticInst);
5857720Sgblack@eecs.umich.edu
58611147Smitch.hayenga@arm.com    TheISA::PCState pc = threadContexts[curThread]->pcState();
5877720Sgblack@eecs.umich.edu    Addr instAddr = pc.instAddr();
5888780Sgblack@eecs.umich.edu    if (FullSystem && thread->profile) {
58911147Smitch.hayenga@arm.com        bool usermode = TheISA::inUserMode(threadContexts[curThread]);
5907720Sgblack@eecs.umich.edu        thread->profilePC = usermode ? 1 : instAddr;
59111147Smitch.hayenga@arm.com        ProfileNode *node = thread->profile->consume(threadContexts[curThread],
59211147Smitch.hayenga@arm.com                                                     curStaticInst);
5932623SN/A        if (node)
5942683Sktlim@umich.edu            thread->profileNode = node;
5952623SN/A    }
5962SN/A
5972623SN/A    if (curStaticInst->isMemRef()) {
59811147Smitch.hayenga@arm.com        t_info.numMemRefs++;
5992SN/A    }
6002SN/A
6012623SN/A    if (curStaticInst->isLoad()) {
60211147Smitch.hayenga@arm.com        ++t_info.numLoad;
60311147Smitch.hayenga@arm.com        comLoadEventQueue[curThread]->serviceEvents(t_info.numLoad);
6042623SN/A    }
6052SN/A
6065953Ssaidi@eecs.umich.edu    if (CPA::available()) {
60711147Smitch.hayenga@arm.com        CPA::cpa()->swAutoBegin(threadContexts[curThread], pc.nextInstAddr());
6085953Ssaidi@eecs.umich.edu    }
6095953Ssaidi@eecs.umich.edu
61010061Sandreas@sandberg.pp.se    if (curStaticInst->isControl()) {
61111147Smitch.hayenga@arm.com        ++t_info.numBranches;
61210061Sandreas@sandberg.pp.se    }
61310061Sandreas@sandberg.pp.se
6147897Shestness@cs.utexas.edu    /* Power model statistics */
6157897Shestness@cs.utexas.edu    //integer alu accesses
6167897Shestness@cs.utexas.edu    if (curStaticInst->isInteger()){
61711147Smitch.hayenga@arm.com        t_info.numIntAluAccesses++;
61811147Smitch.hayenga@arm.com        t_info.numIntInsts++;
6197897Shestness@cs.utexas.edu    }
6207897Shestness@cs.utexas.edu
6217897Shestness@cs.utexas.edu    //float alu accesses
6227897Shestness@cs.utexas.edu    if (curStaticInst->isFloating()){
62311147Smitch.hayenga@arm.com        t_info.numFpAluAccesses++;
62411147Smitch.hayenga@arm.com        t_info.numFpInsts++;
6257897Shestness@cs.utexas.edu    }
62611147Smitch.hayenga@arm.com
62712110SRekai.GonzalezAlberquilla@arm.com    //vector alu accesses
62812110SRekai.GonzalezAlberquilla@arm.com    if (curStaticInst->isVector()){
62912110SRekai.GonzalezAlberquilla@arm.com        t_info.numVecAluAccesses++;
63012110SRekai.GonzalezAlberquilla@arm.com        t_info.numVecInsts++;
63112110SRekai.GonzalezAlberquilla@arm.com    }
63212110SRekai.GonzalezAlberquilla@arm.com
6337897Shestness@cs.utexas.edu    //number of function calls/returns to get window accesses
6347897Shestness@cs.utexas.edu    if (curStaticInst->isCall() || curStaticInst->isReturn()){
63511147Smitch.hayenga@arm.com        t_info.numCallsReturns++;
6367897Shestness@cs.utexas.edu    }
63711147Smitch.hayenga@arm.com
6387897Shestness@cs.utexas.edu    //the number of branch predictions that will be made
6397897Shestness@cs.utexas.edu    if (curStaticInst->isCondCtrl()){
64011147Smitch.hayenga@arm.com        t_info.numCondCtrlInsts++;
6417897Shestness@cs.utexas.edu    }
64211147Smitch.hayenga@arm.com
6437897Shestness@cs.utexas.edu    //result bus acceses
6447897Shestness@cs.utexas.edu    if (curStaticInst->isLoad()){
64511147Smitch.hayenga@arm.com        t_info.numLoadInsts++;
6467897Shestness@cs.utexas.edu    }
64711147Smitch.hayenga@arm.com
6487897Shestness@cs.utexas.edu    if (curStaticInst->isStore()){
64911147Smitch.hayenga@arm.com        t_info.numStoreInsts++;
6507897Shestness@cs.utexas.edu    }
6517897Shestness@cs.utexas.edu    /* End power model statistics */
6527897Shestness@cs.utexas.edu
65311147Smitch.hayenga@arm.com    t_info.statExecutedInstType[curStaticInst->opClass()]++;
65410193SCurtis.Dunham@arm.com
6558780Sgblack@eecs.umich.edu    if (FullSystem)
6568780Sgblack@eecs.umich.edu        traceFunctions(instAddr);
6572644Sstever@eecs.umich.edu
6582644Sstever@eecs.umich.edu    if (traceData) {
6594046Sbinkertn@umich.edu        traceData->dump();
6604046Sbinkertn@umich.edu        delete traceData;
6614046Sbinkertn@umich.edu        traceData = NULL;
6622644Sstever@eecs.umich.edu    }
66310464SAndreas.Sandberg@ARM.com
66410464SAndreas.Sandberg@ARM.com    // Call CPU instruction commit probes
66510464SAndreas.Sandberg@ARM.com    probeInstCommit(curStaticInst);
6662623SN/A}
6672SN/A
6682623SN/Avoid
66910379Sandreas.hansson@arm.comBaseSimpleCPU::advancePC(const Fault &fault)
6702623SN/A{
67111147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
67211147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
67311147Smitch.hayenga@arm.com
67410061Sandreas@sandberg.pp.se    const bool branching(thread->pcState().branching());
67510061Sandreas@sandberg.pp.se
6764377Sgblack@eecs.umich.edu    //Since we're moving to a new pc, zero out the offset
67711147Smitch.hayenga@arm.com    t_info.fetchOffset = 0;
6782090SN/A    if (fault != NoFault) {
6793905Ssaidi@eecs.umich.edu        curMacroStaticInst = StaticInst::nullStaticInstPtr;
68011147Smitch.hayenga@arm.com        fault->invoke(threadContexts[curThread], curStaticInst);
6819023Sgblack@eecs.umich.edu        thread->decoder.reset();
6824377Sgblack@eecs.umich.edu    } else {
6837720Sgblack@eecs.umich.edu        if (curStaticInst) {
6847720Sgblack@eecs.umich.edu            if (curStaticInst->isLastMicroop())
6857720Sgblack@eecs.umich.edu                curMacroStaticInst = StaticInst::nullStaticInstPtr;
6867720Sgblack@eecs.umich.edu            TheISA::PCState pcState = thread->pcState();
6877720Sgblack@eecs.umich.edu            TheISA::advancePC(pcState, curStaticInst);
6887720Sgblack@eecs.umich.edu            thread->pcState(pcState);
6893276Sgblack@eecs.umich.edu        }
6902SN/A    }
69110061Sandreas@sandberg.pp.se
69210061Sandreas@sandberg.pp.se    if (branchPred && curStaticInst && curStaticInst->isControl()) {
69310061Sandreas@sandberg.pp.se        // Use a fake sequence number since we only have one
69410061Sandreas@sandberg.pp.se        // instruction in flight at the same time.
69510061Sandreas@sandberg.pp.se        const InstSeqNum cur_sn(0);
69610061Sandreas@sandberg.pp.se
69711147Smitch.hayenga@arm.com        if (t_info.predPC == thread->pcState()) {
69810061Sandreas@sandberg.pp.se            // Correctly predicted branch
69911147Smitch.hayenga@arm.com            branchPred->update(cur_sn, curThread);
70010061Sandreas@sandberg.pp.se        } else {
70110061Sandreas@sandberg.pp.se            // Mis-predicted branch
70211147Smitch.hayenga@arm.com            branchPred->squash(cur_sn, thread->pcState(), branching, curThread);
70311147Smitch.hayenga@arm.com            ++t_info.numBranchMispred;
70410061Sandreas@sandberg.pp.se        }
70510061Sandreas@sandberg.pp.se    }
7062SN/A}
7072SN/A
7089461Snilay@cs.wisc.eduvoid
7099461Snilay@cs.wisc.eduBaseSimpleCPU::startup()
7109461Snilay@cs.wisc.edu{
7119461Snilay@cs.wisc.edu    BaseCPU::startup();
71211147Smitch.hayenga@arm.com    for (auto& t_info : threadInfo)
71311147Smitch.hayenga@arm.com        t_info->thread->startup();
7149461Snilay@cs.wisc.edu}
715