base.cc revision 5529:9ae69b9cd7fd
16019Shines@cs.fsu.edu/*
210037SARM gem5 Developers * Copyright (c) 2002-2005 The Regents of The University of Michigan
37093Sgblack@eecs.umich.edu * All rights reserved.
47093Sgblack@eecs.umich.edu *
57093Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
67093Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
77093Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
87093Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
97093Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
107093Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
117093Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
127093Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
137093Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
146019Shines@cs.fsu.edu * this software without specific prior written permission.
156019Shines@cs.fsu.edu *
166019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276019Shines@cs.fsu.edu *
286019Shines@cs.fsu.edu * Authors: Steve Reinhardt
296019Shines@cs.fsu.edu */
306019Shines@cs.fsu.edu
316019Shines@cs.fsu.edu#include "arch/utility.hh"
326019Shines@cs.fsu.edu#include "arch/faults.hh"
336019Shines@cs.fsu.edu#include "base/cprintf.hh"
346019Shines@cs.fsu.edu#include "base/inifile.hh"
356019Shines@cs.fsu.edu#include "base/loader/symtab.hh"
366019Shines@cs.fsu.edu#include "base/misc.hh"
376019Shines@cs.fsu.edu#include "base/pollevent.hh"
386019Shines@cs.fsu.edu#include "base/range.hh"
396019Shines@cs.fsu.edu#include "base/stats/events.hh"
407399SAli.Saidi@ARM.com#include "base/trace.hh"
417399SAli.Saidi@ARM.com#include "cpu/base.hh"
426019Shines@cs.fsu.edu#include "cpu/exetrace.hh"
436019Shines@cs.fsu.edu#include "cpu/profile.hh"
446019Shines@cs.fsu.edu#include "cpu/simple/base.hh"
4510873Sandreas.sandberg@arm.com#include "cpu/simple_thread.hh"
4610873Sandreas.sandberg@arm.com#include "cpu/smt.hh"
4710474Sandreas.hansson@arm.com#include "cpu/static_inst.hh"
486019Shines@cs.fsu.edu#include "cpu/thread_context.hh"
496019Shines@cs.fsu.edu#include "mem/packet.hh"
506019Shines@cs.fsu.edu#include "sim/byteswap.hh"
516116Snate@binkert.org#include "sim/debug.hh"
526019Shines@cs.fsu.edu#include "sim/host.hh"
538782Sgblack@eecs.umich.edu#include "sim/sim_events.hh"
548756Sgblack@eecs.umich.edu#include "sim/sim_object.hh"
5510037SARM gem5 Developers#include "sim/stats.hh"
5610037SARM gem5 Developers#include "sim/system.hh"
576019Shines@cs.fsu.edu
586019Shines@cs.fsu.edu#if FULL_SYSTEM
596019Shines@cs.fsu.edu#include "arch/kernel_stats.hh"
606019Shines@cs.fsu.edu#include "arch/stacktrace.hh"
6110024Sdam.sunwoo@arm.com#include "arch/tlb.hh"
626019Shines@cs.fsu.edu#include "arch/vtophys.hh"
638232Snate@binkert.org#include "base/remote_gdb.hh"
648232Snate@binkert.org#else // !FULL_SYSTEM
658232Snate@binkert.org#include "mem/mem_object.hh"
666116Snate@binkert.org#endif // FULL_SYSTEM
676116Snate@binkert.org
688756Sgblack@eecs.umich.edu#include "params/BaseSimpleCPU.hh"
696019Shines@cs.fsu.edu
706019Shines@cs.fsu.eduusing namespace std;
716019Shines@cs.fsu.eduusing namespace TheISA;
726019Shines@cs.fsu.edu
736019Shines@cs.fsu.eduBaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p)
7410037SARM gem5 Developers    : BaseCPU(p), traceData(NULL), thread(NULL), predecoder(NULL)
7510037SARM gem5 Developers{
7610418Sandreas.hansson@arm.com#if FULL_SYSTEM
7710418Sandreas.hansson@arm.com    thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
7810822Sandreas.hansson@arm.com#else
7910537Sandreas.hansson@arm.com    thread = new SimpleThread(this, /* thread_num */ 0, p->workload[0],
8010537Sandreas.hansson@arm.com            p->itb, p->dtb, /* asid */ 0);
8110418Sandreas.hansson@arm.com#endif // !FULL_SYSTEM
826019Shines@cs.fsu.edu
8310037SARM gem5 Developers    thread->setStatus(ThreadContext::Unallocated);
847399SAli.Saidi@ARM.com
8510037SARM gem5 Developers    tc = thread->getTC();
8610037SARM gem5 Developers
8710037SARM gem5 Developers    numInst = 0;
8810037SARM gem5 Developers    startNumInst = 0;
896019Shines@cs.fsu.edu    numLoad = 0;
906019Shines@cs.fsu.edu    startNumLoad = 0;
916019Shines@cs.fsu.edu    lastIcacheStall = 0;
926019Shines@cs.fsu.edu    lastDcacheStall = 0;
9310037SARM gem5 Developers
9410037SARM gem5 Developers    threadContexts.push_back(tc);
9510037SARM gem5 Developers
9610037SARM gem5 Developers
9710037SARM gem5 Developers    fetchOffset = 0;
9810037SARM gem5 Developers    stayAtPC = false;
9910037SARM gem5 Developers}
10010037SARM gem5 Developers
10110037SARM gem5 DevelopersBaseSimpleCPU::~BaseSimpleCPU()
10210037SARM gem5 Developers{
10310037SARM gem5 Developers}
10410717Sandreas.hansson@arm.com
10510037SARM gem5 Developersvoid
10610037SARM gem5 DevelopersBaseSimpleCPU::deallocateContext(int thread_num)
10710717Sandreas.hansson@arm.com{
1086019Shines@cs.fsu.edu    // for now, these are equivalent
1096019Shines@cs.fsu.edu    suspendContext(thread_num);
1107694SAli.Saidi@ARM.com}
1117694SAli.Saidi@ARM.com
1127694SAli.Saidi@ARM.com
11310037SARM gem5 Developersvoid
11410037SARM gem5 DevelopersBaseSimpleCPU::haltContext(int thread_num)
11510037SARM gem5 Developers{
11610037SARM gem5 Developers    // for now, these are equivalent
11710037SARM gem5 Developers    suspendContext(thread_num);
11810037SARM gem5 Developers}
11910037SARM gem5 Developers
12010037SARM gem5 Developers
12110037SARM gem5 Developersvoid
1227694SAli.Saidi@ARM.comBaseSimpleCPU::regStats()
1237694SAli.Saidi@ARM.com{
1247694SAli.Saidi@ARM.com    using namespace Stats;
1257694SAli.Saidi@ARM.com
1267694SAli.Saidi@ARM.com    BaseCPU::regStats();
1277694SAli.Saidi@ARM.com
1289738Sandreas@sandberg.pp.se    numInsts
1299738Sandreas@sandberg.pp.se        .name(name() + ".num_insts")
1309738Sandreas@sandberg.pp.se        .desc("Number of instructions executed")
1319738Sandreas@sandberg.pp.se        ;
1329738Sandreas@sandberg.pp.se
1339738Sandreas@sandberg.pp.se    numMemRefs
1347404SAli.Saidi@ARM.com        .name(name() + ".num_refs")
13510037SARM gem5 Developers        .desc("Number of memory references")
13610037SARM gem5 Developers        ;
1376019Shines@cs.fsu.edu
1387404SAli.Saidi@ARM.com    notIdleFraction
1397404SAli.Saidi@ARM.com        .name(name() + ".not_idle_fraction")
1407404SAli.Saidi@ARM.com        .desc("Percentage of non-idle cycles")
14110037SARM gem5 Developers        ;
1427404SAli.Saidi@ARM.com
1437404SAli.Saidi@ARM.com    idleFraction
14410037SARM gem5 Developers        .name(name() + ".idle_fraction")
14510037SARM gem5 Developers        .desc("Percentage of idle cycles")
14610037SARM gem5 Developers        ;
14710037SARM gem5 Developers
14810037SARM gem5 Developers    icacheStallCycles
1499535Smrinmoy.ghosh@arm.com        .name(name() + ".icache_stall_cycles")
1507697SAli.Saidi@ARM.com        .desc("ICache total stall cycles")
1517697SAli.Saidi@ARM.com        .prereq(icacheStallCycles)
15210037SARM gem5 Developers        ;
1537697SAli.Saidi@ARM.com
1547697SAli.Saidi@ARM.com    dcacheStallCycles
1557697SAli.Saidi@ARM.com        .name(name() + ".dcache_stall_cycles")
1567697SAli.Saidi@ARM.com        .desc("DCache total stall cycles")
1577697SAli.Saidi@ARM.com        .prereq(dcacheStallCycles)
1587404SAli.Saidi@ARM.com        ;
1597404SAli.Saidi@ARM.com
16010037SARM gem5 Developers    icacheRetryCycles
1617404SAli.Saidi@ARM.com        .name(name() + ".icache_retry_cycles")
1627404SAli.Saidi@ARM.com        .desc("ICache total retry cycles")
16310037SARM gem5 Developers        .prereq(icacheRetryCycles)
16410037SARM gem5 Developers        ;
16510037SARM gem5 Developers
16610037SARM gem5 Developers    dcacheRetryCycles
16710037SARM gem5 Developers        .name(name() + ".dcache_retry_cycles")
16810037SARM gem5 Developers        .desc("DCache total retry cycles")
16910037SARM gem5 Developers        .prereq(dcacheRetryCycles)
17010037SARM gem5 Developers        ;
17110367SAndrew.Bardsley@arm.com
17210037SARM gem5 Developers    idleFraction = constant(1.0) - notIdleFraction;
1737404SAli.Saidi@ARM.com}
1746019Shines@cs.fsu.edu
1756019Shines@cs.fsu.eduvoid
1766019Shines@cs.fsu.eduBaseSimpleCPU::resetStats()
1776019Shines@cs.fsu.edu{
1787404SAli.Saidi@ARM.com//    startNumInst = numInst;
1796019Shines@cs.fsu.edu     notIdleFraction = (_status != Idle);
1807404SAli.Saidi@ARM.com}
18110037SARM gem5 Developers
18210037SARM gem5 Developersvoid
18310037SARM gem5 DevelopersBaseSimpleCPU::serialize(ostream &os)
18410037SARM gem5 Developers{
18510037SARM gem5 Developers    SERIALIZE_ENUM(_status);
18610037SARM gem5 Developers    BaseCPU::serialize(os);
1877404SAli.Saidi@ARM.com//    SERIALIZE_SCALAR(inst);
18810037SARM gem5 Developers    nameOut(os, csprintf("%s.xc.0", name()));
18910037SARM gem5 Developers    thread->serialize(os);
19010037SARM gem5 Developers}
1917697SAli.Saidi@ARM.com
19210037SARM gem5 Developersvoid
19310037SARM gem5 DevelopersBaseSimpleCPU::unserialize(Checkpoint *cp, const string &section)
19410037SARM gem5 Developers{
19510037SARM gem5 Developers    UNSERIALIZE_ENUM(_status);
1967404SAli.Saidi@ARM.com    BaseCPU::unserialize(cp, section);
1977697SAli.Saidi@ARM.com//    UNSERIALIZE_SCALAR(inst);
1987404SAli.Saidi@ARM.com    thread->unserialize(cp, csprintf("%s.xc.0", section));
19910037SARM gem5 Developers}
20010037SARM gem5 Developers
2017697SAli.Saidi@ARM.comvoid
2027734SAli.Saidi@ARM.comchange_thread_state(int thread_number, int activate, int priority)
2037734SAli.Saidi@ARM.com{
20410463SAndreas.Sandberg@ARM.com}
2056019Shines@cs.fsu.edu
2066019Shines@cs.fsu.eduFault
2076019Shines@cs.fsu.eduBaseSimpleCPU::copySrcTranslate(Addr src)
20810037SARM gem5 Developers{
2097404SAli.Saidi@ARM.com#if 0
2107404SAli.Saidi@ARM.com    static bool no_warn = true;
2117404SAli.Saidi@ARM.com    int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
2127404SAli.Saidi@ARM.com    // Only support block sizes of 64 atm.
2137404SAli.Saidi@ARM.com    assert(blk_size == 64);
21410037SARM gem5 Developers    int offset = src & (blk_size - 1);
21510037SARM gem5 Developers
21610037SARM gem5 Developers    // Make sure block doesn't span page
21710037SARM gem5 Developers    if (no_warn &&
2187404SAli.Saidi@ARM.com        (src & PageMask) != ((src + blk_size) & PageMask) &&
2197404SAli.Saidi@ARM.com        (src >> 40) != 0xfffffc) {
2207404SAli.Saidi@ARM.com        warn("Copied block source spans pages %x.", src);
2217404SAli.Saidi@ARM.com        no_warn = false;
22210037SARM gem5 Developers    }
2236019Shines@cs.fsu.edu
22410037SARM gem5 Developers    memReq->reset(src & ~(blk_size - 1), blk_size);
22510037SARM gem5 Developers
2267404SAli.Saidi@ARM.com    // translate to physical address
2277404SAli.Saidi@ARM.com    Fault fault = thread->translateDataReadReq(req);
2287404SAli.Saidi@ARM.com
22910037SARM gem5 Developers    if (fault == NoFault) {
23010037SARM gem5 Developers        thread->copySrcAddr = src;
23110037SARM gem5 Developers        thread->copySrcPhysAddr = memReq->paddr + offset;
23210037SARM gem5 Developers    } else {
23310037SARM gem5 Developers        assert(!fault->isAlignmentFault());
23410037SARM gem5 Developers
23510037SARM gem5 Developers        thread->copySrcAddr = 0;
23610037SARM gem5 Developers        thread->copySrcPhysAddr = 0;
23710037SARM gem5 Developers    }
23810037SARM gem5 Developers    return fault;
2397404SAli.Saidi@ARM.com#else
2407404SAli.Saidi@ARM.com    return NoFault;
24110037SARM gem5 Developers#endif
24210037SARM gem5 Developers}
24310037SARM gem5 Developers
24410037SARM gem5 DevelopersFault
24510037SARM gem5 DevelopersBaseSimpleCPU::copy(Addr dest)
24610037SARM gem5 Developers{
24710037SARM gem5 Developers#if 0
24810037SARM gem5 Developers    static bool no_warn = true;
24910037SARM gem5 Developers    int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
25010037SARM gem5 Developers    // Only support block sizes of 64 atm.
25110037SARM gem5 Developers    assert(blk_size == 64);
25210037SARM gem5 Developers    uint8_t data[blk_size];
25310037SARM gem5 Developers    //assert(thread->copySrcAddr);
25410037SARM gem5 Developers    int offset = dest & (blk_size - 1);
25510037SARM gem5 Developers
25610037SARM gem5 Developers    // Make sure block doesn't span page
25710037SARM gem5 Developers    if (no_warn &&
25810037SARM gem5 Developers        (dest & PageMask) != ((dest + blk_size) & PageMask) &&
25910037SARM gem5 Developers        (dest >> 40) != 0xfffffc) {
26010037SARM gem5 Developers        no_warn = false;
26110037SARM gem5 Developers        warn("Copied block destination spans pages %x. ", dest);
26210037SARM gem5 Developers    }
26310037SARM gem5 Developers
26410037SARM gem5 Developers    memReq->reset(dest & ~(blk_size -1), blk_size);
26510037SARM gem5 Developers    // translate to physical address
26610037SARM gem5 Developers    Fault fault = thread->translateDataWriteReq(req);
26710037SARM gem5 Developers
2687734SAli.Saidi@ARM.com    if (fault == NoFault) {
2697734SAli.Saidi@ARM.com        Addr dest_addr = memReq->paddr + offset;
27010037SARM gem5 Developers        // Need to read straight from memory since we have more than 8 bytes.
27110037SARM gem5 Developers        memReq->paddr = thread->copySrcPhysAddr;
27210037SARM gem5 Developers        thread->mem->read(memReq, data);
27310037SARM gem5 Developers        memReq->paddr = dest_addr;
27410037SARM gem5 Developers        thread->mem->write(memReq, data);
2756019Shines@cs.fsu.edu        if (dcacheInterface) {
2766019Shines@cs.fsu.edu            memReq->cmd = Copy;
2777404SAli.Saidi@ARM.com            memReq->completionEvent = NULL;
27810037SARM gem5 Developers            memReq->paddr = thread->copySrcPhysAddr;
2797404SAli.Saidi@ARM.com            memReq->dest = dest_addr;
28010037SARM gem5 Developers            memReq->size = 64;
28110037SARM gem5 Developers            memReq->time = curTick;
28210037SARM gem5 Developers            memReq->flags &= ~INST_READ;
28310037SARM gem5 Developers            dcacheInterface->access(memReq);
2847734SAli.Saidi@ARM.com        }
2857404SAli.Saidi@ARM.com    }
2867404SAli.Saidi@ARM.com    else
2877404SAli.Saidi@ARM.com        assert(!fault->isAlignmentFault());
28810037SARM gem5 Developers
2897404SAli.Saidi@ARM.com    return fault;
29010037SARM gem5 Developers#else
29110037SARM gem5 Developers    panic("copy not implemented");
2927404SAli.Saidi@ARM.com    return NoFault;
29310037SARM gem5 Developers#endif
2947404SAli.Saidi@ARM.com}
2957404SAli.Saidi@ARM.com
2967404SAli.Saidi@ARM.com#if FULL_SYSTEM
2977404SAli.Saidi@ARM.comAddr
29810037SARM gem5 DevelopersBaseSimpleCPU::dbg_vtophys(Addr addr)
29910037SARM gem5 Developers{
30010037SARM gem5 Developers    return vtophys(tc, addr);
30110037SARM gem5 Developers}
3027404SAli.Saidi@ARM.com#endif // FULL_SYSTEM
30310037SARM gem5 Developers
3047734SAli.Saidi@ARM.com#if FULL_SYSTEM
3057404SAli.Saidi@ARM.comvoid
30610037SARM gem5 DevelopersBaseSimpleCPU::post_interrupt(int int_num, int index)
3077404SAli.Saidi@ARM.com{
3087734SAli.Saidi@ARM.com    BaseCPU::post_interrupt(int_num, index);
3097404SAli.Saidi@ARM.com
3107404SAli.Saidi@ARM.com    if (thread->status() == ThreadContext::Suspended) {
3117404SAli.Saidi@ARM.com                DPRINTF(Quiesce,"Suspended Processor awoke\n");
31210037SARM gem5 Developers        thread->activate();
3137404SAli.Saidi@ARM.com    }
31410037SARM gem5 Developers}
31510037SARM gem5 Developers#endif // FULL_SYSTEM
31610037SARM gem5 Developers
31710037SARM gem5 Developersvoid
31810037SARM gem5 DevelopersBaseSimpleCPU::checkForInterrupts()
3197404SAli.Saidi@ARM.com{
32010037SARM gem5 Developers#if FULL_SYSTEM
32110037SARM gem5 Developers    if (check_interrupts(tc)) {
32210037SARM gem5 Developers        Fault interrupt = interrupts.getInterrupt(tc);
32310037SARM gem5 Developers
3247404SAli.Saidi@ARM.com        if (interrupt != NoFault) {
32510037SARM gem5 Developers            interrupts.updateIntrInfo(tc);
32610037SARM gem5 Developers            interrupt->invoke(tc);
32710037SARM gem5 Developers        }
32810037SARM gem5 Developers    }
32910037SARM gem5 Developers#endif
33010037SARM gem5 Developers}
33110037SARM gem5 Developers
3327404SAli.Saidi@ARM.com
3337734SAli.Saidi@ARM.comFault
3347404SAli.Saidi@ARM.comBaseSimpleCPU::setupFetchRequest(Request *req)
33510037SARM gem5 Developers{
33610037SARM gem5 Developers    Addr threadPC = thread->readPC();
3377404SAli.Saidi@ARM.com
33810037SARM gem5 Developers    // set up memory request for instruction fetch
33910037SARM gem5 Developers#if ISA_HAS_DELAY_SLOT
34010037SARM gem5 Developers    DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",threadPC,
34110037SARM gem5 Developers            thread->readNextPC(),thread->readNextNPC());
34210037SARM gem5 Developers#else
34310037SARM gem5 Developers    DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p\n",threadPC,
34410037SARM gem5 Developers            thread->readNextPC());
34510037SARM gem5 Developers#endif
34610037SARM gem5 Developers
34710037SARM gem5 Developers    Addr fetchPC = (threadPC & PCMask) + fetchOffset;
34810037SARM gem5 Developers    req->setVirt(0, fetchPC, sizeof(MachInst), 0, threadPC);
34910037SARM gem5 Developers
35010037SARM gem5 Developers    Fault fault = thread->translateInstReq(req);
35110037SARM gem5 Developers
3527404SAli.Saidi@ARM.com    return fault;
3537404SAli.Saidi@ARM.com}
3546019Shines@cs.fsu.edu
3559439SAndreas.Sandberg@ARM.com
3569439SAndreas.Sandberg@ARM.comvoid
3579439SAndreas.Sandberg@ARM.comBaseSimpleCPU::preExecute()
3589439SAndreas.Sandberg@ARM.com{
3599439SAndreas.Sandberg@ARM.com    // maintain $r0 semantics
3609439SAndreas.Sandberg@ARM.com    thread->setIntReg(ZeroReg, 0);
3619439SAndreas.Sandberg@ARM.com#if THE_ISA == ALPHA_ISA
3629439SAndreas.Sandberg@ARM.com    thread->setFloatReg(ZeroReg, 0.0);
36310194SGeoffrey.Blake@arm.com#endif // ALPHA_ISA
36410194SGeoffrey.Blake@arm.com
36510194SGeoffrey.Blake@arm.com    // check for instruction-count-based events
36610194SGeoffrey.Blake@arm.com    comInstEventQueue[0]->serviceEvents(numInst);
36710194SGeoffrey.Blake@arm.com
36810194SGeoffrey.Blake@arm.com    // decode the instruction
36910194SGeoffrey.Blake@arm.com    inst = gtoh(inst);
37010194SGeoffrey.Blake@arm.com
37110194SGeoffrey.Blake@arm.com    //If we're not in the middle of a macro instruction
37210194SGeoffrey.Blake@arm.com    if (!curMacroStaticInst) {
37310194SGeoffrey.Blake@arm.com
37410194SGeoffrey.Blake@arm.com        StaticInstPtr instPtr = NULL;
37510194SGeoffrey.Blake@arm.com
37610194SGeoffrey.Blake@arm.com        //Predecode, ie bundle up an ExtMachInst
37710194SGeoffrey.Blake@arm.com        //This should go away once the constructor can be set up properly
37810194SGeoffrey.Blake@arm.com        predecoder.setTC(thread->getTC());
37910194SGeoffrey.Blake@arm.com        //If more fetch data is needed, pass it in.
38010194SGeoffrey.Blake@arm.com        Addr fetchPC = (thread->readPC() & PCMask) + fetchOffset;
38110194SGeoffrey.Blake@arm.com        //if(predecoder.needMoreBytes())
38210194SGeoffrey.Blake@arm.com            predecoder.moreBytes(thread->readPC(), fetchPC, inst);
38310194SGeoffrey.Blake@arm.com        //else
38410194SGeoffrey.Blake@arm.com        //    predecoder.process();
38510194SGeoffrey.Blake@arm.com
3866019Shines@cs.fsu.edu        //If an instruction is ready, decode it. Otherwise, we'll have to
3876019Shines@cs.fsu.edu        //fetch beyond the MachInst at the current pc.
3887733SAli.Saidi@ARM.com        if (predecoder.extMachInstReady()) {
3897733SAli.Saidi@ARM.com#if THE_ISA == X86_ISA
3907733SAli.Saidi@ARM.com            thread->setNextPC(thread->readPC() + predecoder.getInstSize());
39110037SARM gem5 Developers#endif // X86_ISA
39210037SARM gem5 Developers            stayAtPC = false;
39310037SARM gem5 Developers            instPtr = StaticInst::decode(predecoder.getExtMachInst(),
3948353SAli.Saidi@ARM.com                                         thread->readPC());
3958353SAli.Saidi@ARM.com        } else {
3968353SAli.Saidi@ARM.com            stayAtPC = true;
3977733SAli.Saidi@ARM.com            fetchOffset += sizeof(MachInst);
3987733SAli.Saidi@ARM.com        }
3997733SAli.Saidi@ARM.com
4007733SAli.Saidi@ARM.com        //If we decoded an instruction and it's microcoded, start pulling
4016019Shines@cs.fsu.edu        //out micro ops
4026019Shines@cs.fsu.edu        if (instPtr && instPtr->isMacroop()) {
4036019Shines@cs.fsu.edu            curMacroStaticInst = instPtr;
4046019Shines@cs.fsu.edu            curStaticInst = curMacroStaticInst->
4056019Shines@cs.fsu.edu                fetchMicroop(thread->readMicroPC());
4067733SAli.Saidi@ARM.com        } else {
4076019Shines@cs.fsu.edu            curStaticInst = instPtr;
4087733SAli.Saidi@ARM.com        }
40910037SARM gem5 Developers    } else {
41010037SARM gem5 Developers        //Read the next micro op from the macro op
41110037SARM gem5 Developers        curStaticInst = curMacroStaticInst->
41210037SARM gem5 Developers            fetchMicroop(thread->readMicroPC());
4138353SAli.Saidi@ARM.com    }
4148353SAli.Saidi@ARM.com
4158353SAli.Saidi@ARM.com    //If we decoded an instruction this "tick", record information about it.
4167733SAli.Saidi@ARM.com    if(curStaticInst)
4177733SAli.Saidi@ARM.com    {
4186019Shines@cs.fsu.edu#if TRACING_ON
4196019Shines@cs.fsu.edu        traceData = tracer->getInstRecord(curTick, tc, curStaticInst,
4206019Shines@cs.fsu.edu                                         thread->readPC());
4216019Shines@cs.fsu.edu
4226019Shines@cs.fsu.edu        DPRINTF(Decode,"Decode: Decoded %s instruction: 0x%x\n",
4237734SAli.Saidi@ARM.com                curStaticInst->getName(), curStaticInst->machInst);
4247734SAli.Saidi@ARM.com#endif // TRACING_ON
4257734SAli.Saidi@ARM.com
4267734SAli.Saidi@ARM.com#if FULL_SYSTEM
4277734SAli.Saidi@ARM.com        thread->setInst(inst);
4287734SAli.Saidi@ARM.com#endif // FULL_SYSTEM
4297734SAli.Saidi@ARM.com    }
4307734SAli.Saidi@ARM.com}
4317734SAli.Saidi@ARM.com
4327734SAli.Saidi@ARM.comvoid
4337734SAli.Saidi@ARM.comBaseSimpleCPU::postExecute()
4347734SAli.Saidi@ARM.com{
4357734SAli.Saidi@ARM.com#if FULL_SYSTEM
4367734SAli.Saidi@ARM.com    if (thread->profile && curStaticInst) {
4377734SAli.Saidi@ARM.com        bool usermode = TheISA::inUserMode(tc);
4387734SAli.Saidi@ARM.com        thread->profilePC = usermode ? 1 : thread->readPC();
4396019Shines@cs.fsu.edu        ProfileNode *node = thread->profile->consume(tc, curStaticInst);
4406019Shines@cs.fsu.edu        if (node)
4416019Shines@cs.fsu.edu            thread->profileNode = node;
4426019Shines@cs.fsu.edu    }
4437734SAli.Saidi@ARM.com#endif
4446019Shines@cs.fsu.edu
4456019Shines@cs.fsu.edu    if (curStaticInst->isMemRef()) {
4466019Shines@cs.fsu.edu        numMemRefs++;
4476019Shines@cs.fsu.edu    }
4487734SAli.Saidi@ARM.com
4496019Shines@cs.fsu.edu    if (curStaticInst->isLoad()) {
4506019Shines@cs.fsu.edu        ++numLoad;
4516019Shines@cs.fsu.edu        comLoadEventQueue[0]->serviceEvents(numLoad);
4526019Shines@cs.fsu.edu    }
4537734SAli.Saidi@ARM.com
4546019Shines@cs.fsu.edu    traceFunctions(thread->readPC());
4556019Shines@cs.fsu.edu
4566019Shines@cs.fsu.edu    if (traceData) {
4576019Shines@cs.fsu.edu        traceData->dump();
4587734SAli.Saidi@ARM.com        delete traceData;
4596019Shines@cs.fsu.edu        traceData = NULL;
4606019Shines@cs.fsu.edu    }
4616019Shines@cs.fsu.edu}
4626019Shines@cs.fsu.edu
4637734SAli.Saidi@ARM.com
4646019Shines@cs.fsu.eduvoid
4656019Shines@cs.fsu.eduBaseSimpleCPU::advancePC(Fault fault)
4666019Shines@cs.fsu.edu{
4676019Shines@cs.fsu.edu    //Since we're moving to a new pc, zero out the offset
4686019Shines@cs.fsu.edu    fetchOffset = 0;
4696019Shines@cs.fsu.edu    if (fault != NoFault) {
4706019Shines@cs.fsu.edu        curMacroStaticInst = StaticInst::nullStaticInstPtr;
4716019Shines@cs.fsu.edu        predecoder.reset();
4726019Shines@cs.fsu.edu        thread->setMicroPC(0);
4736019Shines@cs.fsu.edu        thread->setNextMicroPC(1);
4746019Shines@cs.fsu.edu        fault->invoke(tc);
4756019Shines@cs.fsu.edu    } else {
4766019Shines@cs.fsu.edu        //If we're at the last micro op for this instruction
4776019Shines@cs.fsu.edu        if (curStaticInst && curStaticInst->isLastMicroop()) {
4786019Shines@cs.fsu.edu            //We should be working with a macro op
4796019Shines@cs.fsu.edu            assert(curMacroStaticInst);
4806019Shines@cs.fsu.edu            //Close out this macro op, and clean up the
4816019Shines@cs.fsu.edu            //microcode state
4826019Shines@cs.fsu.edu            curMacroStaticInst = StaticInst::nullStaticInstPtr;
4837734SAli.Saidi@ARM.com            thread->setMicroPC(0);
4847734SAli.Saidi@ARM.com            thread->setNextMicroPC(1);
4857734SAli.Saidi@ARM.com        }
4867734SAli.Saidi@ARM.com        //If we're still in a macro op
4877734SAli.Saidi@ARM.com        if (curMacroStaticInst) {
4887734SAli.Saidi@ARM.com            //Advance the micro pc
4897734SAli.Saidi@ARM.com            thread->setMicroPC(thread->readNextMicroPC());
4907734SAli.Saidi@ARM.com            //Advance the "next" micro pc. Note that there are no delay
4917734SAli.Saidi@ARM.com            //slots, and micro ops are "word" addressed.
4927734SAli.Saidi@ARM.com            thread->setNextMicroPC(thread->readNextMicroPC() + 1);
4937734SAli.Saidi@ARM.com        } else {
4947734SAli.Saidi@ARM.com            // go to the next instruction
4957734SAli.Saidi@ARM.com            thread->setPC(thread->readNextPC());
4967734SAli.Saidi@ARM.com            thread->setNextPC(thread->readNextNPC());
4977734SAli.Saidi@ARM.com            thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
4987734SAli.Saidi@ARM.com            assert(thread->readNextPC() != thread->readNextNPC());
4997734SAli.Saidi@ARM.com        }
5007734SAli.Saidi@ARM.com    }
5017734SAli.Saidi@ARM.com}
5027734SAli.Saidi@ARM.com
5037734SAli.Saidi@ARM.com/*Fault
5047734SAli.Saidi@ARM.comBaseSimpleCPU::CacheOp(uint8_t Op, Addr EffAddr)
5057734SAli.Saidi@ARM.com{
5067734SAli.Saidi@ARM.com    // translate to physical address
5077734SAli.Saidi@ARM.com    Fault fault = NoFault;
5087734SAli.Saidi@ARM.com    int CacheID = Op & 0x3; // Lower 3 bits identify Cache
5097734SAli.Saidi@ARM.com    int CacheOP = Op >> 2; // Upper 3 bits identify Cache Operation
5107734SAli.Saidi@ARM.com    if(CacheID > 1)
5117734SAli.Saidi@ARM.com      {
5127734SAli.Saidi@ARM.com        warn("CacheOps not implemented for secondary/tertiary caches\n");
5137734SAli.Saidi@ARM.com      }
5147734SAli.Saidi@ARM.com    else
5157734SAli.Saidi@ARM.com      {
5167734SAli.Saidi@ARM.com        switch(CacheOP)
5177734SAli.Saidi@ARM.com          { // Fill Packet Type
5187734SAli.Saidi@ARM.com          case 0: warn("Invalidate Cache Op\n");
5197734SAli.Saidi@ARM.com            break;
5207734SAli.Saidi@ARM.com          case 1: warn("Index Load Tag Cache Op\n");
5217734SAli.Saidi@ARM.com            break;
5227734SAli.Saidi@ARM.com          case 2: warn("Index Store Tag Cache Op\n");
5237734SAli.Saidi@ARM.com            break;
5247734SAli.Saidi@ARM.com          case 4: warn("Hit Invalidate Cache Op\n");
5257734SAli.Saidi@ARM.com            break;
5267734SAli.Saidi@ARM.com          case 5: warn("Fill/Hit Writeback Invalidate Cache Op\n");
5277734SAli.Saidi@ARM.com            break;
5287734SAli.Saidi@ARM.com          case 6: warn("Hit Writeback\n");
5297734SAli.Saidi@ARM.com            break;
5307734SAli.Saidi@ARM.com          case 7: warn("Fetch & Lock Cache Op\n");
5317734SAli.Saidi@ARM.com            break;
5327734SAli.Saidi@ARM.com          default: warn("Unimplemented Cache Op\n");
5337734SAli.Saidi@ARM.com          }
5346019Shines@cs.fsu.edu      }
5356019Shines@cs.fsu.edu    return fault;
53610463SAndreas.Sandberg@ARM.com}*/
53710463SAndreas.Sandberg@ARM.com