system.cc revision 8795:0909f8ed7aa0
12SN/A/* 213610Sgiacomo.gabrielli@arm.com * Copyright (c) 2003-2006 The Regents of The University of Michigan 39920Syasuko.eckert@amd.com * Copyright (c) 2011 Regents of the University of California 48733Sgeoffrey.blake@arm.com * All rights reserved. 58733Sgeoffrey.blake@arm.com * 68733Sgeoffrey.blake@arm.com * Redistribution and use in source and binary forms, with or without 78733Sgeoffrey.blake@arm.com * modification, are permitted provided that the following conditions are 88733Sgeoffrey.blake@arm.com * met: redistributions of source code must retain the above copyright 98733Sgeoffrey.blake@arm.com * notice, this list of conditions and the following disclaimer; 108733Sgeoffrey.blake@arm.com * redistributions in binary form must reproduce the above copyright 118733Sgeoffrey.blake@arm.com * notice, this list of conditions and the following disclaimer in the 128733Sgeoffrey.blake@arm.com * documentation and/or other materials provided with the distribution; 138733Sgeoffrey.blake@arm.com * neither the name of the copyright holders nor the names of its 148733Sgeoffrey.blake@arm.com * contributors may be used to endorse or promote products derived from 152190SN/A * this software without specific prior written permission. 162SN/A * 172SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 182SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 192SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 202SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 212SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 222SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 232SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 242SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 252SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 262SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282SN/A * 292SN/A * Authors: Steve Reinhardt 302SN/A * Lisa Hsu 312SN/A * Nathan Binkert 322SN/A * Ali Saidi 332SN/A * Rick Strong 342SN/A */ 352SN/A 362SN/A#include "arch/isa_traits.hh" 372SN/A#include "arch/remote_gdb.hh" 382SN/A#include "arch/utility.hh" 392SN/A#include "arch/vtophys.hh" 402665SN/A#include "base/loader/object_file.hh" 412665SN/A#include "base/loader/symtab.hh" 422SN/A#include "base/trace.hh" 432SN/A#include "config/the_isa.hh" 442680Sktlim@umich.edu#include "cpu/thread_context.hh" 452680Sktlim@umich.edu#include "debug/Loader.hh" 462SN/A#include "kern/kernel_stats.hh" 478229Snate@binkert.org#include "mem/mem_object.hh" 487680Sgblack@eecs.umich.edu#include "mem/physical.hh" 497680Sgblack@eecs.umich.edu#include "mem/vport.hh" 506329Sgblack@eecs.umich.edu#include "params/System.hh" 513453Sgblack@eecs.umich.edu#include "sim/byteswap.hh" 526216Snate@binkert.org#include "sim/debug.hh" 536658Snate@binkert.org#include "sim/full_system.hh" 5412104Snathanael.premillieu@arm.com#include "sim/system.hh" 552SN/A 562190SN/Ausing namespace std; 572190SN/Ausing namespace TheISA; 583453Sgblack@eecs.umich.edu 593453Sgblack@eecs.umich.eduvector<System *> System::systemList; 6013693Sgiacomo.gabrielli@arm.com 619020Sgblack@eecs.umich.eduint System::numSystemsRunning = 0; 623453Sgblack@eecs.umich.edu 632190SN/ASystem::System(Params *p) 6412406Sgabeblack@google.com : SimObject(p), physmem(p->physmem), _numContexts(0), pagePtr(0), 658887Sgeoffrey.blake@arm.com init_param(p->init_param), 667680Sgblack@eecs.umich.edu loadAddrMask(p->load_addr_mask), 672313SN/A nextPID(0), 688706Sandreas.hansson@arm.com memoryMode(p->mem_mode), 692190SN/A workItemsBegin(0), 702190SN/A workItemsEnd(0), 7113905Sgabeblack@google.com _params(p), 7213905Sgabeblack@google.com totalNumInsts(0), 738902Sandreas.hansson@arm.com instEventQueue("system instruction-based event queue") 742SN/A{ 752680Sktlim@umich.edu // add self to global system list 762680Sktlim@umich.edu systemList.push_back(this); 772680Sktlim@umich.edu 782680Sktlim@umich.edu /** Keep track of all memories we can execute code out of 792680Sktlim@umich.edu * in our system 8013865Sgabeblack@google.com */ 8113865Sgabeblack@google.com for (int x = 0; x < p->memories.size(); x++) { 822680Sktlim@umich.edu if (!p->memories[x]) 832680Sktlim@umich.edu continue; 842680Sktlim@umich.edu memRanges.push_back(RangeSize(p->memories[x]->start(), 852680Sktlim@umich.edu p->memories[x]->size())); 862682Sktlim@umich.edu } 872680Sktlim@umich.edu 882680Sktlim@umich.edu if (FullSystem) { 892680Sktlim@umich.edu kernelSymtab = new SymbolTable; 902680Sktlim@umich.edu if (!debugSymbolTable) 912680Sktlim@umich.edu debugSymbolTable = new SymbolTable; 922SN/A 932107SN/A 942107SN/A /** 9512109SRekai.GonzalezAlberquilla@arm.com * Get a functional port to memory 9612109SRekai.GonzalezAlberquilla@arm.com */ 9713610Sgiacomo.gabrielli@arm.com Port *mem_port; 9813610Sgiacomo.gabrielli@arm.com functionalPort = new FunctionalPort(name() + "-fport"); 992SN/A mem_port = physmem->getPort("functional"); 1006029Ssteve.reinhardt@amd.com functionalPort->setPeer(mem_port); 101246SN/A mem_port->setPeer(functionalPort); 102246SN/A 103246SN/A virtPort = new VirtualPort(name() + "-fport"); 104246SN/A mem_port = physmem->getPort("functional"); 105246SN/A virtPort->setPeer(mem_port); 106246SN/A mem_port->setPeer(virtPort); 107246SN/A 1082190SN/A 109246SN/A /** 110246SN/A * Load the kernel code into memory 11113641Sqtt2@cornell.edu */ 11213641Sqtt2@cornell.edu if (params()->kernel == "") { 11313641Sqtt2@cornell.edu inform("No kernel set for full system simulation. " 11413641Sqtt2@cornell.edu "Assuming you know what you're doing...\n"); 115246SN/A } else { 116246SN/A // Load kernel code 117246SN/A kernel = createObjectFile(params()->kernel); 118246SN/A inform("kernel located at: %s", params()->kernel); 119246SN/A 1202SN/A if (kernel == NULL) 1212680Sktlim@umich.edu fatal("Could not load kernel file %s", params()->kernel); 1222423SN/A 1232190SN/A // Load program sections into memory 124180SN/A kernel->loadSections(functionalPort, loadAddrMask); 12510110Sandreas.hansson@arm.com 1262190SN/A // setup entry points 12710190Sakash.bagdia@arm.com kernelStart = kernel->textBase(); 12810190Sakash.bagdia@arm.com kernelEnd = kernel->bssBase() + kernel->bssSize(); 12910110Sandreas.hansson@arm.com kernelEntry = kernel->entryPoint(); 1305715Shsul@eecs.umich.edu 1315715Shsul@eecs.umich.edu // load symbols 1325714Shsul@eecs.umich.edu if (!kernel->loadGlobalSymbols(kernelSymtab)) 13313865Sgabeblack@google.com fatal("could not load kernel symbols\n"); 1345714Shsul@eecs.umich.edu 13513865Sgabeblack@google.com if (!kernel->loadLocalSymbols(kernelSymtab)) 1365714Shsul@eecs.umich.edu fatal("could not load kernel local symbols\n"); 13712406Sgabeblack@google.com 1382190SN/A if (!kernel->loadGlobalSymbols(debugSymbolTable)) 13912406Sgabeblack@google.com fatal("could not load kernel symbols\n"); 1402521SN/A 1418887Sgeoffrey.blake@arm.com if (!kernel->loadLocalSymbols(debugSymbolTable)) 1428733Sgeoffrey.blake@arm.com fatal("could not load kernel local symbols\n"); 14313693Sgiacomo.gabrielli@arm.com 14413693Sgiacomo.gabrielli@arm.com DPRINTF(Loader, "Kernel start = %#x\n", kernelStart); 1459020Sgblack@eecs.umich.edu DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd); 1468541Sgblack@eecs.umich.edu DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry); 1474997Sgblack@eecs.umich.edu DPRINTF(Loader, "Kernel loaded...\n"); 1484997Sgblack@eecs.umich.edu } 14913905Sgabeblack@google.com } 1502654SN/A 1518852Sandreas.hansson@arm.com // increment the number of running systms 1522521SN/A numSystemsRunning++; 15314022Sgabeblack@google.com 1543673Srdreslin@umich.edu activeCpus.clear(); 1558706Sandreas.hansson@arm.com} 1568706Sandreas.hansson@arm.com 1578706Sandreas.hansson@arm.comSystem::~System() 1588706Sandreas.hansson@arm.com{ 1598706Sandreas.hansson@arm.com delete kernelSymtab; 1608706Sandreas.hansson@arm.com delete kernel; 1618706Sandreas.hansson@arm.com} 1628799Sgblack@eecs.umich.edu 16314022Sgabeblack@google.comvoid 1642518SN/ASystem::setMemoryMode(Enums::MemoryMode mode) 1652190SN/A{ 1662190SN/A assert(getState() == Drained); 16711886Sbrandon.potter@amd.com memoryMode = mode; 16811886Sbrandon.potter@amd.com} 1692190SN/A 1702159SN/Abool System::breakpoint() 1712235SN/A{ 1722103SN/A if (remoteGDB.size()) 17310407Smitch.hayenga@arm.com return remoteGDB[0]->breakpoint(); 17410407Smitch.hayenga@arm.com return false; 175393SN/A} 176393SN/A 17710407Smitch.hayenga@arm.com/** 178393SN/A * Setting rgdb_wait to a positive integer waits for a remote debugger to 179393SN/A * connect to that context ID before continuing. This should really 18010407Smitch.hayenga@arm.com be a parameter on the CPU object or something... 1812159SN/A */ 18211627Smichael.lebeane@amd.comint rgdb_wait = -1; 18311627Smichael.lebeane@amd.com 18411627Smichael.lebeane@amd.comint 18511627Smichael.lebeane@amd.comSystem::registerThreadContext(ThreadContext *tc, int assigned) 18611627Smichael.lebeane@amd.com{ 18711627Smichael.lebeane@amd.com int id; 1882190SN/A if (assigned == -1) { 1892159SN/A for (id = 0; id < threadContexts.size(); id++) { 1902680Sktlim@umich.edu if (!threadContexts[id]) 1912159SN/A break; 1922190SN/A } 1932159SN/A 1942313SN/A if (threadContexts.size() <= id) 1952235SN/A threadContexts.resize(id + 1); 1962235SN/A } else { 1972235SN/A if (threadContexts.size() <= assigned) 1982235SN/A threadContexts.resize(assigned + 1); 1992235SN/A id = assigned; 2002254SN/A } 2012254SN/A 2022254SN/A if (threadContexts[id]) 2032235SN/A fatal("Cannot have two CPUs with the same id (%d)\n", id); 2042680Sktlim@umich.edu 2052159SN/A threadContexts[id] = tc; 2062190SN/A _numContexts++; 2072159SN/A 2082159SN/A int port = getRemoteGDBPort(); 2092159SN/A if (port) { 2102159SN/A RemoteGDB *rgdb = new RemoteGDB(this, tc); 21113865Sgabeblack@google.com GDBListener *gdbl = new GDBListener(rgdb, port + id); 2122159SN/A gdbl->listen(); 21313865Sgabeblack@google.com 2142159SN/A if (rgdb_wait != -1 && rgdb_wait == id) 21512109SRekai.GonzalezAlberquilla@arm.com gdbl->accept(); 21612109SRekai.GonzalezAlberquilla@arm.com 21712109SRekai.GonzalezAlberquilla@arm.com if (remoteGDB.size() <= id) { 21812109SRekai.GonzalezAlberquilla@arm.com remoteGDB.resize(id + 1); 21912109SRekai.GonzalezAlberquilla@arm.com } 22012109SRekai.GonzalezAlberquilla@arm.com 22112109SRekai.GonzalezAlberquilla@arm.com remoteGDB[id] = rgdb; 22212109SRekai.GonzalezAlberquilla@arm.com } 22312109SRekai.GonzalezAlberquilla@arm.com 22412109SRekai.GonzalezAlberquilla@arm.com activeCpus.push_back(false); 22512109SRekai.GonzalezAlberquilla@arm.com 22612109SRekai.GonzalezAlberquilla@arm.com return id; 22712109SRekai.GonzalezAlberquilla@arm.com} 22812109SRekai.GonzalezAlberquilla@arm.com 22912109SRekai.GonzalezAlberquilla@arm.comint 23012109SRekai.GonzalezAlberquilla@arm.comSystem::numRunningContexts() 23112109SRekai.GonzalezAlberquilla@arm.com{ 23212109SRekai.GonzalezAlberquilla@arm.com int running = 0; 23312109SRekai.GonzalezAlberquilla@arm.com for (int i = 0; i < _numContexts; ++i) { 23412109SRekai.GonzalezAlberquilla@arm.com if (threadContexts[i]->status() != ThreadContext::Halted) 23512109SRekai.GonzalezAlberquilla@arm.com ++running; 23612109SRekai.GonzalezAlberquilla@arm.com } 23712109SRekai.GonzalezAlberquilla@arm.com return running; 23812109SRekai.GonzalezAlberquilla@arm.com} 23912109SRekai.GonzalezAlberquilla@arm.com 24012109SRekai.GonzalezAlberquilla@arm.comvoid 24112109SRekai.GonzalezAlberquilla@arm.comSystem::initState() 24212109SRekai.GonzalezAlberquilla@arm.com{ 24312109SRekai.GonzalezAlberquilla@arm.com if (FullSystem) { 24412109SRekai.GonzalezAlberquilla@arm.com int i; 24512109SRekai.GonzalezAlberquilla@arm.com for (i = 0; i < threadContexts.size(); i++) 24612109SRekai.GonzalezAlberquilla@arm.com TheISA::startupCPU(threadContexts[i], i); 24712109SRekai.GonzalezAlberquilla@arm.com } 24812109SRekai.GonzalezAlberquilla@arm.com} 24913610Sgiacomo.gabrielli@arm.com 25013610Sgiacomo.gabrielli@arm.comvoid 25113610Sgiacomo.gabrielli@arm.comSystem::replaceThreadContext(ThreadContext *tc, int context_id) 25213610Sgiacomo.gabrielli@arm.com{ 25313865Sgabeblack@google.com if (context_id >= threadContexts.size()) { 2549920Syasuko.eckert@amd.com panic("replaceThreadContext: bad id, %d >= %d\n", 25513865Sgabeblack@google.com context_id, threadContexts.size()); 2562159SN/A } 25713865Sgabeblack@google.com 2582455SN/A threadContexts[context_id] = tc; 25912109SRekai.GonzalezAlberquilla@arm.com if (context_id < remoteGDB.size()) 26012109SRekai.GonzalezAlberquilla@arm.com remoteGDB[context_id]->replaceThreadContext(tc); 26112109SRekai.GonzalezAlberquilla@arm.com} 26212109SRekai.GonzalezAlberquilla@arm.com 26313610Sgiacomo.gabrielli@arm.comAddr 26413610Sgiacomo.gabrielli@arm.comSystem::allocPhysPages(int npages) 26513610Sgiacomo.gabrielli@arm.com{ 26613865Sgabeblack@google.com Addr return_addr = pagePtr << LogVMPageSize; 2679920Syasuko.eckert@amd.com pagePtr += npages; 26813865Sgabeblack@google.com if (return_addr >= physmem->size()) 2692159SN/A fatal("Out of memory, please increase size of physical memory."); 2707720Sgblack@eecs.umich.edu return return_addr; 2712159SN/A} 27211886Sbrandon.potter@amd.com 27311886Sbrandon.potter@amd.comAddr 27411886Sbrandon.potter@amd.comSystem::memSize() 27511886Sbrandon.potter@amd.com{ 27611886Sbrandon.potter@amd.com return physmem->size(); 27711886Sbrandon.potter@amd.com} 27811886Sbrandon.potter@amd.com 27911886Sbrandon.potter@amd.comAddr 2808733Sgeoffrey.blake@arm.comSystem::freeMemSize() 2818733Sgeoffrey.blake@arm.com{ 28213865Sgabeblack@google.com return physmem->size() - (pagePtr << LogVMPageSize); 2832159SN/A} 28413865Sgabeblack@google.com 2852159SN/Abool 28613865Sgabeblack@google.comSystem::isMemory(const Addr addr) const 2875260Sksewell@umich.edu{ 28813865Sgabeblack@google.com std::list<Range<Addr> >::const_iterator i; 2894172Ssaidi@eecs.umich.edu for (i = memRanges.begin(); i != memRanges.end(); i++) { 29013865Sgabeblack@google.com if (*i == addr) 2912159SN/A return true; 29213865Sgabeblack@google.com } 2932190SN/A return false; 29413865Sgabeblack@google.com} 2952190SN/A 29612106SRekai.GonzalezAlberquilla@arm.comvoid 2976313Sgblack@eecs.umich.eduSystem::resume() 2982235SN/A{ 2992235SN/A SimObject::resume(); 30013865Sgabeblack@google.com totalNumInsts = 0; 3012190SN/A} 3022190SN/A 3032159SN/Avoid 3042235SN/ASystem::serialize(ostream &os) 30513865Sgabeblack@google.com{ 3062834Sksewell@umich.edu if (FullSystem) 30711877Sbrandon.potter@amd.com kernelSymtab->serialize("kernel_symtab", os); 3084111Sgblack@eecs.umich.edu SERIALIZE_SCALAR(pagePtr); 3092834Sksewell@umich.edu SERIALIZE_SCALAR(nextPID); 3102834Sksewell@umich.edu} 3112834Sksewell@umich.edu 3122834Sksewell@umich.edu 3132525SN/Avoid 3145217Ssaidi@eecs.umich.eduSystem::unserialize(Checkpoint *cp, const string §ion) 3155217Ssaidi@eecs.umich.edu{ 3169426SAndreas.Sandberg@ARM.com if (FullSystem) 3179426SAndreas.Sandberg@ARM.com kernelSymtab->unserialize("kernel_symtab", cp, section); 3189426SAndreas.Sandberg@ARM.com UNSERIALIZE_SCALAR(pagePtr); 3199426SAndreas.Sandberg@ARM.com UNSERIALIZE_SCALAR(nextPID); 3209426SAndreas.Sandberg@ARM.com} 3219426SAndreas.Sandberg@ARM.com 3229426SAndreas.Sandberg@ARM.comvoid 32312106SRekai.GonzalezAlberquilla@arm.comSystem::printSystems() 3249426SAndreas.Sandberg@ARM.com{ 3259426SAndreas.Sandberg@ARM.com vector<System *>::iterator i = systemList.begin(); 3269426SAndreas.Sandberg@ARM.com vector<System *>::iterator end = systemList.end(); 3279426SAndreas.Sandberg@ARM.com for (; i != end; ++i) { 3289426SAndreas.Sandberg@ARM.com System *sys = *i; 32913865Sgabeblack@google.com cerr << "System " << sys->name() << ": " << hex << sys << endl; 33013865Sgabeblack@google.com } 3319426SAndreas.Sandberg@ARM.com} 33213865Sgabeblack@google.com 33313865Sgabeblack@google.comvoid 3349426SAndreas.Sandberg@ARM.comprintSystems() 33513865Sgabeblack@google.com{ 33613865Sgabeblack@google.com System::printSystems(); 33713865Sgabeblack@google.com} 33812109SRekai.GonzalezAlberquilla@arm.com 33913865Sgabeblack@google.comconst char *System::MemoryModeStrings[3] = {"invalid", "atomic", 34012109SRekai.GonzalezAlberquilla@arm.com "timing"}; 34113865Sgabeblack@google.com 34212109SRekai.GonzalezAlberquilla@arm.comSystem * 34312109SRekai.GonzalezAlberquilla@arm.comSystemParams::create() 34413865Sgabeblack@google.com{ 34513865Sgabeblack@google.com return new System(this); 34613865Sgabeblack@google.com} 34713865Sgabeblack@google.com