base.cc revision 2107
12810Srdreslin@umich.edu/* 29529Sandreas.hansson@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 38702Sandreas.hansson@arm.com * All rights reserved. 48702Sandreas.hansson@arm.com * 58702Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 68702Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 78702Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 88702Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 98702Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 108702Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 118702Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 128702Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 138702Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 142810Srdreslin@umich.edu * this software without specific prior written permission. 152810Srdreslin@umich.edu * 162810Srdreslin@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172810Srdreslin@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182810Srdreslin@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192810Srdreslin@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202810Srdreslin@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212810Srdreslin@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222810Srdreslin@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232810Srdreslin@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242810Srdreslin@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252810Srdreslin@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262810Srdreslin@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272810Srdreslin@umich.edu */ 282810Srdreslin@umich.edu 292810Srdreslin@umich.edu#include <iostream> 302810Srdreslin@umich.edu#include <string> 312810Srdreslin@umich.edu#include <sstream> 322810Srdreslin@umich.edu 332810Srdreslin@umich.edu#include "base/cprintf.hh" 342810Srdreslin@umich.edu#include "base/loader/symtab.hh" 352810Srdreslin@umich.edu#include "base/misc.hh" 362810Srdreslin@umich.edu#include "base/output.hh" 372810Srdreslin@umich.edu#include "cpu/base.hh" 382810Srdreslin@umich.edu#include "cpu/exec_context.hh" 392810Srdreslin@umich.edu#include "cpu/profile.hh" 402810Srdreslin@umich.edu#include "cpu/sampler/sampler.hh" 412810Srdreslin@umich.edu#include "sim/param.hh" 422810Srdreslin@umich.edu#include "sim/sim_events.hh" 434458Sstever@eecs.umich.edu 448856Sandreas.hansson@arm.com#include "base/trace.hh" 452810Srdreslin@umich.edu 462810Srdreslin@umich.eduusing namespace std; 472810Srdreslin@umich.edu 482810Srdreslin@umich.eduvector<BaseCPU *> BaseCPU::cpuList; 492810Srdreslin@umich.edu 502810Srdreslin@umich.edu// This variable reflects the max number of threads in any CPU. Be 512810Srdreslin@umich.edu// careful to only use it once all the CPUs that you care about have 522810Srdreslin@umich.edu// been initialized 532810Srdreslin@umich.eduint maxThreadsPerCPU = 1; 542810Srdreslin@umich.edu 552810Srdreslin@umich.edu#if FULL_SYSTEM 565338Sstever@gmail.comBaseCPU::BaseCPU(Params *p) 575338Sstever@gmail.com : SimObject(p->name), clock(p->clock), checkInterrupts(true), 585338Sstever@gmail.com params(p), number_of_threads(p->numberOfThreads), system(p->system) 594458Sstever@eecs.umich.edu#else 604458Sstever@eecs.umich.eduBaseCPU::BaseCPU(Params *p) 612813Srdreslin@umich.edu : SimObject(p->name), clock(p->clock), params(p), 623861Sstever@eecs.umich.edu number_of_threads(p->numberOfThreads) 632810Srdreslin@umich.edu#endif 642810Srdreslin@umich.edu{ 652810Srdreslin@umich.edu DPRINTF(FullCPU, "BaseCPU: Creating object, mem address %#x.\n", this); 662810Srdreslin@umich.edu 679264Sdjordje.kovacevic@arm.com // add self to global list of CPUs 682810Srdreslin@umich.edu cpuList.push_back(this); 694672Sstever@eecs.umich.edu 702810Srdreslin@umich.edu DPRINTF(FullCPU, "BaseCPU: CPU added to cpuList, mem address %#x.\n", 712810Srdreslin@umich.edu this); 722810Srdreslin@umich.edu 732810Srdreslin@umich.edu if (number_of_threads > maxThreadsPerCPU) 742810Srdreslin@umich.edu maxThreadsPerCPU = number_of_threads; 753860Sstever@eecs.umich.edu 763860Sstever@eecs.umich.edu // allocate per-thread instruction-based event queues 772810Srdreslin@umich.edu comInstEventQueue = new EventQueue *[number_of_threads]; 782810Srdreslin@umich.edu for (int i = 0; i < number_of_threads; ++i) 799347SAndreas.Sandberg@arm.com comInstEventQueue[i] = new EventQueue("instruction-based event queue"); 802810Srdreslin@umich.edu 818856Sandreas.hansson@arm.com // 828856Sandreas.hansson@arm.com // set up instruction-count-based termination events, if any 838856Sandreas.hansson@arm.com // 848856Sandreas.hansson@arm.com if (p->max_insts_any_thread != 0) 858856Sandreas.hansson@arm.com for (int i = 0; i < number_of_threads; ++i) 863738Sstever@eecs.umich.edu new SimExitEvent(comInstEventQueue[i], p->max_insts_any_thread, 878856Sandreas.hansson@arm.com "a thread reached the max instruction count"); 883738Sstever@eecs.umich.edu 898856Sandreas.hansson@arm.com if (p->max_insts_all_threads != 0) { 908856Sandreas.hansson@arm.com // allocate & initialize shared downcounter: each event will 913738Sstever@eecs.umich.edu // decrement this when triggered; simulation will terminate 928856Sandreas.hansson@arm.com // when counter reaches 0 934478Sstever@eecs.umich.edu int *counter = new int; 948975Sandreas.hansson@arm.com *counter = number_of_threads; 958948Sandreas.hansson@arm.com for (int i = 0; i < number_of_threads; ++i) 968975Sandreas.hansson@arm.com new CountedExitEvent(comInstEventQueue[i], 973738Sstever@eecs.umich.edu "all threads reached the max instruction count", 983738Sstever@eecs.umich.edu p->max_insts_all_threads, *counter); 993738Sstever@eecs.umich.edu } 1003738Sstever@eecs.umich.edu 1018856Sandreas.hansson@arm.com // allocate per-thread load-based event queues 1029090Sandreas.hansson@arm.com comLoadEventQueue = new EventQueue *[number_of_threads]; 1038856Sandreas.hansson@arm.com for (int i = 0; i < number_of_threads; ++i) 1048856Sandreas.hansson@arm.com comLoadEventQueue[i] = new EventQueue("load-based event queue"); 1058856Sandreas.hansson@arm.com 1068856Sandreas.hansson@arm.com // 1078856Sandreas.hansson@arm.com // set up instruction-count-based termination events, if any 1088856Sandreas.hansson@arm.com // 1093738Sstever@eecs.umich.edu if (p->max_loads_any_thread != 0) 1103738Sstever@eecs.umich.edu for (int i = 0; i < number_of_threads; ++i) 1118856Sandreas.hansson@arm.com new SimExitEvent(comLoadEventQueue[i], p->max_loads_any_thread, 1128914Sandreas.hansson@arm.com "a thread reached the max load count"); 1138914Sandreas.hansson@arm.com 1148914Sandreas.hansson@arm.com if (p->max_loads_all_threads != 0) { 1158914Sandreas.hansson@arm.com // allocate & initialize shared downcounter: each event will 1168914Sandreas.hansson@arm.com // decrement this when triggered; simulation will terminate 1178975Sandreas.hansson@arm.com // when counter reaches 0 1188914Sandreas.hansson@arm.com int *counter = new int; 1198914Sandreas.hansson@arm.com *counter = number_of_threads; 1208914Sandreas.hansson@arm.com for (int i = 0; i < number_of_threads; ++i) 1218914Sandreas.hansson@arm.com new CountedExitEvent(comLoadEventQueue[i], 1228914Sandreas.hansson@arm.com "all threads reached the max load count", 1238914Sandreas.hansson@arm.com p->max_loads_all_threads, *counter); 1248914Sandreas.hansson@arm.com } 1258914Sandreas.hansson@arm.com 1268975Sandreas.hansson@arm.com#if FULL_SYSTEM 1278914Sandreas.hansson@arm.com memset(interrupts, 0, sizeof(interrupts)); 1288975Sandreas.hansson@arm.com intstatus = 0; 1298914Sandreas.hansson@arm.com#endif 1308914Sandreas.hansson@arm.com 1318914Sandreas.hansson@arm.com functionTracingEnabled = false; 1328914Sandreas.hansson@arm.com if (p->functionTrace) { 1338914Sandreas.hansson@arm.com functionTraceStream = simout.find(csprintf("ftrace.%s", name())); 1348914Sandreas.hansson@arm.com currentFunctionStart = currentFunctionEnd = 0; 1358914Sandreas.hansson@arm.com functionEntryTick = p->functionTraceStart; 1368914Sandreas.hansson@arm.com 1378914Sandreas.hansson@arm.com if (p->functionTraceStart == 0) { 1388914Sandreas.hansson@arm.com functionTracingEnabled = true; 1398914Sandreas.hansson@arm.com } else { 1408856Sandreas.hansson@arm.com Event *e = 1418856Sandreas.hansson@arm.com new EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace>(this, 1428856Sandreas.hansson@arm.com true); 1438856Sandreas.hansson@arm.com e->schedule(p->functionTraceStart); 1443738Sstever@eecs.umich.edu } 1458856Sandreas.hansson@arm.com } 1463738Sstever@eecs.umich.edu#if FULL_SYSTEM 1478914Sandreas.hansson@arm.com profileEvent = NULL; 1488914Sandreas.hansson@arm.com if (params->profile) 1498914Sandreas.hansson@arm.com profileEvent = new ProfileEvent(this, params->profile); 1508856Sandreas.hansson@arm.com#endif 1518856Sandreas.hansson@arm.com} 1523738Sstever@eecs.umich.edu 1538856Sandreas.hansson@arm.comBaseCPU::Params::Params() 1544478Sstever@eecs.umich.edu{ 1558975Sandreas.hansson@arm.com#if FULL_SYSTEM 1568948Sandreas.hansson@arm.com profile = false; 1578975Sandreas.hansson@arm.com#endif 1583738Sstever@eecs.umich.edu} 1598948Sandreas.hansson@arm.com 1603738Sstever@eecs.umich.eduvoid 1618948Sandreas.hansson@arm.comBaseCPU::enableFunctionTrace() 1624458Sstever@eecs.umich.edu{ 1638856Sandreas.hansson@arm.com functionTracingEnabled = true; 1648856Sandreas.hansson@arm.com} 1658856Sandreas.hansson@arm.com 1668856Sandreas.hansson@arm.comBaseCPU::~BaseCPU() 1673738Sstever@eecs.umich.edu{ 1683738Sstever@eecs.umich.edu} 1692810Srdreslin@umich.edu 1702810Srdreslin@umich.eduvoid 1714626Sstever@eecs.umich.eduBaseCPU::init() 1722810Srdreslin@umich.edu{ 1733861Sstever@eecs.umich.edu if (!params->deferRegistration) 1742810Srdreslin@umich.edu registerExecContexts(); 1754671Sstever@eecs.umich.edu} 1764671Sstever@eecs.umich.edu 1774671Sstever@eecs.umich.eduvoid 1782810Srdreslin@umich.eduBaseCPU::startup() 1795707Shsul@eecs.umich.edu{ 1803860Sstever@eecs.umich.edu#if FULL_SYSTEM 1813860Sstever@eecs.umich.edu if (!params->deferRegistration && profileEvent) 1823860Sstever@eecs.umich.edu profileEvent->schedule(curTick); 1835875Ssteve.reinhardt@amd.com#endif 1845875Ssteve.reinhardt@amd.com} 1855875Ssteve.reinhardt@amd.com 1865875Ssteve.reinhardt@amd.com 1873860Sstever@eecs.umich.eduvoid 1883860Sstever@eecs.umich.eduBaseCPU::regStats() 1899063SAli.Saidi@ARM.com{ 1909063SAli.Saidi@ARM.com using namespace Stats; 1919063SAli.Saidi@ARM.com 1929063SAli.Saidi@ARM.com numCycles 1939063SAli.Saidi@ARM.com .name(name() + ".numCycles") 1949063SAli.Saidi@ARM.com .desc("number of cpu cycles simulated") 1959063SAli.Saidi@ARM.com ; 1963860Sstever@eecs.umich.edu 1973860Sstever@eecs.umich.edu int size = execContexts.size(); 1983860Sstever@eecs.umich.edu if (size > 1) { 1993860Sstever@eecs.umich.edu for (int i = 0; i < size; ++i) { 2003860Sstever@eecs.umich.edu stringstream namestr; 2015707Shsul@eecs.umich.edu ccprintf(namestr, "%s.ctx%d", name(), i); 2023860Sstever@eecs.umich.edu execContexts[i]->regStats(namestr.str()); 2035388Sstever@gmail.com } 2049288Sandreas.hansson@arm.com } else if (size == 1) 2054219Srdreslin@umich.edu execContexts[0]->regStats(name()); 2064219Srdreslin@umich.edu} 2074219Srdreslin@umich.edu 2084219Srdreslin@umich.edu 2094626Sstever@eecs.umich.eduvoid 2103860Sstever@eecs.umich.eduBaseCPU::registerExecContexts() 2113860Sstever@eecs.umich.edu{ 21210028SGiacomo.Gabrielli@arm.com for (int i = 0; i < execContexts.size(); ++i) { 21310028SGiacomo.Gabrielli@arm.com ExecContext *xc = execContexts[i]; 21410028SGiacomo.Gabrielli@arm.com#if FULL_SYSTEM 21510028SGiacomo.Gabrielli@arm.com int id = params->cpu_id; 21610028SGiacomo.Gabrielli@arm.com if (id != -1) 2175350Sstever@gmail.com id += i; 21810028SGiacomo.Gabrielli@arm.com 2195350Sstever@gmail.com xc->cpu_id = system->registerExecContext(xc, id); 2205350Sstever@gmail.com#else 2213860Sstever@eecs.umich.edu xc->cpu_id = xc->process->registerExecContext(xc); 2223860Sstever@eecs.umich.edu#endif 2233860Sstever@eecs.umich.edu } 2244626Sstever@eecs.umich.edu} 2253860Sstever@eecs.umich.edu 2263860Sstever@eecs.umich.edu 2273860Sstever@eecs.umich.eduvoid 2283860Sstever@eecs.umich.eduBaseCPU::switchOut(Sampler *sampler) 2294626Sstever@eecs.umich.edu{ 2304626Sstever@eecs.umich.edu panic("This CPU doesn't support sampling!"); 2313860Sstever@eecs.umich.edu} 2329548Sandreas.hansson@arm.com 2339548Sandreas.hansson@arm.comvoid 2349548Sandreas.hansson@arm.comBaseCPU::takeOverFrom(BaseCPU *oldCPU) 2359548Sandreas.hansson@arm.com{ 2369548Sandreas.hansson@arm.com assert(execContexts.size() == oldCPU->execContexts.size()); 2379548Sandreas.hansson@arm.com 2389548Sandreas.hansson@arm.com for (int i = 0; i < execContexts.size(); ++i) { 2399548Sandreas.hansson@arm.com ExecContext *newXC = execContexts[i]; 2409548Sandreas.hansson@arm.com ExecContext *oldXC = oldCPU->execContexts[i]; 2419548Sandreas.hansson@arm.com 2429548Sandreas.hansson@arm.com newXC->takeOverFrom(oldXC); 2439548Sandreas.hansson@arm.com assert(newXC->cpu_id == oldXC->cpu_id); 2449548Sandreas.hansson@arm.com#if FULL_SYSTEM 2459548Sandreas.hansson@arm.com system->replaceExecContext(newXC, newXC->cpu_id); 2469548Sandreas.hansson@arm.com#else 2479548Sandreas.hansson@arm.com assert(newXC->process == oldXC->process); 2489548Sandreas.hansson@arm.com newXC->process->replaceExecContext(newXC, newXC->cpu_id); 2499548Sandreas.hansson@arm.com#endif 2509548Sandreas.hansson@arm.com } 2519548Sandreas.hansson@arm.com 2529548Sandreas.hansson@arm.com#if FULL_SYSTEM 2539548Sandreas.hansson@arm.com for (int i = 0; i < TheISA::NumInterruptLevels; ++i) 2549548Sandreas.hansson@arm.com interrupts[i] = oldCPU->interrupts[i]; 2559548Sandreas.hansson@arm.com intstatus = oldCPU->intstatus; 2569548Sandreas.hansson@arm.com 2579548Sandreas.hansson@arm.com for (int i = 0; i < execContexts.size(); ++i) 2589548Sandreas.hansson@arm.com if (execContexts[i]->profile) 2599548Sandreas.hansson@arm.com execContexts[i]->profile->clear(); 2609548Sandreas.hansson@arm.com 2619782Sandreas.hansson@arm.com if (profileEvent) 2629548Sandreas.hansson@arm.com profileEvent->schedule(curTick); 2639782Sandreas.hansson@arm.com#endif 2649548Sandreas.hansson@arm.com} 2659548Sandreas.hansson@arm.com 2669548Sandreas.hansson@arm.com 2679782Sandreas.hansson@arm.com#if FULL_SYSTEM 2689548Sandreas.hansson@arm.comBaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, int _interval) 2699782Sandreas.hansson@arm.com : Event(&mainEventQueue), cpu(_cpu), interval(_interval) 2709548Sandreas.hansson@arm.com{ } 2719782Sandreas.hansson@arm.com 2729548Sandreas.hansson@arm.comvoid 2739548Sandreas.hansson@arm.comBaseCPU::ProfileEvent::process() 2749548Sandreas.hansson@arm.com{ 2759548Sandreas.hansson@arm.com for (int i = 0, size = cpu->execContexts.size(); i < size; ++i) { 2769548Sandreas.hansson@arm.com ExecContext *xc = cpu->execContexts[i]; 2779548Sandreas.hansson@arm.com xc->profile->sample(xc->profileNode, xc->profilePC); 2789548Sandreas.hansson@arm.com } 2799548Sandreas.hansson@arm.com 2807667Ssteve.reinhardt@amd.com schedule(curTick + interval); 2817667Ssteve.reinhardt@amd.com} 2827667Ssteve.reinhardt@amd.com 2834628Sstever@eecs.umich.eduvoid 2844626Sstever@eecs.umich.eduBaseCPU::post_interrupt(int int_num, int index) 2854670Sstever@eecs.umich.edu{ 2865319Sstever@gmail.com DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); 2873860Sstever@eecs.umich.edu 2883860Sstever@eecs.umich.edu if (int_num < 0 || int_num >= TheISA::NumInterruptLevels) 2893860Sstever@eecs.umich.edu panic("int_num out of bounds\n"); 2903860Sstever@eecs.umich.edu 2913860Sstever@eecs.umich.edu if (index < 0 || index >= sizeof(uint64_t) * 8) 2923860Sstever@eecs.umich.edu panic("int_num out of bounds\n"); 2934670Sstever@eecs.umich.edu 2945319Sstever@gmail.com checkInterrupts = true; 2953860Sstever@eecs.umich.edu interrupts[int_num] |= 1 << index; 2963860Sstever@eecs.umich.edu intstatus |= (ULL(1) << int_num); 2973860Sstever@eecs.umich.edu} 2983860Sstever@eecs.umich.edu 2993860Sstever@eecs.umich.eduvoid 3003860Sstever@eecs.umich.eduBaseCPU::clear_interrupt(int int_num, int index) 3013860Sstever@eecs.umich.edu{ 3023860Sstever@eecs.umich.edu DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); 3039347SAndreas.Sandberg@arm.com 3049347SAndreas.Sandberg@arm.com if (int_num < 0 || int_num >= TheISA::NumInterruptLevels) 3059347SAndreas.Sandberg@arm.com panic("int_num out of bounds\n"); 3069347SAndreas.Sandberg@arm.com 3079347SAndreas.Sandberg@arm.com if (index < 0 || index >= sizeof(uint64_t) * 8) 3089347SAndreas.Sandberg@arm.com panic("int_num out of bounds\n"); 3099347SAndreas.Sandberg@arm.com 3109347SAndreas.Sandberg@arm.com interrupts[int_num] &= ~(1 << index); 3119347SAndreas.Sandberg@arm.com if (interrupts[int_num] == 0) 3129347SAndreas.Sandberg@arm.com intstatus &= ~(ULL(1) << int_num); 3139347SAndreas.Sandberg@arm.com} 3149347SAndreas.Sandberg@arm.com 3159347SAndreas.Sandberg@arm.comvoid 3169347SAndreas.Sandberg@arm.comBaseCPU::clear_interrupts() 3179347SAndreas.Sandberg@arm.com{ 3189347SAndreas.Sandberg@arm.com DPRINTF(Interrupt, "Interrupts all cleared\n"); 3199347SAndreas.Sandberg@arm.com 3209347SAndreas.Sandberg@arm.com memset(interrupts, 0, sizeof(interrupts)); 3219347SAndreas.Sandberg@arm.com intstatus = 0; 3229347SAndreas.Sandberg@arm.com} 3239347SAndreas.Sandberg@arm.com 3249445SAndreas.Sandberg@ARM.com 3259445SAndreas.Sandberg@ARM.comvoid 3269445SAndreas.Sandberg@ARM.comBaseCPU::serialize(std::ostream &os) 3279445SAndreas.Sandberg@ARM.com{ 3289445SAndreas.Sandberg@ARM.com SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels); 3299445SAndreas.Sandberg@ARM.com SERIALIZE_SCALAR(intstatus); 3309445SAndreas.Sandberg@ARM.com} 3319445SAndreas.Sandberg@ARM.com 3329445SAndreas.Sandberg@ARM.comvoid 3339445SAndreas.Sandberg@ARM.comBaseCPU::unserialize(Checkpoint *cp, const std::string §ion) 3349445SAndreas.Sandberg@ARM.com{ 3359445SAndreas.Sandberg@ARM.com UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels); 3362810Srdreslin@umich.edu UNSERIALIZE_SCALAR(intstatus); 3372982Sstever@eecs.umich.edu} 3382810Srdreslin@umich.edu 3392982Sstever@eecs.umich.edu#endif // FULL_SYSTEM 3402810Srdreslin@umich.edu 3414626Sstever@eecs.umich.eduvoid 3424626Sstever@eecs.umich.eduBaseCPU::traceFunctionsInternal(Addr pc) 3434626Sstever@eecs.umich.edu{ 3445365Sstever@gmail.com if (!debugSymbolTable) 3455365Sstever@gmail.com return; 3465365Sstever@gmail.com 3475365Sstever@gmail.com // if pc enters different function, print new function symbol and 3485365Sstever@gmail.com // update saved range. Otherwise do nothing. 3495365Sstever@gmail.com if (pc < currentFunctionStart || pc >= currentFunctionEnd) { 3505365Sstever@gmail.com string sym_str; 3515365Sstever@gmail.com bool found = debugSymbolTable->findNearestSymbol(pc, sym_str, 3525365Sstever@gmail.com currentFunctionStart, 3534626Sstever@eecs.umich.edu currentFunctionEnd); 3544628Sstever@eecs.umich.edu 3559529Sandreas.hansson@arm.com if (!found) { 3565365Sstever@gmail.com // no symbol found: use addr as label 3575365Sstever@gmail.com sym_str = csprintf("0x%x", pc); 3585365Sstever@gmail.com currentFunctionStart = pc; 3595365Sstever@gmail.com currentFunctionEnd = pc + 1; 3605365Sstever@gmail.com } 3615365Sstever@gmail.com 3625365Sstever@gmail.com ccprintf(*functionTraceStream, " (%d)\n%d: %s", 3634626Sstever@eecs.umich.edu curTick - functionEntryTick, curTick, sym_str); 3645365Sstever@gmail.com functionEntryTick = curTick; 3655365Sstever@gmail.com } 3665365Sstever@gmail.com} 3675365Sstever@gmail.com 3685365Sstever@gmail.com 3695365Sstever@gmail.comDEFINE_SIM_OBJECT_CLASS_NAME("BaseCPU", BaseCPU) 3704628Sstever@eecs.umich.edu