12SN/A/*
213954Sgiacomo.gabrielli@arm.com * Copyright (c) 2010-2012, 2015, 2017, 2018 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/stacktrace.hh"
472439SN/A#include "arch/utility.hh"
488779Sgblack@eecs.umich.edu#include "arch/vtophys.hh"
496216Snate@binkert.org#include "base/cp_annotate.hh"
50146SN/A#include "base/cprintf.hh"
51146SN/A#include "base/inifile.hh"
5211793Sbrandon.potter@amd.com#include "base/loader/symtab.hh"
5312334Sgabeblack@google.com#include "base/logging.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"
581717SN/A#include "cpu/base.hh"
598887Sgeoffrey.blake@arm.com#include "cpu/checker/cpu.hh"
608887Sgeoffrey.blake@arm.com#include "cpu/checker/thread_context.hh"
61146SN/A#include "cpu/exetrace.hh"
6210061Sandreas@sandberg.pp.se#include "cpu/pred/bpred_unit.hh"
631977SN/A#include "cpu/profile.hh"
6411147Smitch.hayenga@arm.com#include "cpu/simple/exec_context.hh"
652683Sktlim@umich.edu#include "cpu/simple_thread.hh"
661717SN/A#include "cpu/smt.hh"
67146SN/A#include "cpu/static_inst.hh"
682683Sktlim@umich.edu#include "cpu/thread_context.hh"
698232Snate@binkert.org#include "debug/Decode.hh"
708232Snate@binkert.org#include "debug/Fetch.hh"
718232Snate@binkert.org#include "debug/Quiesce.hh"
723348Sbinkertn@umich.edu#include "mem/packet.hh"
736105Ssteve.reinhardt@amd.com#include "mem/request.hh"
746216Snate@binkert.org#include "params/BaseSimpleCPU.hh"
752036SN/A#include "sim/byteswap.hh"
76146SN/A#include "sim/debug.hh"
778817Sgblack@eecs.umich.edu#include "sim/faults.hh"
788793Sgblack@eecs.umich.edu#include "sim/full_system.hh"
7956SN/A#include "sim/sim_events.hh"
8056SN/A#include "sim/sim_object.hh"
81695SN/A#include "sim/stats.hh"
822901Ssaidi@eecs.umich.edu#include "sim/system.hh"
832SN/A
842SN/Ausing namespace std;
852449SN/Ausing namespace TheISA;
861355SN/A
875529Snate@binkert.orgBaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p)
8810061Sandreas@sandberg.pp.se    : BaseCPU(p),
8911147Smitch.hayenga@arm.com      curThread(0),
9010061Sandreas@sandberg.pp.se      branchPred(p->branchPred),
9111147Smitch.hayenga@arm.com      traceData(NULL),
9211147Smitch.hayenga@arm.com      inst(),
9311147Smitch.hayenga@arm.com      _status(Idle)
94224SN/A{
9511147Smitch.hayenga@arm.com    SimpleThread *thread;
962SN/A
9711147Smitch.hayenga@arm.com    for (unsigned i = 0; i < numThreads; i++) {
9811147Smitch.hayenga@arm.com        if (FullSystem) {
9911147Smitch.hayenga@arm.com            thread = new SimpleThread(this, i, p->system,
10011147Smitch.hayenga@arm.com                                      p->itb, p->dtb, p->isa[i]);
10111147Smitch.hayenga@arm.com        } else {
10211147Smitch.hayenga@arm.com            thread = new SimpleThread(this, i, p->system, p->workload[i],
10311147Smitch.hayenga@arm.com                                      p->itb, p->dtb, p->isa[i]);
10411147Smitch.hayenga@arm.com        }
10511147Smitch.hayenga@arm.com        threadInfo.push_back(new SimpleExecContext(this, thread));
10611147Smitch.hayenga@arm.com        ThreadContext *tc = thread->getTC();
10711147Smitch.hayenga@arm.com        threadContexts.push_back(tc);
10811147Smitch.hayenga@arm.com    }
1092SN/A
1108733Sgeoffrey.blake@arm.com    if (p->checker) {
11111147Smitch.hayenga@arm.com        if (numThreads != 1)
11211147Smitch.hayenga@arm.com            fatal("Checker currently does not support SMT");
11311147Smitch.hayenga@arm.com
1148733Sgeoffrey.blake@arm.com        BaseCPU *temp_checker = p->checker;
1158733Sgeoffrey.blake@arm.com        checker = dynamic_cast<CheckerCPU *>(temp_checker);
1168733Sgeoffrey.blake@arm.com        checker->setSystem(p->system);
1178733Sgeoffrey.blake@arm.com        // Manipulate thread context
11811147Smitch.hayenga@arm.com        ThreadContext *cpu_tc = threadContexts[0];
11911147Smitch.hayenga@arm.com        threadContexts[0] = new CheckerThreadContext<ThreadContext>(cpu_tc, this->checker);
1208733Sgeoffrey.blake@arm.com    } else {
1218733Sgeoffrey.blake@arm.com        checker = NULL;
1228733Sgeoffrey.blake@arm.com    }
12311147Smitch.hayenga@arm.com}
1248733Sgeoffrey.blake@arm.com
12511147Smitch.hayenga@arm.comvoid
12611147Smitch.hayenga@arm.comBaseSimpleCPU::init()
12711147Smitch.hayenga@arm.com{
12811147Smitch.hayenga@arm.com    BaseCPU::init();
1292SN/A
13011147Smitch.hayenga@arm.com    for (auto tc : threadContexts) {
13111147Smitch.hayenga@arm.com        // Initialise the ThreadContext's memory proxies
13211147Smitch.hayenga@arm.com        tc->initMemProxies(tc);
1334377Sgblack@eecs.umich.edu
13411147Smitch.hayenga@arm.com        if (FullSystem && !params()->switched_out) {
13511147Smitch.hayenga@arm.com            // initialize CPU, including PC
13611147Smitch.hayenga@arm.com            TheISA::initCPU(tc, tc->contextId());
13711147Smitch.hayenga@arm.com        }
13811147Smitch.hayenga@arm.com    }
13911147Smitch.hayenga@arm.com}
1405169Ssaidi@eecs.umich.edu
14111147Smitch.hayenga@arm.comvoid
14211147Smitch.hayenga@arm.comBaseSimpleCPU::checkPcEventQueue()
14311147Smitch.hayenga@arm.com{
14411147Smitch.hayenga@arm.com    Addr oldpc, pc = threadInfo[curThread]->thread->instAddr();
14511147Smitch.hayenga@arm.com    do {
14611147Smitch.hayenga@arm.com        oldpc = pc;
14711147Smitch.hayenga@arm.com        system->pcEventQueue.service(threadContexts[curThread]);
14811147Smitch.hayenga@arm.com        pc = threadInfo[curThread]->thread->instAddr();
14911147Smitch.hayenga@arm.com    } while (oldpc != pc);
15011147Smitch.hayenga@arm.com}
15111147Smitch.hayenga@arm.com
15211147Smitch.hayenga@arm.comvoid
15311147Smitch.hayenga@arm.comBaseSimpleCPU::swapActiveThread()
15411147Smitch.hayenga@arm.com{
15511147Smitch.hayenga@arm.com    if (numThreads > 1) {
15611147Smitch.hayenga@arm.com        if ((!curStaticInst || !curStaticInst->isDelayedCommit()) &&
15711147Smitch.hayenga@arm.com             !threadInfo[curThread]->stayAtPC) {
15811147Smitch.hayenga@arm.com            // Swap active threads
15911147Smitch.hayenga@arm.com            if (!activeThreads.empty()) {
16011147Smitch.hayenga@arm.com                curThread = activeThreads.front();
16111147Smitch.hayenga@arm.com                activeThreads.pop_front();
16211147Smitch.hayenga@arm.com                activeThreads.push_back(curThread);
16311147Smitch.hayenga@arm.com            }
16411147Smitch.hayenga@arm.com        }
16511147Smitch.hayenga@arm.com    }
16611147Smitch.hayenga@arm.com}
16711147Smitch.hayenga@arm.com
16811147Smitch.hayenga@arm.comvoid
16911147Smitch.hayenga@arm.comBaseSimpleCPU::countInst()
17011147Smitch.hayenga@arm.com{
17111147Smitch.hayenga@arm.com    SimpleExecContext& t_info = *threadInfo[curThread];
17211147Smitch.hayenga@arm.com
17311147Smitch.hayenga@arm.com    if (!curStaticInst->isMicroop() || curStaticInst->isLastMicroop()) {
17411147Smitch.hayenga@arm.com        t_info.numInst++;
17511147Smitch.hayenga@arm.com        t_info.numInsts++;
17613836Snikos.nikoleris@arm.com
17713836Snikos.nikoleris@arm.com        system->totalNumInsts++;
17813836Snikos.nikoleris@arm.com        t_info.thread->funcExeInst++;
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
18411147Smitch.hayenga@arm.comCounter
18511147Smitch.hayenga@arm.comBaseSimpleCPU::totalInsts() const
18611147Smitch.hayenga@arm.com{
18711147Smitch.hayenga@arm.com    Counter total_inst = 0;
18811147Smitch.hayenga@arm.com    for (auto& t_info : threadInfo) {
18911147Smitch.hayenga@arm.com        total_inst += t_info->numInst;
19011147Smitch.hayenga@arm.com    }
19111147Smitch.hayenga@arm.com
19211147Smitch.hayenga@arm.com    return total_inst;
19311147Smitch.hayenga@arm.com}
19411147Smitch.hayenga@arm.com
19511147Smitch.hayenga@arm.comCounter
19611147Smitch.hayenga@arm.comBaseSimpleCPU::totalOps() const
19711147Smitch.hayenga@arm.com{
19811147Smitch.hayenga@arm.com    Counter total_op = 0;
19911147Smitch.hayenga@arm.com    for (auto& t_info : threadInfo) {
20011147Smitch.hayenga@arm.com        total_op += t_info->numOp;
20111147Smitch.hayenga@arm.com    }
20211147Smitch.hayenga@arm.com
20311147Smitch.hayenga@arm.com    return total_op;
2042SN/A}
2052SN/A
2062623SN/ABaseSimpleCPU::~BaseSimpleCPU()
2072SN/A{
2082SN/A}
2092SN/A
210180SN/Avoid
2118737Skoansin.tan@gmail.comBaseSimpleCPU::haltContext(ThreadID thread_num)
212393SN/A{
213393SN/A    // for now, these are equivalent
214393SN/A    suspendContext(thread_num);
21512284Sjose.marinho@arm.com    updateCycleCounters(BaseCPU::CPU_STATE_SLEEP);
216393SN/A}
217384SN/A
218189SN/A
219189SN/Avoid
2202623SN/ABaseSimpleCPU::regStats()
2212SN/A{
222729SN/A    using namespace Stats;
223334SN/A
2242SN/A    BaseCPU::regStats();
2252SN/A
22611147Smitch.hayenga@arm.com    for (ThreadID tid = 0; tid < numThreads; tid++) {
22711147Smitch.hayenga@arm.com        SimpleExecContext& t_info = *threadInfo[tid];
2288834Satgutier@umich.edu
22911147Smitch.hayenga@arm.com        std::string thread_str = name();
23011147Smitch.hayenga@arm.com        if (numThreads > 1)
23111147Smitch.hayenga@arm.com            thread_str += ".thread" + std::to_string(tid);
2322SN/A
23311147Smitch.hayenga@arm.com        t_info.numInsts
23411147Smitch.hayenga@arm.com            .name(thread_str + ".committedInsts")
23511147Smitch.hayenga@arm.com            .desc("Number of instructions committed")
23611147Smitch.hayenga@arm.com            ;
2377897Shestness@cs.utexas.edu
23811147Smitch.hayenga@arm.com        t_info.numOps
23911147Smitch.hayenga@arm.com            .name(thread_str + ".committedOps")
24011147Smitch.hayenga@arm.com            .desc("Number of ops (including micro ops) committed")
24111147Smitch.hayenga@arm.com            ;
2427897Shestness@cs.utexas.edu
24311147Smitch.hayenga@arm.com        t_info.numIntAluAccesses
24411147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_alu_accesses")
24511147Smitch.hayenga@arm.com            .desc("Number of integer alu accesses")
24611147Smitch.hayenga@arm.com            ;
2477897Shestness@cs.utexas.edu
24811147Smitch.hayenga@arm.com        t_info.numFpAluAccesses
24911147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_alu_accesses")
25011147Smitch.hayenga@arm.com            .desc("Number of float alu accesses")
25111147Smitch.hayenga@arm.com            ;
2527897Shestness@cs.utexas.edu
25312110SRekai.GonzalezAlberquilla@arm.com        t_info.numVecAluAccesses
25412110SRekai.GonzalezAlberquilla@arm.com            .name(thread_str + ".num_vec_alu_accesses")
25512110SRekai.GonzalezAlberquilla@arm.com            .desc("Number of vector alu accesses")
25612110SRekai.GonzalezAlberquilla@arm.com            ;
25712110SRekai.GonzalezAlberquilla@arm.com
25811147Smitch.hayenga@arm.com        t_info.numCallsReturns
25911147Smitch.hayenga@arm.com            .name(thread_str + ".num_func_calls")
26011147Smitch.hayenga@arm.com            .desc("number of times a function call or return occured")
26111147Smitch.hayenga@arm.com            ;
2627897Shestness@cs.utexas.edu
26311147Smitch.hayenga@arm.com        t_info.numCondCtrlInsts
26411147Smitch.hayenga@arm.com            .name(thread_str + ".num_conditional_control_insts")
26511147Smitch.hayenga@arm.com            .desc("number of instructions that are conditional controls")
26611147Smitch.hayenga@arm.com            ;
2677897Shestness@cs.utexas.edu
26811147Smitch.hayenga@arm.com        t_info.numIntInsts
26911147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_insts")
27011147Smitch.hayenga@arm.com            .desc("number of integer instructions")
27111147Smitch.hayenga@arm.com            ;
2727897Shestness@cs.utexas.edu
27311147Smitch.hayenga@arm.com        t_info.numFpInsts
27411147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_insts")
27511147Smitch.hayenga@arm.com            .desc("number of float instructions")
27611147Smitch.hayenga@arm.com            ;
2777897Shestness@cs.utexas.edu
27812110SRekai.GonzalezAlberquilla@arm.com        t_info.numVecInsts
27912110SRekai.GonzalezAlberquilla@arm.com            .name(thread_str + ".num_vec_insts")
28012110SRekai.GonzalezAlberquilla@arm.com            .desc("number of vector instructions")
28112110SRekai.GonzalezAlberquilla@arm.com            ;
28212110SRekai.GonzalezAlberquilla@arm.com
28311147Smitch.hayenga@arm.com        t_info.numIntRegReads
28411147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_register_reads")
28511147Smitch.hayenga@arm.com            .desc("number of times the integer registers were read")
28611147Smitch.hayenga@arm.com            ;
2877897Shestness@cs.utexas.edu
28811147Smitch.hayenga@arm.com        t_info.numIntRegWrites
28911147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_register_writes")
29011147Smitch.hayenga@arm.com            .desc("number of times the integer registers were written")
29111147Smitch.hayenga@arm.com            ;
2927897Shestness@cs.utexas.edu
29311147Smitch.hayenga@arm.com        t_info.numFpRegReads
29411147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_register_reads")
29511147Smitch.hayenga@arm.com            .desc("number of times the floating registers were read")
29611147Smitch.hayenga@arm.com            ;
2979920Syasuko.eckert@amd.com
29811147Smitch.hayenga@arm.com        t_info.numFpRegWrites
29911147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_register_writes")
30011147Smitch.hayenga@arm.com            .desc("number of times the floating registers were written")
30111147Smitch.hayenga@arm.com            ;
3029920Syasuko.eckert@amd.com
30312109SRekai.GonzalezAlberquilla@arm.com        t_info.numVecRegReads
30412109SRekai.GonzalezAlberquilla@arm.com            .name(thread_str + ".num_vec_register_reads")
30512109SRekai.GonzalezAlberquilla@arm.com            .desc("number of times the vector registers were read")
30612109SRekai.GonzalezAlberquilla@arm.com            ;
30712109SRekai.GonzalezAlberquilla@arm.com
30812109SRekai.GonzalezAlberquilla@arm.com        t_info.numVecRegWrites
30912109SRekai.GonzalezAlberquilla@arm.com            .name(thread_str + ".num_vec_register_writes")
31012109SRekai.GonzalezAlberquilla@arm.com            .desc("number of times the vector registers were written")
31112109SRekai.GonzalezAlberquilla@arm.com            ;
31212109SRekai.GonzalezAlberquilla@arm.com
31311147Smitch.hayenga@arm.com        t_info.numCCRegReads
31411147Smitch.hayenga@arm.com            .name(thread_str + ".num_cc_register_reads")
31511147Smitch.hayenga@arm.com            .desc("number of times the CC registers were read")
31611147Smitch.hayenga@arm.com            .flags(nozero)
31711147Smitch.hayenga@arm.com            ;
3187897Shestness@cs.utexas.edu
31911147Smitch.hayenga@arm.com        t_info.numCCRegWrites
32011147Smitch.hayenga@arm.com            .name(thread_str + ".num_cc_register_writes")
32111147Smitch.hayenga@arm.com            .desc("number of times the CC registers were written")
32211147Smitch.hayenga@arm.com            .flags(nozero)
32311147Smitch.hayenga@arm.com            ;
3247897Shestness@cs.utexas.edu
32511147Smitch.hayenga@arm.com        t_info.numMemRefs
32611147Smitch.hayenga@arm.com            .name(thread_str + ".num_mem_refs")
32711147Smitch.hayenga@arm.com            .desc("number of memory refs")
32811147Smitch.hayenga@arm.com            ;
3292SN/A
33011147Smitch.hayenga@arm.com        t_info.numStoreInsts
33111147Smitch.hayenga@arm.com            .name(thread_str + ".num_store_insts")
33211147Smitch.hayenga@arm.com            .desc("Number of store instructions")
33311147Smitch.hayenga@arm.com            ;
3341001SN/A
33511147Smitch.hayenga@arm.com        t_info.numLoadInsts
33611147Smitch.hayenga@arm.com            .name(thread_str + ".num_load_insts")
33711147Smitch.hayenga@arm.com            .desc("Number of load instructions")
33811147Smitch.hayenga@arm.com            ;
3392SN/A
34011147Smitch.hayenga@arm.com        t_info.notIdleFraction
34111147Smitch.hayenga@arm.com            .name(thread_str + ".not_idle_fraction")
34211147Smitch.hayenga@arm.com            .desc("Percentage of non-idle cycles")
34311147Smitch.hayenga@arm.com            ;
3447897Shestness@cs.utexas.edu
34511147Smitch.hayenga@arm.com        t_info.idleFraction
34611147Smitch.hayenga@arm.com            .name(thread_str + ".idle_fraction")
34711147Smitch.hayenga@arm.com            .desc("Percentage of idle cycles")
34811147Smitch.hayenga@arm.com            ;
3497897Shestness@cs.utexas.edu
35011147Smitch.hayenga@arm.com        t_info.numBusyCycles
35111147Smitch.hayenga@arm.com            .name(thread_str + ".num_busy_cycles")
35211147Smitch.hayenga@arm.com            .desc("Number of busy cycles")
35311147Smitch.hayenga@arm.com            ;
3542SN/A
35511147Smitch.hayenga@arm.com        t_info.numIdleCycles
35611147Smitch.hayenga@arm.com            .name(thread_str + ".num_idle_cycles")
35711147Smitch.hayenga@arm.com            .desc("Number of idle cycles")
35811147Smitch.hayenga@arm.com            ;
3592SN/A
36011147Smitch.hayenga@arm.com        t_info.icacheStallCycles
36111147Smitch.hayenga@arm.com            .name(thread_str + ".icache_stall_cycles")
36211147Smitch.hayenga@arm.com            .desc("ICache total stall cycles")
36311147Smitch.hayenga@arm.com            .prereq(t_info.icacheStallCycles)
36411147Smitch.hayenga@arm.com            ;
36511147Smitch.hayenga@arm.com
36611147Smitch.hayenga@arm.com        t_info.dcacheStallCycles
36711147Smitch.hayenga@arm.com            .name(thread_str + ".dcache_stall_cycles")
36811147Smitch.hayenga@arm.com            .desc("DCache total stall cycles")
36911147Smitch.hayenga@arm.com            .prereq(t_info.dcacheStallCycles)
37011147Smitch.hayenga@arm.com            ;
37111147Smitch.hayenga@arm.com
37211147Smitch.hayenga@arm.com        t_info.statExecutedInstType
37311147Smitch.hayenga@arm.com            .init(Enums::Num_OpClass)
37411147Smitch.hayenga@arm.com            .name(thread_str + ".op_class")
37511147Smitch.hayenga@arm.com            .desc("Class of executed instruction")
37611147Smitch.hayenga@arm.com            .flags(total | pdf | dist)
37711147Smitch.hayenga@arm.com            ;
37811147Smitch.hayenga@arm.com
37911147Smitch.hayenga@arm.com        for (unsigned i = 0; i < Num_OpClasses; ++i) {
38011147Smitch.hayenga@arm.com            t_info.statExecutedInstType.subname(i, Enums::OpClassStrings[i]);
38111147Smitch.hayenga@arm.com        }
38211147Smitch.hayenga@arm.com
38311147Smitch.hayenga@arm.com        t_info.idleFraction = constant(1.0) - t_info.notIdleFraction;
38411147Smitch.hayenga@arm.com        t_info.numIdleCycles = t_info.idleFraction * numCycles;
38511147Smitch.hayenga@arm.com        t_info.numBusyCycles = t_info.notIdleFraction * numCycles;
38611147Smitch.hayenga@arm.com
38711147Smitch.hayenga@arm.com        t_info.numBranches
38811147Smitch.hayenga@arm.com            .name(thread_str + ".Branches")
38911147Smitch.hayenga@arm.com            .desc("Number of branches fetched")
39011147Smitch.hayenga@arm.com            .prereq(t_info.numBranches);
39111147Smitch.hayenga@arm.com
39211147Smitch.hayenga@arm.com        t_info.numPredictedBranches
39311147Smitch.hayenga@arm.com            .name(thread_str + ".predictedBranches")
39411147Smitch.hayenga@arm.com            .desc("Number of branches predicted as taken")
39511147Smitch.hayenga@arm.com            .prereq(t_info.numPredictedBranches);
39611147Smitch.hayenga@arm.com
39711147Smitch.hayenga@arm.com        t_info.numBranchMispred
39811147Smitch.hayenga@arm.com            .name(thread_str + ".BranchMispred")
39911147Smitch.hayenga@arm.com            .desc("Number of branch mispredictions")
40011147Smitch.hayenga@arm.com            .prereq(t_info.numBranchMispred);
40110193SCurtis.Dunham@arm.com    }
4022SN/A}
4032SN/A
4042SN/Avoid
4052623SN/ABaseSimpleCPU::resetStats()
406334SN/A{
40711147Smitch.hayenga@arm.com    for (auto &thread_info : threadInfo) {
40811147Smitch.hayenga@arm.com        thread_info->notIdleFraction = (_status != Idle);
40911147Smitch.hayenga@arm.com    }
410334SN/A}
411334SN/A
412334SN/Avoid
41310905Sandreas.sandberg@arm.comBaseSimpleCPU::serializeThread(CheckpointOut &cp, ThreadID tid) const
4142SN/A{
4159448SAndreas.Sandberg@ARM.com    assert(_status == Idle || _status == Running);
4169448SAndreas.Sandberg@ARM.com
41711147Smitch.hayenga@arm.com    threadInfo[tid]->thread->serialize(cp);
4182SN/A}
4192SN/A
4202SN/Avoid
42110905Sandreas.sandberg@arm.comBaseSimpleCPU::unserializeThread(CheckpointIn &cp, ThreadID tid)
4222SN/A{
42311147Smitch.hayenga@arm.com    threadInfo[tid]->thread->unserialize(cp);
4242SN/A}
4252SN/A
4262SN/Avoid
4276221Snate@binkert.orgchange_thread_state(ThreadID tid, int activate, int priority)
4282SN/A{
4292SN/A}
4302SN/A
4312SN/AAddr
4322623SN/ABaseSimpleCPU::dbg_vtophys(Addr addr)
4332SN/A{
43411147Smitch.hayenga@arm.com    return vtophys(threadContexts[curThread], addr);
4352SN/A}
4362SN/A
4372SN/Avoid
43811151Smitch.hayenga@arm.comBaseSimpleCPU::wakeup(ThreadID tid)
4392SN/A{
44011151Smitch.hayenga@arm.com    getCpuAddrMonitor(tid)->gotWakeup = true;
44111151Smitch.hayenga@arm.com
44211151Smitch.hayenga@arm.com    if (threadInfo[tid]->thread->status() == ThreadContext::Suspended) {
44311151Smitch.hayenga@arm.com        DPRINTF(Quiesce,"[tid:%d] Suspended Processor awoke\n", tid);
44411151Smitch.hayenga@arm.com        threadInfo[tid]->thread->activate();
44511147Smitch.hayenga@arm.com    }
4462SN/A}
4472SN/A
4482SN/Avoid
4492623SN/ABaseSimpleCPU::checkForInterrupts()
4502SN/A{
45111147Smitch.hayenga@arm.com    SimpleExecContext&t_info = *threadInfo[curThread];
45211147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
45311147Smitch.hayenga@arm.com    ThreadContext* tc = thread->getTC();
45411147Smitch.hayenga@arm.com
4555704Snate@binkert.org    if (checkInterrupts(tc)) {
45611150Smitch.hayenga@arm.com        Fault interrupt = interrupts[curThread]->getInterrupt(tc);
4572SN/A
4583520Sgblack@eecs.umich.edu        if (interrupt != NoFault) {
45911147Smitch.hayenga@arm.com            t_info.fetchOffset = 0;
46011150Smitch.hayenga@arm.com            interrupts[curThread]->updateIntrInfo(tc);
4613520Sgblack@eecs.umich.edu            interrupt->invoke(tc);
4629023Sgblack@eecs.umich.edu            thread->decoder.reset();
4632SN/A        }
4642SN/A    }
4652623SN/A}
4662SN/A
4672623SN/A
4685894Sgblack@eecs.umich.eduvoid
46912749Sgiacomo.travaglini@arm.comBaseSimpleCPU::setupFetchRequest(const RequestPtr &req)
4702623SN/A{
47111147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
47211147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
47311147Smitch.hayenga@arm.com
4747720Sgblack@eecs.umich.edu    Addr instAddr = thread->instAddr();
47512372Smattdsinclair@gmail.com    Addr fetchPC = (instAddr & PCMask) + t_info.fetchOffset;
4764495Sacolyte@umich.edu
4772623SN/A    // set up memory request for instruction fetch
47812372Smattdsinclair@gmail.com    DPRINTF(Fetch, "Fetch: Inst PC:%08p, Fetch PC:%08p\n", instAddr, fetchPC);
4792623SN/A
48012372Smattdsinclair@gmail.com    req->setVirt(0, fetchPC, sizeof(MachInst), Request::INST_FETCH,
48112372Smattdsinclair@gmail.com                 instMasterId(), instAddr);
4822623SN/A}
4832623SN/A
4842623SN/A
4852623SN/Avoid
4862623SN/ABaseSimpleCPU::preExecute()
4872623SN/A{
48811147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
48911147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
49011147Smitch.hayenga@arm.com
4912SN/A    // maintain $r0 semantics
4922683Sktlim@umich.edu    thread->setIntReg(ZeroReg, 0);
4932427SN/A#if THE_ISA == ALPHA_ISA
49413611Sgabeblack@google.com    thread->setFloatReg(ZeroReg, 0);
4952427SN/A#endif // ALPHA_ISA
4962SN/A
49713954Sgiacomo.gabrielli@arm.com    // resets predicates
49813954Sgiacomo.gabrielli@arm.com    t_info.setPredicate(true);
49913954Sgiacomo.gabrielli@arm.com    t_info.setMemAccPredicate(true);
50013954Sgiacomo.gabrielli@arm.com
5012623SN/A    // check for instruction-count-based events
50211147Smitch.hayenga@arm.com    comInstEventQueue[curThread]->serviceEvents(t_info.numInst);
5037897Shestness@cs.utexas.edu    system->instEventQueue.serviceEvents(system->totalNumInsts);
5042SN/A
5052623SN/A    // decode the instruction
5062623SN/A    inst = gtoh(inst);
5074377Sgblack@eecs.umich.edu
5087720Sgblack@eecs.umich.edu    TheISA::PCState pcState = thread->pcState();
5094377Sgblack@eecs.umich.edu
5107720Sgblack@eecs.umich.edu    if (isRomMicroPC(pcState.microPC())) {
51111147Smitch.hayenga@arm.com        t_info.stayAtPC = false;
5127720Sgblack@eecs.umich.edu        curStaticInst = microcodeRom.fetchMicroop(pcState.microPC(),
5137720Sgblack@eecs.umich.edu                                                  curMacroStaticInst);
5145665Sgblack@eecs.umich.edu    } else if (!curMacroStaticInst) {
5155665Sgblack@eecs.umich.edu        //We're not in the middle of a macro instruction
5164181Sgblack@eecs.umich.edu        StaticInstPtr instPtr = NULL;
5174181Sgblack@eecs.umich.edu
5189023Sgblack@eecs.umich.edu        TheISA::Decoder *decoder = &(thread->decoder);
5199023Sgblack@eecs.umich.edu
5204181Sgblack@eecs.umich.edu        //Predecode, ie bundle up an ExtMachInst
5214182Sgblack@eecs.umich.edu        //If more fetch data is needed, pass it in.
52211147Smitch.hayenga@arm.com        Addr fetchPC = (pcState.instAddr() & PCMask) + t_info.fetchOffset;
52311321Ssteve.reinhardt@amd.com        //if (decoder->needMoreBytes())
5249023Sgblack@eecs.umich.edu            decoder->moreBytes(pcState, fetchPC, inst);
5254593Sgblack@eecs.umich.edu        //else
5269023Sgblack@eecs.umich.edu        //    decoder->process();
5274377Sgblack@eecs.umich.edu
5289023Sgblack@eecs.umich.edu        //Decode an instruction if one is ready. Otherwise, we'll have to
5294377Sgblack@eecs.umich.edu        //fetch beyond the MachInst at the current pc.
5309023Sgblack@eecs.umich.edu        instPtr = decoder->decode(pcState);
5319023Sgblack@eecs.umich.edu        if (instPtr) {
53211147Smitch.hayenga@arm.com            t_info.stayAtPC = false;
5337720Sgblack@eecs.umich.edu            thread->pcState(pcState);
5344377Sgblack@eecs.umich.edu        } else {
53511147Smitch.hayenga@arm.com            t_info.stayAtPC = true;
53611147Smitch.hayenga@arm.com            t_info.fetchOffset += sizeof(MachInst);
5374377Sgblack@eecs.umich.edu        }
5384181Sgblack@eecs.umich.edu
5394181Sgblack@eecs.umich.edu        //If we decoded an instruction and it's microcoded, start pulling
5404181Sgblack@eecs.umich.edu        //out micro ops
5414539Sgblack@eecs.umich.edu        if (instPtr && instPtr->isMacroop()) {
5423276Sgblack@eecs.umich.edu            curMacroStaticInst = instPtr;
54311147Smitch.hayenga@arm.com            curStaticInst =
54411147Smitch.hayenga@arm.com                curMacroStaticInst->fetchMicroop(pcState.microPC());
5453280Sgblack@eecs.umich.edu        } else {
5463280Sgblack@eecs.umich.edu            curStaticInst = instPtr;
5473276Sgblack@eecs.umich.edu        }
5483276Sgblack@eecs.umich.edu    } else {
5493276Sgblack@eecs.umich.edu        //Read the next micro op from the macro op
5507720Sgblack@eecs.umich.edu        curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC());
5513276Sgblack@eecs.umich.edu    }
5523276Sgblack@eecs.umich.edu
5534181Sgblack@eecs.umich.edu    //If we decoded an instruction this "tick", record information about it.
5548955Sgblack@eecs.umich.edu    if (curStaticInst) {
5554522Ssaidi@eecs.umich.edu#if TRACING_ON
55611147Smitch.hayenga@arm.com        traceData = tracer->getInstRecord(curTick(), thread->getTC(),
5577720Sgblack@eecs.umich.edu                curStaticInst, thread->pcState(), curMacroStaticInst);
5582470SN/A
5598955Sgblack@eecs.umich.edu        DPRINTF(Decode,"Decode: Decoded %s instruction: %#x\n",
5604181Sgblack@eecs.umich.edu                curStaticInst->getName(), curStaticInst->machInst);
5614522Ssaidi@eecs.umich.edu#endif // TRACING_ON
5624181Sgblack@eecs.umich.edu    }
56310061Sandreas@sandberg.pp.se
56411147Smitch.hayenga@arm.com    if (branchPred && curStaticInst &&
56511147Smitch.hayenga@arm.com        curStaticInst->isControl()) {
56610061Sandreas@sandberg.pp.se        // Use a fake sequence number since we only have one
56710061Sandreas@sandberg.pp.se        // instruction in flight at the same time.
56810061Sandreas@sandberg.pp.se        const InstSeqNum cur_sn(0);
56911147Smitch.hayenga@arm.com        t_info.predPC = thread->pcState();
57010061Sandreas@sandberg.pp.se        const bool predict_taken(
57111147Smitch.hayenga@arm.com            branchPred->predict(curStaticInst, cur_sn, t_info.predPC,
57211147Smitch.hayenga@arm.com                                curThread));
57310061Sandreas@sandberg.pp.se
57410061Sandreas@sandberg.pp.se        if (predict_taken)
57511147Smitch.hayenga@arm.com            ++t_info.numPredictedBranches;
57610061Sandreas@sandberg.pp.se    }
5772623SN/A}
5782623SN/A
5792623SN/Avoid
5802623SN/ABaseSimpleCPU::postExecute()
5812623SN/A{
58211147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
58311147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
58411147Smitch.hayenga@arm.com
5857720Sgblack@eecs.umich.edu    assert(curStaticInst);
5867720Sgblack@eecs.umich.edu
58711147Smitch.hayenga@arm.com    TheISA::PCState pc = threadContexts[curThread]->pcState();
5887720Sgblack@eecs.umich.edu    Addr instAddr = pc.instAddr();
5898780Sgblack@eecs.umich.edu    if (FullSystem && thread->profile) {
59011147Smitch.hayenga@arm.com        bool usermode = TheISA::inUserMode(threadContexts[curThread]);
5917720Sgblack@eecs.umich.edu        thread->profilePC = usermode ? 1 : instAddr;
59211147Smitch.hayenga@arm.com        ProfileNode *node = thread->profile->consume(threadContexts[curThread],
59311147Smitch.hayenga@arm.com                                                     curStaticInst);
5942623SN/A        if (node)
5952683Sktlim@umich.edu            thread->profileNode = node;
5962623SN/A    }
5972SN/A
5982623SN/A    if (curStaticInst->isMemRef()) {
59911147Smitch.hayenga@arm.com        t_info.numMemRefs++;
6002SN/A    }
6012SN/A
6022623SN/A    if (curStaticInst->isLoad()) {
60311147Smitch.hayenga@arm.com        ++t_info.numLoad;
60411147Smitch.hayenga@arm.com        comLoadEventQueue[curThread]->serviceEvents(t_info.numLoad);
6052623SN/A    }
6062SN/A
6075953Ssaidi@eecs.umich.edu    if (CPA::available()) {
60811147Smitch.hayenga@arm.com        CPA::cpa()->swAutoBegin(threadContexts[curThread], pc.nextInstAddr());
6095953Ssaidi@eecs.umich.edu    }
6105953Ssaidi@eecs.umich.edu
61110061Sandreas@sandberg.pp.se    if (curStaticInst->isControl()) {
61211147Smitch.hayenga@arm.com        ++t_info.numBranches;
61310061Sandreas@sandberg.pp.se    }
61410061Sandreas@sandberg.pp.se
6157897Shestness@cs.utexas.edu    /* Power model statistics */
6167897Shestness@cs.utexas.edu    //integer alu accesses
6177897Shestness@cs.utexas.edu    if (curStaticInst->isInteger()){
61811147Smitch.hayenga@arm.com        t_info.numIntAluAccesses++;
61911147Smitch.hayenga@arm.com        t_info.numIntInsts++;
6207897Shestness@cs.utexas.edu    }
6217897Shestness@cs.utexas.edu
6227897Shestness@cs.utexas.edu    //float alu accesses
6237897Shestness@cs.utexas.edu    if (curStaticInst->isFloating()){
62411147Smitch.hayenga@arm.com        t_info.numFpAluAccesses++;
62511147Smitch.hayenga@arm.com        t_info.numFpInsts++;
6267897Shestness@cs.utexas.edu    }
62711147Smitch.hayenga@arm.com
62812110SRekai.GonzalezAlberquilla@arm.com    //vector alu accesses
62912110SRekai.GonzalezAlberquilla@arm.com    if (curStaticInst->isVector()){
63012110SRekai.GonzalezAlberquilla@arm.com        t_info.numVecAluAccesses++;
63112110SRekai.GonzalezAlberquilla@arm.com        t_info.numVecInsts++;
63212110SRekai.GonzalezAlberquilla@arm.com    }
63312110SRekai.GonzalezAlberquilla@arm.com
6347897Shestness@cs.utexas.edu    //number of function calls/returns to get window accesses
6357897Shestness@cs.utexas.edu    if (curStaticInst->isCall() || curStaticInst->isReturn()){
63611147Smitch.hayenga@arm.com        t_info.numCallsReturns++;
6377897Shestness@cs.utexas.edu    }
63811147Smitch.hayenga@arm.com
6397897Shestness@cs.utexas.edu    //the number of branch predictions that will be made
6407897Shestness@cs.utexas.edu    if (curStaticInst->isCondCtrl()){
64111147Smitch.hayenga@arm.com        t_info.numCondCtrlInsts++;
6427897Shestness@cs.utexas.edu    }
64311147Smitch.hayenga@arm.com
6447897Shestness@cs.utexas.edu    //result bus acceses
6457897Shestness@cs.utexas.edu    if (curStaticInst->isLoad()){
64611147Smitch.hayenga@arm.com        t_info.numLoadInsts++;
6477897Shestness@cs.utexas.edu    }
64811147Smitch.hayenga@arm.com
64913652Sqtt2@cornell.edu    if (curStaticInst->isStore() || curStaticInst->isAtomic()){
65011147Smitch.hayenga@arm.com        t_info.numStoreInsts++;
6517897Shestness@cs.utexas.edu    }
6527897Shestness@cs.utexas.edu    /* End power model statistics */
6537897Shestness@cs.utexas.edu
65411147Smitch.hayenga@arm.com    t_info.statExecutedInstType[curStaticInst->opClass()]++;
65510193SCurtis.Dunham@arm.com
6568780Sgblack@eecs.umich.edu    if (FullSystem)
6578780Sgblack@eecs.umich.edu        traceFunctions(instAddr);
6582644Sstever@eecs.umich.edu
6592644Sstever@eecs.umich.edu    if (traceData) {
6604046Sbinkertn@umich.edu        traceData->dump();
6614046Sbinkertn@umich.edu        delete traceData;
6624046Sbinkertn@umich.edu        traceData = NULL;
6632644Sstever@eecs.umich.edu    }
66410464SAndreas.Sandberg@ARM.com
66510464SAndreas.Sandberg@ARM.com    // Call CPU instruction commit probes
66613818Sjavier.bueno@metempsy.com    probeInstCommit(curStaticInst, instAddr);
6672623SN/A}
6682SN/A
6692623SN/Avoid
67010379Sandreas.hansson@arm.comBaseSimpleCPU::advancePC(const Fault &fault)
6712623SN/A{
67211147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
67311147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
67411147Smitch.hayenga@arm.com
67510061Sandreas@sandberg.pp.se    const bool branching(thread->pcState().branching());
67610061Sandreas@sandberg.pp.se
6774377Sgblack@eecs.umich.edu    //Since we're moving to a new pc, zero out the offset
67811147Smitch.hayenga@arm.com    t_info.fetchOffset = 0;
6792090SN/A    if (fault != NoFault) {
6803905Ssaidi@eecs.umich.edu        curMacroStaticInst = StaticInst::nullStaticInstPtr;
68111147Smitch.hayenga@arm.com        fault->invoke(threadContexts[curThread], curStaticInst);
6829023Sgblack@eecs.umich.edu        thread->decoder.reset();
6834377Sgblack@eecs.umich.edu    } else {
6847720Sgblack@eecs.umich.edu        if (curStaticInst) {
6857720Sgblack@eecs.umich.edu            if (curStaticInst->isLastMicroop())
6867720Sgblack@eecs.umich.edu                curMacroStaticInst = StaticInst::nullStaticInstPtr;
6877720Sgblack@eecs.umich.edu            TheISA::PCState pcState = thread->pcState();
6887720Sgblack@eecs.umich.edu            TheISA::advancePC(pcState, curStaticInst);
6897720Sgblack@eecs.umich.edu            thread->pcState(pcState);
6903276Sgblack@eecs.umich.edu        }
6912SN/A    }
69210061Sandreas@sandberg.pp.se
69310061Sandreas@sandberg.pp.se    if (branchPred && curStaticInst && curStaticInst->isControl()) {
69410061Sandreas@sandberg.pp.se        // Use a fake sequence number since we only have one
69510061Sandreas@sandberg.pp.se        // instruction in flight at the same time.
69610061Sandreas@sandberg.pp.se        const InstSeqNum cur_sn(0);
69710061Sandreas@sandberg.pp.se
69811147Smitch.hayenga@arm.com        if (t_info.predPC == thread->pcState()) {
69910061Sandreas@sandberg.pp.se            // Correctly predicted branch
70011147Smitch.hayenga@arm.com            branchPred->update(cur_sn, curThread);
70110061Sandreas@sandberg.pp.se        } else {
70210061Sandreas@sandberg.pp.se            // Mis-predicted branch
70311147Smitch.hayenga@arm.com            branchPred->squash(cur_sn, thread->pcState(), branching, curThread);
70411147Smitch.hayenga@arm.com            ++t_info.numBranchMispred;
70510061Sandreas@sandberg.pp.se        }
70610061Sandreas@sandberg.pp.se    }
7072SN/A}
7082SN/A
7099461Snilay@cs.wisc.eduvoid
7109461Snilay@cs.wisc.eduBaseSimpleCPU::startup()
7119461Snilay@cs.wisc.edu{
7129461Snilay@cs.wisc.edu    BaseCPU::startup();
71311147Smitch.hayenga@arm.com    for (auto& t_info : threadInfo)
71411147Smitch.hayenga@arm.com        t_info->thread->startup();
7159461Snilay@cs.wisc.edu}
716