simple_thread.cc revision 8793
12SN/A/* 22188SN/A * Copyright (c) 2001-2006 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "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. 272665SN/A * 282665SN/A * Authors: Steve Reinhardt 292665SN/A * Nathan Binkert 302665SN/A * Lisa Hsu 312665SN/A * Kevin Lim 322SN/A */ 332SN/A 342SN/A#include <string> 352SN/A 362465SN/A#include "arch/isa_traits.hh" 373565Sgblack@eecs.umich.edu#include "arch/kernel_stats.hh" 385529Snate@binkert.org#include "arch/stacktrace.hh" 398777Sgblack@eecs.umich.edu#include "arch/utility.hh" 401917SN/A#include "base/callback.hh" 411070SN/A#include "base/cprintf.hh" 421917SN/A#include "base/output.hh" 432188SN/A#include "base/trace.hh" 448777Sgblack@eecs.umich.edu#include "config/the_isa.hh" 458777Sgblack@eecs.umich.edu#include "cpu/base.hh" 461917SN/A#include "cpu/profile.hh" 472290SN/A#include "cpu/quiesce_event.hh" 488777Sgblack@eecs.umich.edu#include "cpu/simple_thread.hh" 498777Sgblack@eecs.umich.edu#include "cpu/thread_context.hh" 508777Sgblack@eecs.umich.edu#include "mem/translating_port.hh" 518777Sgblack@eecs.umich.edu#include "mem/vport.hh" 528777Sgblack@eecs.umich.edu#include "params/BaseCPU.hh" 538793Sgblack@eecs.umich.edu#include "sim/full_system.hh" 548777Sgblack@eecs.umich.edu#include "sim/process.hh" 551070SN/A#include "sim/serialize.hh" 561917SN/A#include "sim/sim_exit.hh" 572519SN/A#include "sim/system.hh" 582SN/A 592SN/Ausing namespace std; 602SN/A 612SN/A// constructor 628766Sgblack@eecs.umich.eduSimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, 638766Sgblack@eecs.umich.edu TheISA::TLB *_itb, TheISA::TLB *_dtb) 648766Sgblack@eecs.umich.edu : ThreadState(_cpu, _thread_num, _process), 658766Sgblack@eecs.umich.edu cpu(_cpu), itb(_itb), dtb(_dtb) 668766Sgblack@eecs.umich.edu{ 678766Sgblack@eecs.umich.edu clearArchRegs(); 688766Sgblack@eecs.umich.edu tc = new ProxyThreadContext<SimpleThread>(this); 698766Sgblack@eecs.umich.edu} 702683Sktlim@umich.eduSimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys, 716022Sgblack@eecs.umich.edu TheISA::TLB *_itb, TheISA::TLB *_dtb, 722683Sktlim@umich.edu bool use_kernel_stats) 738766Sgblack@eecs.umich.edu : ThreadState(_cpu, _thread_num, NULL), 746324Sgblack@eecs.umich.edu cpu(_cpu), system(_sys), itb(_itb), dtb(_dtb) 752521SN/A 762SN/A{ 772683Sktlim@umich.edu tc = new ProxyThreadContext<SimpleThread>(this); 782190SN/A 792680SN/A quiesceEvent = new EndQuiesceEvent(tc); 802290SN/A 816316Sgblack@eecs.umich.edu clearArchRegs(); 821917SN/A 835529Snate@binkert.org if (cpu->params()->profile) { 841982SN/A profile = new FunctionProfile(system->kernelSymtab); 851917SN/A Callback *cb = 862683Sktlim@umich.edu new MakeCallback<SimpleThread, 872683Sktlim@umich.edu &SimpleThread::dumpFuncProfile>(this); 881917SN/A registerExitCallback(cb); 891917SN/A } 901917SN/A 911917SN/A // let's fill with a dummy node for now so we don't get a segfault 921917SN/A // on the first cycle when there's no node available. 931917SN/A static ProfileNode dummyNode; 941917SN/A profileNode = &dummyNode; 951917SN/A profilePC = 3; 962521SN/A 975482Snate@binkert.org if (use_kernel_stats) 983548Sgblack@eecs.umich.edu kernelStats = new TheISA::Kernel::Statistics(system); 992SN/A} 1002862Sktlim@umich.edu 1012864Sktlim@umich.eduSimpleThread::SimpleThread() 1026331Sgblack@eecs.umich.edu : ThreadState(NULL, -1, NULL) 1032190SN/A{ 1042683Sktlim@umich.edu tc = new ProxyThreadContext<SimpleThread>(this); 1052190SN/A} 1062190SN/A 1072683Sktlim@umich.eduSimpleThread::~SimpleThread() 1081070SN/A{ 1098754Sgblack@eecs.umich.edu delete physPort; 1103486Sktlim@umich.edu delete virtPort; 1112680SN/A delete tc; 1121070SN/A} 1131070SN/A 1141917SN/Avoid 1152683Sktlim@umich.eduSimpleThread::takeOverFrom(ThreadContext *oldContext) 116180SN/A{ 117180SN/A // some things should already be set up 1188793Sgblack@eecs.umich.edu if (FullSystem) 1198793Sgblack@eecs.umich.edu assert(system == oldContext->getSystemPtr()); 1202235SN/A assert(process == oldContext->getProcessPtr()); 121180SN/A 1222862Sktlim@umich.edu copyState(oldContext); 1238793Sgblack@eecs.umich.edu if (FullSystem) { 1248793Sgblack@eecs.umich.edu EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent(); 1258793Sgblack@eecs.umich.edu if (quiesce) { 1268793Sgblack@eecs.umich.edu // Point the quiesce event's TC at this TC so that it wakes up 1278793Sgblack@eecs.umich.edu // the proper CPU. 1288793Sgblack@eecs.umich.edu quiesce->tc = tc; 1298793Sgblack@eecs.umich.edu } 1308793Sgblack@eecs.umich.edu if (quiesceEvent) { 1318793Sgblack@eecs.umich.edu quiesceEvent->tc = tc; 1328793Sgblack@eecs.umich.edu } 1338793Sgblack@eecs.umich.edu 1348793Sgblack@eecs.umich.edu TheISA::Kernel::Statistics *stats = oldContext->getKernelStats(); 1358793Sgblack@eecs.umich.edu if (stats) { 1368793Sgblack@eecs.umich.edu kernelStats = stats; 1378793Sgblack@eecs.umich.edu } 1382313SN/A } 139180SN/A 140180SN/A storeCondFailures = 0; 141180SN/A 1426029Ssteve.reinhardt@amd.com oldContext->setStatus(ThreadContext::Halted); 143180SN/A} 144180SN/A 1452SN/Avoid 1462864Sktlim@umich.eduSimpleThread::copyTC(ThreadContext *context) 1472864Sktlim@umich.edu{ 1482864Sktlim@umich.edu copyState(context); 1492864Sktlim@umich.edu 1508793Sgblack@eecs.umich.edu if (FullSystem) { 1518793Sgblack@eecs.umich.edu EndQuiesceEvent *quiesce = context->getQuiesceEvent(); 1528793Sgblack@eecs.umich.edu if (quiesce) { 1538793Sgblack@eecs.umich.edu quiesceEvent = quiesce; 1548793Sgblack@eecs.umich.edu } 1558793Sgblack@eecs.umich.edu TheISA::Kernel::Statistics *stats = context->getKernelStats(); 1568793Sgblack@eecs.umich.edu if (stats) { 1578793Sgblack@eecs.umich.edu kernelStats = stats; 1588793Sgblack@eecs.umich.edu } 1592864Sktlim@umich.edu } 1602864Sktlim@umich.edu} 1612864Sktlim@umich.edu 1622864Sktlim@umich.eduvoid 1632862Sktlim@umich.eduSimpleThread::copyState(ThreadContext *oldContext) 1642862Sktlim@umich.edu{ 1652862Sktlim@umich.edu // copy over functional state 1662862Sktlim@umich.edu _status = oldContext->status(); 1672862Sktlim@umich.edu copyArchRegs(oldContext); 1688793Sgblack@eecs.umich.edu if (FullSystem) 1698793Sgblack@eecs.umich.edu funcExeInst = oldContext->readFuncExeInst(); 1705714Shsul@eecs.umich.edu 1715715Shsul@eecs.umich.edu _threadId = oldContext->threadId(); 1725714Shsul@eecs.umich.edu _contextId = oldContext->contextId(); 1732862Sktlim@umich.edu} 1742862Sktlim@umich.edu 1752862Sktlim@umich.eduvoid 1762683Sktlim@umich.eduSimpleThread::serialize(ostream &os) 177217SN/A{ 1782862Sktlim@umich.edu ThreadState::serialize(os); 1796315Sgblack@eecs.umich.edu SERIALIZE_ARRAY(floatRegs.i, TheISA::NumFloatRegs); 1806316Sgblack@eecs.umich.edu SERIALIZE_ARRAY(intRegs, TheISA::NumIntRegs); 1817720Sgblack@eecs.umich.edu _pcState.serialize(os); 182223SN/A // thread_num and cpu_id are deterministic from the config 1836677SBrad.Beckmann@amd.com 1846677SBrad.Beckmann@amd.com // 1856677SBrad.Beckmann@amd.com // Now must serialize all the ISA dependent state 1866677SBrad.Beckmann@amd.com // 1876678Sgblack@eecs.umich.edu isa.serialize(cpu, os); 188217SN/A} 189217SN/A 190217SN/A 191217SN/Avoid 1922683Sktlim@umich.eduSimpleThread::unserialize(Checkpoint *cp, const std::string §ion) 193217SN/A{ 1942862Sktlim@umich.edu ThreadState::unserialize(cp, section); 1956315Sgblack@eecs.umich.edu UNSERIALIZE_ARRAY(floatRegs.i, TheISA::NumFloatRegs); 1966316Sgblack@eecs.umich.edu UNSERIALIZE_ARRAY(intRegs, TheISA::NumIntRegs); 1977720Sgblack@eecs.umich.edu _pcState.unserialize(cp, section); 198223SN/A // thread_num and cpu_id are deterministic from the config 1996677SBrad.Beckmann@amd.com 2006677SBrad.Beckmann@amd.com // 2016677SBrad.Beckmann@amd.com // Now must unserialize all the ISA dependent state 2026677SBrad.Beckmann@amd.com // 2036678Sgblack@eecs.umich.edu isa.unserialize(cpu, cp, section); 204217SN/A} 205217SN/A 2062683Sktlim@umich.eduvoid 2072683Sktlim@umich.eduSimpleThread::dumpFuncProfile() 2082683Sktlim@umich.edu{ 2092683Sktlim@umich.edu std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); 2102683Sktlim@umich.edu profile->dump(tc, *os); 2112683Sktlim@umich.edu} 212217SN/A 213217SN/Avoid 2142683Sktlim@umich.eduSimpleThread::activate(int delay) 2152SN/A{ 2162680SN/A if (status() == ThreadContext::Active) 2172SN/A return; 2182SN/A 2197823Ssteve.reinhardt@amd.com lastActivate = curTick(); 2202188SN/A 2214400Srdreslin@umich.edu// if (status() == ThreadContext::Unallocated) { 2225715Shsul@eecs.umich.edu// cpu->activateWhenReady(_threadId); 2235543Ssaidi@eecs.umich.edu// return; 2244400Srdreslin@umich.edu// } 2252290SN/A 2262680SN/A _status = ThreadContext::Active; 2272290SN/A 2282290SN/A // status() == Suspended 2295715Shsul@eecs.umich.edu cpu->activateContext(_threadId, delay); 230393SN/A} 231393SN/A 232393SN/Avoid 2332683Sktlim@umich.eduSimpleThread::suspend() 234393SN/A{ 2352680SN/A if (status() == ThreadContext::Suspended) 236393SN/A return; 237393SN/A 2387823Ssteve.reinhardt@amd.com lastActivate = curTick(); 2397823Ssteve.reinhardt@amd.com lastSuspend = curTick(); 2402680SN/A _status = ThreadContext::Suspended; 2415715Shsul@eecs.umich.edu cpu->suspendContext(_threadId); 2422SN/A} 2432SN/A 244393SN/A 245393SN/Avoid 2462683Sktlim@umich.eduSimpleThread::halt() 247393SN/A{ 2482680SN/A if (status() == ThreadContext::Halted) 249393SN/A return; 250393SN/A 2512680SN/A _status = ThreadContext::Halted; 2525715Shsul@eecs.umich.edu cpu->haltContext(_threadId); 253393SN/A} 254393SN/A 255393SN/A 256393SN/Avoid 2572683Sktlim@umich.eduSimpleThread::regStats(const string &name) 2582SN/A{ 2598793Sgblack@eecs.umich.edu if (FullSystem && kernelStats) 2602341SN/A kernelStats->regStats(name + ".kern"); 2612SN/A} 262716SN/A 263716SN/Avoid 2642683Sktlim@umich.eduSimpleThread::copyArchRegs(ThreadContext *src_tc) 2652190SN/A{ 2662680SN/A TheISA::copyRegs(src_tc, tc); 2672190SN/A} 2682190SN/A 269