base.cc revision 595
12SN/A/* 28922Swilliam.wang@arm.com * Copyright (c) 2003 The Regents of The University of Michigan 38707Sandreas.hansson@arm.com * All rights reserved. 48707Sandreas.hansson@arm.com * 58707Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 68707Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 78707Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 88707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 98707Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 108707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 118707Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 128707Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 138707Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 141762SN/A * this software without specific prior written permission. 157897Shestness@cs.utexas.edu * 169983Sstever@gmail.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179983Sstever@gmail.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272SN/A */ 282SN/A 292SN/A#include <cmath> 302SN/A#include <cstdio> 312SN/A#include <cstdlib> 322SN/A#include <iostream> 332SN/A#include <iomanip> 342SN/A#include <list> 352SN/A#include <sstream> 362SN/A#include <string> 372SN/A 382SN/A#include "base/cprintf.hh" 392SN/A#include "base/inifile.hh" 402SN/A#include "base/loader/symtab.hh" 412SN/A#include "base/misc.hh" 422665Ssaidi@eecs.umich.edu#include "base/pollevent.hh" 432665Ssaidi@eecs.umich.edu#include "base/range.hh" 442665Ssaidi@eecs.umich.edu#include "base/trace.hh" 457897Shestness@cs.utexas.edu#include "cpu/base_cpu.hh" 462SN/A#include "cpu/exec_context.hh" 472SN/A#include "cpu/exetrace.hh" 481388SN/A#include "cpu/full_cpu/smt.hh" 498229Snate@binkert.org#include "cpu/simple_cpu/simple_cpu.hh" 502SN/A#include "cpu/static_inst.hh" 512SN/A#include "mem/base_mem.hh" 527781SAli.Saidi@ARM.com#include "mem/mem_interface.hh" 538229Snate@binkert.org#include "sim/annotation.hh" 541191SN/A#include "sim/builder.hh" 551191SN/A#include "sim/debug.hh" 561388SN/A#include "sim/host.hh" 575529Snate@binkert.org#include "sim/sim_events.hh" 5810529Smorr@cs.wisc.edu#include "sim/sim_object.hh" 591717SN/A#include "sim/sim_stats.hh" 602651Ssaidi@eecs.umich.edu 618229Snate@binkert.org#ifdef FULL_SYSTEM 622680Sktlim@umich.edu#include "base/remote_gdb.hh" 6310529Smorr@cs.wisc.edu#include "dev/alpha_access.h" 648232Snate@binkert.org#include "dev/pciareg.h" 6510529Smorr@cs.wisc.edu#include "mem/functional_mem/memory_control.hh" 665529Snate@binkert.org#include "mem/functional_mem/physical_memory.hh" 678779Sgblack@eecs.umich.edu#include "sim/system.hh" 682190SN/A#include "targetarch/alpha_memory.hh" 6956SN/A#include "targetarch/vtophys.hh" 708229Snate@binkert.org#else // !FULL_SYSTEM 712190SN/A#include "eio/eio.hh" 722SN/A#include "mem/functional_mem/functional_memory.hh" 732359SN/A#endif // FULL_SYSTEM 742359SN/A 752359SN/Ausing namespace std; 762SN/A 772SN/ASimpleCPU::TickEvent::TickEvent(SimpleCPU *c) 782SN/A : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c) 792SN/A{ 802SN/A} 812SN/A 822SN/Avoid 832SN/ASimpleCPU::TickEvent::process() 842SN/A{ 855606Snate@binkert.org cpu->tick(); 866144Sksewell@umich.edu} 876144Sksewell@umich.edu 883126Sktlim@umich.educonst char * 896144Sksewell@umich.eduSimpleCPU::TickEvent::description() 907823Ssteve.reinhardt@amd.com{ 913126Sktlim@umich.edu return "SimpleCPU tick event"; 923126Sktlim@umich.edu} 932356SN/A 942356SN/A 952356SN/ASimpleCPU::CacheCompletionEvent::CacheCompletionEvent(SimpleCPU *_cpu) 968834Satgutier@umich.edu : Event(&mainEventQueue), 972356SN/A cpu(_cpu) 989179Sandreas.hansson@arm.com{ 992367SN/A} 1006144Sksewell@umich.edu 1016144Sksewell@umich.eduvoid SimpleCPU::CacheCompletionEvent::process() 1026144Sksewell@umich.edu{ 1032356SN/A cpu->processCacheCompletion(); 1042367SN/A} 1056144Sksewell@umich.edu 1067823Ssteve.reinhardt@amd.comconst char * 1076144Sksewell@umich.eduSimpleCPU::CacheCompletionEvent::description() 1082367SN/A{ 1092356SN/A return "SimpleCPU cache completion event"; 1106144Sksewell@umich.edu} 1116144Sksewell@umich.edu 1127823Ssteve.reinhardt@amd.com#ifdef FULL_SYSTEM 1132356SN/ASimpleCPU::SimpleCPU(const string &_name, 1142356SN/A System *_system, 1152356SN/A Counter max_insts_any_thread, 1165336Shines@cs.fsu.edu Counter max_insts_all_threads, 1172356SN/A Counter max_loads_any_thread, 1184873Sstever@eecs.umich.edu Counter max_loads_all_threads, 1192356SN/A AlphaItb *itb, AlphaDtb *dtb, 1202356SN/A FunctionalMemory *mem, 1218876Sandreas.hansson@arm.com MemInterface *icache_interface, 12210190Sakash.bagdia@arm.com MemInterface *dcache_interface, 1238832SAli.Saidi@ARM.com bool _def_reg, Tick freq) 1248832SAli.Saidi@ARM.com : BaseCPU(_name, /* number_of_threads */ 1, 1259332Sdam.sunwoo@arm.com max_insts_any_thread, max_insts_all_threads, 1269814Sandreas.hansson@arm.com max_loads_any_thread, max_loads_all_threads, 1279220Shestness@cs.wisc.edu _system, freq), 12810529Smorr@cs.wisc.edu#else 12910537Sandreas.hansson@arm.comSimpleCPU::SimpleCPU(const string &_name, Process *_process, 13010537Sandreas.hansson@arm.com Counter max_insts_any_thread, 13110529Smorr@cs.wisc.edu Counter max_insts_all_threads, 1322SN/A Counter max_loads_any_thread, 1335712Shsul@eecs.umich.edu Counter max_loads_all_threads, 1345712Shsul@eecs.umich.edu MemInterface *icache_interface, 1355712Shsul@eecs.umich.edu MemInterface *dcache_interface, 1365712Shsul@eecs.umich.edu bool _def_reg) 1375712Shsul@eecs.umich.edu : BaseCPU(_name, /* number_of_threads */ 1, 1382SN/A max_insts_any_thread, max_insts_all_threads, 1392SN/A max_loads_any_thread, max_loads_all_threads), 1402SN/A#endif 14110190Sakash.bagdia@arm.com tickEvent(this), xc(NULL), defer_registration(_def_reg), 14210190Sakash.bagdia@arm.com cacheCompletionEvent(this) 1435712Shsul@eecs.umich.edu{ 1446221Snate@binkert.org _status = Idle; 1456221Snate@binkert.org#ifdef FULL_SYSTEM 1462SN/A xc = new ExecContext(this, 0, system, itb, dtb, mem); 1472SN/A 1486221Snate@binkert.org // initialize CPU, including PC 1496221Snate@binkert.org TheISA::initCPU(&xc->regs); 1506221Snate@binkert.org#else 1516221Snate@binkert.org xc = new ExecContext(this, /* thread_num */ 0, _process, /* asid */ 0); 1522SN/A#endif // !FULL_SYSTEM 1532SN/A 1542SN/A icacheInterface = icache_interface; 1552SN/A dcacheInterface = dcache_interface; 1565606Snate@binkert.org 1575606Snate@binkert.org memReq = new MemReq(); 1589749Sandreas@sandberg.pp.se memReq->xc = xc; 1599749Sandreas@sandberg.pp.se memReq->asid = 0; 1605606Snate@binkert.org memReq->data = new uint8_t[64]; 1612SN/A 1629647Sdam.sunwoo@arm.com numInst = 0; 1639647Sdam.sunwoo@arm.com startNumInst = 0; 1649647Sdam.sunwoo@arm.com numLoad = 0; 1659647Sdam.sunwoo@arm.com startNumLoad = 0; 1669647Sdam.sunwoo@arm.com lastIcacheStall = 0; 1679647Sdam.sunwoo@arm.com lastDcacheStall = 0; 1689749Sandreas@sandberg.pp.se 1699749Sandreas@sandberg.pp.se execContexts.push_back(xc); 1709647Sdam.sunwoo@arm.com} 1719647Sdam.sunwoo@arm.com 1721400SN/ASimpleCPU::~SimpleCPU() 1735606Snate@binkert.org{ 1745606Snate@binkert.org} 1752SN/A 1762SN/Avoid SimpleCPU::init() 1772SN/A{ 1782SN/A if (!defer_registration) { 1796221Snate@binkert.org this->registerExecContexts(); 1806221Snate@binkert.org } 1815606Snate@binkert.org} 1826670Shsul@eecs.umich.edu 1835606Snate@binkert.orgvoid 1842SN/ASimpleCPU::switchOut() 1852SN/A{ 186124SN/A _status = SwitchedOut; 1876221Snate@binkert.org if (tickEvent.scheduled()) 1886221Snate@binkert.org tickEvent.squash(); 1896221Snate@binkert.org} 190124SN/A 191124SN/A 192124SN/Avoid 193124SN/ASimpleCPU::takeOverFrom(BaseCPU *oldCPU) 1945606Snate@binkert.org{ 1955606Snate@binkert.org BaseCPU::takeOverFrom(oldCPU); 1969749Sandreas@sandberg.pp.se 1979749Sandreas@sandberg.pp.se assert(!tickEvent.scheduled()); 1985606Snate@binkert.org 199124SN/A // if any of this CPU's ExecContexts are active, mark the CPU as 2001400SN/A // running and schedule its tick event. 2015606Snate@binkert.org for (int i = 0; i < execContexts.size(); ++i) { 202124SN/A ExecContext *xc = execContexts[i]; 203124SN/A if (xc->status() == ExecContext::Active && _status != Running) { 204124SN/A _status = Running; 205124SN/A tickEvent.schedule(curTick); 2066221Snate@binkert.org } 2076221Snate@binkert.org } 2085606Snate@binkert.org 2096221Snate@binkert.org oldCPU->switchOut(); 2105606Snate@binkert.org} 211124SN/A 212124SN/A 2131191SN/Avoid 2145529Snate@binkert.orgSimpleCPU::activateContext(int thread_num, int delay) 2158634Schris.emmons@arm.com{ 2168634Schris.emmons@arm.com assert(thread_num == 0); 2178634Schris.emmons@arm.com assert(xc); 2188634Schris.emmons@arm.com 2198634Schris.emmons@arm.com assert(_status == Idle); 2201191SN/A notIdleFraction++; 2215529Snate@binkert.org scheduleTickEvent(delay); 2221191SN/A _status = Running; 2235529Snate@binkert.org} 2241191SN/A 2251191SN/A 2265606Snate@binkert.orgvoid 2275606Snate@binkert.orgSimpleCPU::suspendContext(int thread_num) 2285606Snate@binkert.org{ 2291191SN/A assert(thread_num == 0); 2301191SN/A assert(xc); 2318876Sandreas.hansson@arm.com 2328876Sandreas.hansson@arm.com assert(_status == Running); 2338876Sandreas.hansson@arm.com notIdleFraction--; 2349433SAndreas.Sandberg@ARM.com unscheduleTickEvent(); 2358876Sandreas.hansson@arm.com _status = Idle; 2368876Sandreas.hansson@arm.com} 2378876Sandreas.hansson@arm.com 2388876Sandreas.hansson@arm.com 2398876Sandreas.hansson@arm.comvoid 2408876Sandreas.hansson@arm.comSimpleCPU::deallocateContext(int thread_num) 2418876Sandreas.hansson@arm.com{ 2425810Sgblack@eecs.umich.edu // for now, these are equivalent 2438779Sgblack@eecs.umich.edu suspendContext(thread_num); 2448779Sgblack@eecs.umich.edu} 2458779Sgblack@eecs.umich.edu 2468779Sgblack@eecs.umich.edu 2475529Snate@binkert.orgvoid 2489384SAndreas.Sandberg@arm.comSimpleCPU::haltContext(int thread_num) 2499384SAndreas.Sandberg@arm.com{ 2509384SAndreas.Sandberg@arm.com // for now, these are equivalent 2519384SAndreas.Sandberg@arm.com suspendContext(thread_num); 2529384SAndreas.Sandberg@arm.com} 2531917SN/A 2541191SN/A 2551191SN/Avoid 2561191SN/ASimpleCPU::regStats() 2571191SN/A{ 2581191SN/A using namespace Statistics; 2591191SN/A 2601191SN/A BaseCPU::regStats(); 2611191SN/A 2621191SN/A numInsts 2639086Sandreas.hansson@arm.com .name(name() + ".num_insts") 2649086Sandreas.hansson@arm.com .desc("Number of instructions executed") 2659086Sandreas.hansson@arm.com ; 2661191SN/A 2671191SN/A numMemRefs 2681129SN/A .name(name() + ".num_refs") 26910529Smorr@cs.wisc.edu .desc("Number of memory references") 27010529Smorr@cs.wisc.edu ; 27110529Smorr@cs.wisc.edu 27210529Smorr@cs.wisc.edu idleFraction 27310529Smorr@cs.wisc.edu .name(name() + ".idle_fraction") 27410529Smorr@cs.wisc.edu .desc("Percentage of idle cycles") 27510529Smorr@cs.wisc.edu ; 27610529Smorr@cs.wisc.edu 27710529Smorr@cs.wisc.edu icacheStallCycles 27810529Smorr@cs.wisc.edu .name(name() + ".icache_stall_cycles") 27910529Smorr@cs.wisc.edu .desc("ICache total stall cycles") 28010529Smorr@cs.wisc.edu .prereq(icacheStallCycles) 28110529Smorr@cs.wisc.edu ; 28210529Smorr@cs.wisc.edu 28310529Smorr@cs.wisc.edu dcacheStallCycles 28410529Smorr@cs.wisc.edu .name(name() + ".dcache_stall_cycles") 28510529Smorr@cs.wisc.edu .desc("DCache total stall cycles") 28610529Smorr@cs.wisc.edu .prereq(dcacheStallCycles) 28710529Smorr@cs.wisc.edu ; 28810529Smorr@cs.wisc.edu 28910529Smorr@cs.wisc.edu idleFraction = constant(1.0) - notIdleFraction; 29010529Smorr@cs.wisc.edu numInsts = Statistics::scalar(numInst) - Statistics::scalar(startNumInst); 29110529Smorr@cs.wisc.edu simInsts += numInsts; 29210529Smorr@cs.wisc.edu} 29310529Smorr@cs.wisc.edu 29410529Smorr@cs.wisc.eduvoid 29510529Smorr@cs.wisc.eduSimpleCPU::resetStats() 29610529Smorr@cs.wisc.edu{ 29710529Smorr@cs.wisc.edu startNumInst = numInst; 29810529Smorr@cs.wisc.edu notIdleFraction = (_status != Idle); 29910529Smorr@cs.wisc.edu} 30010529Smorr@cs.wisc.edu 30110529Smorr@cs.wisc.eduvoid 30210529Smorr@cs.wisc.eduSimpleCPU::serialize(ostream &os) 30310529Smorr@cs.wisc.edu{ 30410529Smorr@cs.wisc.edu SERIALIZE_ENUM(_status); 30510529Smorr@cs.wisc.edu SERIALIZE_SCALAR(inst); 30610529Smorr@cs.wisc.edu nameOut(os, csprintf("%s.xc", name())); 30710529Smorr@cs.wisc.edu xc->serialize(os); 30810529Smorr@cs.wisc.edu nameOut(os, csprintf("%s.tickEvent", name())); 30910529Smorr@cs.wisc.edu tickEvent.serialize(os); 31010529Smorr@cs.wisc.edu nameOut(os, csprintf("%s.cacheCompletionEvent", name())); 31110529Smorr@cs.wisc.edu cacheCompletionEvent.serialize(os); 31210529Smorr@cs.wisc.edu} 31310529Smorr@cs.wisc.edu 31410529Smorr@cs.wisc.eduvoid 31510529Smorr@cs.wisc.eduSimpleCPU::unserialize(Checkpoint *cp, const string §ion) 31610529Smorr@cs.wisc.edu{ 31710529Smorr@cs.wisc.edu UNSERIALIZE_ENUM(_status); 31810529Smorr@cs.wisc.edu UNSERIALIZE_SCALAR(inst); 31910529Smorr@cs.wisc.edu xc->unserialize(cp, csprintf("%s.xc", section)); 32010529Smorr@cs.wisc.edu tickEvent.unserialize(cp, csprintf("%s.tickEvent", section)); 32110529Smorr@cs.wisc.edu cacheCompletionEvent 32210529Smorr@cs.wisc.edu .unserialize(cp, csprintf("%s.cacheCompletionEvent", section)); 32310529Smorr@cs.wisc.edu} 32410529Smorr@cs.wisc.edu 32510529Smorr@cs.wisc.eduvoid 3261129SN/Achange_thread_state(int thread_number, int activate, int priority) 3271129SN/A{ 3289523SAndreas.Sandberg@ARM.com} 3292680Sktlim@umich.edu 3309523SAndreas.Sandberg@ARM.comFault 3319523SAndreas.Sandberg@ARM.comSimpleCPU::copySrcTranslate(Addr src) 3329523SAndreas.Sandberg@ARM.com{ 3331129SN/A memReq->reset(src, (dcacheInterface) ? 334180SN/A dcacheInterface->getBlockSize() 3352SN/A : 64); 3361917SN/A 3371917SN/A // translate to physical address 3388779Sgblack@eecs.umich.edu Fault fault = xc->translateDataReadReq(memReq); 3399433SAndreas.Sandberg@ARM.com 3408779Sgblack@eecs.umich.edu if (fault == No_Fault) { 3418779Sgblack@eecs.umich.edu xc->copySrcAddr = src; 3422356SN/A xc->copySrcPhysAddr = memReq->paddr; 3435529Snate@binkert.org } else { 3449179Sandreas.hansson@arm.com xc->copySrcAddr = 0; 3452356SN/A xc->copySrcPhysAddr = 0; 3461917SN/A } 3471917SN/A return fault; 34810464SAndreas.Sandberg@ARM.com} 34910464SAndreas.Sandberg@ARM.com 35010464SAndreas.Sandberg@ARM.comFault 35110464SAndreas.Sandberg@ARM.comSimpleCPU::copy(Addr dest) 35210464SAndreas.Sandberg@ARM.com{ 35310464SAndreas.Sandberg@ARM.com int blk_size = (dcacheInterface) ? dcacheInterface->getBlockSize() : 64; 35410464SAndreas.Sandberg@ARM.com uint8_t data[blk_size]; 35510464SAndreas.Sandberg@ARM.com assert(xc->copySrcPhysAddr); 35610464SAndreas.Sandberg@ARM.com memReq->reset(dest, blk_size); 35710464SAndreas.Sandberg@ARM.com // translate to physical address 35810464SAndreas.Sandberg@ARM.com Fault fault = xc->translateDataWriteReq(memReq); 35910464SAndreas.Sandberg@ARM.com if (fault == No_Fault) { 36010464SAndreas.Sandberg@ARM.com Addr dest_addr = memReq->paddr; 36110464SAndreas.Sandberg@ARM.com // Need to read straight from memory since we have more than 8 bytes. 36210464SAndreas.Sandberg@ARM.com memReq->paddr = xc->copySrcPhysAddr; 36310464SAndreas.Sandberg@ARM.com xc->mem->read(memReq, data); 36410464SAndreas.Sandberg@ARM.com memReq->paddr = dest_addr; 36510464SAndreas.Sandberg@ARM.com xc->mem->write(memReq, data); 36610464SAndreas.Sandberg@ARM.com } 36710464SAndreas.Sandberg@ARM.com return fault; 36810464SAndreas.Sandberg@ARM.com} 36910464SAndreas.Sandberg@ARM.com 37010464SAndreas.Sandberg@ARM.com// precise architected memory state accessor macros 37110464SAndreas.Sandberg@ARM.comtemplate <class T> 37210464SAndreas.Sandberg@ARM.comFault 37310464SAndreas.Sandberg@ARM.comSimpleCPU::read(Addr addr, T &data, unsigned flags) 37410464SAndreas.Sandberg@ARM.com{ 37510464SAndreas.Sandberg@ARM.com memReq->reset(addr, sizeof(T), flags); 37610464SAndreas.Sandberg@ARM.com 37710464SAndreas.Sandberg@ARM.com // translate to physical address 37810464SAndreas.Sandberg@ARM.com Fault fault = xc->translateDataReadReq(memReq); 37910464SAndreas.Sandberg@ARM.com 38010464SAndreas.Sandberg@ARM.com // do functional access 38110464SAndreas.Sandberg@ARM.com if (fault == No_Fault) 38210464SAndreas.Sandberg@ARM.com fault = xc->read(memReq, data); 38310464SAndreas.Sandberg@ARM.com 3841917SN/A if (traceData) { 3851917SN/A traceData->setAddr(addr); 3862SN/A if (fault == No_Fault) 3872SN/A traceData->setData(data); 388729SN/A } 389707SN/A 390707SN/A // if we have a cache, do cache access too 391707SN/A if (fault == No_Fault && dcacheInterface) { 392707SN/A memReq->cmd = Read; 393707SN/A memReq->completionEvent = NULL; 394707SN/A memReq->time = curTick; 3957914SBrad.Beckmann@amd.com MemAccessResult result = dcacheInterface->access(memReq); 3967914SBrad.Beckmann@amd.com 3977914SBrad.Beckmann@amd.com // Ugly hack to get an event scheduled *only* if the access is 3987914SBrad.Beckmann@amd.com // a miss. We really should add first-class support for this 3997914SBrad.Beckmann@amd.com // at some point. 4007914SBrad.Beckmann@amd.com if (result != MA_HIT && dcacheInterface->doEvents()) { 4017914SBrad.Beckmann@amd.com memReq->completionEvent = &cacheCompletionEvent; 4027914SBrad.Beckmann@amd.com lastDcacheStall = curTick; 4037914SBrad.Beckmann@amd.com unscheduleTickEvent(); 4047914SBrad.Beckmann@amd.com _status = DcacheMissStall; 4052680Sktlim@umich.edu } 4062SN/A } 4072SN/A 4082SN/A return fault; 4092SN/A} 4102680Sktlim@umich.edu 4112SN/A#ifndef DOXYGEN_SHOULD_SKIP_THIS 4122SN/A 4132680Sktlim@umich.edutemplate 4142SN/AFault 4152SN/ASimpleCPU::read(Addr addr, uint64_t &data, unsigned flags); 4169294Sandreas.hansson@arm.com 4179294Sandreas.hansson@arm.comtemplate 4188850Sandreas.hansson@arm.comFault 4198850Sandreas.hansson@arm.comSimpleCPU::read(Addr addr, uint32_t &data, unsigned flags); 4208850Sandreas.hansson@arm.com 4218850Sandreas.hansson@arm.comtemplate 4229608Sandreas.hansson@arm.comFault 4238850Sandreas.hansson@arm.comSimpleCPU::read(Addr addr, uint16_t &data, unsigned flags); 4248922Swilliam.wang@arm.com 4258850Sandreas.hansson@arm.comtemplate 4268922Swilliam.wang@arm.comFault 4278850Sandreas.hansson@arm.comSimpleCPU::read(Addr addr, uint8_t &data, unsigned flags); 4288922Swilliam.wang@arm.com 4298850Sandreas.hansson@arm.com#endif //DOXYGEN_SHOULD_SKIP_THIS 4308850Sandreas.hansson@arm.com 431180SN/Atemplate<> 4322680Sktlim@umich.eduFault 433180SN/ASimpleCPU::read(Addr addr, double &data, unsigned flags) 4346221Snate@binkert.org{ 4356221Snate@binkert.org return read(addr, *(uint64_t*)&data, flags); 4366221Snate@binkert.org} 4372378SN/A 4385718Shsul@eecs.umich.edutemplate<> 4395718Shsul@eecs.umich.eduFault 4405718Shsul@eecs.umich.eduSimpleCPU::read(Addr addr, float &data, unsigned flags) 4415718Shsul@eecs.umich.edu{ 4425718Shsul@eecs.umich.edu return read(addr, *(uint32_t*)&data, flags); 4435718Shsul@eecs.umich.edu} 4445718Shsul@eecs.umich.edu 4456221Snate@binkert.org 4465718Shsul@eecs.umich.edutemplate<> 4475718Shsul@eecs.umich.eduFault 4485718Shsul@eecs.umich.eduSimpleCPU::read(Addr addr, int32_t &data, unsigned flags) 4498779Sgblack@eecs.umich.edu{ 4508779Sgblack@eecs.umich.edu return read(addr, (uint32_t&)data, flags); 4518779Sgblack@eecs.umich.edu} 452180SN/A 453180SN/A 454180SN/Atemplate <class T> 455180SN/AFault 4564000Ssaidi@eecs.umich.eduSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) 4574000Ssaidi@eecs.umich.edu{ 4584000Ssaidi@eecs.umich.edu if (traceData) { 4596221Snate@binkert.org traceData->setAddr(addr); 4606221Snate@binkert.org traceData->setData(data); 4616221Snate@binkert.org } 4626221Snate@binkert.org 4634000Ssaidi@eecs.umich.edu memReq->reset(addr, sizeof(T), flags); 4644000Ssaidi@eecs.umich.edu 4654000Ssaidi@eecs.umich.edu // translate to physical address 4664000Ssaidi@eecs.umich.edu Fault fault = xc->translateDataWriteReq(memReq); 467180SN/A 4682798Sktlim@umich.edu // do functional access 469180SN/A if (fault == No_Fault) 4709430SAndreas.Sandberg@ARM.com fault = xc->write(memReq, data); 4719430SAndreas.Sandberg@ARM.com 4722359SN/A if (fault == No_Fault && dcacheInterface) { 4735606Snate@binkert.org memReq->cmd = Write; 4749446SAndreas.Sandberg@ARM.com memcpy(memReq->data,(uint8_t *)&data,memReq->size); 4759446SAndreas.Sandberg@ARM.com memReq->completionEvent = NULL; 4769446SAndreas.Sandberg@ARM.com memReq->time = curTick; 4779446SAndreas.Sandberg@ARM.com MemAccessResult result = dcacheInterface->access(memReq); 478180SN/A 479180SN/A // Ugly hack to get an event scheduled *only* if the access is 480180SN/A // a miss. We really should add first-class support for this 4818737Skoansin.tan@gmail.com // at some point. 482180SN/A if (result != MA_HIT && dcacheInterface->doEvents()) { 4832680Sktlim@umich.edu memReq->completionEvent = &cacheCompletionEvent; 4849152Satgutier@umich.edu lastDcacheStall = curTick; 4859430SAndreas.Sandberg@ARM.com unscheduleTickEvent(); 4869430SAndreas.Sandberg@ARM.com _status = DcacheMissStall; 4879332Sdam.sunwoo@arm.com } 4889332Sdam.sunwoo@arm.com } 4899430SAndreas.Sandberg@ARM.com 4905712Shsul@eecs.umich.edu if (res && (fault == No_Fault)) 4916221Snate@binkert.org *res = memReq->result; 4926221Snate@binkert.org 4932680Sktlim@umich.edu return fault; 4942680Sktlim@umich.edu} 495180SN/A 4962680Sktlim@umich.edu 4972651Ssaidi@eecs.umich.edu#ifndef DOXYGEN_SHOULD_SKIP_THIS 4982680Sktlim@umich.edutemplate 4992651Ssaidi@eecs.umich.eduFault 5005714Shsul@eecs.umich.eduSimpleCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res); 5015715Shsul@eecs.umich.edu 5025714Shsul@eecs.umich.edutemplate 5032359SN/AFault 5045875Ssteve.reinhardt@amd.comSimpleCPU::write(uint32_t data, Addr addr, unsigned flags, uint64_t *res); 5055875Ssteve.reinhardt@amd.com 5065875Ssteve.reinhardt@amd.comtemplate 5075875Ssteve.reinhardt@amd.comFault 5085217Ssaidi@eecs.umich.eduSimpleCPU::write(uint16_t data, Addr addr, unsigned flags, uint64_t *res); 5095875Ssteve.reinhardt@amd.com 5107781SAli.Saidi@ARM.comtemplate 5119294Sandreas.hansson@arm.comFault 5129294Sandreas.hansson@arm.comSimpleCPU::write(uint8_t data, Addr addr, unsigned flags, uint64_t *res); 5139294Sandreas.hansson@arm.com 5149294Sandreas.hansson@arm.com#endif //DOXYGEN_SHOULD_SKIP_THIS 5157781SAli.Saidi@ARM.com 5167781SAli.Saidi@ARM.comtemplate<> 5179178Sandreas.hansson@arm.comFault 5189178Sandreas.hansson@arm.comSimpleCPU::write(double data, Addr addr, unsigned flags, uint64_t *res) 5197781SAli.Saidi@ARM.com{ 5209178Sandreas.hansson@arm.com return write(*(uint64_t*)&data, addr, flags, res); 5219294Sandreas.hansson@arm.com} 5229178Sandreas.hansson@arm.com 5238922Swilliam.wang@arm.comtemplate<> 5247781SAli.Saidi@ARM.comFault 5259178Sandreas.hansson@arm.comSimpleCPU::write(float data, Addr addr, unsigned flags, uint64_t *res) 5269178Sandreas.hansson@arm.com{ 5277781SAli.Saidi@ARM.com return write(*(uint32_t*)&data, addr, flags, res); 5289178Sandreas.hansson@arm.com} 5299294Sandreas.hansson@arm.com 5309178Sandreas.hansson@arm.com 5318922Swilliam.wang@arm.comtemplate<> 5327781SAli.Saidi@ARM.comFault 53310194SGeoffrey.Blake@arm.comSimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res) 53410194SGeoffrey.Blake@arm.com{ 5358733Sgeoffrey.blake@arm.com return write((uint32_t)data, addr, flags, res); 5368887Sgeoffrey.blake@arm.com} 5378887Sgeoffrey.blake@arm.com 5388887Sgeoffrey.blake@arm.com 5398887Sgeoffrey.blake@arm.com#ifdef FULL_SYSTEM 5408887Sgeoffrey.blake@arm.comAddr 5419294Sandreas.hansson@arm.comSimpleCPU::dbg_vtophys(Addr addr) 5428922Swilliam.wang@arm.com{ 5439294Sandreas.hansson@arm.com return vtophys(xc, addr); 5448922Swilliam.wang@arm.com} 5459294Sandreas.hansson@arm.com#endif // FULL_SYSTEM 5468922Swilliam.wang@arm.com 5479294Sandreas.hansson@arm.comTick save_cycle = 0; 5488922Swilliam.wang@arm.com 5498733Sgeoffrey.blake@arm.com 55010194SGeoffrey.Blake@arm.comvoid 55110194SGeoffrey.Blake@arm.comSimpleCPU::processCacheCompletion() 55210194SGeoffrey.Blake@arm.com{ 5538887Sgeoffrey.blake@arm.com switch (status()) { 5549178Sandreas.hansson@arm.com case IcacheMissStall: 5559178Sandreas.hansson@arm.com icacheStallCycles += curTick - lastIcacheStall; 5568887Sgeoffrey.blake@arm.com _status = IcacheMissComplete; 5579178Sandreas.hansson@arm.com scheduleTickEvent(1); 5589294Sandreas.hansson@arm.com break; 5599294Sandreas.hansson@arm.com case DcacheMissStall: 5609178Sandreas.hansson@arm.com dcacheStallCycles += curTick - lastDcacheStall; 5618922Swilliam.wang@arm.com _status = Running; 5628887Sgeoffrey.blake@arm.com scheduleTickEvent(1); 5639178Sandreas.hansson@arm.com break; 5649178Sandreas.hansson@arm.com case SwitchedOut: 5658887Sgeoffrey.blake@arm.com // If this CPU has been switched out due to sampling/warm-up, 5669178Sandreas.hansson@arm.com // ignore any further status changes (e.g., due to cache 5679294Sandreas.hansson@arm.com // misses outstanding at the time of the switch). 5689294Sandreas.hansson@arm.com return; 5699178Sandreas.hansson@arm.com default: 5708922Swilliam.wang@arm.com panic("SimpleCPU::processCacheCompletion: bad state"); 5718887Sgeoffrey.blake@arm.com break; 5728733Sgeoffrey.blake@arm.com } 573180SN/A} 574605SN/A 5753520Sgblack@eecs.umich.edu#ifdef FULL_SYSTEM 5765810Sgblack@eecs.umich.eduvoid 5779152Satgutier@umich.eduSimpleCPU::post_interrupt(int int_num, int index) 5782254SN/A{ 5798779Sgblack@eecs.umich.edu BaseCPU::post_interrupt(int_num, index); 5808779Sgblack@eecs.umich.edu 5818779Sgblack@eecs.umich.edu if (xc->status() == ExecContext::Suspended) { 5822254SN/A DPRINTF(IPI,"Suspended Processor awoke\n"); 5838779Sgblack@eecs.umich.edu xc->activate(); 5848779Sgblack@eecs.umich.edu Annotate::Resume(xc); 5858779Sgblack@eecs.umich.edu } 5864192Sktlim@umich.edu} 5879178Sandreas.hansson@arm.com#endif // FULL_SYSTEM 5889178Sandreas.hansson@arm.com 5899178Sandreas.hansson@arm.com/* start simulation, program loaded, processor precise state initialized */ 5909178Sandreas.hansson@arm.comvoid 5919178Sandreas.hansson@arm.comSimpleCPU::tick() 5929178Sandreas.hansson@arm.com{ 5939294Sandreas.hansson@arm.com traceData = NULL; 5949178Sandreas.hansson@arm.com 5959178Sandreas.hansson@arm.com Fault fault = No_Fault; 5964192Sktlim@umich.edu 5979178Sandreas.hansson@arm.com#ifdef FULL_SYSTEM 5989178Sandreas.hansson@arm.com if (AlphaISA::check_interrupts && 5999294Sandreas.hansson@arm.com xc->cpu->check_interrupts() && 6009178Sandreas.hansson@arm.com !PC_PAL(xc->regs.pc) && 6019178Sandreas.hansson@arm.com status() != IcacheMissComplete) { 602180SN/A int ipl = 0; 603180SN/A int summary = 0; 6049446SAndreas.Sandberg@ARM.com AlphaISA::check_interrupts = 0; 6059446SAndreas.Sandberg@ARM.com IntReg *ipr = xc->regs.ipr; 6069446SAndreas.Sandberg@ARM.com 6079446SAndreas.Sandberg@ARM.com if (xc->regs.ipr[TheISA::IPR_SIRR]) { 6089446SAndreas.Sandberg@ARM.com for (int i = TheISA::INTLEVEL_SOFTWARE_MIN; 6099446SAndreas.Sandberg@ARM.com i < TheISA::INTLEVEL_SOFTWARE_MAX; i++) { 6109446SAndreas.Sandberg@ARM.com if (ipr[TheISA::IPR_SIRR] & (ULL(1) << i)) { 6119446SAndreas.Sandberg@ARM.com // See table 4-19 of 21164 hardware reference 6129446SAndreas.Sandberg@ARM.com ipl = (i - TheISA::INTLEVEL_SOFTWARE_MIN) + 1; 6139446SAndreas.Sandberg@ARM.com summary |= (ULL(1) << i); 6149446SAndreas.Sandberg@ARM.com } 6159446SAndreas.Sandberg@ARM.com } 6169446SAndreas.Sandberg@ARM.com } 6179446SAndreas.Sandberg@ARM.com 6189446SAndreas.Sandberg@ARM.com uint64_t interrupts = xc->cpu->intr_status(); 6199446SAndreas.Sandberg@ARM.com for (int i = TheISA::INTLEVEL_EXTERNAL_MIN; 620180SN/A i < TheISA::INTLEVEL_EXTERNAL_MAX; i++) { 6215536Srstrong@hp.com if (interrupts & (ULL(1) << i)) { 6225606Snate@binkert.org // See table 4-19 of 21164 hardware reference 6231917SN/A ipl = i; 6241917SN/A summary |= (ULL(1) << i); 6251917SN/A } 6261917SN/A } 6271917SN/A 6286221Snate@binkert.org if (ipr[TheISA::IPR_ASTRR]) 6296221Snate@binkert.org panic("asynchronous traps not implemented\n"); 6302680Sktlim@umich.edu 6312680Sktlim@umich.edu if (ipl && ipl > xc->regs.ipr[TheISA::IPR_IPLR]) { 6321917SN/A ipr[TheISA::IPR_ISR] = summary; 6332254SN/A ipr[TheISA::IPR_INTID] = ipl; 6347823Ssteve.reinhardt@amd.com xc->ev5_trap(Interrupt_Fault); 6351917SN/A 6361917SN/A DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", 6372SN/A ipr[TheISA::IPR_IPLR], ipl, summary); 638921SN/A } 639921SN/A } 6404000Ssaidi@eecs.umich.edu#endif 6419332Sdam.sunwoo@arm.com 6429448SAndreas.Sandberg@ARM.com // maintain $r0 semantics 6439448SAndreas.Sandberg@ARM.com xc->regs.intRegFile[ZeroReg] = 0; 6449448SAndreas.Sandberg@ARM.com#ifdef TARGET_ALPHA 6459448SAndreas.Sandberg@ARM.com xc->regs.floatRegFile.d[ZeroReg] = 0.0; 6469448SAndreas.Sandberg@ARM.com#endif // TARGET_ALPHA 6479448SAndreas.Sandberg@ARM.com 6489332Sdam.sunwoo@arm.com if (status() == IcacheMissComplete) { 6499448SAndreas.Sandberg@ARM.com // We've already fetched an instruction and were stalled on an 6509448SAndreas.Sandberg@ARM.com // I-cache miss. No need to fetch it again. 6519448SAndreas.Sandberg@ARM.com 6529448SAndreas.Sandberg@ARM.com // Set status to running; tick event will get rescheduled if 6539448SAndreas.Sandberg@ARM.com // necessary at end of tick() function. 6549448SAndreas.Sandberg@ARM.com _status = Running; 6559448SAndreas.Sandberg@ARM.com } 6569448SAndreas.Sandberg@ARM.com else { 657921SN/A // Try to fetch an instruction 658921SN/A 659921SN/A // set up memory request for instruction fetch 660921SN/A#ifdef FULL_SYSTEM 661921SN/A#define IFETCH_FLAGS(pc) ((pc) & 1) ? PHYSICAL : 0 6624000Ssaidi@eecs.umich.edu#else 6639448SAndreas.Sandberg@ARM.com#define IFETCH_FLAGS(pc) 0 6649448SAndreas.Sandberg@ARM.com#endif 6659448SAndreas.Sandberg@ARM.com 6669448SAndreas.Sandberg@ARM.com memReq->cmd = Read; 6679448SAndreas.Sandberg@ARM.com memReq->reset(xc->regs.pc & ~3, sizeof(uint32_t), 6689448SAndreas.Sandberg@ARM.com IFETCH_FLAGS(xc->regs.pc)); 6699448SAndreas.Sandberg@ARM.com 6709448SAndreas.Sandberg@ARM.com fault = xc->translateInstReq(memReq); 6719448SAndreas.Sandberg@ARM.com 672921SN/A if (fault == No_Fault) 673921SN/A fault = xc->mem->read(memReq, inst); 6741191SN/A 6759749Sandreas@sandberg.pp.se if (icacheInterface && fault == No_Fault) { 6769749Sandreas@sandberg.pp.se memReq->completionEvent = NULL; 6779749Sandreas@sandberg.pp.se 6789983Sstever@gmail.com memReq->time = curTick; 6799749Sandreas@sandberg.pp.se MemAccessResult result = icacheInterface->access(memReq); 6809749Sandreas@sandberg.pp.se 6819749Sandreas@sandberg.pp.se // Ugly hack to get an event scheduled *only* if the access is 6829749Sandreas@sandberg.pp.se // a miss. We really should add first-class support for this 68310529Smorr@cs.wisc.edu // at some point. 68410529Smorr@cs.wisc.edu if (result != MA_HIT && icacheInterface->doEvents()) { 68510529Smorr@cs.wisc.edu memReq->completionEvent = &cacheCompletionEvent; 68610529Smorr@cs.wisc.edu lastIcacheStall = curTick; 68710529Smorr@cs.wisc.edu unscheduleTickEvent(); 68810529Smorr@cs.wisc.edu _status = IcacheMissStall; 68910529Smorr@cs.wisc.edu return; 69010529Smorr@cs.wisc.edu } 69110529Smorr@cs.wisc.edu } 69210529Smorr@cs.wisc.edu } 69310529Smorr@cs.wisc.edu 69410529Smorr@cs.wisc.edu // If we've got a valid instruction (i.e., no fault on instruction 69510529Smorr@cs.wisc.edu // fetch), then execute it. 69610529Smorr@cs.wisc.edu if (fault == No_Fault) { 69710529Smorr@cs.wisc.edu 69810529Smorr@cs.wisc.edu // keep an instruction count 69910529Smorr@cs.wisc.edu numInst++; 70010529Smorr@cs.wisc.edu 70110529Smorr@cs.wisc.edu // check for instruction-count-based events 7029749Sandreas@sandberg.pp.se comInstEventQueue[0]->serviceEvents(numInst); 7039749Sandreas@sandberg.pp.se 7049749Sandreas@sandberg.pp.se // decode the instruction 7059749Sandreas@sandberg.pp.se StaticInstPtr<TheISA> si(inst); 7069983Sstever@gmail.com 7079749Sandreas@sandberg.pp.se traceData = Trace::getInstRecord(curTick, xc, this, si, 7089749Sandreas@sandberg.pp.se xc->regs.pc); 7099749Sandreas@sandberg.pp.se 7109749Sandreas@sandberg.pp.se#ifdef FULL_SYSTEM 7119749Sandreas@sandberg.pp.se xc->regs.opcode = (inst >> 26) & 0x3f; 7129749Sandreas@sandberg.pp.se xc->regs.ra = (inst >> 21) & 0x1f; 7131191SN/A#endif // FULL_SYSTEM 7141191SN/A 7151191SN/A xc->func_exe_inst++; 7161191SN/A 7171191SN/A fault = si->execute(this, xc, traceData); 7181191SN/A#ifdef FS_MEASURE 7191191SN/A if (!(xc->misspeculating()) && (xc->system->bin)) { 7201191SN/A SWContext *ctx = xc->swCtx; 7211191SN/A if (ctx && !ctx->callStack.empty()) { 7221191SN/A if (si->isCall()) { 7231191SN/A ctx->calls++; 7241191SN/A } 7251191SN/A if (si->isReturn()) { 7261191SN/A if (ctx->calls == 0) { 7271191SN/A fnCall *top = ctx->callStack.top(); 7281191SN/A DPRINTF(TCPIP, "Removing %s from callstack.\n", top->name); 7291191SN/A delete top; 7301191SN/A ctx->callStack.pop(); 7311191SN/A if (ctx->callStack.empty()) 7321191SN/A xc->system->nonPath->activate(); 7331191SN/A else 7347823Ssteve.reinhardt@amd.com ctx->callStack.top()->myBin->activate(); 7357823Ssteve.reinhardt@amd.com 7361191SN/A xc->system->dumpState(xc); 7371191SN/A } else { 738 ctx->calls--; 739 } 740 } 741 } 742 } 743#endif 744 if (si->isMemRef()) { 745 numMemRefs++; 746 } 747 748 if (si->isLoad()) { 749 ++numLoad; 750 comLoadEventQueue[0]->serviceEvents(numLoad); 751 } 752 753 if (traceData) 754 traceData->finalize(); 755 756 } // if (fault == No_Fault) 757 758 if (fault != No_Fault) { 759#ifdef FULL_SYSTEM 760 xc->ev5_trap(fault); 761#else // !FULL_SYSTEM 762 fatal("fault (%d) detected @ PC 0x%08p", fault, xc->regs.pc); 763#endif // FULL_SYSTEM 764 } 765 else { 766 // go to the next instruction 767 xc->regs.pc = xc->regs.npc; 768 xc->regs.npc += sizeof(MachInst); 769 } 770 771#ifdef FULL_SYSTEM 772 Addr oldpc; 773 do { 774 oldpc = xc->regs.pc; 775 system->pcEventQueue.service(xc); 776 } while (oldpc != xc->regs.pc); 777#endif 778 779 assert(status() == Running || 780 status() == Idle || 781 status() == DcacheMissStall); 782 783 if (status() == Running && !tickEvent.scheduled()) 784 tickEvent.schedule(curTick + 1); 785} 786 787 788//////////////////////////////////////////////////////////////////////// 789// 790// SimpleCPU Simulation Object 791// 792BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU) 793 794 Param<Counter> max_insts_any_thread; 795 Param<Counter> max_insts_all_threads; 796 Param<Counter> max_loads_any_thread; 797 Param<Counter> max_loads_all_threads; 798 799#ifdef FULL_SYSTEM 800 SimObjectParam<AlphaItb *> itb; 801 SimObjectParam<AlphaDtb *> dtb; 802 SimObjectParam<FunctionalMemory *> mem; 803 SimObjectParam<System *> system; 804 Param<int> mult; 805#else 806 SimObjectParam<Process *> workload; 807#endif // FULL_SYSTEM 808 809 SimObjectParam<BaseMem *> icache; 810 SimObjectParam<BaseMem *> dcache; 811 812 Param<bool> defer_registration; 813 814END_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU) 815 816BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU) 817 818 INIT_PARAM_DFLT(max_insts_any_thread, 819 "terminate when any thread reaches this inst count", 820 0), 821 INIT_PARAM_DFLT(max_insts_all_threads, 822 "terminate when all threads have reached this inst count", 823 0), 824 INIT_PARAM_DFLT(max_loads_any_thread, 825 "terminate when any thread reaches this load count", 826 0), 827 INIT_PARAM_DFLT(max_loads_all_threads, 828 "terminate when all threads have reached this load count", 829 0), 830 831#ifdef FULL_SYSTEM 832 INIT_PARAM(itb, "Instruction TLB"), 833 INIT_PARAM(dtb, "Data TLB"), 834 INIT_PARAM(mem, "memory"), 835 INIT_PARAM(system, "system object"), 836 INIT_PARAM_DFLT(mult, "system clock multiplier", 1), 837#else 838 INIT_PARAM(workload, "processes to run"), 839#endif // FULL_SYSTEM 840 841 INIT_PARAM_DFLT(icache, "L1 instruction cache object", NULL), 842 INIT_PARAM_DFLT(dcache, "L1 data cache object", NULL), 843 INIT_PARAM_DFLT(defer_registration, "defer registration with system " 844 "(for sampling)", false) 845 846END_INIT_SIM_OBJECT_PARAMS(SimpleCPU) 847 848 849CREATE_SIM_OBJECT(SimpleCPU) 850{ 851 SimpleCPU *cpu; 852#ifdef FULL_SYSTEM 853 if (mult != 1) 854 panic("processor clock multiplier must be 1\n"); 855 856 cpu = new SimpleCPU(getInstanceName(), system, 857 max_insts_any_thread, max_insts_all_threads, 858 max_loads_any_thread, max_loads_all_threads, 859 itb, dtb, mem, 860 (icache) ? icache->getInterface() : NULL, 861 (dcache) ? dcache->getInterface() : NULL, 862 defer_registration, 863 ticksPerSecond * mult); 864#else 865 866 cpu = new SimpleCPU(getInstanceName(), workload, 867 max_insts_any_thread, max_insts_all_threads, 868 max_loads_any_thread, max_loads_all_threads, 869 (icache) ? icache->getInterface() : NULL, 870 (dcache) ? dcache->getInterface() : NULL, 871 defer_registration); 872 873#endif // FULL_SYSTEM 874#if 0 875 if (!defer_registration) { 876 cpu->registerExecContexts(); 877 } 878#endif 879 return cpu; 880} 881 882REGISTER_SIM_OBJECT("SimpleCPU", SimpleCPU) 883 884