simple_thread.cc revision 8777
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"
538777Sgblack@eecs.umich.edu#include "sim/process.hh"
541070SN/A#include "sim/serialize.hh"
551917SN/A#include "sim/sim_exit.hh"
562519SN/A#include "sim/system.hh"
572SN/A
582SN/Ausing namespace std;
592SN/A
602SN/A// constructor
618766Sgblack@eecs.umich.edu#if !FULL_SYSTEM
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}
708766Sgblack@eecs.umich.edu#else
712683Sktlim@umich.eduSimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
726022Sgblack@eecs.umich.edu                           TheISA::TLB *_itb, TheISA::TLB *_dtb,
732683Sktlim@umich.edu                           bool use_kernel_stats)
748766Sgblack@eecs.umich.edu    : ThreadState(_cpu, _thread_num, NULL),
756324Sgblack@eecs.umich.edu      cpu(_cpu), system(_sys), itb(_itb), dtb(_dtb)
762521SN/A
772SN/A{
782683Sktlim@umich.edu    tc = new ProxyThreadContext<SimpleThread>(this);
792190SN/A
802680SN/A    quiesceEvent = new EndQuiesceEvent(tc);
812290SN/A
826316Sgblack@eecs.umich.edu    clearArchRegs();
831917SN/A
845529Snate@binkert.org    if (cpu->params()->profile) {
851982SN/A        profile = new FunctionProfile(system->kernelSymtab);
861917SN/A        Callback *cb =
872683Sktlim@umich.edu            new MakeCallback<SimpleThread,
882683Sktlim@umich.edu            &SimpleThread::dumpFuncProfile>(this);
891917SN/A        registerExitCallback(cb);
901917SN/A    }
911917SN/A
921917SN/A    // let's fill with a dummy node for now so we don't get a segfault
931917SN/A    // on the first cycle when there's no node available.
941917SN/A    static ProfileNode dummyNode;
951917SN/A    profileNode = &dummyNode;
961917SN/A    profilePC = 3;
972521SN/A
985482Snate@binkert.org    if (use_kernel_stats)
993548Sgblack@eecs.umich.edu        kernelStats = new TheISA::Kernel::Statistics(system);
1002SN/A}
1012862Sktlim@umich.edu#endif
1022862Sktlim@umich.edu
1032864Sktlim@umich.eduSimpleThread::SimpleThread()
1046331Sgblack@eecs.umich.edu    : ThreadState(NULL, -1, NULL)
1052190SN/A{
1062683Sktlim@umich.edu    tc = new ProxyThreadContext<SimpleThread>(this);
1072190SN/A}
1082190SN/A
1092683Sktlim@umich.eduSimpleThread::~SimpleThread()
1101070SN/A{
1118754Sgblack@eecs.umich.edu    delete physPort;
1123486Sktlim@umich.edu    delete virtPort;
1132680SN/A    delete tc;
1141070SN/A}
1151070SN/A
1161917SN/Avoid
1172683Sktlim@umich.eduSimpleThread::takeOverFrom(ThreadContext *oldContext)
118180SN/A{
119180SN/A    // some things should already be set up
1201858SN/A#if FULL_SYSTEM
1212235SN/A    assert(system == oldContext->getSystemPtr());
1228767Sgblack@eecs.umich.edu#endif
1232235SN/A    assert(process == oldContext->getProcessPtr());
124180SN/A
1252862Sktlim@umich.edu    copyState(oldContext);
1262862Sktlim@umich.edu#if FULL_SYSTEM
1272313SN/A    EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent();
1282313SN/A    if (quiesce) {
1292680SN/A        // Point the quiesce event's TC at this TC so that it wakes up
1302313SN/A        // the proper CPU.
1312680SN/A        quiesce->tc = tc;
1322313SN/A    }
1332313SN/A    if (quiesceEvent) {
1342680SN/A        quiesceEvent->tc = tc;
1352313SN/A    }
1362361SN/A
1373548Sgblack@eecs.umich.edu    TheISA::Kernel::Statistics *stats = oldContext->getKernelStats();
1382361SN/A    if (stats) {
1392361SN/A        kernelStats = stats;
1402361SN/A    }
1412235SN/A#endif
142180SN/A
143180SN/A    storeCondFailures = 0;
144180SN/A
1456029Ssteve.reinhardt@amd.com    oldContext->setStatus(ThreadContext::Halted);
146180SN/A}
147180SN/A
1482SN/Avoid
1492864Sktlim@umich.eduSimpleThread::copyTC(ThreadContext *context)
1502864Sktlim@umich.edu{
1512864Sktlim@umich.edu    copyState(context);
1522864Sktlim@umich.edu
1532864Sktlim@umich.edu#if FULL_SYSTEM
1542864Sktlim@umich.edu    EndQuiesceEvent *quiesce = context->getQuiesceEvent();
1552864Sktlim@umich.edu    if (quiesce) {
1562864Sktlim@umich.edu        quiesceEvent = quiesce;
1572864Sktlim@umich.edu    }
1583548Sgblack@eecs.umich.edu    TheISA::Kernel::Statistics *stats = context->getKernelStats();
1592864Sktlim@umich.edu    if (stats) {
1602864Sktlim@umich.edu        kernelStats = stats;
1612864Sktlim@umich.edu    }
1622864Sktlim@umich.edu#endif
1632864Sktlim@umich.edu}
1642864Sktlim@umich.edu
1652864Sktlim@umich.eduvoid
1662862Sktlim@umich.eduSimpleThread::copyState(ThreadContext *oldContext)
1672862Sktlim@umich.edu{
1682862Sktlim@umich.edu    // copy over functional state
1692862Sktlim@umich.edu    _status = oldContext->status();
1702862Sktlim@umich.edu    copyArchRegs(oldContext);
1712862Sktlim@umich.edu#if !FULL_SYSTEM
1722862Sktlim@umich.edu    funcExeInst = oldContext->readFuncExeInst();
1732862Sktlim@umich.edu#endif
1745714Shsul@eecs.umich.edu
1755715Shsul@eecs.umich.edu    _threadId = oldContext->threadId();
1765714Shsul@eecs.umich.edu    _contextId = oldContext->contextId();
1772862Sktlim@umich.edu}
1782862Sktlim@umich.edu
1792862Sktlim@umich.eduvoid
1802683Sktlim@umich.eduSimpleThread::serialize(ostream &os)
181217SN/A{
1822862Sktlim@umich.edu    ThreadState::serialize(os);
1836315Sgblack@eecs.umich.edu    SERIALIZE_ARRAY(floatRegs.i, TheISA::NumFloatRegs);
1846316Sgblack@eecs.umich.edu    SERIALIZE_ARRAY(intRegs, TheISA::NumIntRegs);
1857720Sgblack@eecs.umich.edu    _pcState.serialize(os);
186223SN/A    // thread_num and cpu_id are deterministic from the config
1876677SBrad.Beckmann@amd.com
1886677SBrad.Beckmann@amd.com    //
1896677SBrad.Beckmann@amd.com    // Now must serialize all the ISA dependent state
1906677SBrad.Beckmann@amd.com    //
1916678Sgblack@eecs.umich.edu    isa.serialize(cpu, os);
192217SN/A}
193217SN/A
194217SN/A
195217SN/Avoid
1962683Sktlim@umich.eduSimpleThread::unserialize(Checkpoint *cp, const std::string &section)
197217SN/A{
1982862Sktlim@umich.edu    ThreadState::unserialize(cp, section);
1996315Sgblack@eecs.umich.edu    UNSERIALIZE_ARRAY(floatRegs.i, TheISA::NumFloatRegs);
2006316Sgblack@eecs.umich.edu    UNSERIALIZE_ARRAY(intRegs, TheISA::NumIntRegs);
2017720Sgblack@eecs.umich.edu    _pcState.unserialize(cp, section);
202223SN/A    // thread_num and cpu_id are deterministic from the config
2036677SBrad.Beckmann@amd.com
2046677SBrad.Beckmann@amd.com    //
2056677SBrad.Beckmann@amd.com    // Now must unserialize all the ISA dependent state
2066677SBrad.Beckmann@amd.com    //
2076678Sgblack@eecs.umich.edu    isa.unserialize(cpu, cp, section);
208217SN/A}
209217SN/A
2102683Sktlim@umich.eduvoid
2112683Sktlim@umich.eduSimpleThread::dumpFuncProfile()
2122683Sktlim@umich.edu{
2132683Sktlim@umich.edu    std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
2142683Sktlim@umich.edu    profile->dump(tc, *os);
2152683Sktlim@umich.edu}
216217SN/A
217217SN/Avoid
2182683Sktlim@umich.eduSimpleThread::activate(int delay)
2192SN/A{
2202680SN/A    if (status() == ThreadContext::Active)
2212SN/A        return;
2222SN/A
2237823Ssteve.reinhardt@amd.com    lastActivate = curTick();
2242188SN/A
2254400Srdreslin@umich.edu//    if (status() == ThreadContext::Unallocated) {
2265715Shsul@eecs.umich.edu//      cpu->activateWhenReady(_threadId);
2275543Ssaidi@eecs.umich.edu//      return;
2284400Srdreslin@umich.edu//   }
2292290SN/A
2302680SN/A    _status = ThreadContext::Active;
2312290SN/A
2322290SN/A    // status() == Suspended
2335715Shsul@eecs.umich.edu    cpu->activateContext(_threadId, delay);
234393SN/A}
235393SN/A
236393SN/Avoid
2372683Sktlim@umich.eduSimpleThread::suspend()
238393SN/A{
2392680SN/A    if (status() == ThreadContext::Suspended)
240393SN/A        return;
241393SN/A
2427823Ssteve.reinhardt@amd.com    lastActivate = curTick();
2437823Ssteve.reinhardt@amd.com    lastSuspend = curTick();
2442188SN/A/*
2451858SN/A#if FULL_SYSTEM
2462SN/A    // Don't change the status from active if there are pending interrupts
2475704Snate@binkert.org    if (cpu->checkInterrupts()) {
2482680SN/A        assert(status() == ThreadContext::Active);
2492SN/A        return;
2502SN/A    }
2512SN/A#endif
2522188SN/A*/
2532680SN/A    _status = ThreadContext::Suspended;
2545715Shsul@eecs.umich.edu    cpu->suspendContext(_threadId);
2552SN/A}
2562SN/A
257393SN/A
258393SN/Avoid
2592683Sktlim@umich.eduSimpleThread::halt()
260393SN/A{
2612680SN/A    if (status() == ThreadContext::Halted)
262393SN/A        return;
263393SN/A
2642680SN/A    _status = ThreadContext::Halted;
2655715Shsul@eecs.umich.edu    cpu->haltContext(_threadId);
266393SN/A}
267393SN/A
268393SN/A
269393SN/Avoid
2702683Sktlim@umich.eduSimpleThread::regStats(const string &name)
2712SN/A{
2722330SN/A#if FULL_SYSTEM
2732341SN/A    if (kernelStats)
2742341SN/A        kernelStats->regStats(name + ".kern");
2752330SN/A#endif
2762SN/A}
277716SN/A
278716SN/Avoid
2792683Sktlim@umich.eduSimpleThread::copyArchRegs(ThreadContext *src_tc)
2802190SN/A{
2812680SN/A    TheISA::copyRegs(src_tc, tc);
2822190SN/A}
2832190SN/A
284