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