base.cc revision 5713
18844SAli.Saidi@ARM.com/* 28844SAli.Saidi@ARM.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 311336Sandreas.hansson@arm.com * All rights reserved. 411502SCurtis.Dunham@arm.com * 511502SCurtis.Dunham@arm.com * Redistribution and use in source and binary forms, with or without 68844SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are 711547Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 811547Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 911547Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 1011547Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 1111547Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 1211502SCurtis.Dunham@arm.com * neither the name of the copyright holders nor the names of its 1311502SCurtis.Dunham@arm.com * contributors may be used to endorse or promote products derived from 1410036SAli.Saidi@ARM.com * this software without specific prior written permission. 1510036SAli.Saidi@ARM.com * 1611530Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1711201Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1810409Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911502SCurtis.Dunham@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011502SCurtis.Dunham@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2111502SCurtis.Dunham@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2211502SCurtis.Dunham@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2310535Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411502SCurtis.Dunham@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511502SCurtis.Dunham@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611502SCurtis.Dunham@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711502SCurtis.Dunham@arm.com * 2811502SCurtis.Dunham@arm.com * Authors: Steve Reinhardt 2910827Sandreas.hansson@arm.com * Nathan Binkert 3010409Sandreas.hansson@arm.com */ 3111502SCurtis.Dunham@arm.com 3211201Sandreas.hansson@arm.com#include <iostream> 3310409Sandreas.hansson@arm.com#include <string> 3411502SCurtis.Dunham@arm.com#include <sstream> 3511502SCurtis.Dunham@arm.com 3611502SCurtis.Dunham@arm.com#include "base/cprintf.hh" 3711502SCurtis.Dunham@arm.com#include "base/loader/symtab.hh" 3810535Sandreas.hansson@arm.com#include "base/misc.hh" 3911502SCurtis.Dunham@arm.com#include "base/output.hh" 4011502SCurtis.Dunham@arm.com#include "base/trace.hh" 4110827Sandreas.hansson@arm.com#include "cpu/base.hh" 4210409Sandreas.hansson@arm.com#include "cpu/cpuevent.hh" 4311502SCurtis.Dunham@arm.com#include "cpu/thread_context.hh" 4411201Sandreas.hansson@arm.com#include "cpu/profile.hh" 4510513SAli.Saidi@ARM.com#include "params/BaseCPU.hh" 4611502SCurtis.Dunham@arm.com#include "sim/sim_exit.hh" 4711502SCurtis.Dunham@arm.com#include "sim/process.hh" 4811502SCurtis.Dunham@arm.com#include "sim/sim_events.hh" 4911502SCurtis.Dunham@arm.com#include "sim/system.hh" 5010535Sandreas.hansson@arm.com 5111502SCurtis.Dunham@arm.com// Hack 5211502SCurtis.Dunham@arm.com#include "sim/stat_control.hh" 5311502SCurtis.Dunham@arm.com 5411502SCurtis.Dunham@arm.comusing namespace std; 5511502SCurtis.Dunham@arm.com 5610827Sandreas.hansson@arm.comvector<BaseCPU *> BaseCPU::cpuList; 5710513SAli.Saidi@ARM.com 5811502SCurtis.Dunham@arm.com// This variable reflects the max number of threads in any CPU. Be 5911502SCurtis.Dunham@arm.com// careful to only use it once all the CPUs that you care about have 6011201Sandreas.hansson@arm.com// been initialized 6110513SAli.Saidi@ARM.comint maxThreadsPerCPU = 1; 6211502SCurtis.Dunham@arm.com 6311502SCurtis.Dunham@arm.comCPUProgressEvent::CPUProgressEvent(BaseCPU *_cpu, Tick ival) 6411502SCurtis.Dunham@arm.com : Event(Event::Progress_Event_Pri), interval(ival), lastNumInst(0), 6511502SCurtis.Dunham@arm.com cpu(_cpu) 6610585Sandreas.hansson@arm.com{ 6711502SCurtis.Dunham@arm.com if (interval) 6811530Sandreas.sandberg@arm.com cpu->schedule(this, curTick + interval); 6910517SAli.Saidi@ARM.com} 7010517SAli.Saidi@ARM.com 7110517SAli.Saidi@ARM.comvoid 7210517SAli.Saidi@ARM.comCPUProgressEvent::process() 7310517SAli.Saidi@ARM.com{ 7410517SAli.Saidi@ARM.com Counter temp = cpu->totalInstructions(); 7510517SAli.Saidi@ARM.com#ifndef NDEBUG 7610517SAli.Saidi@ARM.com double ipc = double(temp - lastNumInst) / (interval / cpu->ticks(1)); 7710517SAli.Saidi@ARM.com 7810517SAli.Saidi@ARM.com DPRINTFN("%s progress event, instructions committed: %lli, IPC: %0.8d\n", 7910517SAli.Saidi@ARM.com cpu->name(), temp - lastNumInst, ipc); 8010517SAli.Saidi@ARM.com ipc = 0.0; 8110517SAli.Saidi@ARM.com#else 8210517SAli.Saidi@ARM.com cprintf("%lli: %s progress event, instructions committed: %lli\n", 8310517SAli.Saidi@ARM.com curTick, cpu->name(), temp - lastNumInst); 8410517SAli.Saidi@ARM.com#endif 8510517SAli.Saidi@ARM.com lastNumInst = temp; 8610517SAli.Saidi@ARM.com cpu->schedule(this, curTick + interval); 8711530Sandreas.sandberg@arm.com} 8811530Sandreas.sandberg@arm.com 8911530Sandreas.sandberg@arm.comconst char * 908844SAli.Saidi@ARM.comCPUProgressEvent::description() const 9110513SAli.Saidi@ARM.com{ 9210513SAli.Saidi@ARM.com return "CPU Progress"; 9310513SAli.Saidi@ARM.com} 9410513SAli.Saidi@ARM.com 9510513SAli.Saidi@ARM.com#if FULL_SYSTEM 9610535Sandreas.hansson@arm.comBaseCPU::BaseCPU(Params *p) 9711530Sandreas.sandberg@arm.com : MemObject(p), clock(p->clock), instCnt(0), _cpuId(p->cpu_id), 9810628Sandreas.hansson@arm.com interrupts(p->interrupts), 9910628Sandreas.hansson@arm.com number_of_threads(p->numThreads), system(p->system), 10010628Sandreas.hansson@arm.com phase(p->phase) 10110628Sandreas.hansson@arm.com#else 10210628Sandreas.hansson@arm.comBaseCPU::BaseCPU(Params *p) 10310628Sandreas.hansson@arm.com : MemObject(p), clock(p->clock), _cpuId(p->cpu_id), 10410628Sandreas.hansson@arm.com number_of_threads(p->numThreads), system(p->system), 10510628Sandreas.hansson@arm.com phase(p->phase) 10610535Sandreas.hansson@arm.com#endif 10710535Sandreas.hansson@arm.com{ 10810535Sandreas.hansson@arm.com// currentTick = curTick; 10910535Sandreas.hansson@arm.com 11010535Sandreas.hansson@arm.com // if Python did not provide a valid ID, do it here 11110535Sandreas.hansson@arm.com if (_cpuId == -1 ) { 11210535Sandreas.hansson@arm.com _cpuId = cpuList.size(); 11310535Sandreas.hansson@arm.com } 11410535Sandreas.hansson@arm.com 11510535Sandreas.hansson@arm.com // add self to global list of CPUs 11610535Sandreas.hansson@arm.com cpuList.push_back(this); 11710535Sandreas.hansson@arm.com 11810535Sandreas.hansson@arm.com DPRINTF(SyscallVerbose, "Constructing CPU with id %d\n", _cpuId); 11910535Sandreas.hansson@arm.com 12010535Sandreas.hansson@arm.com if (number_of_threads > maxThreadsPerCPU) 12110535Sandreas.hansson@arm.com maxThreadsPerCPU = number_of_threads; 12210535Sandreas.hansson@arm.com 12310535Sandreas.hansson@arm.com // allocate per-thread instruction-based event queues 12410535Sandreas.hansson@arm.com comInstEventQueue = new EventQueue *[number_of_threads]; 12510535Sandreas.hansson@arm.com for (int i = 0; i < number_of_threads; ++i) 12610535Sandreas.hansson@arm.com comInstEventQueue[i] = new EventQueue("instruction-based event queue"); 12711530Sandreas.sandberg@arm.com 12811336Sandreas.hansson@arm.com // 12911336Sandreas.hansson@arm.com // set up instruction-count-based termination events, if any 13011336Sandreas.hansson@arm.com // 13111336Sandreas.hansson@arm.com if (p->max_insts_any_thread != 0) { 13211336Sandreas.hansson@arm.com const char *cause = "a thread reached the max instruction count"; 13310628Sandreas.hansson@arm.com for (int i = 0; i < number_of_threads; ++i) { 13410628Sandreas.hansson@arm.com Event *event = new SimLoopExitEvent(cause, 0); 13510628Sandreas.hansson@arm.com comInstEventQueue[i]->schedule(event, p->max_insts_any_thread); 13611336Sandreas.hansson@arm.com } 13711336Sandreas.hansson@arm.com } 13811336Sandreas.hansson@arm.com 13911336Sandreas.hansson@arm.com if (p->max_insts_all_threads != 0) { 14010628Sandreas.hansson@arm.com const char *cause = "all threads reached the max instruction count"; 14111336Sandreas.hansson@arm.com 14211336Sandreas.hansson@arm.com // allocate & initialize shared downcounter: each event will 14310628Sandreas.hansson@arm.com // decrement this when triggered; simulation will terminate 14411336Sandreas.hansson@arm.com // when counter reaches 0 14511336Sandreas.hansson@arm.com int *counter = new int; 14610535Sandreas.hansson@arm.com *counter = number_of_threads; 14710535Sandreas.hansson@arm.com for (int i = 0; i < number_of_threads; ++i) { 14811507SCurtis.Dunham@arm.com Event *event = new CountedExitEvent(cause, *counter); 14911336Sandreas.hansson@arm.com comInstEventQueue[i]->schedule(event, p->max_insts_any_thread); 15011507SCurtis.Dunham@arm.com } 15110535Sandreas.hansson@arm.com } 15210535Sandreas.hansson@arm.com 15310535Sandreas.hansson@arm.com // allocate per-thread load-based event queues 15410535Sandreas.hansson@arm.com comLoadEventQueue = new EventQueue *[number_of_threads]; 15510535Sandreas.hansson@arm.com for (int i = 0; i < number_of_threads; ++i) 15611547Sandreas.sandberg@arm.com comLoadEventQueue[i] = new EventQueue("load-based event queue"); 15710535Sandreas.hansson@arm.com 15810535Sandreas.hansson@arm.com // 15910535Sandreas.hansson@arm.com // set up instruction-count-based termination events, if any 16010535Sandreas.hansson@arm.com // 16111507SCurtis.Dunham@arm.com if (p->max_loads_any_thread != 0) { 16211507SCurtis.Dunham@arm.com const char *cause = "a thread reached the max load count"; 16310535Sandreas.hansson@arm.com for (int i = 0; i < number_of_threads; ++i) { 16411507SCurtis.Dunham@arm.com Event *event = new SimLoopExitEvent(cause, 0); 16511336Sandreas.hansson@arm.com comLoadEventQueue[i]->schedule(event, p->max_loads_any_thread); 16611507SCurtis.Dunham@arm.com } 16711530Sandreas.sandberg@arm.com } 16810628Sandreas.hansson@arm.com 16910628Sandreas.hansson@arm.com if (p->max_loads_all_threads != 0) { 17010628Sandreas.hansson@arm.com const char *cause = "all threads reached the max load count"; 17110628Sandreas.hansson@arm.com // allocate & initialize shared downcounter: each event will 17210628Sandreas.hansson@arm.com // decrement this when triggered; simulation will terminate 17310628Sandreas.hansson@arm.com // when counter reaches 0 17410628Sandreas.hansson@arm.com int *counter = new int; 17510628Sandreas.hansson@arm.com *counter = number_of_threads; 17610535Sandreas.hansson@arm.com for (int i = 0; i < number_of_threads; ++i) { 17710535Sandreas.hansson@arm.com Event *event = new CountedExitEvent(cause, *counter); 17810535Sandreas.hansson@arm.com comLoadEventQueue[i]->schedule(event, p->max_loads_all_threads); 17910535Sandreas.hansson@arm.com } 18010535Sandreas.hansson@arm.com } 18110535Sandreas.hansson@arm.com 18210535Sandreas.hansson@arm.com functionTracingEnabled = false; 18310535Sandreas.hansson@arm.com if (p->function_trace) { 18410535Sandreas.hansson@arm.com functionTraceStream = simout.find(csprintf("ftrace.%s", name())); 18510535Sandreas.hansson@arm.com currentFunctionStart = currentFunctionEnd = 0; 18610535Sandreas.hansson@arm.com functionEntryTick = p->function_trace_start; 18710535Sandreas.hansson@arm.com 18810535Sandreas.hansson@arm.com if (p->function_trace_start == 0) { 18910535Sandreas.hansson@arm.com functionTracingEnabled = true; 19010535Sandreas.hansson@arm.com } else { 19110535Sandreas.hansson@arm.com typedef EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace> wrap; 19210535Sandreas.hansson@arm.com Event *event = new wrap(this, true); 19310535Sandreas.hansson@arm.com schedule(event, p->function_trace_start); 19410535Sandreas.hansson@arm.com } 19510535Sandreas.hansson@arm.com } 19610535Sandreas.hansson@arm.com#if FULL_SYSTEM 19711530Sandreas.sandberg@arm.com profileEvent = NULL; 19810628Sandreas.hansson@arm.com if (params()->profile) 19910628Sandreas.hansson@arm.com profileEvent = new ProfileEvent(this, params()->profile); 20010628Sandreas.hansson@arm.com#endif 20110628Sandreas.hansson@arm.com tracer = params()->tracer; 20210628Sandreas.hansson@arm.com} 20310628Sandreas.hansson@arm.com 20410628Sandreas.hansson@arm.comvoid 20510628Sandreas.hansson@arm.comBaseCPU::enableFunctionTrace() 20610628Sandreas.hansson@arm.com{ 20710628Sandreas.hansson@arm.com functionTracingEnabled = true; 20810628Sandreas.hansson@arm.com} 20910628Sandreas.hansson@arm.com 21010628Sandreas.hansson@arm.comBaseCPU::~BaseCPU() 21110628Sandreas.hansson@arm.com{ 21210628Sandreas.hansson@arm.com} 21310628Sandreas.hansson@arm.com 21410628Sandreas.hansson@arm.comvoid 21510628Sandreas.hansson@arm.comBaseCPU::init() 21611502SCurtis.Dunham@arm.com{ 21710535Sandreas.hansson@arm.com if (!params()->defer_registration) 21810535Sandreas.hansson@arm.com registerThreadContexts(); 21910535Sandreas.hansson@arm.com} 22010535Sandreas.hansson@arm.com 22110535Sandreas.hansson@arm.comvoid 22210535Sandreas.hansson@arm.comBaseCPU::startup() 22310535Sandreas.hansson@arm.com{ 22410535Sandreas.hansson@arm.com#if FULL_SYSTEM 22510535Sandreas.hansson@arm.com if (!params()->defer_registration && profileEvent) 22611547Sandreas.sandberg@arm.com schedule(profileEvent, curTick); 22710535Sandreas.hansson@arm.com#endif 22810535Sandreas.hansson@arm.com 22910535Sandreas.hansson@arm.com if (params()->progress_interval) { 23010535Sandreas.hansson@arm.com Tick num_ticks = ticks(params()->progress_interval); 23110535Sandreas.hansson@arm.com Event *event = new CPUProgressEvent(this, num_ticks); 23210535Sandreas.hansson@arm.com schedule(event, curTick + num_ticks); 23311502SCurtis.Dunham@arm.com } 23411502SCurtis.Dunham@arm.com} 23510535Sandreas.hansson@arm.com 23611502SCurtis.Dunham@arm.com 23711530Sandreas.sandberg@arm.comvoid 23811530Sandreas.sandberg@arm.comBaseCPU::regStats() 23911530Sandreas.sandberg@arm.com{ 24011530Sandreas.sandberg@arm.com using namespace Stats; 24111530Sandreas.sandberg@arm.com 24211530Sandreas.sandberg@arm.com numCycles 24311530Sandreas.sandberg@arm.com .name(name() + ".numCycles") 24411530Sandreas.sandberg@arm.com .desc("number of cpu cycles simulated") 24511530Sandreas.sandberg@arm.com ; 24611530Sandreas.sandberg@arm.com 24711530Sandreas.sandberg@arm.com int size = threadContexts.size(); 24811530Sandreas.sandberg@arm.com if (size > 1) { 24911530Sandreas.sandberg@arm.com for (int i = 0; i < size; ++i) { 25011530Sandreas.sandberg@arm.com stringstream namestr; 25111502SCurtis.Dunham@arm.com ccprintf(namestr, "%s.ctx%d", name(), i); 25210535Sandreas.hansson@arm.com threadContexts[i]->regStats(namestr.str()); 25310535Sandreas.hansson@arm.com } 25411201Sandreas.hansson@arm.com } else if (size == 1) 25511502SCurtis.Dunham@arm.com threadContexts[0]->regStats(name()); 25611502SCurtis.Dunham@arm.com 25711502SCurtis.Dunham@arm.com#if FULL_SYSTEM 25811502SCurtis.Dunham@arm.com#endif 25910535Sandreas.hansson@arm.com} 26011502SCurtis.Dunham@arm.com 26111502SCurtis.Dunham@arm.comTick 26211502SCurtis.Dunham@arm.comBaseCPU::nextCycle() 26310535Sandreas.hansson@arm.com{ 26411515Sandreas.sandberg@arm.com Tick next_tick = curTick - phase + clock - 1; 26511507SCurtis.Dunham@arm.com next_tick -= (next_tick % clock); 26610535Sandreas.hansson@arm.com next_tick += phase; 26710535Sandreas.hansson@arm.com return next_tick; 26811502SCurtis.Dunham@arm.com} 26911502SCurtis.Dunham@arm.com 27011502SCurtis.Dunham@arm.comTick 27111502SCurtis.Dunham@arm.comBaseCPU::nextCycle(Tick begin_tick) 27211502SCurtis.Dunham@arm.com{ 27311502SCurtis.Dunham@arm.com Tick next_tick = begin_tick; 27411502SCurtis.Dunham@arm.com if (next_tick % clock != 0) 27510535Sandreas.hansson@arm.com next_tick = next_tick - (next_tick % clock) + clock; 27610535Sandreas.hansson@arm.com next_tick += phase; 27711502SCurtis.Dunham@arm.com 27810535Sandreas.hansson@arm.com assert(next_tick >= curTick); 27911502SCurtis.Dunham@arm.com return next_tick; 28011336Sandreas.hansson@arm.com} 28110535Sandreas.hansson@arm.com 28210535Sandreas.hansson@arm.comvoid 28310535Sandreas.hansson@arm.comBaseCPU::registerThreadContexts() 28410535Sandreas.hansson@arm.com{ 28510535Sandreas.hansson@arm.com for (int i = 0; i < threadContexts.size(); ++i) { 28610535Sandreas.hansson@arm.com ThreadContext *tc = threadContexts[i]; 28710535Sandreas.hansson@arm.com 28810535Sandreas.hansson@arm.com system->registerThreadContext(tc); 28910535Sandreas.hansson@arm.com#if !FULL_SYSTEM 29010535Sandreas.hansson@arm.com tc->getProcessPtr()->assignThreadContext(tc->cpuId()); 29110535Sandreas.hansson@arm.com#endif 29210535Sandreas.hansson@arm.com } 29310535Sandreas.hansson@arm.com} 29410535Sandreas.hansson@arm.com 29510535Sandreas.hansson@arm.com 29610535Sandreas.hansson@arm.comint 29710535Sandreas.hansson@arm.comBaseCPU::findContext(ThreadContext *tc) 29810535Sandreas.hansson@arm.com{ 29910535Sandreas.hansson@arm.com for (int i = 0; i < threadContexts.size(); ++i) { 30010535Sandreas.hansson@arm.com if (tc == threadContexts[i]) 30110535Sandreas.hansson@arm.com return i; 30210535Sandreas.hansson@arm.com } 30310535Sandreas.hansson@arm.com return 0; 30410535Sandreas.hansson@arm.com} 30510535Sandreas.hansson@arm.com 30610535Sandreas.hansson@arm.comvoid 30710535Sandreas.hansson@arm.comBaseCPU::switchOut() 30811502SCurtis.Dunham@arm.com{ 30911502SCurtis.Dunham@arm.com// panic("This CPU doesn't support sampling!"); 31010535Sandreas.hansson@arm.com#if FULL_SYSTEM 31110535Sandreas.hansson@arm.com if (profileEvent && profileEvent->scheduled()) 31211502SCurtis.Dunham@arm.com deschedule(profileEvent); 31311530Sandreas.sandberg@arm.com#endif 31411502SCurtis.Dunham@arm.com} 31511502SCurtis.Dunham@arm.com 31611507SCurtis.Dunham@arm.comvoid 31711502SCurtis.Dunham@arm.comBaseCPU::takeOverFrom(BaseCPU *oldCPU, Port *ic, Port *dc) 31811507SCurtis.Dunham@arm.com{ 31910827Sandreas.hansson@arm.com assert(threadContexts.size() == oldCPU->threadContexts.size()); 32011502SCurtis.Dunham@arm.com 32110535Sandreas.hansson@arm.com _cpuId = oldCPU->cpuId(); 32210535Sandreas.hansson@arm.com 32310535Sandreas.hansson@arm.com for (int i = 0; i < threadContexts.size(); ++i) { 32410535Sandreas.hansson@arm.com ThreadContext *newTC = threadContexts[i]; 32510535Sandreas.hansson@arm.com ThreadContext *oldTC = oldCPU->threadContexts[i]; 32610535Sandreas.hansson@arm.com 32710535Sandreas.hansson@arm.com newTC->takeOverFrom(oldTC); 32811507SCurtis.Dunham@arm.com 32911507SCurtis.Dunham@arm.com CpuEvent::replaceThreadContext(oldTC, newTC); 33011530Sandreas.sandberg@arm.com 33111507SCurtis.Dunham@arm.com assert(newTC->cpuId() == oldTC->cpuId()); 33211507SCurtis.Dunham@arm.com system->replaceThreadContext(newTC, newTC->cpuId()); 33311507SCurtis.Dunham@arm.com 33411507SCurtis.Dunham@arm.com if (DTRACE(Context)) 33511502SCurtis.Dunham@arm.com ThreadContext::compare(oldTC, newTC); 33611502SCurtis.Dunham@arm.com } 33711502SCurtis.Dunham@arm.com 33811502SCurtis.Dunham@arm.com#if FULL_SYSTEM 33911502SCurtis.Dunham@arm.com interrupts = oldCPU->interrupts; 34011502SCurtis.Dunham@arm.com 34111507SCurtis.Dunham@arm.com for (int i = 0; i < threadContexts.size(); ++i) 34211507SCurtis.Dunham@arm.com threadContexts[i]->profileClear(); 34311507SCurtis.Dunham@arm.com 34411507SCurtis.Dunham@arm.com if (profileEvent) 34511502SCurtis.Dunham@arm.com schedule(profileEvent, curTick); 34611502SCurtis.Dunham@arm.com#endif 34711502SCurtis.Dunham@arm.com 34811502SCurtis.Dunham@arm.com // Connect new CPU to old CPU's memory only if new CPU isn't 34911502SCurtis.Dunham@arm.com // connected to anything. Also connect old CPU's memory to new 35011502SCurtis.Dunham@arm.com // CPU. 35111336Sandreas.hansson@arm.com if (!ic->isConnected()) { 35211336Sandreas.hansson@arm.com Port *peer = oldCPU->getPort("icache_port")->getPeer(); 35311502SCurtis.Dunham@arm.com ic->setPeer(peer); 35411502SCurtis.Dunham@arm.com peer->setPeer(ic); 35511502SCurtis.Dunham@arm.com } 35611502SCurtis.Dunham@arm.com 35711502SCurtis.Dunham@arm.com if (!dc->isConnected()) { 35811502SCurtis.Dunham@arm.com Port *peer = oldCPU->getPort("dcache_port")->getPeer(); 35911507SCurtis.Dunham@arm.com dc->setPeer(peer); 36011507SCurtis.Dunham@arm.com peer->setPeer(dc); 36111507SCurtis.Dunham@arm.com } 36211507SCurtis.Dunham@arm.com} 36311502SCurtis.Dunham@arm.com 36411502SCurtis.Dunham@arm.com 36511502SCurtis.Dunham@arm.com#if FULL_SYSTEM 36611502SCurtis.Dunham@arm.comBaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, Tick _interval) 36711502SCurtis.Dunham@arm.com : cpu(_cpu), interval(_interval) 36811502SCurtis.Dunham@arm.com{ } 36911507SCurtis.Dunham@arm.com 37011507SCurtis.Dunham@arm.comvoid 37111507SCurtis.Dunham@arm.comBaseCPU::ProfileEvent::process() 37211507SCurtis.Dunham@arm.com{ 37311336Sandreas.hansson@arm.com for (int i = 0, size = cpu->threadContexts.size(); i < size; ++i) { 37411336Sandreas.hansson@arm.com ThreadContext *tc = cpu->threadContexts[i]; 37511201Sandreas.hansson@arm.com tc->profileSample(); 37611201Sandreas.hansson@arm.com } 37711502SCurtis.Dunham@arm.com 37811502SCurtis.Dunham@arm.com cpu->schedule(this, curTick + interval); 37911336Sandreas.hansson@arm.com} 38011336Sandreas.hansson@arm.com 38111502SCurtis.Dunham@arm.comvoid 38211502SCurtis.Dunham@arm.comBaseCPU::postInterrupt(int int_num, int index) 38311201Sandreas.hansson@arm.com{ 38411201Sandreas.hansson@arm.com interrupts->post(int_num, index); 38511201Sandreas.hansson@arm.com} 38611201Sandreas.hansson@arm.com 38710535Sandreas.hansson@arm.comvoid 38810535Sandreas.hansson@arm.comBaseCPU::clearInterrupt(int int_num, int index) 38910535Sandreas.hansson@arm.com{ 39010535Sandreas.hansson@arm.com interrupts->clear(int_num, index); 39110535Sandreas.hansson@arm.com} 39210535Sandreas.hansson@arm.com 39311502SCurtis.Dunham@arm.comvoid 39411502SCurtis.Dunham@arm.comBaseCPU::clearInterrupts() 39511530Sandreas.sandberg@arm.com{ 39611502SCurtis.Dunham@arm.com interrupts->clearAll(); 39711336Sandreas.hansson@arm.com} 39811502SCurtis.Dunham@arm.com 39911502SCurtis.Dunham@arm.comvoid 40011502SCurtis.Dunham@arm.comBaseCPU::serialize(std::ostream &os) 40110535Sandreas.hansson@arm.com{ 40211336Sandreas.hansson@arm.com SERIALIZE_SCALAR(instCnt); 40310535Sandreas.hansson@arm.com interrupts->serialize(os); 40410535Sandreas.hansson@arm.com} 40510535Sandreas.hansson@arm.com 40610535Sandreas.hansson@arm.comvoid 40710535Sandreas.hansson@arm.comBaseCPU::unserialize(Checkpoint *cp, const std::string §ion) 40810535Sandreas.hansson@arm.com{ 40910535Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(instCnt); 41011502SCurtis.Dunham@arm.com interrupts->unserialize(cp, section); 41111502SCurtis.Dunham@arm.com} 41211530Sandreas.sandberg@arm.com 41311502SCurtis.Dunham@arm.com#endif // FULL_SYSTEM 41411502SCurtis.Dunham@arm.com 41511502SCurtis.Dunham@arm.comvoid 41611502SCurtis.Dunham@arm.comBaseCPU::traceFunctionsInternal(Addr pc) 41711502SCurtis.Dunham@arm.com{ 41811502SCurtis.Dunham@arm.com if (!debugSymbolTable) 41911502SCurtis.Dunham@arm.com return; 42011502SCurtis.Dunham@arm.com 42111502SCurtis.Dunham@arm.com // if pc enters different function, print new function symbol and 42211502SCurtis.Dunham@arm.com // update saved range. Otherwise do nothing. 42311502SCurtis.Dunham@arm.com if (pc < currentFunctionStart || pc >= currentFunctionEnd) { 42411502SCurtis.Dunham@arm.com string sym_str; 42511502SCurtis.Dunham@arm.com bool found = debugSymbolTable->findNearestSymbol(pc, sym_str, 42611502SCurtis.Dunham@arm.com currentFunctionStart, 42711502SCurtis.Dunham@arm.com currentFunctionEnd); 42811502SCurtis.Dunham@arm.com 42911502SCurtis.Dunham@arm.com if (!found) { 43011502SCurtis.Dunham@arm.com // no symbol found: use addr as label 43111336Sandreas.hansson@arm.com sym_str = csprintf("0x%x", pc); 43211336Sandreas.hansson@arm.com currentFunctionStart = pc; 43311336Sandreas.hansson@arm.com currentFunctionEnd = pc + 1; 43411336Sandreas.hansson@arm.com } 43511336Sandreas.hansson@arm.com 43611336Sandreas.hansson@arm.com ccprintf(*functionTraceStream, " (%d)\n%d: %s", 43710535Sandreas.hansson@arm.com curTick - functionEntryTick, curTick, sym_str); 43810535Sandreas.hansson@arm.com functionEntryTick = curTick; 43910535Sandreas.hansson@arm.com } 44010535Sandreas.hansson@arm.com} 44110535Sandreas.hansson@arm.com