base.cc revision 3541:d74340b852f6
112837Sgabeblack@google.com/*
212837Sgabeblack@google.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
312837Sgabeblack@google.com * All rights reserved.
412837Sgabeblack@google.com *
512837Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
612837Sgabeblack@google.com * modification, are permitted provided that the following conditions are
712837Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
812837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
912837Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1012837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1112837Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1212837Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1312837Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1412837Sgabeblack@google.com * this software without specific prior written permission.
1512837Sgabeblack@google.com *
1612837Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712837Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812837Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912837Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012837Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112837Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212837Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312837Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412837Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512837Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612837Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712837Sgabeblack@google.com *
2812837Sgabeblack@google.com * Authors: Steve Reinhardt
2912837Sgabeblack@google.com *          Nathan Binkert
3012955Sgabeblack@google.com */
3112837Sgabeblack@google.com
3213279Sgabeblack@google.com#include <iostream>
3312837Sgabeblack@google.com#include <string>
3412837Sgabeblack@google.com#include <sstream>
3512837Sgabeblack@google.com
3612837Sgabeblack@google.com#include "base/cprintf.hh"
3712955Sgabeblack@google.com#include "base/loader/symtab.hh"
3812955Sgabeblack@google.com#include "base/misc.hh"
3912955Sgabeblack@google.com#include "base/output.hh"
4012955Sgabeblack@google.com#include "cpu/base.hh"
4112955Sgabeblack@google.com#include "cpu/cpuevent.hh"
4212955Sgabeblack@google.com#include "cpu/thread_context.hh"
4312955Sgabeblack@google.com#include "cpu/profile.hh"
4412955Sgabeblack@google.com#include "sim/sim_exit.hh"
4512955Sgabeblack@google.com#include "sim/param.hh"
4612955Sgabeblack@google.com#include "sim/process.hh"
4712955Sgabeblack@google.com#include "sim/sim_events.hh"
4812955Sgabeblack@google.com#include "sim/system.hh"
4912837Sgabeblack@google.com
5012955Sgabeblack@google.com#include "base/trace.hh"
5112837Sgabeblack@google.com
5212837Sgabeblack@google.com// Hack
5312955Sgabeblack@google.com#include "sim/stat_control.hh"
5412955Sgabeblack@google.com
5512955Sgabeblack@google.comusing namespace std;
5612837Sgabeblack@google.com
5712955Sgabeblack@google.comvector<BaseCPU *> BaseCPU::cpuList;
5812837Sgabeblack@google.com
5912837Sgabeblack@google.com// This variable reflects the max number of threads in any CPU.  Be
6012955Sgabeblack@google.com// careful to only use it once all the CPUs that you care about have
6112837Sgabeblack@google.com// been initialized
6212955Sgabeblack@google.comint maxThreadsPerCPU = 1;
6312837Sgabeblack@google.com
6412837Sgabeblack@google.comCPUProgressEvent::CPUProgressEvent(EventQueue *q, Tick ival,
6512837Sgabeblack@google.com                                   BaseCPU *_cpu)
6612837Sgabeblack@google.com    : Event(q, Event::Stat_Event_Pri), interval(ival),
6712837Sgabeblack@google.com      lastNumInst(0), cpu(_cpu)
6812837Sgabeblack@google.com{
6912955Sgabeblack@google.com    if (interval)
7012837Sgabeblack@google.com        schedule(curTick + interval);
7112837Sgabeblack@google.com}
7212837Sgabeblack@google.com
7312955Sgabeblack@google.comvoid
7412837Sgabeblack@google.comCPUProgressEvent::process()
7512955Sgabeblack@google.com{
7612837Sgabeblack@google.com    Counter temp = cpu->totalInstructions();
7712837Sgabeblack@google.com#ifndef NDEBUG
7812837Sgabeblack@google.com    double ipc = double(temp - lastNumInst) / (interval / cpu->cycles(1));
7912955Sgabeblack@google.com
8012837Sgabeblack@google.com    DPRINTFN("%s progress event, instructions committed: %lli, IPC: %0.8d\n",
8112955Sgabeblack@google.com             cpu->name(), temp - lastNumInst, ipc);
8212837Sgabeblack@google.com    ipc = 0.0;
8312837Sgabeblack@google.com#else
8412837Sgabeblack@google.com    cprintf("%lli: %s progress event, instructions committed: %lli\n",
8512837Sgabeblack@google.com            curTick, cpu->name(), temp - lastNumInst);
8612955Sgabeblack@google.com#endif
8712837Sgabeblack@google.com    lastNumInst = temp;
8812955Sgabeblack@google.com    schedule(curTick + interval);
8912837Sgabeblack@google.com}
9012837Sgabeblack@google.com
9112837Sgabeblack@google.comconst char *
9212837Sgabeblack@google.comCPUProgressEvent::description()
9312955Sgabeblack@google.com{
9412837Sgabeblack@google.com    return "CPU Progress event";
9512955Sgabeblack@google.com}
9612955Sgabeblack@google.com
9712955Sgabeblack@google.com#if FULL_SYSTEM
9812955Sgabeblack@google.comBaseCPU::BaseCPU(Params *p)
9912837Sgabeblack@google.com    : MemObject(p->name), clock(p->clock), checkInterrupts(true),
10012837Sgabeblack@google.com      params(p), number_of_threads(p->numberOfThreads), system(p->system)
10112837Sgabeblack@google.com#else
10213406Sgabeblack@google.comBaseCPU::BaseCPU(Params *p)
10312837Sgabeblack@google.com    : MemObject(p->name), clock(p->clock), params(p),
10412955Sgabeblack@google.com      number_of_threads(p->numberOfThreads), system(p->system)
10512955Sgabeblack@google.com#endif
10612955Sgabeblack@google.com{
10712955Sgabeblack@google.com//    currentTick = curTick;
10812837Sgabeblack@google.com    DPRINTF(FullCPU, "BaseCPU: Creating object, mem address %#x.\n", this);
10912837Sgabeblack@google.com
11012955Sgabeblack@google.com    // add self to global list of CPUs
11112955Sgabeblack@google.com    cpuList.push_back(this);
11212837Sgabeblack@google.com
11312955Sgabeblack@google.com    DPRINTF(FullCPU, "BaseCPU: CPU added to cpuList, mem address %#x.\n",
11412837Sgabeblack@google.com            this);
11512837Sgabeblack@google.com
11612955Sgabeblack@google.com    if (number_of_threads > maxThreadsPerCPU)
11712955Sgabeblack@google.com        maxThreadsPerCPU = number_of_threads;
11812837Sgabeblack@google.com
11912955Sgabeblack@google.com    // allocate per-thread instruction-based event queues
12012837Sgabeblack@google.com    comInstEventQueue = new EventQueue *[number_of_threads];
12112837Sgabeblack@google.com    for (int i = 0; i < number_of_threads; ++i)
12212955Sgabeblack@google.com        comInstEventQueue[i] = new EventQueue("instruction-based event queue");
12312955Sgabeblack@google.com
12412955Sgabeblack@google.com    //
12512955Sgabeblack@google.com    // set up instruction-count-based termination events, if any
12612955Sgabeblack@google.com    //
12712955Sgabeblack@google.com    if (p->max_insts_any_thread != 0)
12812955Sgabeblack@google.com        for (int i = 0; i < number_of_threads; ++i)
12912955Sgabeblack@google.com            schedExitSimLoop("a thread reached the max instruction count",
13012955Sgabeblack@google.com                             p->max_insts_any_thread, 0,
13112955Sgabeblack@google.com                             comInstEventQueue[i]);
13212955Sgabeblack@google.com
13312955Sgabeblack@google.com    if (p->max_insts_all_threads != 0) {
13412837Sgabeblack@google.com        // allocate & initialize shared downcounter: each event will
13512955Sgabeblack@google.com        // decrement this when triggered; simulation will terminate
13612837Sgabeblack@google.com        // when counter reaches 0
13712837Sgabeblack@google.com        int *counter = new int;
13812955Sgabeblack@google.com        *counter = number_of_threads;
13912955Sgabeblack@google.com        for (int i = 0; i < number_of_threads; ++i)
14012955Sgabeblack@google.com            new CountedExitEvent(comInstEventQueue[i],
14112955Sgabeblack@google.com                "all threads reached the max instruction count",
14212955Sgabeblack@google.com                p->max_insts_all_threads, *counter);
14312955Sgabeblack@google.com    }
14412837Sgabeblack@google.com
14512955Sgabeblack@google.com    // allocate per-thread load-based event queues
14612837Sgabeblack@google.com    comLoadEventQueue = new EventQueue *[number_of_threads];
14712837Sgabeblack@google.com    for (int i = 0; i < number_of_threads; ++i)
14812837Sgabeblack@google.com        comLoadEventQueue[i] = new EventQueue("load-based event queue");
14912955Sgabeblack@google.com
15012837Sgabeblack@google.com    //
15112837Sgabeblack@google.com    // set up instruction-count-based termination events, if any
15212837Sgabeblack@google.com    //
15312837Sgabeblack@google.com    if (p->max_loads_any_thread != 0)
15412955Sgabeblack@google.com        for (int i = 0; i < number_of_threads; ++i)
15512837Sgabeblack@google.com            schedExitSimLoop("a thread reached the max load count",
15612837Sgabeblack@google.com                             p->max_loads_any_thread, 0,
15712837Sgabeblack@google.com                             comLoadEventQueue[i]);
15812955Sgabeblack@google.com
15912837Sgabeblack@google.com    if (p->max_loads_all_threads != 0) {
16012955Sgabeblack@google.com        // allocate & initialize shared downcounter: each event will
16112837Sgabeblack@google.com        // decrement this when triggered; simulation will terminate
16212837Sgabeblack@google.com        // when counter reaches 0
16312837Sgabeblack@google.com        int *counter = new int;
16412955Sgabeblack@google.com        *counter = number_of_threads;
16512837Sgabeblack@google.com        for (int i = 0; i < number_of_threads; ++i)
16612955Sgabeblack@google.com            new CountedExitEvent(comLoadEventQueue[i],
16712837Sgabeblack@google.com                "all threads reached the max load count",
16812837Sgabeblack@google.com                p->max_loads_all_threads, *counter);
16912837Sgabeblack@google.com    }
17012837Sgabeblack@google.com
17112955Sgabeblack@google.com    functionTracingEnabled = false;
17212837Sgabeblack@google.com    if (p->functionTrace) {
17312955Sgabeblack@google.com        functionTraceStream = simout.find(csprintf("ftrace.%s", name()));
17412837Sgabeblack@google.com        currentFunctionStart = currentFunctionEnd = 0;
17512837Sgabeblack@google.com        functionEntryTick = p->functionTraceStart;
17612837Sgabeblack@google.com
17712837Sgabeblack@google.com        if (p->functionTraceStart == 0) {
17812955Sgabeblack@google.com            functionTracingEnabled = true;
17912837Sgabeblack@google.com        } else {
18012955Sgabeblack@google.com            Event *e =
18112955Sgabeblack@google.com                new EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace>(this,
18212955Sgabeblack@google.com                                                                         true);
18312955Sgabeblack@google.com            e->schedule(p->functionTraceStart);
18412837Sgabeblack@google.com        }
18512837Sgabeblack@google.com    }
18612837Sgabeblack@google.com#if FULL_SYSTEM
18712955Sgabeblack@google.com    profileEvent = NULL;
18812837Sgabeblack@google.com    if (params->profile)
18912955Sgabeblack@google.com        profileEvent = new ProfileEvent(this, params->profile);
19012955Sgabeblack@google.com#endif
19112955Sgabeblack@google.com}
19212955Sgabeblack@google.com
19312955Sgabeblack@google.comBaseCPU::Params::Params()
19412955Sgabeblack@google.com{
19512955Sgabeblack@google.com#if FULL_SYSTEM
19612955Sgabeblack@google.com    profile = false;
19712955Sgabeblack@google.com#endif
19812955Sgabeblack@google.com    checker = NULL;
19912955Sgabeblack@google.com}
20012955Sgabeblack@google.com
20112955Sgabeblack@google.comvoid
20212955Sgabeblack@google.comBaseCPU::enableFunctionTrace()
20312955Sgabeblack@google.com{
20412955Sgabeblack@google.com    functionTracingEnabled = true;
20512955Sgabeblack@google.com}
20612955Sgabeblack@google.com
20712955Sgabeblack@google.comBaseCPU::~BaseCPU()
20812955Sgabeblack@google.com{
20912955Sgabeblack@google.com}
21012955Sgabeblack@google.com
21112955Sgabeblack@google.comvoid
21212955Sgabeblack@google.comBaseCPU::init()
21312955Sgabeblack@google.com{
21412955Sgabeblack@google.com    if (!params->deferRegistration)
21512955Sgabeblack@google.com        registerThreadContexts();
21612955Sgabeblack@google.com}
21712837Sgabeblack@google.com
21812837Sgabeblack@google.comvoid
21912837Sgabeblack@google.comBaseCPU::startup()
22012837Sgabeblack@google.com{
22112955Sgabeblack@google.com#if FULL_SYSTEM
22212955Sgabeblack@google.com    if (!params->deferRegistration && profileEvent)
22312955Sgabeblack@google.com        profileEvent->schedule(curTick);
22412837Sgabeblack@google.com#endif
22512837Sgabeblack@google.com
22612955Sgabeblack@google.com    if (params->progress_interval) {
22712955Sgabeblack@google.com        new CPUProgressEvent(&mainEventQueue, params->progress_interval,
22812955Sgabeblack@google.com                             this);
22912955Sgabeblack@google.com    }
23012955Sgabeblack@google.com}
23112955Sgabeblack@google.com
23212955Sgabeblack@google.com
23312955Sgabeblack@google.comvoid
23412955Sgabeblack@google.comBaseCPU::regStats()
23512955Sgabeblack@google.com{
23612955Sgabeblack@google.com    using namespace Stats;
23712955Sgabeblack@google.com
23812955Sgabeblack@google.com    numCycles
23912955Sgabeblack@google.com        .name(name() + ".numCycles")
24012955Sgabeblack@google.com        .desc("number of cpu cycles simulated")
24112955Sgabeblack@google.com        ;
24212955Sgabeblack@google.com
24312955Sgabeblack@google.com    int size = threadContexts.size();
24412837Sgabeblack@google.com    if (size > 1) {
24512955Sgabeblack@google.com        for (int i = 0; i < size; ++i) {
24612837Sgabeblack@google.com            stringstream namestr;
24712955Sgabeblack@google.com            ccprintf(namestr, "%s.ctx%d", name(), i);
24812837Sgabeblack@google.com            threadContexts[i]->regStats(namestr.str());
24912837Sgabeblack@google.com        }
25012837Sgabeblack@google.com    } else if (size == 1)
25112837Sgabeblack@google.com        threadContexts[0]->regStats(name());
25212955Sgabeblack@google.com
25312837Sgabeblack@google.com#if FULL_SYSTEM
25412955Sgabeblack@google.com#endif
25512837Sgabeblack@google.com}
25612837Sgabeblack@google.com
25712837Sgabeblack@google.comTick
25812955Sgabeblack@google.comBaseCPU::nextCycle()
25912955Sgabeblack@google.com{
26012955Sgabeblack@google.com    Tick next_tick = curTick + clock - 1;
26112955Sgabeblack@google.com    next_tick -= (next_tick % clock);
26212955Sgabeblack@google.com    return next_tick;
26312955Sgabeblack@google.com}
26412955Sgabeblack@google.com
26512955Sgabeblack@google.comTick
26612955Sgabeblack@google.comBaseCPU::nextCycle(Tick begin_tick)
26712955Sgabeblack@google.com{
26812955Sgabeblack@google.com    Tick next_tick = begin_tick;
26912955Sgabeblack@google.com
27012837Sgabeblack@google.com    while (next_tick < curTick)
27112837Sgabeblack@google.com        next_tick += clock;
27212955Sgabeblack@google.com
27312955Sgabeblack@google.com    next_tick -= (next_tick % clock);
27412955Sgabeblack@google.com    assert(next_tick >= curTick);
27512837Sgabeblack@google.com    return next_tick;
27612837Sgabeblack@google.com}
27712955Sgabeblack@google.com
27812955Sgabeblack@google.comvoid
27912955Sgabeblack@google.comBaseCPU::registerThreadContexts()
28012955Sgabeblack@google.com{
28112955Sgabeblack@google.com    for (int i = 0; i < threadContexts.size(); ++i) {
28212955Sgabeblack@google.com        ThreadContext *tc = threadContexts[i];
28312955Sgabeblack@google.com
28412955Sgabeblack@google.com#if FULL_SYSTEM
28512955Sgabeblack@google.com        int id = params->cpu_id;
28612955Sgabeblack@google.com        if (id != -1)
28712955Sgabeblack@google.com            id += i;
28812955Sgabeblack@google.com
28912955Sgabeblack@google.com        tc->setCpuId(system->registerThreadContext(tc, id));
29012955Sgabeblack@google.com#else
29112955Sgabeblack@google.com        tc->setCpuId(tc->getProcessPtr()->registerThreadContext(tc));
29212955Sgabeblack@google.com#endif
29312955Sgabeblack@google.com    }
29412955Sgabeblack@google.com}
29512837Sgabeblack@google.com
29612955Sgabeblack@google.com
29712837Sgabeblack@google.comvoid
29812955Sgabeblack@google.comBaseCPU::switchOut()
29912837Sgabeblack@google.com{
30012837Sgabeblack@google.com//    panic("This CPU doesn't support sampling!");
30112837Sgabeblack@google.com#if FULL_SYSTEM
30212837Sgabeblack@google.com    if (profileEvent && profileEvent->scheduled())
30312955Sgabeblack@google.com        profileEvent->deschedule();
30412837Sgabeblack@google.com#endif
30512955Sgabeblack@google.com}
30612837Sgabeblack@google.com
30712837Sgabeblack@google.comvoid
30812837Sgabeblack@google.comBaseCPU::takeOverFrom(BaseCPU *oldCPU)
30912837Sgabeblack@google.com{
31012955Sgabeblack@google.com    assert(threadContexts.size() == oldCPU->threadContexts.size());
31112955Sgabeblack@google.com
31212955Sgabeblack@google.com    for (int i = 0; i < threadContexts.size(); ++i) {
31312837Sgabeblack@google.com        ThreadContext *newTC = threadContexts[i];
31413279Sgabeblack@google.com        ThreadContext *oldTC = oldCPU->threadContexts[i];
31513279Sgabeblack@google.com
31613279Sgabeblack@google.com        newTC->takeOverFrom(oldTC);
31713279Sgabeblack@google.com
31812837Sgabeblack@google.com        CpuEvent::replaceThreadContext(oldTC, newTC);
31912955Sgabeblack@google.com
32012955Sgabeblack@google.com        assert(newTC->readCpuId() == oldTC->readCpuId());
32112955Sgabeblack@google.com#if FULL_SYSTEM
32212837Sgabeblack@google.com        system->replaceThreadContext(newTC, newTC->readCpuId());
32312955Sgabeblack@google.com#else
32412955Sgabeblack@google.com        assert(newTC->getProcessPtr() == oldTC->getProcessPtr());
32512955Sgabeblack@google.com        newTC->getProcessPtr()->replaceThreadContext(newTC, newTC->readCpuId());
32612837Sgabeblack@google.com#endif
32712837Sgabeblack@google.com
32812837Sgabeblack@google.com//    TheISA::compareXCs(oldXC, newXC);
32912955Sgabeblack@google.com    }
33012837Sgabeblack@google.com
33112955Sgabeblack@google.com#if FULL_SYSTEM
33212837Sgabeblack@google.com    interrupts = oldCPU->interrupts;
33312837Sgabeblack@google.com    checkInterrupts = oldCPU->checkInterrupts;
33412837Sgabeblack@google.com
33512837Sgabeblack@google.com    for (int i = 0; i < threadContexts.size(); ++i)
33612955Sgabeblack@google.com        threadContexts[i]->profileClear();
33712837Sgabeblack@google.com
33812837Sgabeblack@google.com    // The Sampler must take care of this!
33912955Sgabeblack@google.com//    if (profileEvent)
34012955Sgabeblack@google.com//        profileEvent->schedule(curTick);
34112955Sgabeblack@google.com#endif
34212955Sgabeblack@google.com}
34312955Sgabeblack@google.com
34413299Sgabeblack@google.com
34513299Sgabeblack@google.com#if FULL_SYSTEM
34613299Sgabeblack@google.comBaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, int _interval)
34713299Sgabeblack@google.com    : Event(&mainEventQueue), cpu(_cpu), interval(_interval)
34813299Sgabeblack@google.com{ }
34913299Sgabeblack@google.com
35013299Sgabeblack@google.comvoid
35113299Sgabeblack@google.comBaseCPU::ProfileEvent::process()
35213299Sgabeblack@google.com{
35313299Sgabeblack@google.com    for (int i = 0, size = cpu->threadContexts.size(); i < size; ++i) {
35412955Sgabeblack@google.com        ThreadContext *tc = cpu->threadContexts[i];
35512955Sgabeblack@google.com        tc->profileSample();
35612955Sgabeblack@google.com    }
35712837Sgabeblack@google.com
35812955Sgabeblack@google.com    schedule(curTick + interval);
35912955Sgabeblack@google.com}
36012955Sgabeblack@google.com
36112955Sgabeblack@google.comvoid
36212915Sgabeblack@google.comBaseCPU::post_interrupt(int int_num, int index)
36312915Sgabeblack@google.com{
36412837Sgabeblack@google.com    checkInterrupts = true;
36512955Sgabeblack@google.com    interrupts.post(int_num, index);
36612837Sgabeblack@google.com}
36712955Sgabeblack@google.com
36812955Sgabeblack@google.comvoid
36912955Sgabeblack@google.comBaseCPU::clear_interrupt(int int_num, int index)
37012955Sgabeblack@google.com{
37112837Sgabeblack@google.com    interrupts.clear(int_num, index);
37212837Sgabeblack@google.com}
37312837Sgabeblack@google.com
37412955Sgabeblack@google.comvoid
37512837Sgabeblack@google.comBaseCPU::clear_interrupts()
37612955Sgabeblack@google.com{
37712955Sgabeblack@google.com    interrupts.clear_all();
37812955Sgabeblack@google.com}
37912955Sgabeblack@google.com
38012837Sgabeblack@google.com
38112837Sgabeblack@google.comvoid
38212837Sgabeblack@google.comBaseCPU::serialize(std::ostream &os)
38312955Sgabeblack@google.com{
38412837Sgabeblack@google.com    interrupts.serialize(os);
38512955Sgabeblack@google.com}
38612955Sgabeblack@google.com
38712955Sgabeblack@google.comvoid
38812955Sgabeblack@google.comBaseCPU::unserialize(Checkpoint *cp, const std::string &section)
38912837Sgabeblack@google.com{
39012837Sgabeblack@google.com    interrupts.unserialize(cp, section);
39113303Sgabeblack@google.com}
39213303Sgabeblack@google.com
39313303Sgabeblack@google.com#endif // FULL_SYSTEM
39413303Sgabeblack@google.com
39513303Sgabeblack@google.comvoid
39613303Sgabeblack@google.comBaseCPU::traceFunctionsInternal(Addr pc)
39713303Sgabeblack@google.com{
39813303Sgabeblack@google.com    if (!debugSymbolTable)
39913303Sgabeblack@google.com        return;
40013303Sgabeblack@google.com
40113303Sgabeblack@google.com    // if pc enters different function, print new function symbol and
40213303Sgabeblack@google.com    // update saved range.  Otherwise do nothing.
40313303Sgabeblack@google.com    if (pc < currentFunctionStart || pc >= currentFunctionEnd) {
40412837Sgabeblack@google.com        string sym_str;
40512837Sgabeblack@google.com        bool found = debugSymbolTable->findNearestSymbol(pc, sym_str,
40612837Sgabeblack@google.com                                                         currentFunctionStart,
40712955Sgabeblack@google.com                                                         currentFunctionEnd);
40812837Sgabeblack@google.com
40912837Sgabeblack@google.com        if (!found) {
41012837Sgabeblack@google.com            // no symbol found: use addr as label
41112955Sgabeblack@google.com            sym_str = csprintf("0x%x", pc);
41212837Sgabeblack@google.com            currentFunctionStart = pc;
41312955Sgabeblack@google.com            currentFunctionEnd = pc + 1;
41412955Sgabeblack@google.com        }
41512955Sgabeblack@google.com
41612837Sgabeblack@google.com        ccprintf(*functionTraceStream, " (%d)\n%d: %s",
41712837Sgabeblack@google.com                 curTick - functionEntryTick, curTick, sym_str);
41812837Sgabeblack@google.com        functionEntryTick = curTick;
41913303Sgabeblack@google.com    }
42013303Sgabeblack@google.com}
42113303Sgabeblack@google.com
42213303Sgabeblack@google.com
42313303Sgabeblack@google.comDEFINE_SIM_OBJECT_CLASS_NAME("BaseCPU", BaseCPU)
42413303Sgabeblack@google.com