base.cc revision 7678:f19b6a3a8cec
112027Sjungma@eit.uni-kl.de/*
212027Sjungma@eit.uni-kl.de * Copyright (c) 2010 ARM Limited
312027Sjungma@eit.uni-kl.de * All rights reserved
412027Sjungma@eit.uni-kl.de *
512027Sjungma@eit.uni-kl.de * The license below extends only to copyright in the software and shall
612027Sjungma@eit.uni-kl.de * not be construed as granting a license to any other intellectual
712027Sjungma@eit.uni-kl.de * property including but not limited to intellectual property relating
812027Sjungma@eit.uni-kl.de * to a hardware implementation of the functionality of the software
912027Sjungma@eit.uni-kl.de * licensed hereunder.  You may use the software subject to the license
1012027Sjungma@eit.uni-kl.de * terms below provided that you ensure that this notice is replicated
1112027Sjungma@eit.uni-kl.de * unmodified and in its entirety in all distributions of the software,
1212027Sjungma@eit.uni-kl.de * modified or unmodified, in source code or in binary form.
1312027Sjungma@eit.uni-kl.de *
1412027Sjungma@eit.uni-kl.de * Copyright (c) 2002-2005 The Regents of The University of Michigan
1512027Sjungma@eit.uni-kl.de * All rights reserved.
1612027Sjungma@eit.uni-kl.de *
1712027Sjungma@eit.uni-kl.de * Redistribution and use in source and binary forms, with or without
1812027Sjungma@eit.uni-kl.de * modification, are permitted provided that the following conditions are
1912027Sjungma@eit.uni-kl.de * met: redistributions of source code must retain the above copyright
2012027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer;
2112027Sjungma@eit.uni-kl.de * redistributions in binary form must reproduce the above copyright
2212027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer in the
2312027Sjungma@eit.uni-kl.de * documentation and/or other materials provided with the distribution;
2412027Sjungma@eit.uni-kl.de * neither the name of the copyright holders nor the names of its
2512027Sjungma@eit.uni-kl.de * contributors may be used to endorse or promote products derived from
2612027Sjungma@eit.uni-kl.de * this software without specific prior written permission.
2712027Sjungma@eit.uni-kl.de *
2812027Sjungma@eit.uni-kl.de * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2912027Sjungma@eit.uni-kl.de * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3012027Sjungma@eit.uni-kl.de * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3112027Sjungma@eit.uni-kl.de * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3212027Sjungma@eit.uni-kl.de * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3312027Sjungma@eit.uni-kl.de * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3412027Sjungma@eit.uni-kl.de * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3512027Sjungma@eit.uni-kl.de * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3612027Sjungma@eit.uni-kl.de * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3712027Sjungma@eit.uni-kl.de * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3812027Sjungma@eit.uni-kl.de * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3912027Sjungma@eit.uni-kl.de *
4012027Sjungma@eit.uni-kl.de * Authors: Steve Reinhardt
4112027Sjungma@eit.uni-kl.de */
4212027Sjungma@eit.uni-kl.de
4312027Sjungma@eit.uni-kl.de#include "arch/faults.hh"
4412027Sjungma@eit.uni-kl.de#include "arch/utility.hh"
4512027Sjungma@eit.uni-kl.de#include "base/cp_annotate.hh"
4612027Sjungma@eit.uni-kl.de#include "base/cprintf.hh"
4712027Sjungma@eit.uni-kl.de#include "base/inifile.hh"
4812027Sjungma@eit.uni-kl.de#include "base/loader/symtab.hh"
4912027Sjungma@eit.uni-kl.de#include "base/misc.hh"
5012027Sjungma@eit.uni-kl.de#include "base/pollevent.hh"
5112027Sjungma@eit.uni-kl.de#include "base/range.hh"
5212027Sjungma@eit.uni-kl.de#include "base/trace.hh"
5312027Sjungma@eit.uni-kl.de#include "base/types.hh"
5412027Sjungma@eit.uni-kl.de#include "config/the_isa.hh"
5512027Sjungma@eit.uni-kl.de#include "cpu/base.hh"
5612027Sjungma@eit.uni-kl.de#include "cpu/exetrace.hh"
5712027Sjungma@eit.uni-kl.de#include "cpu/profile.hh"
5812027Sjungma@eit.uni-kl.de#include "cpu/simple/base.hh"
5912027Sjungma@eit.uni-kl.de#include "cpu/simple_thread.hh"
6012027Sjungma@eit.uni-kl.de#include "cpu/smt.hh"
6112027Sjungma@eit.uni-kl.de#include "cpu/static_inst.hh"
6212027Sjungma@eit.uni-kl.de#include "cpu/thread_context.hh"
6312027Sjungma@eit.uni-kl.de#include "mem/packet.hh"
6412027Sjungma@eit.uni-kl.de#include "mem/request.hh"
6512027Sjungma@eit.uni-kl.de#include "params/BaseSimpleCPU.hh"
6612027Sjungma@eit.uni-kl.de#include "sim/byteswap.hh"
6712027Sjungma@eit.uni-kl.de#include "sim/debug.hh"
6812027Sjungma@eit.uni-kl.de#include "sim/sim_events.hh"
6912027Sjungma@eit.uni-kl.de#include "sim/sim_object.hh"
7012027Sjungma@eit.uni-kl.de#include "sim/stats.hh"
7112027Sjungma@eit.uni-kl.de#include "sim/system.hh"
7212027Sjungma@eit.uni-kl.de
7312027Sjungma@eit.uni-kl.de#if FULL_SYSTEM
7412027Sjungma@eit.uni-kl.de#include "arch/kernel_stats.hh"
7512027Sjungma@eit.uni-kl.de#include "arch/stacktrace.hh"
7612027Sjungma@eit.uni-kl.de#include "arch/tlb.hh"
7712027Sjungma@eit.uni-kl.de#include "arch/vtophys.hh"
7812027Sjungma@eit.uni-kl.de#else // !FULL_SYSTEM
7912027Sjungma@eit.uni-kl.de#include "mem/mem_object.hh"
8012027Sjungma@eit.uni-kl.de#endif // FULL_SYSTEM
8112027Sjungma@eit.uni-kl.de
8212027Sjungma@eit.uni-kl.deusing namespace std;
8312027Sjungma@eit.uni-kl.deusing namespace TheISA;
8412027Sjungma@eit.uni-kl.de
8512027Sjungma@eit.uni-kl.deBaseSimpleCPU::BaseSimpleCPU(BaseSimpleCPUParams *p)
8612027Sjungma@eit.uni-kl.de    : BaseCPU(p), traceData(NULL), thread(NULL), predecoder(NULL)
8712027Sjungma@eit.uni-kl.de{
8812027Sjungma@eit.uni-kl.de#if FULL_SYSTEM
8912027Sjungma@eit.uni-kl.de    thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
9012027Sjungma@eit.uni-kl.de#else
9112027Sjungma@eit.uni-kl.de    thread = new SimpleThread(this, /* thread_num */ 0, p->workload[0],
9212027Sjungma@eit.uni-kl.de            p->itb, p->dtb);
9312027Sjungma@eit.uni-kl.de#endif // !FULL_SYSTEM
9412027Sjungma@eit.uni-kl.de
9512027Sjungma@eit.uni-kl.de    thread->setStatus(ThreadContext::Halted);
9612027Sjungma@eit.uni-kl.de
9712027Sjungma@eit.uni-kl.de    tc = thread->getTC();
9812027Sjungma@eit.uni-kl.de
9912027Sjungma@eit.uni-kl.de    numInst = 0;
10012027Sjungma@eit.uni-kl.de    startNumInst = 0;
10112027Sjungma@eit.uni-kl.de    numLoad = 0;
10212027Sjungma@eit.uni-kl.de    startNumLoad = 0;
10312027Sjungma@eit.uni-kl.de    lastIcacheStall = 0;
10412027Sjungma@eit.uni-kl.de    lastDcacheStall = 0;
10512027Sjungma@eit.uni-kl.de
10612027Sjungma@eit.uni-kl.de    threadContexts.push_back(tc);
10712027Sjungma@eit.uni-kl.de
10812027Sjungma@eit.uni-kl.de
10912027Sjungma@eit.uni-kl.de    fetchOffset = 0;
11012027Sjungma@eit.uni-kl.de    stayAtPC = false;
11112027Sjungma@eit.uni-kl.de}
11212027Sjungma@eit.uni-kl.de
11312027Sjungma@eit.uni-kl.deBaseSimpleCPU::~BaseSimpleCPU()
11412027Sjungma@eit.uni-kl.de{
11512027Sjungma@eit.uni-kl.de}
11612027Sjungma@eit.uni-kl.de
11712027Sjungma@eit.uni-kl.devoid
11812027Sjungma@eit.uni-kl.deBaseSimpleCPU::deallocateContext(int thread_num)
11912027Sjungma@eit.uni-kl.de{
12012027Sjungma@eit.uni-kl.de    // for now, these are equivalent
12112027Sjungma@eit.uni-kl.de    suspendContext(thread_num);
12212027Sjungma@eit.uni-kl.de}
12312027Sjungma@eit.uni-kl.de
12412027Sjungma@eit.uni-kl.de
12512027Sjungma@eit.uni-kl.devoid
12612027Sjungma@eit.uni-kl.deBaseSimpleCPU::haltContext(int thread_num)
12712027Sjungma@eit.uni-kl.de{
12812027Sjungma@eit.uni-kl.de    // for now, these are equivalent
12912027Sjungma@eit.uni-kl.de    suspendContext(thread_num);
13012027Sjungma@eit.uni-kl.de}
13112027Sjungma@eit.uni-kl.de
13212027Sjungma@eit.uni-kl.de
13312027Sjungma@eit.uni-kl.devoid
13412027Sjungma@eit.uni-kl.deBaseSimpleCPU::regStats()
13512027Sjungma@eit.uni-kl.de{
13612027Sjungma@eit.uni-kl.de    using namespace Stats;
13712027Sjungma@eit.uni-kl.de
13812027Sjungma@eit.uni-kl.de    BaseCPU::regStats();
13912027Sjungma@eit.uni-kl.de
14012027Sjungma@eit.uni-kl.de    numInsts
14112027Sjungma@eit.uni-kl.de        .name(name() + ".num_insts")
14212027Sjungma@eit.uni-kl.de        .desc("Number of instructions executed")
14312027Sjungma@eit.uni-kl.de        ;
14412027Sjungma@eit.uni-kl.de
14512027Sjungma@eit.uni-kl.de    numMemRefs
14612027Sjungma@eit.uni-kl.de        .name(name() + ".num_refs")
14712027Sjungma@eit.uni-kl.de        .desc("Number of memory references")
14812027Sjungma@eit.uni-kl.de        ;
14912027Sjungma@eit.uni-kl.de
15012027Sjungma@eit.uni-kl.de    notIdleFraction
15112027Sjungma@eit.uni-kl.de        .name(name() + ".not_idle_fraction")
15212027Sjungma@eit.uni-kl.de        .desc("Percentage of non-idle cycles")
15312027Sjungma@eit.uni-kl.de        ;
15412027Sjungma@eit.uni-kl.de
15512027Sjungma@eit.uni-kl.de    idleFraction
15612027Sjungma@eit.uni-kl.de        .name(name() + ".idle_fraction")
15712027Sjungma@eit.uni-kl.de        .desc("Percentage of idle cycles")
15812027Sjungma@eit.uni-kl.de        ;
15912027Sjungma@eit.uni-kl.de
16012027Sjungma@eit.uni-kl.de    icacheStallCycles
16112027Sjungma@eit.uni-kl.de        .name(name() + ".icache_stall_cycles")
16212027Sjungma@eit.uni-kl.de        .desc("ICache total stall cycles")
16312027Sjungma@eit.uni-kl.de        .prereq(icacheStallCycles)
16412027Sjungma@eit.uni-kl.de        ;
16512027Sjungma@eit.uni-kl.de
16612027Sjungma@eit.uni-kl.de    dcacheStallCycles
16712027Sjungma@eit.uni-kl.de        .name(name() + ".dcache_stall_cycles")
16812027Sjungma@eit.uni-kl.de        .desc("DCache total stall cycles")
16912027Sjungma@eit.uni-kl.de        .prereq(dcacheStallCycles)
17012027Sjungma@eit.uni-kl.de        ;
17112027Sjungma@eit.uni-kl.de
17212027Sjungma@eit.uni-kl.de    icacheRetryCycles
17312027Sjungma@eit.uni-kl.de        .name(name() + ".icache_retry_cycles")
17412027Sjungma@eit.uni-kl.de        .desc("ICache total retry cycles")
17512027Sjungma@eit.uni-kl.de        .prereq(icacheRetryCycles)
17612027Sjungma@eit.uni-kl.de        ;
17712027Sjungma@eit.uni-kl.de
17812027Sjungma@eit.uni-kl.de    dcacheRetryCycles
17912027Sjungma@eit.uni-kl.de        .name(name() + ".dcache_retry_cycles")
18012027Sjungma@eit.uni-kl.de        .desc("DCache total retry cycles")
18112027Sjungma@eit.uni-kl.de        .prereq(dcacheRetryCycles)
18212027Sjungma@eit.uni-kl.de        ;
18312027Sjungma@eit.uni-kl.de
18412027Sjungma@eit.uni-kl.de    idleFraction = constant(1.0) - notIdleFraction;
18512027Sjungma@eit.uni-kl.de}
18612027Sjungma@eit.uni-kl.de
18712027Sjungma@eit.uni-kl.devoid
18812027Sjungma@eit.uni-kl.deBaseSimpleCPU::resetStats()
18912027Sjungma@eit.uni-kl.de{
19012027Sjungma@eit.uni-kl.de//    startNumInst = numInst;
19112027Sjungma@eit.uni-kl.de     notIdleFraction = (_status != Idle);
19212027Sjungma@eit.uni-kl.de}
19312027Sjungma@eit.uni-kl.de
19412027Sjungma@eit.uni-kl.devoid
19512027Sjungma@eit.uni-kl.deBaseSimpleCPU::serialize(ostream &os)
19612027Sjungma@eit.uni-kl.de{
19712027Sjungma@eit.uni-kl.de    SERIALIZE_ENUM(_status);
19812027Sjungma@eit.uni-kl.de    BaseCPU::serialize(os);
19912027Sjungma@eit.uni-kl.de//    SERIALIZE_SCALAR(inst);
20012027Sjungma@eit.uni-kl.de    nameOut(os, csprintf("%s.xc.0", name()));
20112027Sjungma@eit.uni-kl.de    thread->serialize(os);
20212027Sjungma@eit.uni-kl.de}
20312027Sjungma@eit.uni-kl.de
20412027Sjungma@eit.uni-kl.devoid
20512027Sjungma@eit.uni-kl.deBaseSimpleCPU::unserialize(Checkpoint *cp, const string &section)
20612027Sjungma@eit.uni-kl.de{
20712027Sjungma@eit.uni-kl.de    UNSERIALIZE_ENUM(_status);
20812027Sjungma@eit.uni-kl.de    BaseCPU::unserialize(cp, section);
20912027Sjungma@eit.uni-kl.de//    UNSERIALIZE_SCALAR(inst);
21012027Sjungma@eit.uni-kl.de    thread->unserialize(cp, csprintf("%s.xc.0", section));
21112027Sjungma@eit.uni-kl.de}
21212027Sjungma@eit.uni-kl.de
21312027Sjungma@eit.uni-kl.devoid
21412027Sjungma@eit.uni-kl.dechange_thread_state(ThreadID tid, int activate, int priority)
21512027Sjungma@eit.uni-kl.de{
21612027Sjungma@eit.uni-kl.de}
21712027Sjungma@eit.uni-kl.de
21812027Sjungma@eit.uni-kl.devoid
21912027Sjungma@eit.uni-kl.deBaseSimpleCPU::prefetch(Addr addr, unsigned flags)
22012027Sjungma@eit.uni-kl.de{
22112027Sjungma@eit.uni-kl.de    if (traceData) {
22212027Sjungma@eit.uni-kl.de        traceData->setAddr(addr);
22312027Sjungma@eit.uni-kl.de    }
22412027Sjungma@eit.uni-kl.de
22512027Sjungma@eit.uni-kl.de    // need to do this...
22612027Sjungma@eit.uni-kl.de}
22712027Sjungma@eit.uni-kl.de
22812027Sjungma@eit.uni-kl.devoid
22912027Sjungma@eit.uni-kl.deBaseSimpleCPU::writeHint(Addr addr, int size, unsigned flags)
23012027Sjungma@eit.uni-kl.de{
23112027Sjungma@eit.uni-kl.de    if (traceData) {
23212027Sjungma@eit.uni-kl.de        traceData->setAddr(addr);
23312027Sjungma@eit.uni-kl.de    }
23412027Sjungma@eit.uni-kl.de
23512027Sjungma@eit.uni-kl.de    // need to do this...
23612027Sjungma@eit.uni-kl.de}
23712027Sjungma@eit.uni-kl.de
23812027Sjungma@eit.uni-kl.de
23912027Sjungma@eit.uni-kl.deFault
24012027Sjungma@eit.uni-kl.deBaseSimpleCPU::copySrcTranslate(Addr src)
24112027Sjungma@eit.uni-kl.de{
24212027Sjungma@eit.uni-kl.de#if 0
24312027Sjungma@eit.uni-kl.de    static bool no_warn = true;
24412027Sjungma@eit.uni-kl.de    unsigned blk_size =
24512027Sjungma@eit.uni-kl.de        (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
24612027Sjungma@eit.uni-kl.de    // Only support block sizes of 64 atm.
24712027Sjungma@eit.uni-kl.de    assert(blk_size == 64);
24812027Sjungma@eit.uni-kl.de    int offset = src & (blk_size - 1);
24912027Sjungma@eit.uni-kl.de
25012027Sjungma@eit.uni-kl.de    // Make sure block doesn't span page
25112027Sjungma@eit.uni-kl.de    if (no_warn &&
25212027Sjungma@eit.uni-kl.de        (src & PageMask) != ((src + blk_size) & PageMask) &&
25312027Sjungma@eit.uni-kl.de        (src >> 40) != 0xfffffc) {
25412027Sjungma@eit.uni-kl.de        warn("Copied block source spans pages %x.", src);
25512027Sjungma@eit.uni-kl.de        no_warn = false;
25612027Sjungma@eit.uni-kl.de    }
25712027Sjungma@eit.uni-kl.de
25812027Sjungma@eit.uni-kl.de    memReq->reset(src & ~(blk_size - 1), blk_size);
25912027Sjungma@eit.uni-kl.de
26012027Sjungma@eit.uni-kl.de    // translate to physical address
26112027Sjungma@eit.uni-kl.de    Fault fault = thread->translateDataReadReq(req);
26212027Sjungma@eit.uni-kl.de
26312027Sjungma@eit.uni-kl.de    if (fault == NoFault) {
26412027Sjungma@eit.uni-kl.de        thread->copySrcAddr = src;
26512027Sjungma@eit.uni-kl.de        thread->copySrcPhysAddr = memReq->paddr + offset;
26612027Sjungma@eit.uni-kl.de    } else {
26712027Sjungma@eit.uni-kl.de        assert(!fault->isAlignmentFault());
26812027Sjungma@eit.uni-kl.de
26912027Sjungma@eit.uni-kl.de        thread->copySrcAddr = 0;
27012027Sjungma@eit.uni-kl.de        thread->copySrcPhysAddr = 0;
27112027Sjungma@eit.uni-kl.de    }
27212027Sjungma@eit.uni-kl.de    return fault;
27312027Sjungma@eit.uni-kl.de#else
27412027Sjungma@eit.uni-kl.de    return NoFault;
27512027Sjungma@eit.uni-kl.de#endif
27612027Sjungma@eit.uni-kl.de}
27712027Sjungma@eit.uni-kl.de
27812027Sjungma@eit.uni-kl.deFault
27912027Sjungma@eit.uni-kl.deBaseSimpleCPU::copy(Addr dest)
28012027Sjungma@eit.uni-kl.de{
28112027Sjungma@eit.uni-kl.de#if 0
28212027Sjungma@eit.uni-kl.de    static bool no_warn = true;
28312027Sjungma@eit.uni-kl.de    unsigned blk_size =
28412027Sjungma@eit.uni-kl.de        (dcacheInterface) ? dcacheInterface->getBlockSize() : 64;
28512027Sjungma@eit.uni-kl.de    // Only support block sizes of 64 atm.
28612027Sjungma@eit.uni-kl.de    assert(blk_size == 64);
28712027Sjungma@eit.uni-kl.de    uint8_t data[blk_size];
28812027Sjungma@eit.uni-kl.de    //assert(thread->copySrcAddr);
28912027Sjungma@eit.uni-kl.de    int offset = dest & (blk_size - 1);
29012027Sjungma@eit.uni-kl.de
29112027Sjungma@eit.uni-kl.de    // Make sure block doesn't span page
29212027Sjungma@eit.uni-kl.de    if (no_warn &&
29312027Sjungma@eit.uni-kl.de        (dest & PageMask) != ((dest + blk_size) & PageMask) &&
29412027Sjungma@eit.uni-kl.de        (dest >> 40) != 0xfffffc) {
29512027Sjungma@eit.uni-kl.de        no_warn = false;
29612027Sjungma@eit.uni-kl.de        warn("Copied block destination spans pages %x. ", dest);
29712027Sjungma@eit.uni-kl.de    }
29812027Sjungma@eit.uni-kl.de
29912027Sjungma@eit.uni-kl.de    memReq->reset(dest & ~(blk_size -1), blk_size);
30012027Sjungma@eit.uni-kl.de    // translate to physical address
30112027Sjungma@eit.uni-kl.de    Fault fault = thread->translateDataWriteReq(req);
30212027Sjungma@eit.uni-kl.de
30312027Sjungma@eit.uni-kl.de    if (fault == NoFault) {
30412027Sjungma@eit.uni-kl.de        Addr dest_addr = memReq->paddr + offset;
30512027Sjungma@eit.uni-kl.de        // Need to read straight from memory since we have more than 8 bytes.
30612027Sjungma@eit.uni-kl.de        memReq->paddr = thread->copySrcPhysAddr;
30712027Sjungma@eit.uni-kl.de        thread->mem->read(memReq, data);
30812027Sjungma@eit.uni-kl.de        memReq->paddr = dest_addr;
30912027Sjungma@eit.uni-kl.de        thread->mem->write(memReq, data);
31012027Sjungma@eit.uni-kl.de        if (dcacheInterface) {
31112027Sjungma@eit.uni-kl.de            memReq->cmd = Copy;
31212027Sjungma@eit.uni-kl.de            memReq->completionEvent = NULL;
31312027Sjungma@eit.uni-kl.de            memReq->paddr = thread->copySrcPhysAddr;
31412027Sjungma@eit.uni-kl.de            memReq->dest = dest_addr;
31512027Sjungma@eit.uni-kl.de            memReq->size = 64;
31612027Sjungma@eit.uni-kl.de            memReq->time = curTick;
31712027Sjungma@eit.uni-kl.de            dcacheInterface->access(memReq);
31812027Sjungma@eit.uni-kl.de        }
31912027Sjungma@eit.uni-kl.de    }
32012027Sjungma@eit.uni-kl.de    else
32112027Sjungma@eit.uni-kl.de        assert(!fault->isAlignmentFault());
32212027Sjungma@eit.uni-kl.de
32312027Sjungma@eit.uni-kl.de    return fault;
32412027Sjungma@eit.uni-kl.de#else
32512027Sjungma@eit.uni-kl.de    panic("copy not implemented");
32612027Sjungma@eit.uni-kl.de    return NoFault;
32712027Sjungma@eit.uni-kl.de#endif
32812027Sjungma@eit.uni-kl.de}
32912027Sjungma@eit.uni-kl.de
33012027Sjungma@eit.uni-kl.de#if FULL_SYSTEM
33112027Sjungma@eit.uni-kl.deAddr
33212027Sjungma@eit.uni-kl.deBaseSimpleCPU::dbg_vtophys(Addr addr)
33312027Sjungma@eit.uni-kl.de{
33412027Sjungma@eit.uni-kl.de    return vtophys(tc, addr);
33512027Sjungma@eit.uni-kl.de}
33612027Sjungma@eit.uni-kl.de#endif // FULL_SYSTEM
33712027Sjungma@eit.uni-kl.de
33812027Sjungma@eit.uni-kl.de#if FULL_SYSTEM
33912027Sjungma@eit.uni-kl.devoid
34012027Sjungma@eit.uni-kl.deBaseSimpleCPU::wakeup()
34112027Sjungma@eit.uni-kl.de{
34212027Sjungma@eit.uni-kl.de    if (thread->status() != ThreadContext::Suspended)
34312027Sjungma@eit.uni-kl.de        return;
34412027Sjungma@eit.uni-kl.de
34512027Sjungma@eit.uni-kl.de    DPRINTF(Quiesce,"Suspended Processor awoke\n");
34612027Sjungma@eit.uni-kl.de    thread->activate();
34712027Sjungma@eit.uni-kl.de}
34812027Sjungma@eit.uni-kl.de#endif // FULL_SYSTEM
34912027Sjungma@eit.uni-kl.de
35012027Sjungma@eit.uni-kl.devoid
35112027Sjungma@eit.uni-kl.deBaseSimpleCPU::checkForInterrupts()
35212027Sjungma@eit.uni-kl.de{
35312027Sjungma@eit.uni-kl.de#if FULL_SYSTEM
35412027Sjungma@eit.uni-kl.de    if (checkInterrupts(tc)) {
35512027Sjungma@eit.uni-kl.de        Fault interrupt = interrupts->getInterrupt(tc);
35612027Sjungma@eit.uni-kl.de
35712027Sjungma@eit.uni-kl.de        if (interrupt != NoFault) {
35812027Sjungma@eit.uni-kl.de            fetchOffset = 0;
35912027Sjungma@eit.uni-kl.de            interrupts->updateIntrInfo(tc);
36012027Sjungma@eit.uni-kl.de            interrupt->invoke(tc);
36112027Sjungma@eit.uni-kl.de            predecoder.reset();
36212027Sjungma@eit.uni-kl.de        }
36312027Sjungma@eit.uni-kl.de    }
36412027Sjungma@eit.uni-kl.de#endif
36512027Sjungma@eit.uni-kl.de}
36612027Sjungma@eit.uni-kl.de
36712027Sjungma@eit.uni-kl.de
36812027Sjungma@eit.uni-kl.devoid
36912027Sjungma@eit.uni-kl.deBaseSimpleCPU::setupFetchRequest(Request *req)
37012027Sjungma@eit.uni-kl.de{
37112027Sjungma@eit.uni-kl.de    Addr threadPC = thread->readPC();
37212027Sjungma@eit.uni-kl.de
37312027Sjungma@eit.uni-kl.de    // set up memory request for instruction fetch
37412027Sjungma@eit.uni-kl.de#if ISA_HAS_DELAY_SLOT
37512027Sjungma@eit.uni-kl.de    DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",threadPC,
37612027Sjungma@eit.uni-kl.de            thread->readNextPC(),thread->readNextNPC());
37712027Sjungma@eit.uni-kl.de#else
37812027Sjungma@eit.uni-kl.de    DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p\n",threadPC,
37912027Sjungma@eit.uni-kl.de            thread->readNextPC());
38012027Sjungma@eit.uni-kl.de#endif
38112027Sjungma@eit.uni-kl.de
38212027Sjungma@eit.uni-kl.de    Addr fetchPC = (threadPC & PCMask) + fetchOffset;
38312027Sjungma@eit.uni-kl.de    req->setVirt(0, fetchPC, sizeof(MachInst), Request::INST_FETCH, threadPC);
38412027Sjungma@eit.uni-kl.de}
38512027Sjungma@eit.uni-kl.de
38612027Sjungma@eit.uni-kl.de
38712027Sjungma@eit.uni-kl.devoid
38812027Sjungma@eit.uni-kl.deBaseSimpleCPU::preExecute()
38912027Sjungma@eit.uni-kl.de{
39012027Sjungma@eit.uni-kl.de    // maintain $r0 semantics
39112027Sjungma@eit.uni-kl.de    thread->setIntReg(ZeroReg, 0);
39212027Sjungma@eit.uni-kl.de#if THE_ISA == ALPHA_ISA
39312027Sjungma@eit.uni-kl.de    thread->setFloatReg(ZeroReg, 0.0);
39412027Sjungma@eit.uni-kl.de#endif // ALPHA_ISA
39512027Sjungma@eit.uni-kl.de
39612027Sjungma@eit.uni-kl.de    // check for instruction-count-based events
39712027Sjungma@eit.uni-kl.de    comInstEventQueue[0]->serviceEvents(numInst);
39812027Sjungma@eit.uni-kl.de
39912027Sjungma@eit.uni-kl.de    // decode the instruction
40012027Sjungma@eit.uni-kl.de    inst = gtoh(inst);
40112027Sjungma@eit.uni-kl.de
40212027Sjungma@eit.uni-kl.de    MicroPC upc = thread->readMicroPC();
40312027Sjungma@eit.uni-kl.de
40412027Sjungma@eit.uni-kl.de    if (isRomMicroPC(upc)) {
40512027Sjungma@eit.uni-kl.de        stayAtPC = false;
40612027Sjungma@eit.uni-kl.de        curStaticInst = microcodeRom.fetchMicroop(upc, curMacroStaticInst);
40712027Sjungma@eit.uni-kl.de    } else if (!curMacroStaticInst) {
40812027Sjungma@eit.uni-kl.de        //We're not in the middle of a macro instruction
40912027Sjungma@eit.uni-kl.de        StaticInstPtr instPtr = NULL;
41012027Sjungma@eit.uni-kl.de
41112027Sjungma@eit.uni-kl.de        //Predecode, ie bundle up an ExtMachInst
41212027Sjungma@eit.uni-kl.de        //This should go away once the constructor can be set up properly
41312027Sjungma@eit.uni-kl.de        predecoder.setTC(thread->getTC());
41412027Sjungma@eit.uni-kl.de        //If more fetch data is needed, pass it in.
41512027Sjungma@eit.uni-kl.de        Addr fetchPC = (thread->readPC() & PCMask) + fetchOffset;
41612027Sjungma@eit.uni-kl.de        //if(predecoder.needMoreBytes())
41712027Sjungma@eit.uni-kl.de            predecoder.moreBytes(thread->readPC(), fetchPC, inst);
41812027Sjungma@eit.uni-kl.de        //else
41912027Sjungma@eit.uni-kl.de        //    predecoder.process();
42012027Sjungma@eit.uni-kl.de
42112027Sjungma@eit.uni-kl.de        //If an instruction is ready, decode it. Otherwise, we'll have to
42212027Sjungma@eit.uni-kl.de        //fetch beyond the MachInst at the current pc.
42312027Sjungma@eit.uni-kl.de        if (predecoder.extMachInstReady()) {
42412027Sjungma@eit.uni-kl.de#if THE_ISA == X86_ISA || THE_ISA == ARM_ISA
42512027Sjungma@eit.uni-kl.de            thread->setNextPC(thread->readPC() + predecoder.getInstSize());
42612027Sjungma@eit.uni-kl.de#endif // X86_ISA
42712027Sjungma@eit.uni-kl.de            stayAtPC = false;
42812027Sjungma@eit.uni-kl.de            instPtr = StaticInst::decode(predecoder.getExtMachInst(),
42912027Sjungma@eit.uni-kl.de                                         thread->readPC());
43012027Sjungma@eit.uni-kl.de        } else {
43112027Sjungma@eit.uni-kl.de            stayAtPC = true;
43212027Sjungma@eit.uni-kl.de            fetchOffset += sizeof(MachInst);
43312027Sjungma@eit.uni-kl.de        }
43412027Sjungma@eit.uni-kl.de
43512027Sjungma@eit.uni-kl.de        //If we decoded an instruction and it's microcoded, start pulling
43612027Sjungma@eit.uni-kl.de        //out micro ops
43712027Sjungma@eit.uni-kl.de        if (instPtr && instPtr->isMacroop()) {
43812027Sjungma@eit.uni-kl.de            curMacroStaticInst = instPtr;
43912027Sjungma@eit.uni-kl.de            curStaticInst = curMacroStaticInst->fetchMicroop(upc);
44012027Sjungma@eit.uni-kl.de        } else {
44112027Sjungma@eit.uni-kl.de            curStaticInst = instPtr;
44212027Sjungma@eit.uni-kl.de        }
44312027Sjungma@eit.uni-kl.de    } else {
44412027Sjungma@eit.uni-kl.de        //Read the next micro op from the macro op
44512027Sjungma@eit.uni-kl.de        curStaticInst = curMacroStaticInst->fetchMicroop(upc);
44612027Sjungma@eit.uni-kl.de    }
44712027Sjungma@eit.uni-kl.de
44812027Sjungma@eit.uni-kl.de    //If we decoded an instruction this "tick", record information about it.
44912027Sjungma@eit.uni-kl.de    if(curStaticInst)
45012027Sjungma@eit.uni-kl.de    {
45112027Sjungma@eit.uni-kl.de#if TRACING_ON
45212027Sjungma@eit.uni-kl.de        traceData = tracer->getInstRecord(curTick, tc,
45312027Sjungma@eit.uni-kl.de                curStaticInst, thread->readPC(),
45412027Sjungma@eit.uni-kl.de                curMacroStaticInst, thread->readMicroPC());
45512027Sjungma@eit.uni-kl.de
45612027Sjungma@eit.uni-kl.de        DPRINTF(Decode,"Decode: Decoded %s instruction: 0x%x\n",
45712027Sjungma@eit.uni-kl.de                curStaticInst->getName(), curStaticInst->machInst);
45812027Sjungma@eit.uni-kl.de#endif // TRACING_ON
45912027Sjungma@eit.uni-kl.de
46012027Sjungma@eit.uni-kl.de#if FULL_SYSTEM
46112027Sjungma@eit.uni-kl.de        thread->setInst(inst);
46212027Sjungma@eit.uni-kl.de#endif // FULL_SYSTEM
46312027Sjungma@eit.uni-kl.de    }
46412027Sjungma@eit.uni-kl.de}
46512027Sjungma@eit.uni-kl.de
46612027Sjungma@eit.uni-kl.devoid
46712027Sjungma@eit.uni-kl.deBaseSimpleCPU::postExecute()
46812027Sjungma@eit.uni-kl.de{
46912027Sjungma@eit.uni-kl.de#if FULL_SYSTEM
47012027Sjungma@eit.uni-kl.de    if (thread->profile && curStaticInst) {
47112027Sjungma@eit.uni-kl.de        bool usermode = TheISA::inUserMode(tc);
47212027Sjungma@eit.uni-kl.de        thread->profilePC = usermode ? 1 : thread->readPC();
47312027Sjungma@eit.uni-kl.de        ProfileNode *node = thread->profile->consume(tc, curStaticInst);
47412027Sjungma@eit.uni-kl.de        if (node)
47512027Sjungma@eit.uni-kl.de            thread->profileNode = node;
47612027Sjungma@eit.uni-kl.de    }
47712027Sjungma@eit.uni-kl.de#endif
47812027Sjungma@eit.uni-kl.de
47912027Sjungma@eit.uni-kl.de    if (curStaticInst->isMemRef()) {
48012027Sjungma@eit.uni-kl.de        numMemRefs++;
48112027Sjungma@eit.uni-kl.de    }
48212027Sjungma@eit.uni-kl.de
48312027Sjungma@eit.uni-kl.de    if (curStaticInst->isLoad()) {
48412027Sjungma@eit.uni-kl.de        ++numLoad;
48512027Sjungma@eit.uni-kl.de        comLoadEventQueue[0]->serviceEvents(numLoad);
48612027Sjungma@eit.uni-kl.de    }
48712027Sjungma@eit.uni-kl.de
48812027Sjungma@eit.uni-kl.de    if (CPA::available()) {
48912027Sjungma@eit.uni-kl.de        CPA::cpa()->swAutoBegin(tc, thread->readNextPC());
49012027Sjungma@eit.uni-kl.de    }
49112027Sjungma@eit.uni-kl.de
49212027Sjungma@eit.uni-kl.de    traceFunctions(thread->readPC());
49312027Sjungma@eit.uni-kl.de
49412027Sjungma@eit.uni-kl.de    if (traceData) {
49512027Sjungma@eit.uni-kl.de        traceData->dump();
49612027Sjungma@eit.uni-kl.de        delete traceData;
49712027Sjungma@eit.uni-kl.de        traceData = NULL;
49812027Sjungma@eit.uni-kl.de    }
49912027Sjungma@eit.uni-kl.de}
50012027Sjungma@eit.uni-kl.de
50112027Sjungma@eit.uni-kl.de
50212027Sjungma@eit.uni-kl.devoid
50312027Sjungma@eit.uni-kl.deBaseSimpleCPU::advancePC(Fault fault)
50412027Sjungma@eit.uni-kl.de{
50512027Sjungma@eit.uni-kl.de    //Since we're moving to a new pc, zero out the offset
50612027Sjungma@eit.uni-kl.de    fetchOffset = 0;
50712027Sjungma@eit.uni-kl.de    if (fault != NoFault) {
50812027Sjungma@eit.uni-kl.de        curMacroStaticInst = StaticInst::nullStaticInstPtr;
50912027Sjungma@eit.uni-kl.de        fault->invoke(tc, curStaticInst);
51012027Sjungma@eit.uni-kl.de        predecoder.reset();
51112027Sjungma@eit.uni-kl.de    } else {
51212027Sjungma@eit.uni-kl.de        //If we're at the last micro op for this instruction
51312027Sjungma@eit.uni-kl.de        if (curStaticInst && curStaticInst->isLastMicroop()) {
51412027Sjungma@eit.uni-kl.de            //We should be working with a macro op or be in the ROM
51512027Sjungma@eit.uni-kl.de            assert(curMacroStaticInst ||
51612027Sjungma@eit.uni-kl.de                    isRomMicroPC(thread->readMicroPC()));
51712027Sjungma@eit.uni-kl.de            //Close out this macro op, and clean up the
51812027Sjungma@eit.uni-kl.de            //microcode state
51912027Sjungma@eit.uni-kl.de            curMacroStaticInst = StaticInst::nullStaticInstPtr;
52012027Sjungma@eit.uni-kl.de            thread->setMicroPC(normalMicroPC(0));
52112027Sjungma@eit.uni-kl.de            thread->setNextMicroPC(normalMicroPC(1));
52212027Sjungma@eit.uni-kl.de        }
52312027Sjungma@eit.uni-kl.de        //If we're still in a macro op
52412027Sjungma@eit.uni-kl.de        if (curMacroStaticInst || isRomMicroPC(thread->readMicroPC())) {
52512027Sjungma@eit.uni-kl.de            //Advance the micro pc
52612027Sjungma@eit.uni-kl.de            thread->setMicroPC(thread->readNextMicroPC());
52712027Sjungma@eit.uni-kl.de            //Advance the "next" micro pc. Note that there are no delay
52812027Sjungma@eit.uni-kl.de            //slots, and micro ops are "word" addressed.
52912027Sjungma@eit.uni-kl.de            thread->setNextMicroPC(thread->readNextMicroPC() + 1);
53012027Sjungma@eit.uni-kl.de        } else {
53112027Sjungma@eit.uni-kl.de            // go to the next instruction
53212027Sjungma@eit.uni-kl.de            thread->setPC(thread->readNextPC());
53312027Sjungma@eit.uni-kl.de            thread->setNextPC(thread->readNextNPC());
53412027Sjungma@eit.uni-kl.de            thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
53512027Sjungma@eit.uni-kl.de            assert(thread->readNextPC() != thread->readNextNPC());
53612027Sjungma@eit.uni-kl.de        }
53712027Sjungma@eit.uni-kl.de    }
53812027Sjungma@eit.uni-kl.de}
53912027Sjungma@eit.uni-kl.de
54012027Sjungma@eit.uni-kl.de/*Fault
54112027Sjungma@eit.uni-kl.deBaseSimpleCPU::CacheOp(uint8_t Op, Addr EffAddr)
54212027Sjungma@eit.uni-kl.de{
54312027Sjungma@eit.uni-kl.de    // translate to physical address
54412027Sjungma@eit.uni-kl.de    Fault fault = NoFault;
54512027Sjungma@eit.uni-kl.de    int CacheID = Op & 0x3; // Lower 3 bits identify Cache
54612027Sjungma@eit.uni-kl.de    int CacheOP = Op >> 2; // Upper 3 bits identify Cache Operation
54712027Sjungma@eit.uni-kl.de    if(CacheID > 1)
54812027Sjungma@eit.uni-kl.de      {
54912027Sjungma@eit.uni-kl.de        warn("CacheOps not implemented for secondary/tertiary caches\n");
55012027Sjungma@eit.uni-kl.de      }
55112027Sjungma@eit.uni-kl.de    else
55212027Sjungma@eit.uni-kl.de      {
55312027Sjungma@eit.uni-kl.de        switch(CacheOP)
55412027Sjungma@eit.uni-kl.de          { // Fill Packet Type
55512027Sjungma@eit.uni-kl.de          case 0: warn("Invalidate Cache Op\n");
55612027Sjungma@eit.uni-kl.de            break;
55712027Sjungma@eit.uni-kl.de          case 1: warn("Index Load Tag Cache Op\n");
55812027Sjungma@eit.uni-kl.de            break;
55912027Sjungma@eit.uni-kl.de          case 2: warn("Index Store Tag Cache Op\n");
56012027Sjungma@eit.uni-kl.de            break;
56112027Sjungma@eit.uni-kl.de          case 4: warn("Hit Invalidate Cache Op\n");
56212027Sjungma@eit.uni-kl.de            break;
56312027Sjungma@eit.uni-kl.de          case 5: warn("Fill/Hit Writeback Invalidate Cache Op\n");
56412027Sjungma@eit.uni-kl.de            break;
56512027Sjungma@eit.uni-kl.de          case 6: warn("Hit Writeback\n");
56612027Sjungma@eit.uni-kl.de            break;
56712027Sjungma@eit.uni-kl.de          case 7: warn("Fetch & Lock Cache Op\n");
56812027Sjungma@eit.uni-kl.de            break;
56912027Sjungma@eit.uni-kl.de          default: warn("Unimplemented Cache Op\n");
57012027Sjungma@eit.uni-kl.de          }
57112027Sjungma@eit.uni-kl.de      }
57212027Sjungma@eit.uni-kl.de    return fault;
57312027Sjungma@eit.uni-kl.de}*/
57412027Sjungma@eit.uni-kl.de