base.cc revision 9384
111012Sandreas.sandberg@arm.com/*
211897Ssudhanshu.jha@arm.com * Copyright (c) 2010-2011 ARM Limited
311012Sandreas.sandberg@arm.com * All rights reserved
411012Sandreas.sandberg@arm.com *
511012Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
611012Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
711012Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
811012Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
911012Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1011012Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1111012Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1211012Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1311012Sandreas.sandberg@arm.com *
1411012Sandreas.sandberg@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
1511012Sandreas.sandberg@arm.com * All rights reserved.
1611012Sandreas.sandberg@arm.com *
1711012Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
1811012Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
1911012Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
2011012Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
2111012Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
2211012Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
2311012Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
2411012Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
2511012Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
2611012Sandreas.sandberg@arm.com * this software without specific prior written permission.
2711012Sandreas.sandberg@arm.com *
2811012Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2911012Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3011012Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3111012Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3211012Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3311012Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3411012Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3511012Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3611012Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3711012Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3811012Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3911012Sandreas.sandberg@arm.com *
4011012Sandreas.sandberg@arm.com * Authors: Steve Reinhardt
4111012Sandreas.sandberg@arm.com */
4211012Sandreas.sandberg@arm.com
4311012Sandreas.sandberg@arm.com#include "arch/kernel_stats.hh"
4411012Sandreas.sandberg@arm.com#include "arch/stacktrace.hh"
4511012Sandreas.sandberg@arm.com#include "arch/tlb.hh"
4611012Sandreas.sandberg@arm.com#include "arch/utility.hh"
4711012Sandreas.sandberg@arm.com#include "arch/vtophys.hh"
4811012Sandreas.sandberg@arm.com#include "base/loader/symtab.hh"
4911012Sandreas.sandberg@arm.com#include "base/cp_annotate.hh"
5011012Sandreas.sandberg@arm.com#include "base/cprintf.hh"
5111012Sandreas.sandberg@arm.com#include "base/inifile.hh"
5211012Sandreas.sandberg@arm.com#include "base/misc.hh"
5311012Sandreas.sandberg@arm.com#include "base/pollevent.hh"
5411012Sandreas.sandberg@arm.com#include "base/trace.hh"
5511012Sandreas.sandberg@arm.com#include "base/types.hh"
5611012Sandreas.sandberg@arm.com#include "config/the_isa.hh"
5711012Sandreas.sandberg@arm.com#include "cpu/simple/base.hh"
5811012Sandreas.sandberg@arm.com#include "cpu/base.hh"
5911012Sandreas.sandberg@arm.com#include "cpu/checker/cpu.hh"
6011012Sandreas.sandberg@arm.com#include "cpu/checker/thread_context.hh"
6111012Sandreas.sandberg@arm.com#include "cpu/exetrace.hh"
6211012Sandreas.sandberg@arm.com#include "cpu/profile.hh"
6311012Sandreas.sandberg@arm.com#include "cpu/simple_thread.hh"
6411012Sandreas.sandberg@arm.com#include "cpu/smt.hh"
6511012Sandreas.sandberg@arm.com#include "cpu/static_inst.hh"
6611012Sandreas.sandberg@arm.com#include "cpu/thread_context.hh"
6711012Sandreas.sandberg@arm.com#include "debug/Decode.hh"
6811012Sandreas.sandberg@arm.com#include "debug/Fetch.hh"
6911012Sandreas.sandberg@arm.com#include "debug/Quiesce.hh"
7011012Sandreas.sandberg@arm.com#include "mem/mem_object.hh"
7111012Sandreas.sandberg@arm.com#include "mem/packet.hh"
7211012Sandreas.sandberg@arm.com#include "mem/request.hh"
7311012Sandreas.sandberg@arm.com#include "params/BaseSimpleCPU.hh"
7411012Sandreas.sandberg@arm.com#include "sim/byteswap.hh"
7511012Sandreas.sandberg@arm.com#include "sim/debug.hh"
7611012Sandreas.sandberg@arm.com#include "sim/faults.hh"
7711012Sandreas.sandberg@arm.com#include "sim/full_system.hh"
7811012Sandreas.sandberg@arm.com#include "sim/sim_events.hh"
7911012Sandreas.sandberg@arm.com#include "sim/sim_object.hh"
8011012Sandreas.sandberg@arm.com#include "sim/stats.hh"
8111012Sandreas.sandberg@arm.com#include "sim/system.hh"
8211012Sandreas.sandberg@arm.com
8311012Sandreas.sandberg@arm.comusing namespace std;
8411012Sandreas.sandberg@arm.comusing namespace TheISA;
8511012Sandreas.sandberg@arm.com
8611012Sandreas.sandberg@arm.comBaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p)
8711012Sandreas.sandberg@arm.com    : BaseCPU(p), traceData(NULL), thread(NULL)
8811012Sandreas.sandberg@arm.com{
8911012Sandreas.sandberg@arm.com    if (FullSystem)
9011012Sandreas.sandberg@arm.com        thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb,
9111012Sandreas.sandberg@arm.com                                  p->isa[0]);
9211012Sandreas.sandberg@arm.com    else
9311012Sandreas.sandberg@arm.com        thread = new SimpleThread(this, /* thread_num */ 0, p->system,
9411012Sandreas.sandberg@arm.com                                  p->workload[0], p->itb, p->dtb, p->isa[0]);
9511012Sandreas.sandberg@arm.com
9611012Sandreas.sandberg@arm.com    thread->setStatus(ThreadContext::Halted);
9711012Sandreas.sandberg@arm.com
9811012Sandreas.sandberg@arm.com    tc = thread->getTC();
9911012Sandreas.sandberg@arm.com
10011012Sandreas.sandberg@arm.com    if (p->checker) {
10111012Sandreas.sandberg@arm.com        BaseCPU *temp_checker = p->checker;
10211012Sandreas.sandberg@arm.com        checker = dynamic_cast<CheckerCPU *>(temp_checker);
10311012Sandreas.sandberg@arm.com        checker->setSystem(p->system);
10411012Sandreas.sandberg@arm.com        // Manipulate thread context
10511012Sandreas.sandberg@arm.com        ThreadContext *cpu_tc = tc;
10611012Sandreas.sandberg@arm.com        tc = new CheckerThreadContext<ThreadContext>(cpu_tc, this->checker);
10711012Sandreas.sandberg@arm.com    } else {
10811012Sandreas.sandberg@arm.com        checker = NULL;
10911012Sandreas.sandberg@arm.com    }
11011012Sandreas.sandberg@arm.com
11111012Sandreas.sandberg@arm.com    numInst = 0;
11211012Sandreas.sandberg@arm.com    startNumInst = 0;
11311012Sandreas.sandberg@arm.com    numOp = 0;
11411012Sandreas.sandberg@arm.com    startNumOp = 0;
11511012Sandreas.sandberg@arm.com    numLoad = 0;
11611012Sandreas.sandberg@arm.com    startNumLoad = 0;
11711012Sandreas.sandberg@arm.com    lastIcacheStall = 0;
11811012Sandreas.sandberg@arm.com    lastDcacheStall = 0;
11911012Sandreas.sandberg@arm.com
12011012Sandreas.sandberg@arm.com    threadContexts.push_back(tc);
12111012Sandreas.sandberg@arm.com
12211012Sandreas.sandberg@arm.com
12311012Sandreas.sandberg@arm.com    fetchOffset = 0;
12411012Sandreas.sandberg@arm.com    stayAtPC = false;
12511012Sandreas.sandberg@arm.com}
12611012Sandreas.sandberg@arm.com
12711012Sandreas.sandberg@arm.comBaseSimpleCPU::~BaseSimpleCPU()
12811012Sandreas.sandberg@arm.com{
12911012Sandreas.sandberg@arm.com}
13011012Sandreas.sandberg@arm.com
13111012Sandreas.sandberg@arm.comvoid
13211012Sandreas.sandberg@arm.comBaseSimpleCPU::deallocateContext(ThreadID thread_num)
13311012Sandreas.sandberg@arm.com{
13411012Sandreas.sandberg@arm.com    // for now, these are equivalent
13511012Sandreas.sandberg@arm.com    suspendContext(thread_num);
13611012Sandreas.sandberg@arm.com}
13711012Sandreas.sandberg@arm.com
13811012Sandreas.sandberg@arm.com
13911897Ssudhanshu.jha@arm.comvoid
14011897Ssudhanshu.jha@arm.comBaseSimpleCPU::haltContext(ThreadID thread_num)
14111897Ssudhanshu.jha@arm.com{
14211897Ssudhanshu.jha@arm.com    // for now, these are equivalent
14311012Sandreas.sandberg@arm.com    suspendContext(thread_num);
14411012Sandreas.sandberg@arm.com}
14511012Sandreas.sandberg@arm.com
14611012Sandreas.sandberg@arm.com
14711012Sandreas.sandberg@arm.comvoid
14811012Sandreas.sandberg@arm.comBaseSimpleCPU::regStats()
14911012Sandreas.sandberg@arm.com{
15011012Sandreas.sandberg@arm.com    using namespace Stats;
15111012Sandreas.sandberg@arm.com
15211012Sandreas.sandberg@arm.com    BaseCPU::regStats();
15311897Ssudhanshu.jha@arm.com
15411897Ssudhanshu.jha@arm.com    numInsts
15511897Ssudhanshu.jha@arm.com        .name(name() + ".committedInsts")
15611897Ssudhanshu.jha@arm.com        .desc("Number of instructions committed")
15711897Ssudhanshu.jha@arm.com        ;
15811012Sandreas.sandberg@arm.com
15911012Sandreas.sandberg@arm.com    numOps
16011012Sandreas.sandberg@arm.com        .name(name() + ".committedOps")
16111897Ssudhanshu.jha@arm.com        .desc("Number of ops (including micro ops) committed")
16211012Sandreas.sandberg@arm.com        ;
16311012Sandreas.sandberg@arm.com
16411012Sandreas.sandberg@arm.com    numIntAluAccesses
16511012Sandreas.sandberg@arm.com        .name(name() + ".num_int_alu_accesses")
16611012Sandreas.sandberg@arm.com        .desc("Number of integer alu accesses")
16711012Sandreas.sandberg@arm.com        ;
16811012Sandreas.sandberg@arm.com
16911012Sandreas.sandberg@arm.com    numFpAluAccesses
17011012Sandreas.sandberg@arm.com        .name(name() + ".num_fp_alu_accesses")
17111012Sandreas.sandberg@arm.com        .desc("Number of float alu accesses")
17211012Sandreas.sandberg@arm.com        ;
17311012Sandreas.sandberg@arm.com
17411012Sandreas.sandberg@arm.com    numCallsReturns
17511012Sandreas.sandberg@arm.com        .name(name() + ".num_func_calls")
17611012Sandreas.sandberg@arm.com        .desc("number of times a function call or return occured")
17711012Sandreas.sandberg@arm.com        ;
17811012Sandreas.sandberg@arm.com
17911012Sandreas.sandberg@arm.com    numCondCtrlInsts
18011012Sandreas.sandberg@arm.com        .name(name() + ".num_conditional_control_insts")
18111012Sandreas.sandberg@arm.com        .desc("number of instructions that are conditional controls")
18211012Sandreas.sandberg@arm.com        ;
18311012Sandreas.sandberg@arm.com
18411012Sandreas.sandberg@arm.com    numIntInsts
18511012Sandreas.sandberg@arm.com        .name(name() + ".num_int_insts")
18611012Sandreas.sandberg@arm.com        .desc("number of integer instructions")
18711012Sandreas.sandberg@arm.com        ;
18811012Sandreas.sandberg@arm.com
18911012Sandreas.sandberg@arm.com    numFpInsts
19011012Sandreas.sandberg@arm.com        .name(name() + ".num_fp_insts")
19111012Sandreas.sandberg@arm.com        .desc("number of float instructions")
19211012Sandreas.sandberg@arm.com        ;
19311012Sandreas.sandberg@arm.com
19411012Sandreas.sandberg@arm.com    numIntRegReads
19511012Sandreas.sandberg@arm.com        .name(name() + ".num_int_register_reads")
19611012Sandreas.sandberg@arm.com        .desc("number of times the integer registers were read")
19711012Sandreas.sandberg@arm.com        ;
19811012Sandreas.sandberg@arm.com
19911012Sandreas.sandberg@arm.com    numIntRegWrites
20011012Sandreas.sandberg@arm.com        .name(name() + ".num_int_register_writes")
20111012Sandreas.sandberg@arm.com        .desc("number of times the integer registers were written")
20211012Sandreas.sandberg@arm.com        ;
20311012Sandreas.sandberg@arm.com
20411012Sandreas.sandberg@arm.com    numFpRegReads
20511012Sandreas.sandberg@arm.com        .name(name() + ".num_fp_register_reads")
20611012Sandreas.sandberg@arm.com        .desc("number of times the floating registers were read")
20711012Sandreas.sandberg@arm.com        ;
20811012Sandreas.sandberg@arm.com
20911012Sandreas.sandberg@arm.com    numFpRegWrites
21011012Sandreas.sandberg@arm.com        .name(name() + ".num_fp_register_writes")
21111012Sandreas.sandberg@arm.com        .desc("number of times the floating registers were written")
21211012Sandreas.sandberg@arm.com        ;
21311012Sandreas.sandberg@arm.com
21411012Sandreas.sandberg@arm.com    numMemRefs
21511012Sandreas.sandberg@arm.com        .name(name()+".num_mem_refs")
21611012Sandreas.sandberg@arm.com        .desc("number of memory refs")
21711012Sandreas.sandberg@arm.com        ;
21811012Sandreas.sandberg@arm.com
21911012Sandreas.sandberg@arm.com    numStoreInsts
22011012Sandreas.sandberg@arm.com        .name(name() + ".num_store_insts")
22111012Sandreas.sandberg@arm.com        .desc("Number of store instructions")
22211012Sandreas.sandberg@arm.com        ;
22311012Sandreas.sandberg@arm.com
22411012Sandreas.sandberg@arm.com    numLoadInsts
22511012Sandreas.sandberg@arm.com        .name(name() + ".num_load_insts")
22611012Sandreas.sandberg@arm.com        .desc("Number of load instructions")
22711012Sandreas.sandberg@arm.com        ;
22811012Sandreas.sandberg@arm.com
22911012Sandreas.sandberg@arm.com    notIdleFraction
23011012Sandreas.sandberg@arm.com        .name(name() + ".not_idle_fraction")
23111012Sandreas.sandberg@arm.com        .desc("Percentage of non-idle cycles")
23211012Sandreas.sandberg@arm.com        ;
23311012Sandreas.sandberg@arm.com
23411012Sandreas.sandberg@arm.com    idleFraction
23511012Sandreas.sandberg@arm.com        .name(name() + ".idle_fraction")
23611012Sandreas.sandberg@arm.com        .desc("Percentage of idle cycles")
23711012Sandreas.sandberg@arm.com        ;
23811012Sandreas.sandberg@arm.com
23911012Sandreas.sandberg@arm.com    numBusyCycles
24011012Sandreas.sandberg@arm.com        .name(name() + ".num_busy_cycles")
24111012Sandreas.sandberg@arm.com        .desc("Number of busy cycles")
24211012Sandreas.sandberg@arm.com        ;
24311012Sandreas.sandberg@arm.com
24411012Sandreas.sandberg@arm.com    numIdleCycles
24511012Sandreas.sandberg@arm.com        .name(name()+".num_idle_cycles")
24611012Sandreas.sandberg@arm.com        .desc("Number of idle cycles")
24711012Sandreas.sandberg@arm.com        ;
24811012Sandreas.sandberg@arm.com
24911012Sandreas.sandberg@arm.com    icacheStallCycles
25011012Sandreas.sandberg@arm.com        .name(name() + ".icache_stall_cycles")
25111897Ssudhanshu.jha@arm.com        .desc("ICache total stall cycles")
25211897Ssudhanshu.jha@arm.com        .prereq(icacheStallCycles)
25311897Ssudhanshu.jha@arm.com        ;
25411897Ssudhanshu.jha@arm.com
25511897Ssudhanshu.jha@arm.com    dcacheStallCycles
25611897Ssudhanshu.jha@arm.com        .name(name() + ".dcache_stall_cycles")
25711897Ssudhanshu.jha@arm.com        .desc("DCache total stall cycles")
25811897Ssudhanshu.jha@arm.com        .prereq(dcacheStallCycles)
25911897Ssudhanshu.jha@arm.com        ;
26011897Ssudhanshu.jha@arm.com
26111897Ssudhanshu.jha@arm.com    icacheRetryCycles
26211897Ssudhanshu.jha@arm.com        .name(name() + ".icache_retry_cycles")
26311897Ssudhanshu.jha@arm.com        .desc("ICache total retry cycles")
26411897Ssudhanshu.jha@arm.com        .prereq(icacheRetryCycles)
26511897Ssudhanshu.jha@arm.com        ;
26611897Ssudhanshu.jha@arm.com
26711897Ssudhanshu.jha@arm.com    dcacheRetryCycles
26811897Ssudhanshu.jha@arm.com        .name(name() + ".dcache_retry_cycles")
26911897Ssudhanshu.jha@arm.com        .desc("DCache total retry cycles")
27011897Ssudhanshu.jha@arm.com        .prereq(dcacheRetryCycles)
27111897Ssudhanshu.jha@arm.com        ;
27211897Ssudhanshu.jha@arm.com
27311897Ssudhanshu.jha@arm.com    idleFraction = constant(1.0) - notIdleFraction;
27411897Ssudhanshu.jha@arm.com    numIdleCycles = idleFraction * numCycles;
27511897Ssudhanshu.jha@arm.com    numBusyCycles = (notIdleFraction)*numCycles;
27611897Ssudhanshu.jha@arm.com}
27711897Ssudhanshu.jha@arm.com
27811897Ssudhanshu.jha@arm.comvoid
27911897Ssudhanshu.jha@arm.comBaseSimpleCPU::resetStats()
28011897Ssudhanshu.jha@arm.com{
28111897Ssudhanshu.jha@arm.com//    startNumInst = numInst;
28211897Ssudhanshu.jha@arm.com     notIdleFraction = (_status != Idle);
28311897Ssudhanshu.jha@arm.com}
28411897Ssudhanshu.jha@arm.com
28511897Ssudhanshu.jha@arm.comvoid
28611897Ssudhanshu.jha@arm.comBaseSimpleCPU::serialize(ostream &os)
28711897Ssudhanshu.jha@arm.com{
28811897Ssudhanshu.jha@arm.com    SERIALIZE_ENUM(_status);
28911897Ssudhanshu.jha@arm.com    BaseCPU::serialize(os);
29011897Ssudhanshu.jha@arm.com//    SERIALIZE_SCALAR(inst);
29111897Ssudhanshu.jha@arm.com    nameOut(os, csprintf("%s.xc.0", name()));
29211897Ssudhanshu.jha@arm.com    thread->serialize(os);
29311897Ssudhanshu.jha@arm.com}
29411897Ssudhanshu.jha@arm.com
29511897Ssudhanshu.jha@arm.comvoid
29611897Ssudhanshu.jha@arm.comBaseSimpleCPU::unserialize(Checkpoint *cp, const string &section)
29711897Ssudhanshu.jha@arm.com{
29811897Ssudhanshu.jha@arm.com    UNSERIALIZE_ENUM(_status);
29911012Sandreas.sandberg@arm.com    BaseCPU::unserialize(cp, section);
30011012Sandreas.sandberg@arm.com//    UNSERIALIZE_SCALAR(inst);
30111012Sandreas.sandberg@arm.com    thread->unserialize(cp, csprintf("%s.xc.0", section));
30211012Sandreas.sandberg@arm.com}
30311012Sandreas.sandberg@arm.com
30411012Sandreas.sandberg@arm.comvoid
30511012Sandreas.sandberg@arm.comchange_thread_state(ThreadID tid, int activate, int priority)
30611012Sandreas.sandberg@arm.com{
30711012Sandreas.sandberg@arm.com}
30811012Sandreas.sandberg@arm.com
30911012Sandreas.sandberg@arm.comAddr
31011012Sandreas.sandberg@arm.comBaseSimpleCPU::dbg_vtophys(Addr addr)
31111012Sandreas.sandberg@arm.com{
31211012Sandreas.sandberg@arm.com    return vtophys(tc, addr);
31311012Sandreas.sandberg@arm.com}
31411012Sandreas.sandberg@arm.com
31511012Sandreas.sandberg@arm.comvoid
31611012Sandreas.sandberg@arm.comBaseSimpleCPU::wakeup()
31711012Sandreas.sandberg@arm.com{
31811012Sandreas.sandberg@arm.com    if (thread->status() != ThreadContext::Suspended)
31911012Sandreas.sandberg@arm.com        return;
32011012Sandreas.sandberg@arm.com
32111012Sandreas.sandberg@arm.com    DPRINTF(Quiesce,"Suspended Processor awoke\n");
32211012Sandreas.sandberg@arm.com    thread->activate();
32311012Sandreas.sandberg@arm.com}
32411012Sandreas.sandberg@arm.com
32511012Sandreas.sandberg@arm.comvoid
32611012Sandreas.sandberg@arm.comBaseSimpleCPU::checkForInterrupts()
32711012Sandreas.sandberg@arm.com{
32811012Sandreas.sandberg@arm.com    if (checkInterrupts(tc)) {
32911012Sandreas.sandberg@arm.com        Fault interrupt = interrupts->getInterrupt(tc);
33011012Sandreas.sandberg@arm.com
33111012Sandreas.sandberg@arm.com        if (interrupt != NoFault) {
33211012Sandreas.sandberg@arm.com            fetchOffset = 0;
33311012Sandreas.sandberg@arm.com            interrupts->updateIntrInfo(tc);
33411012Sandreas.sandberg@arm.com            interrupt->invoke(tc);
33511012Sandreas.sandberg@arm.com            thread->decoder.reset();
33611012Sandreas.sandberg@arm.com        }
33711012Sandreas.sandberg@arm.com    }
33811012Sandreas.sandberg@arm.com}
33911012Sandreas.sandberg@arm.com
34011012Sandreas.sandberg@arm.com
34111012Sandreas.sandberg@arm.comvoid
34211012Sandreas.sandberg@arm.comBaseSimpleCPU::setupFetchRequest(Request *req)
34311012Sandreas.sandberg@arm.com{
34411012Sandreas.sandberg@arm.com    Addr instAddr = thread->instAddr();
34511012Sandreas.sandberg@arm.com
34611012Sandreas.sandberg@arm.com    // set up memory request for instruction fetch
34711012Sandreas.sandberg@arm.com    DPRINTF(Fetch, "Fetch: PC:%08p\n", instAddr);
34811012Sandreas.sandberg@arm.com
34911012Sandreas.sandberg@arm.com    Addr fetchPC = (instAddr & PCMask) + fetchOffset;
35011012Sandreas.sandberg@arm.com    req->setVirt(0, fetchPC, sizeof(MachInst), Request::INST_FETCH, instMasterId(),
35111012Sandreas.sandberg@arm.com            instAddr);
35211012Sandreas.sandberg@arm.com}
35311012Sandreas.sandberg@arm.com
35411012Sandreas.sandberg@arm.com
35511012Sandreas.sandberg@arm.comvoid
35611012Sandreas.sandberg@arm.comBaseSimpleCPU::preExecute()
35711012Sandreas.sandberg@arm.com{
35811012Sandreas.sandberg@arm.com    // maintain $r0 semantics
35911012Sandreas.sandberg@arm.com    thread->setIntReg(ZeroReg, 0);
36011012Sandreas.sandberg@arm.com#if THE_ISA == ALPHA_ISA
36111012Sandreas.sandberg@arm.com    thread->setFloatReg(ZeroReg, 0.0);
362#endif // ALPHA_ISA
363
364    // check for instruction-count-based events
365    comInstEventQueue[0]->serviceEvents(numInst);
366    system->instEventQueue.serviceEvents(system->totalNumInsts);
367
368    // decode the instruction
369    inst = gtoh(inst);
370
371    TheISA::PCState pcState = thread->pcState();
372
373    if (isRomMicroPC(pcState.microPC())) {
374        stayAtPC = false;
375        curStaticInst = microcodeRom.fetchMicroop(pcState.microPC(),
376                                                  curMacroStaticInst);
377    } else if (!curMacroStaticInst) {
378        //We're not in the middle of a macro instruction
379        StaticInstPtr instPtr = NULL;
380
381        TheISA::Decoder *decoder = &(thread->decoder);
382
383        //Predecode, ie bundle up an ExtMachInst
384        //If more fetch data is needed, pass it in.
385        Addr fetchPC = (pcState.instAddr() & PCMask) + fetchOffset;
386        //if(decoder->needMoreBytes())
387            decoder->moreBytes(pcState, fetchPC, inst);
388        //else
389        //    decoder->process();
390
391        //Decode an instruction if one is ready. Otherwise, we'll have to
392        //fetch beyond the MachInst at the current pc.
393        instPtr = decoder->decode(pcState);
394        if (instPtr) {
395            stayAtPC = false;
396            thread->pcState(pcState);
397        } else {
398            stayAtPC = true;
399            fetchOffset += sizeof(MachInst);
400        }
401
402        //If we decoded an instruction and it's microcoded, start pulling
403        //out micro ops
404        if (instPtr && instPtr->isMacroop()) {
405            curMacroStaticInst = instPtr;
406            curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC());
407        } else {
408            curStaticInst = instPtr;
409        }
410    } else {
411        //Read the next micro op from the macro op
412        curStaticInst = curMacroStaticInst->fetchMicroop(pcState.microPC());
413    }
414
415    //If we decoded an instruction this "tick", record information about it.
416    if (curStaticInst) {
417#if TRACING_ON
418        traceData = tracer->getInstRecord(curTick(), tc,
419                curStaticInst, thread->pcState(), curMacroStaticInst);
420
421        DPRINTF(Decode,"Decode: Decoded %s instruction: %#x\n",
422                curStaticInst->getName(), curStaticInst->machInst);
423#endif // TRACING_ON
424    }
425}
426
427void
428BaseSimpleCPU::postExecute()
429{
430    assert(curStaticInst);
431
432    TheISA::PCState pc = tc->pcState();
433    Addr instAddr = pc.instAddr();
434    if (FullSystem && thread->profile) {
435        bool usermode = TheISA::inUserMode(tc);
436        thread->profilePC = usermode ? 1 : instAddr;
437        ProfileNode *node = thread->profile->consume(tc, curStaticInst);
438        if (node)
439            thread->profileNode = node;
440    }
441
442    if (curStaticInst->isMemRef()) {
443        numMemRefs++;
444    }
445
446    if (curStaticInst->isLoad()) {
447        ++numLoad;
448        comLoadEventQueue[0]->serviceEvents(numLoad);
449    }
450
451    if (CPA::available()) {
452        CPA::cpa()->swAutoBegin(tc, pc.nextInstAddr());
453    }
454
455    /* Power model statistics */
456    //integer alu accesses
457    if (curStaticInst->isInteger()){
458        numIntAluAccesses++;
459        numIntInsts++;
460    }
461
462    //float alu accesses
463    if (curStaticInst->isFloating()){
464        numFpAluAccesses++;
465        numFpInsts++;
466    }
467
468    //number of function calls/returns to get window accesses
469    if (curStaticInst->isCall() || curStaticInst->isReturn()){
470        numCallsReturns++;
471    }
472
473    //the number of branch predictions that will be made
474    if (curStaticInst->isCondCtrl()){
475        numCondCtrlInsts++;
476    }
477
478    //result bus acceses
479    if (curStaticInst->isLoad()){
480        numLoadInsts++;
481    }
482
483    if (curStaticInst->isStore()){
484        numStoreInsts++;
485    }
486    /* End power model statistics */
487
488    if (FullSystem)
489        traceFunctions(instAddr);
490
491    if (traceData) {
492        traceData->dump();
493        delete traceData;
494        traceData = NULL;
495    }
496}
497
498
499void
500BaseSimpleCPU::advancePC(Fault fault)
501{
502    //Since we're moving to a new pc, zero out the offset
503    fetchOffset = 0;
504    if (fault != NoFault) {
505        curMacroStaticInst = StaticInst::nullStaticInstPtr;
506        fault->invoke(tc, curStaticInst);
507        thread->decoder.reset();
508    } else {
509        if (curStaticInst) {
510            if (curStaticInst->isLastMicroop())
511                curMacroStaticInst = StaticInst::nullStaticInstPtr;
512            TheISA::PCState pcState = thread->pcState();
513            TheISA::advancePC(pcState, curStaticInst);
514            thread->pcState(pcState);
515        }
516    }
517}
518
519/*Fault
520BaseSimpleCPU::CacheOp(uint8_t Op, Addr EffAddr)
521{
522    // translate to physical address
523    Fault fault = NoFault;
524    int CacheID = Op & 0x3; // Lower 3 bits identify Cache
525    int CacheOP = Op >> 2; // Upper 3 bits identify Cache Operation
526    if(CacheID > 1)
527      {
528        warn("CacheOps not implemented for secondary/tertiary caches\n");
529      }
530    else
531      {
532        switch(CacheOP)
533          { // Fill Packet Type
534          case 0: warn("Invalidate Cache Op\n");
535            break;
536          case 1: warn("Index Load Tag Cache Op\n");
537            break;
538          case 2: warn("Index Store Tag Cache Op\n");
539            break;
540          case 4: warn("Hit Invalidate Cache Op\n");
541            break;
542          case 5: warn("Fill/Hit Writeback Invalidate Cache Op\n");
543            break;
544          case 6: warn("Hit Writeback\n");
545            break;
546          case 7: warn("Fetch & Lock Cache Op\n");
547            break;
548          default: warn("Unimplemented Cache Op\n");
549          }
550      }
551    return fault;
552}*/
553