base.cc revision 2356
11689SN/A/*
210331Smitch.hayenga@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
39916Ssteve.reinhardt@amd.com * All rights reserved.
48707Sandreas.hansson@arm.com *
58707Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
68707Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
78707Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
88707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
98707Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
108707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
118707Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
128707Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
138707Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
148707Sandreas.hansson@arm.com * this software without specific prior written permission.
152325SN/A *
167897Shestness@cs.utexas.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
271689SN/A */
281689SN/A
291689SN/A#include <iostream>
301689SN/A#include <string>
311689SN/A#include <sstream>
321689SN/A
331689SN/A#include "base/cprintf.hh"
341689SN/A#include "base/loader/symtab.hh"
351689SN/A#include "base/misc.hh"
361689SN/A#include "base/output.hh"
371689SN/A#include "cpu/base.hh"
381689SN/A#include "cpu/exec_context.hh"
391689SN/A#include "cpu/profile.hh"
401689SN/A#include "cpu/sampler/sampler.hh"
412665Ssaidi@eecs.umich.edu#include "sim/param.hh"
422665Ssaidi@eecs.umich.edu#include "sim/process.hh"
432756Sksewell@umich.edu#include "sim/sim_events.hh"
447897Shestness@cs.utexas.edu#include "sim/system.hh"
451689SN/A
461689SN/A#include "base/trace.hh"
478779Sgblack@eecs.umich.edu
486658Snate@binkert.orgusing namespace std;
498887Sgeoffrey.blake@arm.com
508887Sgeoffrey.blake@arm.comvector<BaseCPU *> BaseCPU::cpuList;
518229Snate@binkert.org
528229Snate@binkert.org// This variable reflects the max number of threads in any CPU.  Be
538229Snate@binkert.org// careful to only use it once all the CPUs that you care about have
544762Snate@binkert.org// been initialized
558779Sgblack@eecs.umich.eduint maxThreadsPerCPU = 1;
564762Snate@binkert.org
574762Snate@binkert.orgvoid
588232Snate@binkert.orgCPUProgressEvent::process()
599152Satgutier@umich.edu{
608232Snate@binkert.org#ifndef NDEBUG
618232Snate@binkert.org    Counter temp = cpu->totalInstructions();
624762Snate@binkert.org    double ipc = double(temp - lastNumInst) / (interval / cpu->cycles(1));
634762Snate@binkert.org    DPRINTFN("%s progress event, instructions committed: %lli, IPC: %0.8d\n",
648793Sgblack@eecs.umich.edu             cpu->name(), temp - lastNumInst, ipc);
658779Sgblack@eecs.umich.edu    ipc = 0.0;
664762Snate@binkert.org    lastNumInst = temp;
678460SAli.Saidi@ARM.com    schedule(curTick + interval);
684762Snate@binkert.org#endif
695702Ssaidi@eecs.umich.edu}
705702Ssaidi@eecs.umich.edu
718232Snate@binkert.orgconst char *
725702Ssaidi@eecs.umich.eduCPUProgressEvent::description()
735702Ssaidi@eecs.umich.edu{
748737Skoansin.tan@gmail.com    return "CPU Progress event";
755529Snate@binkert.org}
762669Sktlim@umich.edu
776221Snate@binkert.org#if FULL_SYSTEM
781060SN/ABaseCPU::BaseCPU(Params *p)
795529Snate@binkert.org    : SimObject(p->name), clock(p->clock), checkInterrupts(true),
805712Shsul@eecs.umich.edu      params(p), number_of_threads(p->numberOfThreads), system(p->system)
811060SN/A#else
821060SN/ABaseCPU::BaseCPU(Params *p)
831060SN/A    : SimObject(p->name), clock(p->clock), params(p),
842292SN/A      number_of_threads(p->numberOfThreads)
852733Sktlim@umich.edu#endif
862292SN/A{
872292SN/A    DPRINTF(FullCPU, "BaseCPU: Creating object, mem address %#x.\n", this);
882292SN/A
892292SN/A    // add self to global list of CPUs
908707Sandreas.hansson@arm.com    cpuList.push_back(this);
918707Sandreas.hansson@arm.com
928975Sandreas.hansson@arm.com    DPRINTF(FullCPU, "BaseCPU: CPU added to cpuList, mem address %#x.\n",
938707Sandreas.hansson@arm.com            this);
948707Sandreas.hansson@arm.com
958948Sandreas.hansson@arm.com    if (number_of_threads > maxThreadsPerCPU)
968948Sandreas.hansson@arm.com        maxThreadsPerCPU = number_of_threads;
978948Sandreas.hansson@arm.com
988707Sandreas.hansson@arm.com    // allocate per-thread instruction-based event queues
998707Sandreas.hansson@arm.com    comInstEventQueue = new EventQueue *[number_of_threads];
1008707Sandreas.hansson@arm.com    for (int i = 0; i < number_of_threads; ++i)
1018707Sandreas.hansson@arm.com        comInstEventQueue[i] = new EventQueue("instruction-based event queue");
1028707Sandreas.hansson@arm.com
1038707Sandreas.hansson@arm.com    //
1048707Sandreas.hansson@arm.com    // set up instruction-count-based termination events, if any
1058707Sandreas.hansson@arm.com    //
1068707Sandreas.hansson@arm.com    if (p->max_insts_any_thread != 0)
1078707Sandreas.hansson@arm.com        for (int i = 0; i < number_of_threads; ++i)
1088707Sandreas.hansson@arm.com            new SimExitEvent(comInstEventQueue[i], p->max_insts_any_thread,
1098707Sandreas.hansson@arm.com                "a thread reached the max instruction count");
1108707Sandreas.hansson@arm.com
1118975Sandreas.hansson@arm.com    if (p->max_insts_all_threads != 0) {
1128707Sandreas.hansson@arm.com        // allocate & initialize shared downcounter: each event will
1138975Sandreas.hansson@arm.com        // decrement this when triggered; simulation will terminate
1148707Sandreas.hansson@arm.com        // when counter reaches 0
1158707Sandreas.hansson@arm.com        int *counter = new int;
1168707Sandreas.hansson@arm.com        *counter = number_of_threads;
1178975Sandreas.hansson@arm.com        for (int i = 0; i < number_of_threads; ++i)
1188975Sandreas.hansson@arm.com            new CountedExitEvent(comInstEventQueue[i],
1198948Sandreas.hansson@arm.com                "all threads reached the max instruction count",
1208975Sandreas.hansson@arm.com                p->max_insts_all_threads, *counter);
1218948Sandreas.hansson@arm.com    }
1228948Sandreas.hansson@arm.com
1238948Sandreas.hansson@arm.com    // allocate per-thread load-based event queues
1248707Sandreas.hansson@arm.com    comLoadEventQueue = new EventQueue *[number_of_threads];
1258707Sandreas.hansson@arm.com    for (int i = 0; i < number_of_threads; ++i)
1268707Sandreas.hansson@arm.com        comLoadEventQueue[i] = new EventQueue("load-based event queue");
1278707Sandreas.hansson@arm.com
1288707Sandreas.hansson@arm.com    //
1298707Sandreas.hansson@arm.com    // set up instruction-count-based termination events, if any
1301060SN/A    //
1311755SN/A    if (p->max_loads_any_thread != 0)
1325606Snate@binkert.org        for (int i = 0; i < number_of_threads; ++i)
1331060SN/A            new SimExitEvent(comLoadEventQueue[i], p->max_loads_any_thread,
1341060SN/A                "a thread reached the max load count");
1351060SN/A
1361060SN/A    if (p->max_loads_all_threads != 0) {
1371060SN/A        // allocate & initialize shared downcounter: each event will
1381755SN/A        // decrement this when triggered; simulation will terminate
1391060SN/A        // when counter reaches 0
1401060SN/A        int *counter = new int;
1411060SN/A        *counter = number_of_threads;
1421060SN/A        for (int i = 0; i < number_of_threads; ++i)
1431060SN/A            new CountedExitEvent(comLoadEventQueue[i],
1441060SN/A                "all threads reached the max load count",
1455336Shines@cs.fsu.edu                p->max_loads_all_threads, *counter);
1461060SN/A    }
1474873Sstever@eecs.umich.edu
1481060SN/A#if FULL_SYSTEM
1491060SN/A    memset(interrupts, 0, sizeof(interrupts));
1501060SN/A    intstatus = 0;
1515595Sgblack@eecs.umich.edu#endif
1522733Sktlim@umich.edu
1533781Sgblack@eecs.umich.edu    functionTracingEnabled = false;
1543781Sgblack@eecs.umich.edu    if (p->functionTrace) {
1551060SN/A        functionTraceStream = simout.find(csprintf("ftrace.%s", name()));
1565737Scws3k@cs.virginia.edu        currentFunctionStart = currentFunctionEnd = 0;
1575737Scws3k@cs.virginia.edu        functionEntryTick = p->functionTraceStart;
1585737Scws3k@cs.virginia.edu
1592292SN/A        if (p->functionTraceStart == 0) {
1605595Sgblack@eecs.umich.edu            functionTracingEnabled = true;
1615595Sgblack@eecs.umich.edu        } else {
1625595Sgblack@eecs.umich.edu            Event *e =
1635595Sgblack@eecs.umich.edu                new EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace>(this,
1645595Sgblack@eecs.umich.edu                                                                         true);
1651060SN/A            e->schedule(p->functionTraceStart);
1669915Ssteve.reinhardt@amd.com        }
1679920Syasuko.eckert@amd.com    }
1689920Syasuko.eckert@amd.com#if FULL_SYSTEM
1691060SN/A    profileEvent = NULL;
1709919Ssteve.reinhardt@amd.com    if (params->profile)
1711060SN/A        profileEvent = new ProfileEvent(this, params->profile);
1729954SFaissal.Sleiman@arm.com#endif
1731060SN/A}
1749916Ssteve.reinhardt@amd.com
1759916Ssteve.reinhardt@amd.comBaseCPU::Params::Params()
1769916Ssteve.reinhardt@amd.com{
1771060SN/A#if FULL_SYSTEM
1789384SAndreas.Sandberg@arm.com    profile = false;
1799384SAndreas.Sandberg@arm.com#endif
1808707Sandreas.hansson@arm.com    checker = NULL;
1818707Sandreas.hansson@arm.com}
1828707Sandreas.hansson@arm.com
1832873Sktlim@umich.eduvoid
1842873Sktlim@umich.eduBaseCPU::enableFunctionTrace()
1852873Sktlim@umich.edu{
1862873Sktlim@umich.edu    functionTracingEnabled = true;
1872873Sktlim@umich.edu}
1885804Snate@binkert.org
1892873Sktlim@umich.eduBaseCPU::~BaseCPU()
1902873Sktlim@umich.edu{
1911060SN/A}
1921060SN/A
1932292SN/Avoid
1949444SAndreas.Sandberg@ARM.comBaseCPU::init()
1959180Sandreas.hansson@arm.com{
1961060SN/A    if (!params->deferRegistration)
1979433SAndreas.Sandberg@ARM.com        registerExecContexts();
1983221Sktlim@umich.edu}
1993221Sktlim@umich.edu
2009152Satgutier@umich.eduvoid
2013221Sktlim@umich.eduBaseCPU::startup()
2021681SN/A{
2032794Sktlim@umich.edu#if FULL_SYSTEM
2042316SN/A    if (!params->deferRegistration && profileEvent)
2058733Sgeoffrey.blake@arm.com        profileEvent->schedule(curTick);
2068707Sandreas.hansson@arm.com#endif
2072316SN/A
2084598Sbinkertn@umich.edu    if (params->progress_interval) {
2094598Sbinkertn@umich.edu        new CPUProgressEvent(&mainEventQueue, params->progress_interval,
2104598Sbinkertn@umich.edu                             this);
2112316SN/A    }
2128793Sgblack@eecs.umich.edu}
2138793Sgblack@eecs.umich.edu
2148793Sgblack@eecs.umich.edu
2158793Sgblack@eecs.umich.eduvoid
2161681SN/ABaseCPU::regStats()
2172325SN/A{
2182325SN/A    using namespace Stats;
2192325SN/A
2201060SN/A    numCycles
2212292SN/A        .name(name() + ".numCycles")
2222292SN/A        .desc("number of cpu cycles simulated")
2232292SN/A        ;
2242292SN/A
2252292SN/A    int size = execContexts.size();
2262292SN/A    if (size > 1) {
2271060SN/A        for (int i = 0; i < size; ++i) {
2281060SN/A            stringstream namestr;
2291060SN/A            ccprintf(namestr, "%s.ctx%d", name(), i);
2301060SN/A            execContexts[i]->regStats(namestr.str());
2311060SN/A        }
2321060SN/A    } else if (size == 1)
2331060SN/A        execContexts[0]->regStats(name());
2341060SN/A
2351060SN/A#if FULL_SYSTEM
2361060SN/A#endif
2371060SN/A}
2382292SN/A
2391060SN/A
2401060SN/Avoid
2411060SN/ABaseCPU::registerExecContexts()
2421060SN/A{
2431060SN/A    for (int i = 0; i < execContexts.size(); ++i) {
2441060SN/A        ExecContext *xc = execContexts[i];
2451060SN/A
2461060SN/A        if (xc->status() == ExecContext::Suspended) {
2472292SN/A#if FULL_SYSTEM
2482292SN/A            int id = params->cpu_id;
2492292SN/A            if (id != -1)
2502292SN/A                id += i;
2518793Sgblack@eecs.umich.edu
2528793Sgblack@eecs.umich.edu        xc->setCpuId(system->registerExecContext(xc, id));
2538793Sgblack@eecs.umich.edu#else
2548793Sgblack@eecs.umich.edu        xc->setCpuId(xc->getProcessPtr()->registerExecContext(xc));
2558793Sgblack@eecs.umich.edu#endif
2562831Sksewell@umich.edu        }
2578793Sgblack@eecs.umich.edu    }
2588793Sgblack@eecs.umich.edu}
2598793Sgblack@eecs.umich.edu
2608793Sgblack@eecs.umich.edu
2618793Sgblack@eecs.umich.eduvoid
2622831Sksewell@umich.eduBaseCPU::switchOut(Sampler *sampler)
2632292SN/A{
2642316SN/A    panic("This CPU doesn't support sampling!");
2652292SN/A}
2662292SN/A
2679920Syasuko.eckert@amd.comvoid
2682292SN/ABaseCPU::takeOverFrom(BaseCPU *oldCPU)
2692292SN/A{
2702292SN/A    assert(execContexts.size() == oldCPU->execContexts.size());
2712292SN/A
2721060SN/A    for (int i = 0; i < execContexts.size(); ++i) {
2736221Snate@binkert.org        ExecContext *newXC = execContexts[i];
2749384SAndreas.Sandberg@arm.com        ExecContext *oldXC = oldCPU->execContexts[i];
2759384SAndreas.Sandberg@arm.com
2769919Ssteve.reinhardt@amd.com        newXC->takeOverFrom(oldXC);
2779919Ssteve.reinhardt@amd.com        assert(newXC->readCpuId() == oldXC->readCpuId());
2789919Ssteve.reinhardt@amd.com#if FULL_SYSTEM
2799919Ssteve.reinhardt@amd.com        system->replaceExecContext(newXC, newXC->readCpuId());
2809919Ssteve.reinhardt@amd.com#else
2819919Ssteve.reinhardt@amd.com        assert(newXC->getProcessPtr() == oldXC->getProcessPtr());
2822292SN/A        newXC->getProcessPtr()->replaceExecContext(newXC, newXC->readCpuId());
2839919Ssteve.reinhardt@amd.com#endif
2849919Ssteve.reinhardt@amd.com    }
2852292SN/A
2869919Ssteve.reinhardt@amd.com#if FULL_SYSTEM
2879919Ssteve.reinhardt@amd.com    for (int i = 0; i < TheISA::NumInterruptLevels; ++i)
2882292SN/A        interrupts[i] = oldCPU->interrupts[i];
2892292SN/A    intstatus = oldCPU->intstatus;
2909919Ssteve.reinhardt@amd.com
2919919Ssteve.reinhardt@amd.com    for (int i = 0; i < execContexts.size(); ++i)
2929919Ssteve.reinhardt@amd.com        execContexts[i]->profileClear();
2939919Ssteve.reinhardt@amd.com
2949919Ssteve.reinhardt@amd.com    if (profileEvent)
2959919Ssteve.reinhardt@amd.com        profileEvent->schedule(curTick);
2969919Ssteve.reinhardt@amd.com#endif
2979919Ssteve.reinhardt@amd.com}
2989919Ssteve.reinhardt@amd.com
2999919Ssteve.reinhardt@amd.com
3009919Ssteve.reinhardt@amd.com#if FULL_SYSTEM
3019919Ssteve.reinhardt@amd.comBaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, int _interval)
3029919Ssteve.reinhardt@amd.com    : Event(&mainEventQueue), cpu(_cpu), interval(_interval)
3039919Ssteve.reinhardt@amd.com{ }
3049919Ssteve.reinhardt@amd.com
3059919Ssteve.reinhardt@amd.comvoid
3069920Syasuko.eckert@amd.comBaseCPU::ProfileEvent::process()
3079920Syasuko.eckert@amd.com{
3089920Syasuko.eckert@amd.com    for (int i = 0, size = cpu->execContexts.size(); i < size; ++i) {
3099920Syasuko.eckert@amd.com        ExecContext *xc = cpu->execContexts[i];
3109920Syasuko.eckert@amd.com        xc->profileSample();
3119920Syasuko.eckert@amd.com    }
3129919Ssteve.reinhardt@amd.com
3139919Ssteve.reinhardt@amd.com    schedule(curTick + interval);
3142292SN/A}
3152292SN/A
3161060SN/Avoid
3172292SN/ABaseCPU::post_interrupt(int int_num, int index)
3181060SN/A{
3191060SN/A    DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
3202292SN/A
3219158Sandreas.hansson@arm.com    if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
3226221Snate@binkert.org        panic("int_num out of bounds\n");
3233093Sksewell@umich.edu
3246221Snate@binkert.org    if (index < 0 || index >= sizeof(uint64_t) * 8)
3256221Snate@binkert.org        panic("int_num out of bounds\n");
3266221Snate@binkert.org
3273093Sksewell@umich.edu    checkInterrupts = true;
3285595Sgblack@eecs.umich.edu    interrupts[int_num] |= 1 << index;
3295595Sgblack@eecs.umich.edu    intstatus |= (ULL(1) << int_num);
3305595Sgblack@eecs.umich.edu}
3315595Sgblack@eecs.umich.edu
3325595Sgblack@eecs.umich.eduvoid
3336221Snate@binkert.orgBaseCPU::clear_interrupt(int int_num, int index)
3348793Sgblack@eecs.umich.edu{
3358793Sgblack@eecs.umich.edu    DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
3368793Sgblack@eecs.umich.edu
3378793Sgblack@eecs.umich.edu    if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
3388793Sgblack@eecs.umich.edu        panic("int_num out of bounds\n");
3398793Sgblack@eecs.umich.edu
3408793Sgblack@eecs.umich.edu    if (index < 0 || index >= sizeof(uint64_t) * 8)
3418793Sgblack@eecs.umich.edu        panic("int_num out of bounds\n");
3428793Sgblack@eecs.umich.edu
3438793Sgblack@eecs.umich.edu    interrupts[int_num] &= ~(1 << index);
3448793Sgblack@eecs.umich.edu    if (interrupts[int_num] == 0)
3455595Sgblack@eecs.umich.edu        intstatus &= ~(ULL(1) << int_num);
3468793Sgblack@eecs.umich.edu}
3478793Sgblack@eecs.umich.edu
3488793Sgblack@eecs.umich.eduvoid
3498793Sgblack@eecs.umich.eduBaseCPU::clear_interrupts()
3508793Sgblack@eecs.umich.edu{
3518793Sgblack@eecs.umich.edu    DPRINTF(Interrupt, "Interrupts all cleared\n");
3525595Sgblack@eecs.umich.edu
3538793Sgblack@eecs.umich.edu    memset(interrupts, 0, sizeof(interrupts));
3548793Sgblack@eecs.umich.edu    intstatus = 0;
3558793Sgblack@eecs.umich.edu}
3568793Sgblack@eecs.umich.edu
3578793Sgblack@eecs.umich.edu
3585595Sgblack@eecs.umich.eduvoid
3595595Sgblack@eecs.umich.eduBaseCPU::serialize(std::ostream &os)
3605595Sgblack@eecs.umich.edu{
3615595Sgblack@eecs.umich.edu    SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
3625595Sgblack@eecs.umich.edu    SERIALIZE_SCALAR(intstatus);
3635595Sgblack@eecs.umich.edu}
3645595Sgblack@eecs.umich.edu
3655595Sgblack@eecs.umich.eduvoid
3665595Sgblack@eecs.umich.eduBaseCPU::unserialize(Checkpoint *cp, const std::string &section)
3675595Sgblack@eecs.umich.edu{
3685595Sgblack@eecs.umich.edu    UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
3695595Sgblack@eecs.umich.edu    UNSERIALIZE_SCALAR(intstatus);
3705595Sgblack@eecs.umich.edu}
3715595Sgblack@eecs.umich.edu
3725595Sgblack@eecs.umich.edu#endif // FULL_SYSTEM
3735595Sgblack@eecs.umich.edu
3745595Sgblack@eecs.umich.eduvoid
3755595Sgblack@eecs.umich.eduBaseCPU::traceFunctionsInternal(Addr pc)
3766221Snate@binkert.org{
3775595Sgblack@eecs.umich.edu    if (!debugSymbolTable)
3788793Sgblack@eecs.umich.edu        return;
3798793Sgblack@eecs.umich.edu
3808793Sgblack@eecs.umich.edu    // if pc enters different function, print new function symbol and
3818793Sgblack@eecs.umich.edu    // update saved range.  Otherwise do nothing.
3825595Sgblack@eecs.umich.edu    if (pc < currentFunctionStart || pc >= currentFunctionEnd) {
3836221Snate@binkert.org        string sym_str;
3845595Sgblack@eecs.umich.edu        bool found = debugSymbolTable->findNearestSymbol(pc, sym_str,
3855595Sgblack@eecs.umich.edu                                                         currentFunctionStart,
3865595Sgblack@eecs.umich.edu                                                         currentFunctionEnd);
3875595Sgblack@eecs.umich.edu
3885595Sgblack@eecs.umich.edu        if (!found) {
3898876Sandreas.hansson@arm.com            // no symbol found: use addr as label
3909433SAndreas.Sandberg@ARM.com            sym_str = csprintf("0x%x", pc);
3918876Sandreas.hansson@arm.com            currentFunctionStart = pc;
3928876Sandreas.hansson@arm.com            currentFunctionEnd = pc + 1;
3938876Sandreas.hansson@arm.com        }
3948876Sandreas.hansson@arm.com
3956221Snate@binkert.org        ccprintf(*functionTraceStream, " (%d)\n%d: %s",
3966221Snate@binkert.org                 curTick - functionEntryTick, curTick, sym_str);
3971060SN/A        functionEntryTick = curTick;
3981060SN/A    }
3991060SN/A}
4001755SN/A
4011060SN/A
4021060SN/ADEFINE_SIM_OBJECT_CLASS_NAME("BaseCPU", BaseCPU)
4031060SN/A