simple_thread.cc revision 8761
17860SN/A/* 27860SN/A * Copyright (c) 2001-2006 The Regents of The University of Michigan 37860SN/A * All rights reserved. 49988Snilay@cs.wisc.edu * 58825Snilay@cs.wisc.edu * Redistribution and use in source and binary forms, with or without 69988Snilay@cs.wisc.edu * modification, are permitted provided that the following conditions are 77935SN/A * met: redistributions of source code must retain the above copyright 87935SN/A * notice, this list of conditions and the following disclaimer; 97935SN/A * redistributions in binary form must reproduce the above copyright 107860SN/A * notice, this list of conditions and the following disclaimer in the 117860SN/A * documentation and/or other materials provided with the distribution; 127860SN/A * neither the name of the copyright holders nor the names of its 1310315Snilay@cs.wisc.edu * contributors may be used to endorse or promote products derived from 148825Snilay@cs.wisc.edu * this software without specific prior written permission. 159885Sstever@gmail.com * 169885Sstever@gmail.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179988Snilay@cs.wisc.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 188825Snilay@cs.wisc.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 198825Snilay@cs.wisc.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2010315Snilay@cs.wisc.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 218825Snilay@cs.wisc.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2210038SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239449SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249449SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 258464SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2610798Ssteve.reinhardt@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 278721SN/A * 288825Snilay@cs.wisc.edu * Authors: Steve Reinhardt 298825Snilay@cs.wisc.edu * Nathan Binkert 307935SN/A * Lisa Hsu 317935SN/A * Kevin Lim 327935SN/A */ 337935SN/A 347935SN/A#include <string> 357935SN/A 367935SN/A#include "arch/isa_traits.hh" 378893Ssaidi@eecs.umich.edu#include "arch/utility.hh" 387860SN/A#include "config/the_isa.hh" 399885Sstever@gmail.com#include "cpu/base.hh" 409885Sstever@gmail.com#include "cpu/simple_thread.hh" 419885Sstever@gmail.com#include "cpu/thread_context.hh" 4210315Snilay@cs.wisc.edu#include "mem/vport.hh" 439988Snilay@cs.wisc.edu#include "params/BaseCPU.hh" 4410315Snilay@cs.wisc.edu 459885Sstever@gmail.com#if FULL_SYSTEM 469885Sstever@gmail.com#include "arch/kernel_stats.hh" 477860SN/A#include "arch/stacktrace.hh" 487860SN/A#include "base/callback.hh" 4910038SAli.Saidi@ARM.com#include "base/cprintf.hh" 507860SN/A#include "base/output.hh" 5110451Snilay@cs.wisc.edu#include "base/trace.hh" 528210SN/A#include "cpu/profile.hh" 5310451Snilay@cs.wisc.edu#include "cpu/quiesce_event.hh" 5410451Snilay@cs.wisc.edu#include "sim/serialize.hh" 557860SN/A#include "sim/sim_exit.hh" 567860SN/A#else 577860SN/A#include "mem/translating_port.hh" 589481Snilay@cs.wisc.edu#include "sim/process.hh" 597860SN/A#include "sim/system.hh" 607860SN/A#endif 619885Sstever@gmail.com 627860SN/Ausing namespace std; 637860SN/A 647860SN/A// constructor 657860SN/A#if FULL_SYSTEM 667860SN/ASimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys, 677860SN/A TheISA::TLB *_itb, TheISA::TLB *_dtb, 687860SN/A bool use_kernel_stats) 6910451Snilay@cs.wisc.edu : ThreadState(_cpu, _thread_num), 7010451Snilay@cs.wisc.edu cpu(_cpu), system(_sys), itb(_itb), dtb(_dtb) 7110451Snilay@cs.wisc.edu 727860SN/A{ 738825Snilay@cs.wisc.edu tc = new ProxyThreadContext<SimpleThread>(this); 747860SN/A 7510038SAli.Saidi@ARM.com quiesceEvent = new EndQuiesceEvent(tc); 767860SN/A 779988Snilay@cs.wisc.edu clearArchRegs(); 7810451Snilay@cs.wisc.edu 7910451Snilay@cs.wisc.edu if (cpu->params()->profile) { 8010451Snilay@cs.wisc.edu profile = new FunctionProfile(system->kernelSymtab); 817860SN/A Callback *cb = 8210451Snilay@cs.wisc.edu new MakeCallback<SimpleThread, 837860SN/A &SimpleThread::dumpFuncProfile>(this); 847860SN/A registerExitCallback(cb); 857860SN/A } 867860SN/A 877860SN/A // let's fill with a dummy node for now so we don't get a segfault 887860SN/A // on the first cycle when there's no node available. 897860SN/A static ProfileNode dummyNode; 907860SN/A profileNode = &dummyNode; 918825Snilay@cs.wisc.edu profilePC = 3; 929449SAli.Saidi@ARM.com 937860SN/A if (use_kernel_stats) 947860SN/A kernelStats = new TheISA::Kernel::Statistics(system); 9510038SAli.Saidi@ARM.com} 967860SN/A#else 977860SN/ASimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, 987860SN/A TheISA::TLB *_itb, TheISA::TLB *_dtb) 997860SN/A : ThreadState(_cpu, _thread_num, _process), 1007860SN/A cpu(_cpu), itb(_itb), dtb(_dtb) 1018825Snilay@cs.wisc.edu{ 10210451Snilay@cs.wisc.edu clearArchRegs(); 10310451Snilay@cs.wisc.edu tc = new ProxyThreadContext<SimpleThread>(this); 10410451Snilay@cs.wisc.edu} 10510451Snilay@cs.wisc.edu 10610451Snilay@cs.wisc.edu#endif 1077860SN/A 1087860SN/ASimpleThread::SimpleThread() 1098825Snilay@cs.wisc.edu#if FULL_SYSTEM 1107860SN/A : ThreadState(NULL, -1) 1117860SN/A#else 1127860SN/A : ThreadState(NULL, -1, NULL) 11310451Snilay@cs.wisc.edu#endif 1147860SN/A{ 11510451Snilay@cs.wisc.edu tc = new ProxyThreadContext<SimpleThread>(this); 1169885Sstever@gmail.com} 1177860SN/A 1187860SN/ASimpleThread::~SimpleThread() 1197860SN/A{ 1207860SN/A delete physPort; 1217860SN/A delete virtPort; 1227860SN/A delete tc; 1237860SN/A} 1247860SN/A 1257860SN/Avoid 12610242Ssteve.reinhardt@amd.comSimpleThread::takeOverFrom(ThreadContext *oldContext) 1277860SN/A{ 1288521SN/A // some things should already be set up 1299449SAli.Saidi@ARM.com#if FULL_SYSTEM 1307860SN/A assert(system == oldContext->getSystemPtr()); 1317860SN/A#else 1327860SN/A assert(process == oldContext->getProcessPtr()); 1337860SN/A#endif 1347860SN/A 1357860SN/A copyState(oldContext); 1367860SN/A#if FULL_SYSTEM 1377860SN/A EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent(); 1389481Snilay@cs.wisc.edu if (quiesce) { 13910798Ssteve.reinhardt@amd.com // Point the quiesce event's TC at this TC so that it wakes up 14010451Snilay@cs.wisc.edu // the proper CPU. 14110451Snilay@cs.wisc.edu quiesce->tc = tc; 1429481Snilay@cs.wisc.edu } 1439481Snilay@cs.wisc.edu if (quiesceEvent) { 1449481Snilay@cs.wisc.edu quiesceEvent->tc = tc; 1459988Snilay@cs.wisc.edu } 1469481Snilay@cs.wisc.edu 1479481Snilay@cs.wisc.edu TheISA::Kernel::Statistics *stats = oldContext->getKernelStats(); 1489481Snilay@cs.wisc.edu if (stats) { 1499481Snilay@cs.wisc.edu kernelStats = stats; 1509481Snilay@cs.wisc.edu } 1517860SN/A#endif 1527860SN/A 1539885Sstever@gmail.com storeCondFailures = 0; 1548893Ssaidi@eecs.umich.edu 1557860SN/A oldContext->setStatus(ThreadContext::Halted); 1569885Sstever@gmail.com} 15710798Ssteve.reinhardt@amd.com 1589988Snilay@cs.wisc.eduvoid 1597860SN/ASimpleThread::copyTC(ThreadContext *context) 1609348SAli.Saidi@ARM.com{ 1618150SN/A copyState(context); 1627860SN/A 16310451Snilay@cs.wisc.edu#if FULL_SYSTEM 1647860SN/A EndQuiesceEvent *quiesce = context->getQuiesceEvent(); 1658835SAli.Saidi@ARM.com if (quiesce) { 1669348SAli.Saidi@ARM.com quiesceEvent = quiesce; 16710036SAli.Saidi@ARM.com } 16810451Snilay@cs.wisc.edu TheISA::Kernel::Statistics *stats = context->getKernelStats(); 1698835SAli.Saidi@ARM.com if (stats) { 1709885Sstever@gmail.com kernelStats = stats; 17110451Snilay@cs.wisc.edu } 1727860SN/A#endif 17310451Snilay@cs.wisc.edu} 1747860SN/A 1758893Ssaidi@eecs.umich.eduvoid 1767860SN/ASimpleThread::copyState(ThreadContext *oldContext) 1779885Sstever@gmail.com{ 1789885Sstever@gmail.com // copy over functional state 1799885Sstever@gmail.com _status = oldContext->status(); 1809885Sstever@gmail.com copyArchRegs(oldContext); 1819885Sstever@gmail.com#if !FULL_SYSTEM 1829988Snilay@cs.wisc.edu funcExeInst = oldContext->readFuncExeInst(); 1839885Sstever@gmail.com#endif 18410036SAli.Saidi@ARM.com 18510451Snilay@cs.wisc.edu _threadId = oldContext->threadId(); 1869885Sstever@gmail.com _contextId = oldContext->contextId(); 18710038SAli.Saidi@ARM.com} 18810038SAli.Saidi@ARM.com 18910038SAli.Saidi@ARM.comvoid 19010038SAli.Saidi@ARM.comSimpleThread::serialize(ostream &os) 19110038SAli.Saidi@ARM.com{ 19210798Ssteve.reinhardt@amd.com ThreadState::serialize(os); 19310038SAli.Saidi@ARM.com SERIALIZE_ARRAY(floatRegs.i, TheISA::NumFloatRegs); 19410038SAli.Saidi@ARM.com SERIALIZE_ARRAY(intRegs, TheISA::NumIntRegs); 19510038SAli.Saidi@ARM.com _pcState.serialize(os); 19610038SAli.Saidi@ARM.com // thread_num and cpu_id are deterministic from the config 19710038SAli.Saidi@ARM.com 19810038SAli.Saidi@ARM.com // 19910038SAli.Saidi@ARM.com // Now must serialize all the ISA dependent state 20010038SAli.Saidi@ARM.com // 20110038SAli.Saidi@ARM.com isa.serialize(cpu, os); 20210038SAli.Saidi@ARM.com} 20310038SAli.Saidi@ARM.com 20410038SAli.Saidi@ARM.com 20510038SAli.Saidi@ARM.comvoid 20610038SAli.Saidi@ARM.comSimpleThread::unserialize(Checkpoint *cp, const std::string §ion) 20710038SAli.Saidi@ARM.com{ 20810038SAli.Saidi@ARM.com ThreadState::unserialize(cp, section); 20910038SAli.Saidi@ARM.com UNSERIALIZE_ARRAY(floatRegs.i, TheISA::NumFloatRegs); 21010038SAli.Saidi@ARM.com UNSERIALIZE_ARRAY(intRegs, TheISA::NumIntRegs); 2117860SN/A _pcState.unserialize(cp, section); 2127860SN/A // thread_num and cpu_id are deterministic from the config 2138825Snilay@cs.wisc.edu 2149988Snilay@cs.wisc.edu // 21510038SAli.Saidi@ARM.com // Now must unserialize all the ISA dependent state 2167860SN/A // 2178825Snilay@cs.wisc.edu isa.unserialize(cpu, cp, section); 2188825Snilay@cs.wisc.edu} 2198825Snilay@cs.wisc.edu 2208825Snilay@cs.wisc.edu#if FULL_SYSTEM 2219885Sstever@gmail.comvoid 2229988Snilay@cs.wisc.eduSimpleThread::dumpFuncProfile() 22310038SAli.Saidi@ARM.com{ 2249265SAli.Saidi@ARM.com std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); 2258825Snilay@cs.wisc.edu profile->dump(tc, *os); 2268893Ssaidi@eecs.umich.edu} 2277860SN/A#endif 2287860SN/A 2297860SN/Avoid 23010451Snilay@cs.wisc.eduSimpleThread::activate(int delay) 23110451Snilay@cs.wisc.edu{ 2329988Snilay@cs.wisc.edu if (status() == ThreadContext::Active) 2337860SN/A return; 2347860SN/A 2357860SN/A lastActivate = curTick(); 2367860SN/A 23710451Snilay@cs.wisc.edu// if (status() == ThreadContext::Unallocated) { 2389988Snilay@cs.wisc.edu// cpu->activateWhenReady(_threadId); 2397860SN/A// return; 2407860SN/A// } 2417860SN/A 2427860SN/A _status = ThreadContext::Active; 2439988Snilay@cs.wisc.edu 2447860SN/A // status() == Suspended 2457860SN/A cpu->activateContext(_threadId, delay); 2467860SN/A} 2477860SN/A 2487860SN/Avoid 2497860SN/ASimpleThread::suspend() 25010451Snilay@cs.wisc.edu{ 25110451Snilay@cs.wisc.edu if (status() == ThreadContext::Suspended) 2529988Snilay@cs.wisc.edu return; 25310451Snilay@cs.wisc.edu 2547860SN/A lastActivate = curTick(); 2557860SN/A lastSuspend = curTick(); 2567860SN/A/* 2579988Snilay@cs.wisc.edu#if FULL_SYSTEM 2587860SN/A // Don't change the status from active if there are pending interrupts 2597860SN/A if (cpu->checkInterrupts()) { 2607860SN/A assert(status() == ThreadContext::Active); 2617860SN/A return; 2627860SN/A } 2637860SN/A#endif 2649988Snilay@cs.wisc.edu*/ 26510451Snilay@cs.wisc.edu _status = ThreadContext::Suspended; 2667860SN/A cpu->suspendContext(_threadId); 26710451Snilay@cs.wisc.edu} 26810451Snilay@cs.wisc.edu 26910451Snilay@cs.wisc.edu 27010451Snilay@cs.wisc.eduvoid 27110451Snilay@cs.wisc.eduSimpleThread::halt() 27210451Snilay@cs.wisc.edu{ 27310451Snilay@cs.wisc.edu if (status() == ThreadContext::Halted) 27410451Snilay@cs.wisc.edu return; 2757860SN/A 2767860SN/A _status = ThreadContext::Halted; 2777860SN/A cpu->haltContext(_threadId); 27810451Snilay@cs.wisc.edu} 27910451Snilay@cs.wisc.edu 2809988Snilay@cs.wisc.edu 28110451Snilay@cs.wisc.eduvoid 2827860SN/ASimpleThread::regStats(const string &name) 28310451Snilay@cs.wisc.edu{ 2847860SN/A#if FULL_SYSTEM 2859988Snilay@cs.wisc.edu if (kernelStats) 2867860SN/A kernelStats->regStats(name + ".kern"); 28710451Snilay@cs.wisc.edu#endif 2887860SN/A} 2897860SN/A 2907860SN/Avoid 2917860SN/ASimpleThread::copyArchRegs(ThreadContext *src_tc) 29210451Snilay@cs.wisc.edu{ 29310451Snilay@cs.wisc.edu TheISA::copyRegs(src_tc, tc); 2949988Snilay@cs.wisc.edu} 29510451Snilay@cs.wisc.edu 2967860SN/A