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 §ion) 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