base.cc revision 2190
13691SN/A/* 23691SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 39449SAli.Saidi@ARM.com * All rights reserved. 49729Sandreas.hansson@arm.com * 59729Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 68721SN/A * modification, are permitted provided that the following conditions are 710352Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 810352Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 910352Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 1010352Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 1110352Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 129729Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 139729Sandreas.hansson@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 * 169729Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179729Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189729Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 199729Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 209729Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 219729Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 229729Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239055Ssaidi@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249729Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259729Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 269729Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279729Sandreas.hansson@arm.com */ 289729Sandreas.hansson@arm.com 299729Sandreas.hansson@arm.com#include <iostream> 309055Ssaidi@eecs.umich.edu#include <string> 319729Sandreas.hansson@arm.com#include <sstream> 329729Sandreas.hansson@arm.com 339729Sandreas.hansson@arm.com#include "base/cprintf.hh" 349729Sandreas.hansson@arm.com#include "base/loader/symtab.hh" 359729Sandreas.hansson@arm.com#include "base/misc.hh" 369729Sandreas.hansson@arm.com#include "base/output.hh" 379729Sandreas.hansson@arm.com#include "cpu/base.hh" 389729Sandreas.hansson@arm.com#include "cpu/exec_context.hh" 399247Sandreas.hansson@arm.com#include "cpu/profile.hh" 409729Sandreas.hansson@arm.com#include "cpu/sampler/sampler.hh" 419729Sandreas.hansson@arm.com#include "sim/param.hh" 429729Sandreas.hansson@arm.com#include "sim/process.hh" 439729Sandreas.hansson@arm.com#include "sim/sim_events.hh" 449729Sandreas.hansson@arm.com#include "sim/system.hh" 459729Sandreas.hansson@arm.com 469729Sandreas.hansson@arm.com#include "base/trace.hh" 479729Sandreas.hansson@arm.com 488721SN/A#if FULL_SYSTEM 498721SN/A#include "kern/kernel_stats.hh" 508721SN/A#endif 518721SN/A 528721SN/Ausing namespace std; 538721SN/A 548721SN/Avector<BaseCPU *> BaseCPU::cpuList; 558721SN/A 568721SN/A// This variable reflects the max number of threads in any CPU. Be 578721SN/A// careful to only use it once all the CPUs that you care about have 588721SN/A// been initialized 598721SN/Aint maxThreadsPerCPU = 1; 6010036SAli.Saidi@ARM.com 618721SN/A#if FULL_SYSTEM 628721SN/ABaseCPU::BaseCPU(Params *p) 638721SN/A : SimObject(p->name), clock(p->clock), checkInterrupts(true), 648721SN/A params(p), number_of_threads(p->numberOfThreads), system(p->system) 659729Sandreas.hansson@arm.com#else 668721SN/ABaseCPU::BaseCPU(Params *p) 678721SN/A : SimObject(p->name), clock(p->clock), params(p), 688721SN/A number_of_threads(p->numberOfThreads) 699729Sandreas.hansson@arm.com#endif 708721SN/A{ 718721SN/A DPRINTF(FullCPU, "BaseCPU: Creating object, mem address %#x.\n", this); 728721SN/A 739729Sandreas.hansson@arm.com // add self to global list of CPUs 746024SN/A cpuList.push_back(this); 758721SN/A 768721SN/A DPRINTF(FullCPU, "BaseCPU: CPU added to cpuList, mem address %#x.\n", 779729Sandreas.hansson@arm.com this); 788721SN/A 798721SN/A if (number_of_threads > maxThreadsPerCPU) 809729Sandreas.hansson@arm.com maxThreadsPerCPU = number_of_threads; 818721SN/A 828721SN/A // allocate per-thread instruction-based event queues 838721SN/A comInstEventQueue = new EventQueue *[number_of_threads]; 848721SN/A for (int i = 0; i < number_of_threads; ++i) 858721SN/A comInstEventQueue[i] = new EventQueue("instruction-based event queue"); 868721SN/A 878721SN/A // 888721SN/A // set up instruction-count-based termination events, if any 896024SN/A // 906024SN/A if (p->max_insts_any_thread != 0) 918721SN/A for (int i = 0; i < number_of_threads; ++i) 928721SN/A new SimExitEvent(comInstEventQueue[i], p->max_insts_any_thread, 939729Sandreas.hansson@arm.com "a thread reached the max instruction count"); 948721SN/A 958721SN/A if (p->max_insts_all_threads != 0) { 969729Sandreas.hansson@arm.com // allocate & initialize shared downcounter: each event will 979729Sandreas.hansson@arm.com // decrement this when triggered; simulation will terminate 989729Sandreas.hansson@arm.com // when counter reaches 0 999729Sandreas.hansson@arm.com int *counter = new int; 1009729Sandreas.hansson@arm.com *counter = number_of_threads; 1019729Sandreas.hansson@arm.com for (int i = 0; i < number_of_threads; ++i) 1029729Sandreas.hansson@arm.com new CountedExitEvent(comInstEventQueue[i], 1039729Sandreas.hansson@arm.com "all threads reached the max instruction count", 1049729Sandreas.hansson@arm.com p->max_insts_all_threads, *counter); 1059729Sandreas.hansson@arm.com } 1069729Sandreas.hansson@arm.com 1079729Sandreas.hansson@arm.com // allocate per-thread load-based event queues 1089729Sandreas.hansson@arm.com comLoadEventQueue = new EventQueue *[number_of_threads]; 1099729Sandreas.hansson@arm.com for (int i = 0; i < number_of_threads; ++i) 1109729Sandreas.hansson@arm.com comLoadEventQueue[i] = new EventQueue("load-based event queue"); 1119729Sandreas.hansson@arm.com 1129729Sandreas.hansson@arm.com // 1139729Sandreas.hansson@arm.com // set up instruction-count-based termination events, if any 1149729Sandreas.hansson@arm.com // 11510063Snilay@cs.wisc.edu if (p->max_loads_any_thread != 0) 11610220Sandreas.hansson@arm.com for (int i = 0; i < number_of_threads; ++i) 11710352Sandreas.hansson@arm.com new SimExitEvent(comLoadEventQueue[i], p->max_loads_any_thread, 11810220Sandreas.hansson@arm.com "a thread reached the max load count"); 11910220Sandreas.hansson@arm.com 12010352Sandreas.hansson@arm.com if (p->max_loads_all_threads != 0) { 12110220Sandreas.hansson@arm.com // allocate & initialize shared downcounter: each event will 12210220Sandreas.hansson@arm.com // decrement this when triggered; simulation will terminate 12310220Sandreas.hansson@arm.com // when counter reaches 0 12410220Sandreas.hansson@arm.com int *counter = new int; 12510220Sandreas.hansson@arm.com *counter = number_of_threads; 12610220Sandreas.hansson@arm.com for (int i = 0; i < number_of_threads; ++i) 12710220Sandreas.hansson@arm.com new CountedExitEvent(comLoadEventQueue[i], 12810220Sandreas.hansson@arm.com "all threads reached the max load count", 12910220Sandreas.hansson@arm.com p->max_loads_all_threads, *counter); 13010220Sandreas.hansson@arm.com } 13110220Sandreas.hansson@arm.com 13210220Sandreas.hansson@arm.com#if FULL_SYSTEM 13310220Sandreas.hansson@arm.com memset(interrupts, 0, sizeof(interrupts)); 13410220Sandreas.hansson@arm.com intstatus = 0; 13510220Sandreas.hansson@arm.com#endif 13610220Sandreas.hansson@arm.com 13710220Sandreas.hansson@arm.com functionTracingEnabled = false; 13810220Sandreas.hansson@arm.com if (p->functionTrace) { 13910220Sandreas.hansson@arm.com functionTraceStream = simout.find(csprintf("ftrace.%s", name())); 14010220Sandreas.hansson@arm.com currentFunctionStart = currentFunctionEnd = 0; 14110220Sandreas.hansson@arm.com functionEntryTick = p->functionTraceStart; 14210220Sandreas.hansson@arm.com 14310220Sandreas.hansson@arm.com if (p->functionTraceStart == 0) { 14410220Sandreas.hansson@arm.com functionTracingEnabled = true; 14510220Sandreas.hansson@arm.com } else { 14610220Sandreas.hansson@arm.com Event *e = 14710220Sandreas.hansson@arm.com new EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace>(this, 14810220Sandreas.hansson@arm.com true); 14910220Sandreas.hansson@arm.com e->schedule(p->functionTraceStart); 15010220Sandreas.hansson@arm.com } 1513691SN/A } 1529729Sandreas.hansson@arm.com#if FULL_SYSTEM 1539729Sandreas.hansson@arm.com profileEvent = NULL; 1549729Sandreas.hansson@arm.com if (params->profile) 1559729Sandreas.hansson@arm.com profileEvent = new ProfileEvent(this, params->profile); 1569449SAli.Saidi@ARM.com 1579729Sandreas.hansson@arm.com kernelStats = new Kernel::Statistics(system); 1589729Sandreas.hansson@arm.com#endif 1599729Sandreas.hansson@arm.com 1609729Sandreas.hansson@arm.com} 1619729Sandreas.hansson@arm.com 1629729Sandreas.hansson@arm.comBaseCPU::Params::Params() 1639729Sandreas.hansson@arm.com{ 1649729Sandreas.hansson@arm.com#if FULL_SYSTEM 1659729Sandreas.hansson@arm.com profile = false; 1669449SAli.Saidi@ARM.com#endif 1679729Sandreas.hansson@arm.com} 1689729Sandreas.hansson@arm.com 1699449SAli.Saidi@ARM.comvoid 1706127SN/ABaseCPU::enableFunctionTrace() 1716127SN/A{ 1729729Sandreas.hansson@arm.com functionTracingEnabled = true; 1739729Sandreas.hansson@arm.com} 1746291SN/A 1756291SN/ABaseCPU::~BaseCPU() 1766291SN/A{ 1776291SN/A#if FULL_SYSTEM 1786291SN/A if (kernelStats) 1796291SN/A delete kernelStats; 1806291SN/A#endif 1816291SN/A} 1826291SN/A 1836291SN/Avoid 1846291SN/ABaseCPU::init() 1856291SN/A{ 1866291SN/A if (!params->deferRegistration) 1876291SN/A registerExecContexts(); 1886291SN/A} 1896291SN/A 1906291SN/Avoid 1916291SN/ABaseCPU::startup() 1926291SN/A{ 1936291SN/A#if FULL_SYSTEM 1946291SN/A if (!params->deferRegistration && profileEvent) 1956127SN/A profileEvent->schedule(curTick); 1969729Sandreas.hansson@arm.com#endif 1979449SAli.Saidi@ARM.com} 1989729Sandreas.hansson@arm.com 1999449SAli.Saidi@ARM.com 2009449SAli.Saidi@ARM.comvoid 2019490Sandreas.hansson@arm.comBaseCPU::regStats() 2029490Sandreas.hansson@arm.com{ 2039449SAli.Saidi@ARM.com using namespace Stats; 2049449SAli.Saidi@ARM.com 2059729Sandreas.hansson@arm.com numCycles 2069729Sandreas.hansson@arm.com .name(name() + ".numCycles") 2079729Sandreas.hansson@arm.com .desc("number of cpu cycles simulated") 2089729Sandreas.hansson@arm.com ; 2099449SAli.Saidi@ARM.com 2109729Sandreas.hansson@arm.com int size = execContexts.size(); 2119729Sandreas.hansson@arm.com if (size > 1) { 2129729Sandreas.hansson@arm.com for (int i = 0; i < size; ++i) { 2138721SN/A stringstream namestr; 2149729Sandreas.hansson@arm.com ccprintf(namestr, "%s.ctx%d", name(), i); 2159490Sandreas.hansson@arm.com execContexts[i]->regStats(namestr.str()); 2169729Sandreas.hansson@arm.com } 2179729Sandreas.hansson@arm.com } else if (size == 1) 2189729Sandreas.hansson@arm.com execContexts[0]->regStats(name()); 2199729Sandreas.hansson@arm.com 22010036SAli.Saidi@ARM.com#if FULL_SYSTEM 2218721SN/A if (kernelStats) 2228721SN/A kernelStats->regStats(name() + ".kern"); 2238721SN/A#endif 2248721SN/A} 2258721SN/A 2268721SN/A 2278721SN/Avoid 2288721SN/ABaseCPU::registerExecContexts() 2298721SN/A{ 2308721SN/A for (int i = 0; i < execContexts.size(); ++i) { 2319729Sandreas.hansson@arm.com ExecContext *xc = execContexts[i]; 2323691SN/A#if FULL_SYSTEM 2339729Sandreas.hansson@arm.com int id = params->cpu_id; 2343691SN/A if (id != -1) 2359449SAli.Saidi@ARM.com id += i; 2368721SN/A 2373691SN/A xc->setCpuId(system->registerExecContext(xc, id)); 2387461SN/A#else 2399449SAli.Saidi@ARM.com xc->setCpuId(xc->getProcessPtr()->registerExecContext(xc)); 2409449SAli.Saidi@ARM.com#endif 2418721SN/A } 2428721SN/A} 2438721SN/A 2448721SN/A 2458721SN/Avoid 2468721SN/ABaseCPU::switchOut(Sampler *sampler) 2478721SN/A{ 2488721SN/A panic("This CPU doesn't support sampling!"); 2498721SN/A} 2508721SN/A 2518721SN/Avoid 2529247Sandreas.hansson@arm.comBaseCPU::takeOverFrom(BaseCPU *oldCPU) 2538721SN/A{ 2543691SN/A assert(execContexts.size() == oldCPU->execContexts.size()); 2558721SN/A 2568721SN/A for (int i = 0; i < execContexts.size(); ++i) { 2578721SN/A ExecContext *newXC = execContexts[i]; 2589490Sandreas.hansson@arm.com ExecContext *oldXC = oldCPU->execContexts[i]; 2599247Sandreas.hansson@arm.com 2609729Sandreas.hansson@arm.com newXC->takeOverFrom(oldXC); 2618721SN/A assert(newXC->readCpuId() == oldXC->readCpuId()); 2628721SN/A#if FULL_SYSTEM 2638721SN/A system->replaceExecContext(newXC, newXC->readCpuId()); 2648721SN/A#else 2658721SN/A assert(newXC->getProcessPtr() == oldXC->getProcessPtr()); 2663691SN/A newXC->getProcessPtr()->replaceExecContext(newXC, newXC->readCpuId()); 2678721SN/A#endif 2689729Sandreas.hansson@arm.com } 2698721SN/A 2709729Sandreas.hansson@arm.com#if FULL_SYSTEM 2719729Sandreas.hansson@arm.com for (int i = 0; i < TheISA::NumInterruptLevels; ++i) 27210036SAli.Saidi@ARM.com interrupts[i] = oldCPU->interrupts[i]; 27310036SAli.Saidi@ARM.com intstatus = oldCPU->intstatus; 2749729Sandreas.hansson@arm.com/* 2759729Sandreas.hansson@arm.com for (int i = 0; i < execContexts.size(); ++i) 2769729Sandreas.hansson@arm.com if (execContexts[i]->profile) 2779729Sandreas.hansson@arm.com execContexts[i]->profile->clear(); 2789729Sandreas.hansson@arm.com*/ 2799729Sandreas.hansson@arm.com if (profileEvent) 2809729Sandreas.hansson@arm.com profileEvent->schedule(curTick); 2819055Ssaidi@eecs.umich.edu#endif 2829729Sandreas.hansson@arm.com} 2839729Sandreas.hansson@arm.com 2849729Sandreas.hansson@arm.com 2859729Sandreas.hansson@arm.com#if FULL_SYSTEM 2869729Sandreas.hansson@arm.comBaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, int _interval) 2879729Sandreas.hansson@arm.com : Event(&mainEventQueue), cpu(_cpu), interval(_interval) 2889055Ssaidi@eecs.umich.edu{ } 2899729Sandreas.hansson@arm.com 2909729Sandreas.hansson@arm.comvoid 2919729Sandreas.hansson@arm.comBaseCPU::ProfileEvent::process() 2929729Sandreas.hansson@arm.com{ 2939729Sandreas.hansson@arm.com/* for (int i = 0, size = cpu->execContexts.size(); i < size; ++i) { 2949729Sandreas.hansson@arm.com ExecContext *xc = cpu->execContexts[i]; 2959729Sandreas.hansson@arm.com xc->profile->sample(xc->profileNode, xc->profilePC); 2969729Sandreas.hansson@arm.com } 2979449SAli.Saidi@ARM.com*/ 2989729Sandreas.hansson@arm.com schedule(curTick + interval); 2999729Sandreas.hansson@arm.com} 3009729Sandreas.hansson@arm.com 3019729Sandreas.hansson@arm.comvoid 3029729Sandreas.hansson@arm.comBaseCPU::post_interrupt(int int_num, int index) 3039729Sandreas.hansson@arm.com{ 3049729Sandreas.hansson@arm.com DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); 3059729Sandreas.hansson@arm.com 3068721SN/A if (int_num < 0 || int_num >= TheISA::NumInterruptLevels) 3078721SN/A panic("int_num out of bounds\n"); 3088721SN/A 3098721SN/A if (index < 0 || index >= sizeof(uint64_t) * 8) 3108721SN/A panic("int_num out of bounds\n"); 3118721SN/A 3128721SN/A checkInterrupts = true; 3138721SN/A interrupts[int_num] |= 1 << index; 3148721SN/A intstatus |= (ULL(1) << int_num); 3158721SN/A} 3168721SN/A 3178721SN/Avoid 31810036SAli.Saidi@ARM.comBaseCPU::clear_interrupt(int int_num, int index) 3198721SN/A{ 3208721SN/A DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); 3218721SN/A 3228721SN/A if (int_num < 0 || int_num >= TheISA::NumInterruptLevels) 3239729Sandreas.hansson@arm.com panic("int_num out of bounds\n"); 3248721SN/A 3258721SN/A if (index < 0 || index >= sizeof(uint64_t) * 8) 3269247Sandreas.hansson@arm.com panic("int_num out of bounds\n"); 3279729Sandreas.hansson@arm.com 3288721SN/A interrupts[int_num] &= ~(1 << index); 3298721SN/A if (interrupts[int_num] == 0) 3309247Sandreas.hansson@arm.com intstatus &= ~(ULL(1) << int_num); 3319729Sandreas.hansson@arm.com} 3328721SN/A 3338721SN/Avoid 3349247Sandreas.hansson@arm.comBaseCPU::clear_interrupts() 3359729Sandreas.hansson@arm.com{ 3368721SN/A DPRINTF(Interrupt, "Interrupts all cleared\n"); 3378721SN/A 3389729Sandreas.hansson@arm.com memset(interrupts, 0, sizeof(interrupts)); 3398721SN/A intstatus = 0; 3408721SN/A} 3418721SN/A 3428721SN/A 3438721SN/Avoid 3448721SN/ABaseCPU::serialize(std::ostream &os) 3458721SN/A{ 3468721SN/A SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels); 3478721SN/A SERIALIZE_SCALAR(intstatus); 3488721SN/A 3498721SN/A#if FULL_SYSTEM 3508721SN/A if (kernelStats) 3519729Sandreas.hansson@arm.com kernelStats->serialize(os); 3528721SN/A#endif 3538721SN/A 3549729Sandreas.hansson@arm.com} 3559729Sandreas.hansson@arm.com 3569729Sandreas.hansson@arm.comvoid 3579247Sandreas.hansson@arm.comBaseCPU::unserialize(Checkpoint *cp, const std::string §ion) 3589729Sandreas.hansson@arm.com{ 3599729Sandreas.hansson@arm.com UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels); 3609729Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(intstatus); 3619247Sandreas.hansson@arm.com 3629729Sandreas.hansson@arm.com#if FULL_SYSTEM 3639729Sandreas.hansson@arm.com if (kernelStats) 3649247Sandreas.hansson@arm.com kernelStats->unserialize(cp, section); 3659247Sandreas.hansson@arm.com#endif 3669729Sandreas.hansson@arm.com} 3679729Sandreas.hansson@arm.com 3689729Sandreas.hansson@arm.com#endif // FULL_SYSTEM 3699729Sandreas.hansson@arm.com 3709729Sandreas.hansson@arm.comvoid 3719729Sandreas.hansson@arm.comBaseCPU::traceFunctionsInternal(Addr pc) 3729729Sandreas.hansson@arm.com{ 37310063Snilay@cs.wisc.edu if (!debugSymbolTable) 37410220Sandreas.hansson@arm.com return; 37510352Sandreas.hansson@arm.com 37610220Sandreas.hansson@arm.com // if pc enters different function, print new function symbol and 37710220Sandreas.hansson@arm.com // update saved range. Otherwise do nothing. 37810352Sandreas.hansson@arm.com if (pc < currentFunctionStart || pc >= currentFunctionEnd) { 37910220Sandreas.hansson@arm.com string sym_str; 38010220Sandreas.hansson@arm.com bool found = debugSymbolTable->findNearestSymbol(pc, sym_str, 38110220Sandreas.hansson@arm.com currentFunctionStart, 38210220Sandreas.hansson@arm.com currentFunctionEnd); 38310220Sandreas.hansson@arm.com 38410220Sandreas.hansson@arm.com if (!found) { 38510220Sandreas.hansson@arm.com // no symbol found: use addr as label 38610220Sandreas.hansson@arm.com sym_str = csprintf("0x%x", pc); 38710220Sandreas.hansson@arm.com currentFunctionStart = pc; 38810220Sandreas.hansson@arm.com currentFunctionEnd = pc + 1; 38910220Sandreas.hansson@arm.com } 39010220Sandreas.hansson@arm.com 39110220Sandreas.hansson@arm.com ccprintf(*functionTraceStream, " (%d)\n%d: %s", 39210220Sandreas.hansson@arm.com curTick - functionEntryTick, curTick, sym_str); 39310220Sandreas.hansson@arm.com functionEntryTick = curTick; 39410220Sandreas.hansson@arm.com } 39510220Sandreas.hansson@arm.com} 39610220Sandreas.hansson@arm.com 39710220Sandreas.hansson@arm.com 39810220Sandreas.hansson@arm.comDEFINE_SIM_OBJECT_CLASS_NAME("BaseCPU", BaseCPU) 39910220Sandreas.hansson@arm.com