base.cc revision 8711
12SN/A/* 28707Sandreas.hansson@arm.com * Copyright (c) 2011 ARM Limited 38707Sandreas.hansson@arm.com * All rights reserved 48707Sandreas.hansson@arm.com * 58707Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 68707Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 78707Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 88707Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 98707Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 108707Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 118707Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 128707Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 138707Sandreas.hansson@arm.com * 141762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 157897Shestness@cs.utexas.edu * Copyright (c) 2011 Regents of the University of California 162SN/A * All rights reserved. 172SN/A * 182SN/A * Redistribution and use in source and binary forms, with or without 192SN/A * modification, are permitted provided that the following conditions are 202SN/A * met: redistributions of source code must retain the above copyright 212SN/A * notice, this list of conditions and the following disclaimer; 222SN/A * redistributions in binary form must reproduce the above copyright 232SN/A * notice, this list of conditions and the following disclaimer in the 242SN/A * documentation and/or other materials provided with the distribution; 252SN/A * neither the name of the copyright holders nor the names of its 262SN/A * contributors may be used to endorse or promote products derived from 272SN/A * this software without specific prior written permission. 282SN/A * 292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 302SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 312SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 322SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 332SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 342SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 352SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 362SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 372SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 382SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 392SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402665Ssaidi@eecs.umich.edu * 412665Ssaidi@eecs.umich.edu * Authors: Steve Reinhardt 422665Ssaidi@eecs.umich.edu * Nathan Binkert 437897Shestness@cs.utexas.edu * Rick Strong 442SN/A */ 452SN/A 461388SN/A#include <iostream> 478229Snate@binkert.org#include <sstream> 482SN/A#include <string> 492SN/A 507781SAli.Saidi@ARM.com#include "arch/tlb.hh" 518229Snate@binkert.org#include "base/loader/symtab.hh" 521191SN/A#include "base/cprintf.hh" 531191SN/A#include "base/misc.hh" 541388SN/A#include "base/output.hh" 555529Snate@binkert.org#include "base/trace.hh" 561717SN/A#include "cpu/base.hh" 572651Ssaidi@eecs.umich.edu#include "cpu/cpuevent.hh" 588229Snate@binkert.org#include "cpu/profile.hh" 592680Sktlim@umich.edu#include "cpu/thread_context.hh" 608232Snate@binkert.org#include "debug/SyscallVerbose.hh" 615529Snate@binkert.org#include "params/BaseCPU.hh" 622190SN/A#include "sim/process.hh" 6356SN/A#include "sim/sim_events.hh" 648229Snate@binkert.org#include "sim/sim_exit.hh" 652190SN/A#include "sim/system.hh" 662SN/A 672359SN/A// Hack 682359SN/A#include "sim/stat_control.hh" 692359SN/A 702SN/Ausing namespace std; 712SN/A 722SN/Avector<BaseCPU *> BaseCPU::cpuList; 732SN/A 742SN/A// This variable reflects the max number of threads in any CPU. Be 752SN/A// careful to only use it once all the CPUs that you care about have 762SN/A// been initialized 772SN/Aint maxThreadsPerCPU = 1; 782SN/A 795606Snate@binkert.orgCPUProgressEvent::CPUProgressEvent(BaseCPU *_cpu, Tick ival) 806144Sksewell@umich.edu : Event(Event::Progress_Event_Pri), _interval(ival), lastNumInst(0), 816144Sksewell@umich.edu cpu(_cpu), _repeatEvent(true) 823126Sktlim@umich.edu{ 836144Sksewell@umich.edu if (_interval) 847823Ssteve.reinhardt@amd.com cpu->schedule(this, curTick() + _interval); 853126Sktlim@umich.edu} 863126Sktlim@umich.edu 872356SN/Avoid 882356SN/ACPUProgressEvent::process() 892356SN/A{ 902367SN/A Counter temp = cpu->totalInstructions(); 912356SN/A#ifndef NDEBUG 926144Sksewell@umich.edu double ipc = double(temp - lastNumInst) / (_interval / cpu->ticks(1)); 932367SN/A 946144Sksewell@umich.edu DPRINTFN("%s progress event, total committed:%i, progress insts committed: " 956144Sksewell@umich.edu "%lli, IPC: %0.8d\n", cpu->name(), temp, temp - lastNumInst, 966144Sksewell@umich.edu ipc); 972356SN/A ipc = 0.0; 982367SN/A#else 996144Sksewell@umich.edu cprintf("%lli: %s progress event, total committed:%i, progress insts " 1007823Ssteve.reinhardt@amd.com "committed: %lli\n", curTick(), cpu->name(), temp, 1016144Sksewell@umich.edu temp - lastNumInst); 1022367SN/A#endif 1032356SN/A lastNumInst = temp; 1046144Sksewell@umich.edu 1056144Sksewell@umich.edu if (_repeatEvent) 1067823Ssteve.reinhardt@amd.com cpu->schedule(this, curTick() + _interval); 1072356SN/A} 1082356SN/A 1092356SN/Aconst char * 1105336Shines@cs.fsu.eduCPUProgressEvent::description() const 1112356SN/A{ 1124873Sstever@eecs.umich.edu return "CPU Progress"; 1132356SN/A} 1142356SN/A 1151858SN/A#if FULL_SYSTEM 1161400SN/ABaseCPU::BaseCPU(Params *p) 1175712Shsul@eecs.umich.edu : MemObject(p), clock(p->clock), instCnt(0), _cpuId(p->cpu_id), 1185712Shsul@eecs.umich.edu interrupts(p->interrupts), 1196221Snate@binkert.org numThreads(p->numThreads), system(p->system), 1203661Srdreslin@umich.edu phase(p->phase) 1212SN/A#else 1221400SN/ABaseCPU::BaseCPU(Params *p) 1235712Shsul@eecs.umich.edu : MemObject(p), clock(p->clock), _cpuId(p->cpu_id), 1246221Snate@binkert.org numThreads(p->numThreads), system(p->system), 1253661Srdreslin@umich.edu phase(p->phase) 1262SN/A#endif 1272SN/A{ 1287823Ssteve.reinhardt@amd.com// currentTick = curTick(); 1291062SN/A 1305712Shsul@eecs.umich.edu // if Python did not provide a valid ID, do it here 1315712Shsul@eecs.umich.edu if (_cpuId == -1 ) { 1325712Shsul@eecs.umich.edu _cpuId = cpuList.size(); 1335712Shsul@eecs.umich.edu } 1345712Shsul@eecs.umich.edu 1352SN/A // add self to global list of CPUs 1362SN/A cpuList.push_back(this); 1372SN/A 1385712Shsul@eecs.umich.edu DPRINTF(SyscallVerbose, "Constructing CPU with id %d\n", _cpuId); 1395712Shsul@eecs.umich.edu 1406221Snate@binkert.org if (numThreads > maxThreadsPerCPU) 1416221Snate@binkert.org maxThreadsPerCPU = numThreads; 1422SN/A 1432SN/A // allocate per-thread instruction-based event queues 1446221Snate@binkert.org comInstEventQueue = new EventQueue *[numThreads]; 1456221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; ++tid) 1466221Snate@binkert.org comInstEventQueue[tid] = 1476221Snate@binkert.org new EventQueue("instruction-based event queue"); 1482SN/A 1492SN/A // 1502SN/A // set up instruction-count-based termination events, if any 1512SN/A // 1525606Snate@binkert.org if (p->max_insts_any_thread != 0) { 1535606Snate@binkert.org const char *cause = "a thread reached the max instruction count"; 1546221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; ++tid) { 1555606Snate@binkert.org Event *event = new SimLoopExitEvent(cause, 0); 1566221Snate@binkert.org comInstEventQueue[tid]->schedule(event, p->max_insts_any_thread); 1575606Snate@binkert.org } 1585606Snate@binkert.org } 1592SN/A 1601400SN/A if (p->max_insts_all_threads != 0) { 1615606Snate@binkert.org const char *cause = "all threads reached the max instruction count"; 1625606Snate@binkert.org 1632SN/A // allocate & initialize shared downcounter: each event will 1642SN/A // decrement this when triggered; simulation will terminate 1652SN/A // when counter reaches 0 1662SN/A int *counter = new int; 1676221Snate@binkert.org *counter = numThreads; 1686221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; ++tid) { 1695606Snate@binkert.org Event *event = new CountedExitEvent(cause, *counter); 1706670Shsul@eecs.umich.edu comInstEventQueue[tid]->schedule(event, p->max_insts_all_threads); 1715606Snate@binkert.org } 1722SN/A } 1732SN/A 174124SN/A // allocate per-thread load-based event queues 1756221Snate@binkert.org comLoadEventQueue = new EventQueue *[numThreads]; 1766221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; ++tid) 1776221Snate@binkert.org comLoadEventQueue[tid] = new EventQueue("load-based event queue"); 178124SN/A 179124SN/A // 180124SN/A // set up instruction-count-based termination events, if any 181124SN/A // 1825606Snate@binkert.org if (p->max_loads_any_thread != 0) { 1835606Snate@binkert.org const char *cause = "a thread reached the max load count"; 1846221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; ++tid) { 1855606Snate@binkert.org Event *event = new SimLoopExitEvent(cause, 0); 1866221Snate@binkert.org comLoadEventQueue[tid]->schedule(event, p->max_loads_any_thread); 1875606Snate@binkert.org } 1885606Snate@binkert.org } 189124SN/A 1901400SN/A if (p->max_loads_all_threads != 0) { 1915606Snate@binkert.org const char *cause = "all threads reached the max load count"; 192124SN/A // allocate & initialize shared downcounter: each event will 193124SN/A // decrement this when triggered; simulation will terminate 194124SN/A // when counter reaches 0 195124SN/A int *counter = new int; 1966221Snate@binkert.org *counter = numThreads; 1976221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; ++tid) { 1985606Snate@binkert.org Event *event = new CountedExitEvent(cause, *counter); 1996221Snate@binkert.org comLoadEventQueue[tid]->schedule(event, p->max_loads_all_threads); 2005606Snate@binkert.org } 201124SN/A } 202124SN/A 2031191SN/A functionTracingEnabled = false; 2045529Snate@binkert.org if (p->function_trace) { 2058634Schris.emmons@arm.com const string fname = csprintf("ftrace.%s", name()); 2068634Schris.emmons@arm.com functionTraceStream = simout.find(fname); 2078634Schris.emmons@arm.com if (!functionTraceStream) 2088634Schris.emmons@arm.com functionTraceStream = simout.create(fname); 2098634Schris.emmons@arm.com 2101191SN/A currentFunctionStart = currentFunctionEnd = 0; 2115529Snate@binkert.org functionEntryTick = p->function_trace_start; 2121191SN/A 2135529Snate@binkert.org if (p->function_trace_start == 0) { 2141191SN/A functionTracingEnabled = true; 2151191SN/A } else { 2165606Snate@binkert.org typedef EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace> wrap; 2175606Snate@binkert.org Event *event = new wrap(this, true); 2185606Snate@binkert.org schedule(event, p->function_trace_start); 2191191SN/A } 2201191SN/A } 2211917SN/A#if FULL_SYSTEM 2225810Sgblack@eecs.umich.edu interrupts->setCPU(this); 2235810Sgblack@eecs.umich.edu 2241917SN/A profileEvent = NULL; 2255529Snate@binkert.org if (params()->profile) 2265529Snate@binkert.org profileEvent = new ProfileEvent(this, params()->profile); 2271917SN/A#endif 2285529Snate@binkert.org tracer = params()->tracer; 2291917SN/A} 2301191SN/A 2311191SN/Avoid 2321191SN/ABaseCPU::enableFunctionTrace() 2331191SN/A{ 2341191SN/A functionTracingEnabled = true; 2351191SN/A} 2361191SN/A 2371191SN/ABaseCPU::~BaseCPU() 2381191SN/A{ 2391191SN/A} 2401191SN/A 2411129SN/Avoid 2421129SN/ABaseCPU::init() 2431129SN/A{ 2445529Snate@binkert.org if (!params()->defer_registration) 2452680Sktlim@umich.edu registerThreadContexts(); 2461129SN/A} 247180SN/A 2482SN/Avoid 2491917SN/ABaseCPU::startup() 2501917SN/A{ 2511917SN/A#if FULL_SYSTEM 2525529Snate@binkert.org if (!params()->defer_registration && profileEvent) 2537823Ssteve.reinhardt@amd.com schedule(profileEvent, curTick()); 2541917SN/A#endif 2552356SN/A 2565529Snate@binkert.org if (params()->progress_interval) { 2575606Snate@binkert.org Tick num_ticks = ticks(params()->progress_interval); 2586144Sksewell@umich.edu 2598607Sgblack@eecs.umich.edu new CPUProgressEvent(this, num_ticks); 2602356SN/A } 2611917SN/A} 2621917SN/A 2631917SN/A 2641917SN/Avoid 2652SN/ABaseCPU::regStats() 2662SN/A{ 267729SN/A using namespace Stats; 268707SN/A 269707SN/A numCycles 270707SN/A .name(name() + ".numCycles") 271707SN/A .desc("number of cpu cycles simulated") 272707SN/A ; 273707SN/A 2747914SBrad.Beckmann@amd.com numWorkItemsStarted 2757914SBrad.Beckmann@amd.com .name(name() + ".numWorkItemsStarted") 2767914SBrad.Beckmann@amd.com .desc("number of work items this cpu started") 2777914SBrad.Beckmann@amd.com ; 2787914SBrad.Beckmann@amd.com 2797914SBrad.Beckmann@amd.com numWorkItemsCompleted 2807914SBrad.Beckmann@amd.com .name(name() + ".numWorkItemsCompleted") 2817914SBrad.Beckmann@amd.com .desc("number of work items this cpu completed") 2827914SBrad.Beckmann@amd.com ; 2837914SBrad.Beckmann@amd.com 2842680Sktlim@umich.edu int size = threadContexts.size(); 2852SN/A if (size > 1) { 2862SN/A for (int i = 0; i < size; ++i) { 2872SN/A stringstream namestr; 2882SN/A ccprintf(namestr, "%s.ctx%d", name(), i); 2892680Sktlim@umich.edu threadContexts[i]->regStats(namestr.str()); 2902SN/A } 2912SN/A } else if (size == 1) 2922680Sktlim@umich.edu threadContexts[0]->regStats(name()); 2932190SN/A 2942190SN/A#if FULL_SYSTEM 2952190SN/A#endif 2962SN/A} 2972SN/A 2983495Sktlim@umich.eduTick 2993495Sktlim@umich.eduBaseCPU::nextCycle() 3003495Sktlim@umich.edu{ 3017823Ssteve.reinhardt@amd.com Tick next_tick = curTick() - phase + clock - 1; 3023495Sktlim@umich.edu next_tick -= (next_tick % clock); 3033661Srdreslin@umich.edu next_tick += phase; 3043495Sktlim@umich.edu return next_tick; 3053495Sktlim@umich.edu} 3063495Sktlim@umich.edu 3073495Sktlim@umich.eduTick 3083495Sktlim@umich.eduBaseCPU::nextCycle(Tick begin_tick) 3093495Sktlim@umich.edu{ 3103495Sktlim@umich.edu Tick next_tick = begin_tick; 3114599Sacolyte@umich.edu if (next_tick % clock != 0) 3124599Sacolyte@umich.edu next_tick = next_tick - (next_tick % clock) + clock; 3133661Srdreslin@umich.edu next_tick += phase; 3143495Sktlim@umich.edu 3157823Ssteve.reinhardt@amd.com assert(next_tick >= curTick()); 3163495Sktlim@umich.edu return next_tick; 3173495Sktlim@umich.edu} 318180SN/A 319180SN/Avoid 3202680Sktlim@umich.eduBaseCPU::registerThreadContexts() 321180SN/A{ 3226221Snate@binkert.org ThreadID size = threadContexts.size(); 3236221Snate@binkert.org for (ThreadID tid = 0; tid < size; ++tid) { 3246221Snate@binkert.org ThreadContext *tc = threadContexts[tid]; 3252378SN/A 3265718Shsul@eecs.umich.edu /** This is so that contextId and cpuId match where there is a 3275718Shsul@eecs.umich.edu * 1cpu:1context relationship. Otherwise, the order of registration 3285718Shsul@eecs.umich.edu * could affect the assignment and cpu 1 could have context id 3, for 3295718Shsul@eecs.umich.edu * example. We may even want to do something like this for SMT so that 3305718Shsul@eecs.umich.edu * cpu 0 has the lowest thread contexts and cpu N has the highest, but 3315718Shsul@eecs.umich.edu * I'll just do this for now 3325718Shsul@eecs.umich.edu */ 3336221Snate@binkert.org if (numThreads == 1) 3345718Shsul@eecs.umich.edu tc->setContextId(system->registerThreadContext(tc, _cpuId)); 3355718Shsul@eecs.umich.edu else 3365718Shsul@eecs.umich.edu tc->setContextId(system->registerThreadContext(tc)); 3375713Shsul@eecs.umich.edu#if !FULL_SYSTEM 3385714Shsul@eecs.umich.edu tc->getProcessPtr()->assignThreadContext(tc->contextId()); 339180SN/A#endif 340180SN/A } 341180SN/A} 342180SN/A 343180SN/A 3444000Ssaidi@eecs.umich.eduint 3454000Ssaidi@eecs.umich.eduBaseCPU::findContext(ThreadContext *tc) 3464000Ssaidi@eecs.umich.edu{ 3476221Snate@binkert.org ThreadID size = threadContexts.size(); 3486221Snate@binkert.org for (ThreadID tid = 0; tid < size; ++tid) { 3496221Snate@binkert.org if (tc == threadContexts[tid]) 3506221Snate@binkert.org return tid; 3514000Ssaidi@eecs.umich.edu } 3524000Ssaidi@eecs.umich.edu return 0; 3534000Ssaidi@eecs.umich.edu} 3544000Ssaidi@eecs.umich.edu 355180SN/Avoid 3562798Sktlim@umich.eduBaseCPU::switchOut() 357180SN/A{ 3582359SN/A// panic("This CPU doesn't support sampling!"); 3592359SN/A#if FULL_SYSTEM 3602359SN/A if (profileEvent && profileEvent->scheduled()) 3615606Snate@binkert.org deschedule(profileEvent); 3622359SN/A#endif 363180SN/A} 364180SN/A 365180SN/Avoid 3664192Sktlim@umich.eduBaseCPU::takeOverFrom(BaseCPU *oldCPU, Port *ic, Port *dc) 367180SN/A{ 3682680Sktlim@umich.edu assert(threadContexts.size() == oldCPU->threadContexts.size()); 369180SN/A 3705712Shsul@eecs.umich.edu _cpuId = oldCPU->cpuId(); 3715712Shsul@eecs.umich.edu 3726221Snate@binkert.org ThreadID size = threadContexts.size(); 3736221Snate@binkert.org for (ThreadID i = 0; i < size; ++i) { 3742680Sktlim@umich.edu ThreadContext *newTC = threadContexts[i]; 3752680Sktlim@umich.edu ThreadContext *oldTC = oldCPU->threadContexts[i]; 376180SN/A 3772680Sktlim@umich.edu newTC->takeOverFrom(oldTC); 3782651Ssaidi@eecs.umich.edu 3792680Sktlim@umich.edu CpuEvent::replaceThreadContext(oldTC, newTC); 3802651Ssaidi@eecs.umich.edu 3815714Shsul@eecs.umich.edu assert(newTC->contextId() == oldTC->contextId()); 3825715Shsul@eecs.umich.edu assert(newTC->threadId() == oldTC->threadId()); 3835714Shsul@eecs.umich.edu system->replaceThreadContext(newTC, newTC->contextId()); 3842359SN/A 3855875Ssteve.reinhardt@amd.com /* This code no longer works since the zero register (e.g., 3865875Ssteve.reinhardt@amd.com * r31 on Alpha) doesn't necessarily contain zero at this 3875875Ssteve.reinhardt@amd.com * point. 3885875Ssteve.reinhardt@amd.com if (DTRACE(Context)) 3895217Ssaidi@eecs.umich.edu ThreadContext::compare(oldTC, newTC); 3905875Ssteve.reinhardt@amd.com */ 3917781SAli.Saidi@ARM.com 3927781SAli.Saidi@ARM.com Port *old_itb_port, *old_dtb_port, *new_itb_port, *new_dtb_port; 3937781SAli.Saidi@ARM.com old_itb_port = oldTC->getITBPtr()->getPort(); 3947781SAli.Saidi@ARM.com old_dtb_port = oldTC->getDTBPtr()->getPort(); 3957781SAli.Saidi@ARM.com new_itb_port = newTC->getITBPtr()->getPort(); 3967781SAli.Saidi@ARM.com new_dtb_port = newTC->getDTBPtr()->getPort(); 3977781SAli.Saidi@ARM.com 3987781SAli.Saidi@ARM.com // Move over any table walker ports if they exist 3997781SAli.Saidi@ARM.com if (new_itb_port && !new_itb_port->isConnected()) { 4007781SAli.Saidi@ARM.com assert(old_itb_port); 4017781SAli.Saidi@ARM.com Port *peer = old_itb_port->getPeer();; 4027781SAli.Saidi@ARM.com new_itb_port->setPeer(peer); 4037781SAli.Saidi@ARM.com peer->setPeer(new_itb_port); 4047781SAli.Saidi@ARM.com } 4057781SAli.Saidi@ARM.com if (new_dtb_port && !new_dtb_port->isConnected()) { 4067781SAli.Saidi@ARM.com assert(old_dtb_port); 4077781SAli.Saidi@ARM.com Port *peer = old_dtb_port->getPeer();; 4087781SAli.Saidi@ARM.com new_dtb_port->setPeer(peer); 4097781SAli.Saidi@ARM.com peer->setPeer(new_dtb_port); 4107781SAli.Saidi@ARM.com } 411180SN/A } 412605SN/A 4131858SN/A#if FULL_SYSTEM 4143520Sgblack@eecs.umich.edu interrupts = oldCPU->interrupts; 4155810Sgblack@eecs.umich.edu interrupts->setCPU(this); 4162254SN/A 4176221Snate@binkert.org for (ThreadID i = 0; i < size; ++i) 4182680Sktlim@umich.edu threadContexts[i]->profileClear(); 4192254SN/A 4204947Snate@binkert.org if (profileEvent) 4217823Ssteve.reinhardt@amd.com schedule(profileEvent, curTick()); 422612SN/A#endif 4234192Sktlim@umich.edu 4244192Sktlim@umich.edu // Connect new CPU to old CPU's memory only if new CPU isn't 4254192Sktlim@umich.edu // connected to anything. Also connect old CPU's memory to new 4264192Sktlim@umich.edu // CPU. 4275476Snate@binkert.org if (!ic->isConnected()) { 4285476Snate@binkert.org Port *peer = oldCPU->getPort("icache_port")->getPeer(); 4294192Sktlim@umich.edu ic->setPeer(peer); 4305476Snate@binkert.org peer->setPeer(ic); 4314192Sktlim@umich.edu } 4324192Sktlim@umich.edu 4335476Snate@binkert.org if (!dc->isConnected()) { 4345476Snate@binkert.org Port *peer = oldCPU->getPort("dcache_port")->getPeer(); 4354192Sktlim@umich.edu dc->setPeer(peer); 4365476Snate@binkert.org peer->setPeer(dc); 4374192Sktlim@umich.edu } 438180SN/A} 439180SN/A 440180SN/A 4411858SN/A#if FULL_SYSTEM 4425536Srstrong@hp.comBaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, Tick _interval) 4435606Snate@binkert.org : cpu(_cpu), interval(_interval) 4441917SN/A{ } 4451917SN/A 4461917SN/Avoid 4471917SN/ABaseCPU::ProfileEvent::process() 4481917SN/A{ 4496221Snate@binkert.org ThreadID size = cpu->threadContexts.size(); 4506221Snate@binkert.org for (ThreadID i = 0; i < size; ++i) { 4512680Sktlim@umich.edu ThreadContext *tc = cpu->threadContexts[i]; 4522680Sktlim@umich.edu tc->profileSample(); 4531917SN/A } 4542254SN/A 4557823Ssteve.reinhardt@amd.com cpu->schedule(this, curTick() + interval); 4561917SN/A} 4571917SN/A 4582SN/Avoid 459921SN/ABaseCPU::serialize(std::ostream &os) 460921SN/A{ 4614000Ssaidi@eecs.umich.edu SERIALIZE_SCALAR(instCnt); 4625647Sgblack@eecs.umich.edu interrupts->serialize(os); 463921SN/A} 464921SN/A 465921SN/Avoid 466921SN/ABaseCPU::unserialize(Checkpoint *cp, const std::string §ion) 467921SN/A{ 4684000Ssaidi@eecs.umich.edu UNSERIALIZE_SCALAR(instCnt); 4695647Sgblack@eecs.umich.edu interrupts->unserialize(cp, section); 470921SN/A} 471921SN/A 4722SN/A#endif // FULL_SYSTEM 4732SN/A 4741191SN/Avoid 4751191SN/ABaseCPU::traceFunctionsInternal(Addr pc) 4761191SN/A{ 4771191SN/A if (!debugSymbolTable) 4781191SN/A return; 4791191SN/A 4801191SN/A // if pc enters different function, print new function symbol and 4811191SN/A // update saved range. Otherwise do nothing. 4821191SN/A if (pc < currentFunctionStart || pc >= currentFunctionEnd) { 4831191SN/A string sym_str; 4841191SN/A bool found = debugSymbolTable->findNearestSymbol(pc, sym_str, 4851191SN/A currentFunctionStart, 4861191SN/A currentFunctionEnd); 4871191SN/A 4881191SN/A if (!found) { 4891191SN/A // no symbol found: use addr as label 4901191SN/A sym_str = csprintf("0x%x", pc); 4911191SN/A currentFunctionStart = pc; 4921191SN/A currentFunctionEnd = pc + 1; 4931191SN/A } 4941191SN/A 4951191SN/A ccprintf(*functionTraceStream, " (%d)\n%d: %s", 4967823Ssteve.reinhardt@amd.com curTick() - functionEntryTick, curTick(), sym_str); 4977823Ssteve.reinhardt@amd.com functionEntryTick = curTick(); 4981191SN/A } 4991191SN/A} 5008707Sandreas.hansson@arm.com 5018707Sandreas.hansson@arm.combool 5028707Sandreas.hansson@arm.comBaseCPU::CpuPort::recvTiming(PacketPtr pkt) 5038707Sandreas.hansson@arm.com{ 5048707Sandreas.hansson@arm.com panic("BaseCPU doesn't expect recvTiming callback!"); 5058707Sandreas.hansson@arm.com return true; 5068707Sandreas.hansson@arm.com} 5078707Sandreas.hansson@arm.com 5088707Sandreas.hansson@arm.comvoid 5098707Sandreas.hansson@arm.comBaseCPU::CpuPort::recvRetry() 5108707Sandreas.hansson@arm.com{ 5118707Sandreas.hansson@arm.com panic("BaseCPU doesn't expect recvRetry callback!"); 5128707Sandreas.hansson@arm.com} 5138707Sandreas.hansson@arm.com 5148707Sandreas.hansson@arm.comTick 5158707Sandreas.hansson@arm.comBaseCPU::CpuPort::recvAtomic(PacketPtr pkt) 5168707Sandreas.hansson@arm.com{ 5178707Sandreas.hansson@arm.com panic("BaseCPU doesn't expect recvAtomic callback!"); 5188707Sandreas.hansson@arm.com return curTick(); 5198707Sandreas.hansson@arm.com} 5208707Sandreas.hansson@arm.com 5218707Sandreas.hansson@arm.comvoid 5228707Sandreas.hansson@arm.comBaseCPU::CpuPort::recvFunctional(PacketPtr pkt) 5238707Sandreas.hansson@arm.com{ 5248707Sandreas.hansson@arm.com // No internal storage to update (in the general case). In the 5258707Sandreas.hansson@arm.com // long term this should never be called, but that assumed a split 5268707Sandreas.hansson@arm.com // into master/slave and request/response. 5278707Sandreas.hansson@arm.com} 5288707Sandreas.hansson@arm.com 5298707Sandreas.hansson@arm.comvoid 5308711Sandreas.hansson@arm.comBaseCPU::CpuPort::recvRangeChange() 5318707Sandreas.hansson@arm.com{ 5328707Sandreas.hansson@arm.com} 533