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 &section)
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