base.cc revision 13652
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"
482439SN/A#include "arch/utility.hh"
498779Sgblack@eecs.umich.edu#include "arch/vtophys.hh"
506216Snate@binkert.org#include "base/cp_annotate.hh"
51146SN/A#include "base/cprintf.hh"
52146SN/A#include "base/inifile.hh"
5311793Sbrandon.potter@amd.com#include "base/loader/symtab.hh"
5412334Sgabeblack@google.com#include "base/logging.hh"
55146SN/A#include "base/pollevent.hh"
56146SN/A#include "base/trace.hh"
576216Snate@binkert.org#include "base/types.hh"
586658Snate@binkert.org#include "config/the_isa.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);
21712284Sjose.marinho@arm.com    updateCycleCounters(BaseCPU::CPU_STATE_SLEEP);
218393SN/A}
219384SN/A
220189SN/A
221189SN/Avoid
2222623SN/ABaseSimpleCPU::regStats()
2232SN/A{
224729SN/A    using namespace Stats;
225334SN/A
2262SN/A    BaseCPU::regStats();
2272SN/A
22811147Smitch.hayenga@arm.com    for (ThreadID tid = 0; tid < numThreads; tid++) {
22911147Smitch.hayenga@arm.com        SimpleExecContext& t_info = *threadInfo[tid];
2308834Satgutier@umich.edu
23111147Smitch.hayenga@arm.com        std::string thread_str = name();
23211147Smitch.hayenga@arm.com        if (numThreads > 1)
23311147Smitch.hayenga@arm.com            thread_str += ".thread" + std::to_string(tid);
2342SN/A
23511147Smitch.hayenga@arm.com        t_info.numInsts
23611147Smitch.hayenga@arm.com            .name(thread_str + ".committedInsts")
23711147Smitch.hayenga@arm.com            .desc("Number of instructions committed")
23811147Smitch.hayenga@arm.com            ;
2397897Shestness@cs.utexas.edu
24011147Smitch.hayenga@arm.com        t_info.numOps
24111147Smitch.hayenga@arm.com            .name(thread_str + ".committedOps")
24211147Smitch.hayenga@arm.com            .desc("Number of ops (including micro ops) committed")
24311147Smitch.hayenga@arm.com            ;
2447897Shestness@cs.utexas.edu
24511147Smitch.hayenga@arm.com        t_info.numIntAluAccesses
24611147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_alu_accesses")
24711147Smitch.hayenga@arm.com            .desc("Number of integer alu accesses")
24811147Smitch.hayenga@arm.com            ;
2497897Shestness@cs.utexas.edu
25011147Smitch.hayenga@arm.com        t_info.numFpAluAccesses
25111147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_alu_accesses")
25211147Smitch.hayenga@arm.com            .desc("Number of float alu accesses")
25311147Smitch.hayenga@arm.com            ;
2547897Shestness@cs.utexas.edu
25512110SRekai.GonzalezAlberquilla@arm.com        t_info.numVecAluAccesses
25612110SRekai.GonzalezAlberquilla@arm.com            .name(thread_str + ".num_vec_alu_accesses")
25712110SRekai.GonzalezAlberquilla@arm.com            .desc("Number of vector alu accesses")
25812110SRekai.GonzalezAlberquilla@arm.com            ;
25912110SRekai.GonzalezAlberquilla@arm.com
26011147Smitch.hayenga@arm.com        t_info.numCallsReturns
26111147Smitch.hayenga@arm.com            .name(thread_str + ".num_func_calls")
26211147Smitch.hayenga@arm.com            .desc("number of times a function call or return occured")
26311147Smitch.hayenga@arm.com            ;
2647897Shestness@cs.utexas.edu
26511147Smitch.hayenga@arm.com        t_info.numCondCtrlInsts
26611147Smitch.hayenga@arm.com            .name(thread_str + ".num_conditional_control_insts")
26711147Smitch.hayenga@arm.com            .desc("number of instructions that are conditional controls")
26811147Smitch.hayenga@arm.com            ;
2697897Shestness@cs.utexas.edu
27011147Smitch.hayenga@arm.com        t_info.numIntInsts
27111147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_insts")
27211147Smitch.hayenga@arm.com            .desc("number of integer instructions")
27311147Smitch.hayenga@arm.com            ;
2747897Shestness@cs.utexas.edu
27511147Smitch.hayenga@arm.com        t_info.numFpInsts
27611147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_insts")
27711147Smitch.hayenga@arm.com            .desc("number of float instructions")
27811147Smitch.hayenga@arm.com            ;
2797897Shestness@cs.utexas.edu
28012110SRekai.GonzalezAlberquilla@arm.com        t_info.numVecInsts
28112110SRekai.GonzalezAlberquilla@arm.com            .name(thread_str + ".num_vec_insts")
28212110SRekai.GonzalezAlberquilla@arm.com            .desc("number of vector instructions")
28312110SRekai.GonzalezAlberquilla@arm.com            ;
28412110SRekai.GonzalezAlberquilla@arm.com
28511147Smitch.hayenga@arm.com        t_info.numIntRegReads
28611147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_register_reads")
28711147Smitch.hayenga@arm.com            .desc("number of times the integer registers were read")
28811147Smitch.hayenga@arm.com            ;
2897897Shestness@cs.utexas.edu
29011147Smitch.hayenga@arm.com        t_info.numIntRegWrites
29111147Smitch.hayenga@arm.com            .name(thread_str + ".num_int_register_writes")
29211147Smitch.hayenga@arm.com            .desc("number of times the integer registers were written")
29311147Smitch.hayenga@arm.com            ;
2947897Shestness@cs.utexas.edu
29511147Smitch.hayenga@arm.com        t_info.numFpRegReads
29611147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_register_reads")
29711147Smitch.hayenga@arm.com            .desc("number of times the floating registers were read")
29811147Smitch.hayenga@arm.com            ;
2999920Syasuko.eckert@amd.com
30011147Smitch.hayenga@arm.com        t_info.numFpRegWrites
30111147Smitch.hayenga@arm.com            .name(thread_str + ".num_fp_register_writes")
30211147Smitch.hayenga@arm.com            .desc("number of times the floating registers were written")
30311147Smitch.hayenga@arm.com            ;
3049920Syasuko.eckert@amd.com
30512109SRekai.GonzalezAlberquilla@arm.com        t_info.numVecRegReads
30612109SRekai.GonzalezAlberquilla@arm.com            .name(thread_str + ".num_vec_register_reads")
30712109SRekai.GonzalezAlberquilla@arm.com            .desc("number of times the vector registers were read")
30812109SRekai.GonzalezAlberquilla@arm.com            ;
30912109SRekai.GonzalezAlberquilla@arm.com
31012109SRekai.GonzalezAlberquilla@arm.com        t_info.numVecRegWrites
31112109SRekai.GonzalezAlberquilla@arm.com            .name(thread_str + ".num_vec_register_writes")
31212109SRekai.GonzalezAlberquilla@arm.com            .desc("number of times the vector registers were written")
31312109SRekai.GonzalezAlberquilla@arm.com            ;
31412109SRekai.GonzalezAlberquilla@arm.com
31511147Smitch.hayenga@arm.com        t_info.numCCRegReads
31611147Smitch.hayenga@arm.com            .name(thread_str + ".num_cc_register_reads")
31711147Smitch.hayenga@arm.com            .desc("number of times the CC registers were read")
31811147Smitch.hayenga@arm.com            .flags(nozero)
31911147Smitch.hayenga@arm.com            ;
3207897Shestness@cs.utexas.edu
32111147Smitch.hayenga@arm.com        t_info.numCCRegWrites
32211147Smitch.hayenga@arm.com            .name(thread_str + ".num_cc_register_writes")
32311147Smitch.hayenga@arm.com            .desc("number of times the CC registers were written")
32411147Smitch.hayenga@arm.com            .flags(nozero)
32511147Smitch.hayenga@arm.com            ;
3267897Shestness@cs.utexas.edu
32711147Smitch.hayenga@arm.com        t_info.numMemRefs
32811147Smitch.hayenga@arm.com            .name(thread_str + ".num_mem_refs")
32911147Smitch.hayenga@arm.com            .desc("number of memory refs")
33011147Smitch.hayenga@arm.com            ;
3312SN/A
33211147Smitch.hayenga@arm.com        t_info.numStoreInsts
33311147Smitch.hayenga@arm.com            .name(thread_str + ".num_store_insts")
33411147Smitch.hayenga@arm.com            .desc("Number of store instructions")
33511147Smitch.hayenga@arm.com            ;
3361001SN/A
33711147Smitch.hayenga@arm.com        t_info.numLoadInsts
33811147Smitch.hayenga@arm.com            .name(thread_str + ".num_load_insts")
33911147Smitch.hayenga@arm.com            .desc("Number of load instructions")
34011147Smitch.hayenga@arm.com            ;
3412SN/A
34211147Smitch.hayenga@arm.com        t_info.notIdleFraction
34311147Smitch.hayenga@arm.com            .name(thread_str + ".not_idle_fraction")
34411147Smitch.hayenga@arm.com            .desc("Percentage of non-idle cycles")
34511147Smitch.hayenga@arm.com            ;
3467897Shestness@cs.utexas.edu
34711147Smitch.hayenga@arm.com        t_info.idleFraction
34811147Smitch.hayenga@arm.com            .name(thread_str + ".idle_fraction")
34911147Smitch.hayenga@arm.com            .desc("Percentage of idle cycles")
35011147Smitch.hayenga@arm.com            ;
3517897Shestness@cs.utexas.edu
35211147Smitch.hayenga@arm.com        t_info.numBusyCycles
35311147Smitch.hayenga@arm.com            .name(thread_str + ".num_busy_cycles")
35411147Smitch.hayenga@arm.com            .desc("Number of busy cycles")
35511147Smitch.hayenga@arm.com            ;
3562SN/A
35711147Smitch.hayenga@arm.com        t_info.numIdleCycles
35811147Smitch.hayenga@arm.com            .name(thread_str + ".num_idle_cycles")
35911147Smitch.hayenga@arm.com            .desc("Number of idle cycles")
36011147Smitch.hayenga@arm.com            ;
3612SN/A
36211147Smitch.hayenga@arm.com        t_info.icacheStallCycles
36311147Smitch.hayenga@arm.com            .name(thread_str + ".icache_stall_cycles")
36411147Smitch.hayenga@arm.com            .desc("ICache total stall cycles")
36511147Smitch.hayenga@arm.com            .prereq(t_info.icacheStallCycles)
36611147Smitch.hayenga@arm.com            ;
36711147Smitch.hayenga@arm.com
36811147Smitch.hayenga@arm.com        t_info.dcacheStallCycles
36911147Smitch.hayenga@arm.com            .name(thread_str + ".dcache_stall_cycles")
37011147Smitch.hayenga@arm.com            .desc("DCache total stall cycles")
37111147Smitch.hayenga@arm.com            .prereq(t_info.dcacheStallCycles)
37211147Smitch.hayenga@arm.com            ;
37311147Smitch.hayenga@arm.com
37411147Smitch.hayenga@arm.com        t_info.statExecutedInstType
37511147Smitch.hayenga@arm.com            .init(Enums::Num_OpClass)
37611147Smitch.hayenga@arm.com            .name(thread_str + ".op_class")
37711147Smitch.hayenga@arm.com            .desc("Class of executed instruction")
37811147Smitch.hayenga@arm.com            .flags(total | pdf | dist)
37911147Smitch.hayenga@arm.com            ;
38011147Smitch.hayenga@arm.com
38111147Smitch.hayenga@arm.com        for (unsigned i = 0; i < Num_OpClasses; ++i) {
38211147Smitch.hayenga@arm.com            t_info.statExecutedInstType.subname(i, Enums::OpClassStrings[i]);
38311147Smitch.hayenga@arm.com        }
38411147Smitch.hayenga@arm.com
38511147Smitch.hayenga@arm.com        t_info.idleFraction = constant(1.0) - t_info.notIdleFraction;
38611147Smitch.hayenga@arm.com        t_info.numIdleCycles = t_info.idleFraction * numCycles;
38711147Smitch.hayenga@arm.com        t_info.numBusyCycles = t_info.notIdleFraction * numCycles;
38811147Smitch.hayenga@arm.com
38911147Smitch.hayenga@arm.com        t_info.numBranches
39011147Smitch.hayenga@arm.com            .name(thread_str + ".Branches")
39111147Smitch.hayenga@arm.com            .desc("Number of branches fetched")
39211147Smitch.hayenga@arm.com            .prereq(t_info.numBranches);
39311147Smitch.hayenga@arm.com
39411147Smitch.hayenga@arm.com        t_info.numPredictedBranches
39511147Smitch.hayenga@arm.com            .name(thread_str + ".predictedBranches")
39611147Smitch.hayenga@arm.com            .desc("Number of branches predicted as taken")
39711147Smitch.hayenga@arm.com            .prereq(t_info.numPredictedBranches);
39811147Smitch.hayenga@arm.com
39911147Smitch.hayenga@arm.com        t_info.numBranchMispred
40011147Smitch.hayenga@arm.com            .name(thread_str + ".BranchMispred")
40111147Smitch.hayenga@arm.com            .desc("Number of branch mispredictions")
40211147Smitch.hayenga@arm.com            .prereq(t_info.numBranchMispred);
40310193SCurtis.Dunham@arm.com    }
4042SN/A}
4052SN/A
4062SN/Avoid
4072623SN/ABaseSimpleCPU::resetStats()
408334SN/A{
40911147Smitch.hayenga@arm.com    for (auto &thread_info : threadInfo) {
41011147Smitch.hayenga@arm.com        thread_info->notIdleFraction = (_status != Idle);
41111147Smitch.hayenga@arm.com    }
412334SN/A}
413334SN/A
414334SN/Avoid
41510905Sandreas.sandberg@arm.comBaseSimpleCPU::serializeThread(CheckpointOut &cp, ThreadID tid) const
4162SN/A{
4179448SAndreas.Sandberg@ARM.com    assert(_status == Idle || _status == Running);
4189448SAndreas.Sandberg@ARM.com
41911147Smitch.hayenga@arm.com    threadInfo[tid]->thread->serialize(cp);
4202SN/A}
4212SN/A
4222SN/Avoid
42310905Sandreas.sandberg@arm.comBaseSimpleCPU::unserializeThread(CheckpointIn &cp, ThreadID tid)
4242SN/A{
42511147Smitch.hayenga@arm.com    threadInfo[tid]->thread->unserialize(cp);
4262SN/A}
4272SN/A
4282SN/Avoid
4296221Snate@binkert.orgchange_thread_state(ThreadID tid, int activate, int priority)
4302SN/A{
4312SN/A}
4322SN/A
4332SN/AAddr
4342623SN/ABaseSimpleCPU::dbg_vtophys(Addr addr)
4352SN/A{
43611147Smitch.hayenga@arm.com    return vtophys(threadContexts[curThread], addr);
4372SN/A}
4382SN/A
4392SN/Avoid
44011151Smitch.hayenga@arm.comBaseSimpleCPU::wakeup(ThreadID tid)
4412SN/A{
44211151Smitch.hayenga@arm.com    getCpuAddrMonitor(tid)->gotWakeup = true;
44311151Smitch.hayenga@arm.com
44411151Smitch.hayenga@arm.com    if (threadInfo[tid]->thread->status() == ThreadContext::Suspended) {
44511151Smitch.hayenga@arm.com        DPRINTF(Quiesce,"[tid:%d] Suspended Processor awoke\n", tid);
44611151Smitch.hayenga@arm.com        threadInfo[tid]->thread->activate();
44711147Smitch.hayenga@arm.com    }
4482SN/A}
4492SN/A
4502SN/Avoid
4512623SN/ABaseSimpleCPU::checkForInterrupts()
4522SN/A{
45311147Smitch.hayenga@arm.com    SimpleExecContext&t_info = *threadInfo[curThread];
45411147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
45511147Smitch.hayenga@arm.com    ThreadContext* tc = thread->getTC();
45611147Smitch.hayenga@arm.com
4575704Snate@binkert.org    if (checkInterrupts(tc)) {
45811150Smitch.hayenga@arm.com        Fault interrupt = interrupts[curThread]->getInterrupt(tc);
4592SN/A
4603520Sgblack@eecs.umich.edu        if (interrupt != NoFault) {
46111147Smitch.hayenga@arm.com            t_info.fetchOffset = 0;
46211150Smitch.hayenga@arm.com            interrupts[curThread]->updateIntrInfo(tc);
4633520Sgblack@eecs.umich.edu            interrupt->invoke(tc);
4649023Sgblack@eecs.umich.edu            thread->decoder.reset();
4652SN/A        }
4662SN/A    }
4672623SN/A}
4682SN/A
4692623SN/A
4705894Sgblack@eecs.umich.eduvoid
47112749Sgiacomo.travaglini@arm.comBaseSimpleCPU::setupFetchRequest(const RequestPtr &req)
4722623SN/A{
47311147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
47411147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
47511147Smitch.hayenga@arm.com
4767720Sgblack@eecs.umich.edu    Addr instAddr = thread->instAddr();
47712372Smattdsinclair@gmail.com    Addr fetchPC = (instAddr & PCMask) + t_info.fetchOffset;
4784495Sacolyte@umich.edu
4792623SN/A    // set up memory request for instruction fetch
48012372Smattdsinclair@gmail.com    DPRINTF(Fetch, "Fetch: Inst PC:%08p, Fetch PC:%08p\n", instAddr, fetchPC);
4812623SN/A
48212372Smattdsinclair@gmail.com    req->setVirt(0, fetchPC, sizeof(MachInst), Request::INST_FETCH,
48312372Smattdsinclair@gmail.com                 instMasterId(), instAddr);
4842623SN/A}
4852623SN/A
4862623SN/A
4872623SN/Avoid
4882623SN/ABaseSimpleCPU::preExecute()
4892623SN/A{
49011147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
49111147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
49211147Smitch.hayenga@arm.com
4932SN/A    // maintain $r0 semantics
4942683Sktlim@umich.edu    thread->setIntReg(ZeroReg, 0);
4952427SN/A#if THE_ISA == ALPHA_ISA
49613611Sgabeblack@google.com    thread->setFloatReg(ZeroReg, 0);
4972427SN/A#endif // ALPHA_ISA
4982SN/A
4992623SN/A    // check for instruction-count-based events
50011147Smitch.hayenga@arm.com    comInstEventQueue[curThread]->serviceEvents(t_info.numInst);
5017897Shestness@cs.utexas.edu    system->instEventQueue.serviceEvents(system->totalNumInsts);
5022SN/A
5032623SN/A    // decode the instruction
5042623SN/A    inst = gtoh(inst);
5054377Sgblack@eecs.umich.edu
5067720Sgblack@eecs.umich.edu    TheISA::PCState pcState = thread->pcState();
5074377Sgblack@eecs.umich.edu
5087720Sgblack@eecs.umich.edu    if (isRomMicroPC(pcState.microPC())) {
50911147Smitch.hayenga@arm.com        t_info.stayAtPC = false;
5107720Sgblack@eecs.umich.edu        curStaticInst = microcodeRom.fetchMicroop(pcState.microPC(),
5117720Sgblack@eecs.umich.edu                                                  curMacroStaticInst);
5125665Sgblack@eecs.umich.edu    } else if (!curMacroStaticInst) {
5135665Sgblack@eecs.umich.edu        //We're not in the middle of a macro instruction
5144181Sgblack@eecs.umich.edu        StaticInstPtr instPtr = NULL;
5154181Sgblack@eecs.umich.edu
5169023Sgblack@eecs.umich.edu        TheISA::Decoder *decoder = &(thread->decoder);
5179023Sgblack@eecs.umich.edu
5184181Sgblack@eecs.umich.edu        //Predecode, ie bundle up an ExtMachInst
5194182Sgblack@eecs.umich.edu        //If more fetch data is needed, pass it in.
52011147Smitch.hayenga@arm.com        Addr fetchPC = (pcState.instAddr() & PCMask) + t_info.fetchOffset;
52111321Ssteve.reinhardt@amd.com        //if (decoder->needMoreBytes())
5229023Sgblack@eecs.umich.edu            decoder->moreBytes(pcState, fetchPC, inst);
5234593Sgblack@eecs.umich.edu        //else
5249023Sgblack@eecs.umich.edu        //    decoder->process();
5254377Sgblack@eecs.umich.edu
5269023Sgblack@eecs.umich.edu        //Decode an instruction if one is ready. Otherwise, we'll have to
5274377Sgblack@eecs.umich.edu        //fetch beyond the MachInst at the current pc.
5289023Sgblack@eecs.umich.edu        instPtr = decoder->decode(pcState);
5299023Sgblack@eecs.umich.edu        if (instPtr) {
53011147Smitch.hayenga@arm.com            t_info.stayAtPC = false;
5317720Sgblack@eecs.umich.edu            thread->pcState(pcState);
5324377Sgblack@eecs.umich.edu        } else {
53311147Smitch.hayenga@arm.com            t_info.stayAtPC = true;
53411147Smitch.hayenga@arm.com            t_info.fetchOffset += sizeof(MachInst);
5354377Sgblack@eecs.umich.edu        }
5364181Sgblack@eecs.umich.edu
5374181Sgblack@eecs.umich.edu        //If we decoded an instruction and it's microcoded, start pulling
5384181Sgblack@eecs.umich.edu        //out micro ops
5394539Sgblack@eecs.umich.edu        if (instPtr && instPtr->isMacroop()) {
5403276Sgblack@eecs.umich.edu            curMacroStaticInst = instPtr;
54111147Smitch.hayenga@arm.com            curStaticInst =
54211147Smitch.hayenga@arm.com                curMacroStaticInst->fetchMicroop(pcState.microPC());
5433280Sgblack@eecs.umich.edu        } else {
5443280Sgblack@eecs.umich.edu            curStaticInst = instPtr;
5453276Sgblack@eecs.umich.edu        }
5463276Sgblack@eecs.umich.edu    } else {
5473276Sgblack@eecs.umich.edu        //Read the next micro op from the macro op
5487720Sgblack@eecs.umich.edu        curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC());
5493276Sgblack@eecs.umich.edu    }
5503276Sgblack@eecs.umich.edu
5514181Sgblack@eecs.umich.edu    //If we decoded an instruction this "tick", record information about it.
5528955Sgblack@eecs.umich.edu    if (curStaticInst) {
5534522Ssaidi@eecs.umich.edu#if TRACING_ON
55411147Smitch.hayenga@arm.com        traceData = tracer->getInstRecord(curTick(), thread->getTC(),
5557720Sgblack@eecs.umich.edu                curStaticInst, thread->pcState(), curMacroStaticInst);
5562470SN/A
5578955Sgblack@eecs.umich.edu        DPRINTF(Decode,"Decode: Decoded %s instruction: %#x\n",
5584181Sgblack@eecs.umich.edu                curStaticInst->getName(), curStaticInst->machInst);
5594522Ssaidi@eecs.umich.edu#endif // TRACING_ON
5604181Sgblack@eecs.umich.edu    }
56110061Sandreas@sandberg.pp.se
56211147Smitch.hayenga@arm.com    if (branchPred && curStaticInst &&
56311147Smitch.hayenga@arm.com        curStaticInst->isControl()) {
56410061Sandreas@sandberg.pp.se        // Use a fake sequence number since we only have one
56510061Sandreas@sandberg.pp.se        // instruction in flight at the same time.
56610061Sandreas@sandberg.pp.se        const InstSeqNum cur_sn(0);
56711147Smitch.hayenga@arm.com        t_info.predPC = thread->pcState();
56810061Sandreas@sandberg.pp.se        const bool predict_taken(
56911147Smitch.hayenga@arm.com            branchPred->predict(curStaticInst, cur_sn, t_info.predPC,
57011147Smitch.hayenga@arm.com                                curThread));
57110061Sandreas@sandberg.pp.se
57210061Sandreas@sandberg.pp.se        if (predict_taken)
57311147Smitch.hayenga@arm.com            ++t_info.numPredictedBranches;
57410061Sandreas@sandberg.pp.se    }
5752623SN/A}
5762623SN/A
5772623SN/Avoid
5782623SN/ABaseSimpleCPU::postExecute()
5792623SN/A{
58011147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
58111147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
58211147Smitch.hayenga@arm.com
5837720Sgblack@eecs.umich.edu    assert(curStaticInst);
5847720Sgblack@eecs.umich.edu
58511147Smitch.hayenga@arm.com    TheISA::PCState pc = threadContexts[curThread]->pcState();
5867720Sgblack@eecs.umich.edu    Addr instAddr = pc.instAddr();
5878780Sgblack@eecs.umich.edu    if (FullSystem && thread->profile) {
58811147Smitch.hayenga@arm.com        bool usermode = TheISA::inUserMode(threadContexts[curThread]);
5897720Sgblack@eecs.umich.edu        thread->profilePC = usermode ? 1 : instAddr;
59011147Smitch.hayenga@arm.com        ProfileNode *node = thread->profile->consume(threadContexts[curThread],
59111147Smitch.hayenga@arm.com                                                     curStaticInst);
5922623SN/A        if (node)
5932683Sktlim@umich.edu            thread->profileNode = node;
5942623SN/A    }
5952SN/A
5962623SN/A    if (curStaticInst->isMemRef()) {
59711147Smitch.hayenga@arm.com        t_info.numMemRefs++;
5982SN/A    }
5992SN/A
6002623SN/A    if (curStaticInst->isLoad()) {
60111147Smitch.hayenga@arm.com        ++t_info.numLoad;
60211147Smitch.hayenga@arm.com        comLoadEventQueue[curThread]->serviceEvents(t_info.numLoad);
6032623SN/A    }
6042SN/A
6055953Ssaidi@eecs.umich.edu    if (CPA::available()) {
60611147Smitch.hayenga@arm.com        CPA::cpa()->swAutoBegin(threadContexts[curThread], pc.nextInstAddr());
6075953Ssaidi@eecs.umich.edu    }
6085953Ssaidi@eecs.umich.edu
60910061Sandreas@sandberg.pp.se    if (curStaticInst->isControl()) {
61011147Smitch.hayenga@arm.com        ++t_info.numBranches;
61110061Sandreas@sandberg.pp.se    }
61210061Sandreas@sandberg.pp.se
6137897Shestness@cs.utexas.edu    /* Power model statistics */
6147897Shestness@cs.utexas.edu    //integer alu accesses
6157897Shestness@cs.utexas.edu    if (curStaticInst->isInteger()){
61611147Smitch.hayenga@arm.com        t_info.numIntAluAccesses++;
61711147Smitch.hayenga@arm.com        t_info.numIntInsts++;
6187897Shestness@cs.utexas.edu    }
6197897Shestness@cs.utexas.edu
6207897Shestness@cs.utexas.edu    //float alu accesses
6217897Shestness@cs.utexas.edu    if (curStaticInst->isFloating()){
62211147Smitch.hayenga@arm.com        t_info.numFpAluAccesses++;
62311147Smitch.hayenga@arm.com        t_info.numFpInsts++;
6247897Shestness@cs.utexas.edu    }
62511147Smitch.hayenga@arm.com
62612110SRekai.GonzalezAlberquilla@arm.com    //vector alu accesses
62712110SRekai.GonzalezAlberquilla@arm.com    if (curStaticInst->isVector()){
62812110SRekai.GonzalezAlberquilla@arm.com        t_info.numVecAluAccesses++;
62912110SRekai.GonzalezAlberquilla@arm.com        t_info.numVecInsts++;
63012110SRekai.GonzalezAlberquilla@arm.com    }
63112110SRekai.GonzalezAlberquilla@arm.com
6327897Shestness@cs.utexas.edu    //number of function calls/returns to get window accesses
6337897Shestness@cs.utexas.edu    if (curStaticInst->isCall() || curStaticInst->isReturn()){
63411147Smitch.hayenga@arm.com        t_info.numCallsReturns++;
6357897Shestness@cs.utexas.edu    }
63611147Smitch.hayenga@arm.com
6377897Shestness@cs.utexas.edu    //the number of branch predictions that will be made
6387897Shestness@cs.utexas.edu    if (curStaticInst->isCondCtrl()){
63911147Smitch.hayenga@arm.com        t_info.numCondCtrlInsts++;
6407897Shestness@cs.utexas.edu    }
64111147Smitch.hayenga@arm.com
6427897Shestness@cs.utexas.edu    //result bus acceses
6437897Shestness@cs.utexas.edu    if (curStaticInst->isLoad()){
64411147Smitch.hayenga@arm.com        t_info.numLoadInsts++;
6457897Shestness@cs.utexas.edu    }
64611147Smitch.hayenga@arm.com
64713652Sqtt2@cornell.edu    if (curStaticInst->isStore() || curStaticInst->isAtomic()){
64811147Smitch.hayenga@arm.com        t_info.numStoreInsts++;
6497897Shestness@cs.utexas.edu    }
6507897Shestness@cs.utexas.edu    /* End power model statistics */
6517897Shestness@cs.utexas.edu
65211147Smitch.hayenga@arm.com    t_info.statExecutedInstType[curStaticInst->opClass()]++;
65310193SCurtis.Dunham@arm.com
6548780Sgblack@eecs.umich.edu    if (FullSystem)
6558780Sgblack@eecs.umich.edu        traceFunctions(instAddr);
6562644Sstever@eecs.umich.edu
6572644Sstever@eecs.umich.edu    if (traceData) {
6584046Sbinkertn@umich.edu        traceData->dump();
6594046Sbinkertn@umich.edu        delete traceData;
6604046Sbinkertn@umich.edu        traceData = NULL;
6612644Sstever@eecs.umich.edu    }
66210464SAndreas.Sandberg@ARM.com
66310464SAndreas.Sandberg@ARM.com    // Call CPU instruction commit probes
66410464SAndreas.Sandberg@ARM.com    probeInstCommit(curStaticInst);
6652623SN/A}
6662SN/A
6672623SN/Avoid
66810379Sandreas.hansson@arm.comBaseSimpleCPU::advancePC(const Fault &fault)
6692623SN/A{
67011147Smitch.hayenga@arm.com    SimpleExecContext &t_info = *threadInfo[curThread];
67111147Smitch.hayenga@arm.com    SimpleThread* thread = t_info.thread;
67211147Smitch.hayenga@arm.com
67310061Sandreas@sandberg.pp.se    const bool branching(thread->pcState().branching());
67410061Sandreas@sandberg.pp.se
6754377Sgblack@eecs.umich.edu    //Since we're moving to a new pc, zero out the offset
67611147Smitch.hayenga@arm.com    t_info.fetchOffset = 0;
6772090SN/A    if (fault != NoFault) {
6783905Ssaidi@eecs.umich.edu        curMacroStaticInst = StaticInst::nullStaticInstPtr;
67911147Smitch.hayenga@arm.com        fault->invoke(threadContexts[curThread], curStaticInst);
6809023Sgblack@eecs.umich.edu        thread->decoder.reset();
6814377Sgblack@eecs.umich.edu    } else {
6827720Sgblack@eecs.umich.edu        if (curStaticInst) {
6837720Sgblack@eecs.umich.edu            if (curStaticInst->isLastMicroop())
6847720Sgblack@eecs.umich.edu                curMacroStaticInst = StaticInst::nullStaticInstPtr;
6857720Sgblack@eecs.umich.edu            TheISA::PCState pcState = thread->pcState();
6867720Sgblack@eecs.umich.edu            TheISA::advancePC(pcState, curStaticInst);
6877720Sgblack@eecs.umich.edu            thread->pcState(pcState);
6883276Sgblack@eecs.umich.edu        }
6892SN/A    }
69010061Sandreas@sandberg.pp.se
69110061Sandreas@sandberg.pp.se    if (branchPred && curStaticInst && curStaticInst->isControl()) {
69210061Sandreas@sandberg.pp.se        // Use a fake sequence number since we only have one
69310061Sandreas@sandberg.pp.se        // instruction in flight at the same time.
69410061Sandreas@sandberg.pp.se        const InstSeqNum cur_sn(0);
69510061Sandreas@sandberg.pp.se
69611147Smitch.hayenga@arm.com        if (t_info.predPC == thread->pcState()) {
69710061Sandreas@sandberg.pp.se            // Correctly predicted branch
69811147Smitch.hayenga@arm.com            branchPred->update(cur_sn, curThread);
69910061Sandreas@sandberg.pp.se        } else {
70010061Sandreas@sandberg.pp.se            // Mis-predicted branch
70111147Smitch.hayenga@arm.com            branchPred->squash(cur_sn, thread->pcState(), branching, curThread);
70211147Smitch.hayenga@arm.com            ++t_info.numBranchMispred;
70310061Sandreas@sandberg.pp.se        }
70410061Sandreas@sandberg.pp.se    }
7052SN/A}
7062SN/A
7079461Snilay@cs.wisc.eduvoid
7089461Snilay@cs.wisc.eduBaseSimpleCPU::startup()
7099461Snilay@cs.wisc.edu{
7109461Snilay@cs.wisc.edu    BaseCPU::startup();
71111147Smitch.hayenga@arm.com    for (auto& t_info : threadInfo)
71211147Smitch.hayenga@arm.com        t_info->thread->startup();
7139461Snilay@cs.wisc.edu}
714