simple_thread.cc revision 2862:7bc3562e6405
12SN/A/*
212276Sanouk.vanlaer@arm.com * Copyright (c) 2001-2006 The Regents of The University of Michigan
38707Sandreas.hansson@arm.com * All rights reserved.
48707Sandreas.hansson@arm.com *
58707Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
68707Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
78707Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
88707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
98707Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
108707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
118707Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
128707Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
138707Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
141762SN/A * this software without specific prior written permission.
157897Shestness@cs.utexas.edu *
169983Sstever@gmail.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
179983Sstever@gmail.com * "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.
272SN/A *
282SN/A * Authors: Steve Reinhardt
292SN/A *          Nathan Binkert
302SN/A *          Lisa Hsu
312SN/A *          Kevin Lim
322SN/A */
332SN/A
342SN/A#include <string>
352SN/A
362SN/A#include "arch/isa_traits.hh"
372SN/A#include "cpu/base.hh"
382SN/A#include "cpu/simple_thread.hh"
392SN/A#include "cpu/thread_context.hh"
402SN/A
412SN/A#if FULL_SYSTEM
422665Ssaidi@eecs.umich.edu#include "base/callback.hh"
432665Ssaidi@eecs.umich.edu#include "base/cprintf.hh"
442665Ssaidi@eecs.umich.edu#include "base/output.hh"
457897Shestness@cs.utexas.edu#include "base/trace.hh"
462SN/A#include "cpu/profile.hh"
472SN/A#include "cpu/quiesce_event.hh"
4811793Sbrandon.potter@amd.com#include "kern/kernel_stats.hh"
4911793Sbrandon.potter@amd.com#include "sim/serialize.hh"
501388SN/A#include "sim/sim_exit.hh"
518229Snate@binkert.org#include "arch/stacktrace.hh"
522SN/A#else
532SN/A#include "sim/process.hh"
5412406Sgabeblack@google.com#include "sim/system.hh"
5511793Sbrandon.potter@amd.com#include "mem/translating_port.hh"
568229Snate@binkert.org#endif
5712334Sgabeblack@google.com
581388SN/Ausing namespace std;
595529Snate@binkert.org
6010529Smorr@cs.wisc.edu// constructor
612651Ssaidi@eecs.umich.edu#if FULL_SYSTEM
628229Snate@binkert.orgSimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
632680Sktlim@umich.edu                           AlphaITB *_itb, AlphaDTB *_dtb,
6410529Smorr@cs.wisc.edu                           bool use_kernel_stats)
658232Snate@binkert.org    : ThreadState(-1, _thread_num), cpu(_cpu), system(_sys), itb(_itb),
6610529Smorr@cs.wisc.edu      dtb(_dtb)
675529Snate@binkert.org
6811526Sdavid.guillen@arm.com{
698779Sgblack@eecs.umich.edu    tc = new ProxyThreadContext<SimpleThread>(this);
702190SN/A
7156SN/A    quiesceEvent = new EndQuiesceEvent(tc);
728229Snate@binkert.org
732190SN/A    regs.clear();
742SN/A
752359SN/A    if (cpu->params->profile) {
762359SN/A        profile = new FunctionProfile(system->kernelSymtab);
772359SN/A        Callback *cb =
782SN/A            new MakeCallback<SimpleThread,
792SN/A            &SimpleThread::dumpFuncProfile>(this);
802SN/A        registerExitCallback(cb);
812SN/A    }
822SN/A
832SN/A    // let's fill with a dummy node for now so we don't get a segfault
842SN/A    // on the first cycle when there's no node available.
852SN/A    static ProfileNode dummyNode;
862SN/A    profileNode = &dummyNode;
875606Snate@binkert.org    profilePC = 3;
886144Sksewell@umich.edu
896144Sksewell@umich.edu    if (use_kernel_stats) {
903126Sktlim@umich.edu        kernelStats = new Kernel::Statistics(system);
916144Sksewell@umich.edu    } else {
927823Ssteve.reinhardt@amd.com        kernelStats = NULL;
933126Sktlim@umich.edu    }
943126Sktlim@umich.edu    Port *mem_port;
952356SN/A    physPort = new FunctionalPort(csprintf("%s-%d-funcport",
962356SN/A                                           cpu->name(), tid));
972356SN/A    mem_port = system->physmem->getPort("functional");
988834Satgutier@umich.edu    mem_port->setPeer(physPort);
9910786Smalek.musleh@gmail.com    physPort->setPeer(mem_port);
10010786Smalek.musleh@gmail.com
10110786Smalek.musleh@gmail.com    virtPort = new VirtualPort(csprintf("%s-%d-vport",
10210786Smalek.musleh@gmail.com                                        cpu->name(), tid));
10311321Ssteve.reinhardt@amd.com    mem_port = system->physmem->getPort("functional");
10410786Smalek.musleh@gmail.com    mem_port->setPeer(virtPort);
10510786Smalek.musleh@gmail.com    virtPort->setPeer(mem_port);
10610786Smalek.musleh@gmail.com}
1072356SN/A#else
1089179Sandreas.hansson@arm.comSimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num,
1092367SN/A                         Process *_process, int _asid, MemObject* memobj)
1106144Sksewell@umich.edu    : ThreadState(-1, _thread_num, _process, _asid, memobj),
1116144Sksewell@umich.edu      cpu(_cpu)
1126144Sksewell@umich.edu{
1132356SN/A    /* Use this port to for syscall emulation writes to memory. */
1142367SN/A    Port *mem_port;
1156144Sksewell@umich.edu    port = new TranslatingPort(csprintf("%s-%d-funcport",
1167823Ssteve.reinhardt@amd.com                                        cpu->name(), tid),
1176144Sksewell@umich.edu                               process->pTable, false);
1182367SN/A    mem_port = memobj->getPort("functional");
1192356SN/A    mem_port->setPeer(port);
1202356SN/A    port->setPeer(mem_port);
1212356SN/A
1222356SN/A    regs.clear();
1235336Shines@cs.fsu.edu    tc = new ProxyThreadContext<SimpleThread>(this);
1242356SN/A}
1254873Sstever@eecs.umich.edu
1262356SN/A#endif
1272356SN/A
1288876Sandreas.hansson@arm.comSimpleThread::SimpleThread(ThreadContext *oldContext)
12910190Sakash.bagdia@arm.com#if FULL_SYSTEM
13012680Sgiacomo.travaglini@arm.com    : ThreadState(-1, -1)
13112680Sgiacomo.travaglini@arm.com#else
13211050Sandreas.hansson@arm.com    : ThreadState(-1, -1, NULL, -1, NULL)
1339814Sandreas.hansson@arm.com#endif
1349220Shestness@cs.wisc.edu{
13510529Smorr@cs.wisc.edu    tc = new ProxyThreadContext<SimpleThread>(this);
13612284Sjose.marinho@arm.com    regs.clear();
13710537Sandreas.hansson@arm.com
13810537Sandreas.hansson@arm.com    copyState(oldContext);
13911877Sbrandon.potter@amd.com
14012276Sanouk.vanlaer@arm.com#if FULL_SYSTEM
14112276Sanouk.vanlaer@arm.com    EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent();
14212277Sjose.marinho@arm.com    if (quiesce) {
14312276Sanouk.vanlaer@arm.com        quiesceEvent = quiesce;
1442SN/A    }
1455712Shsul@eecs.umich.edu    Kernel::Statistics *stats = oldContext->getKernelStats();
1465712Shsul@eecs.umich.edu    if (stats) {
1475712Shsul@eecs.umich.edu        kernelStats = stats;
1485712Shsul@eecs.umich.edu    }
1495712Shsul@eecs.umich.edu#endif
1502SN/A}
1512SN/A
1522SN/ASimpleThread::~SimpleThread()
15310190Sakash.bagdia@arm.com{
15410190Sakash.bagdia@arm.com    delete tc;
1555712Shsul@eecs.umich.edu}
1566221Snate@binkert.org
1576221Snate@binkert.orgvoid
1582SN/ASimpleThread::takeOverFrom(ThreadContext *oldContext)
1592SN/A{
1606221Snate@binkert.org    // some things should already be set up
1616221Snate@binkert.org#if FULL_SYSTEM
1626221Snate@binkert.org    assert(system == oldContext->getSystemPtr());
1636221Snate@binkert.org#else
1642SN/A    assert(process == oldContext->getProcessPtr());
1652SN/A#endif
1662SN/A
1672SN/A    copyState(oldContext);
1685606Snate@binkert.org#if FULL_SYSTEM
1695606Snate@binkert.org    EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent();
1709749Sandreas@sandberg.pp.se    if (quiesce) {
1719749Sandreas@sandberg.pp.se        // Point the quiesce event's TC at this TC so that it wakes up
1725606Snate@binkert.org        // the proper CPU.
1732SN/A        quiesce->tc = tc;
1749647Sdam.sunwoo@arm.com    }
1759647Sdam.sunwoo@arm.com    if (quiesceEvent) {
1769647Sdam.sunwoo@arm.com        quiesceEvent->tc = tc;
1779647Sdam.sunwoo@arm.com    }
1789647Sdam.sunwoo@arm.com#endif
1799647Sdam.sunwoo@arm.com
1809749Sandreas@sandberg.pp.se    storeCondFailures = 0;
1819749Sandreas@sandberg.pp.se
1829647Sdam.sunwoo@arm.com    oldContext->setStatus(ThreadContext::Unallocated);
1839647Sdam.sunwoo@arm.com}
1841400SN/A
1855606Snate@binkert.orgvoid
1865606Snate@binkert.orgSimpleThread::copyState(ThreadContext *oldContext)
1872SN/A{
1882SN/A    // copy over functional state
1892SN/A    _status = oldContext->status();
1902SN/A    copyArchRegs(oldContext);
1916221Snate@binkert.org    cpuId = oldContext->readCpuId();
1926221Snate@binkert.org#if !FULL_SYSTEM
1935606Snate@binkert.org    funcExeInst = oldContext->readFuncExeInst();
1946670Shsul@eecs.umich.edu#endif
1955606Snate@binkert.org}
1962SN/A
1972SN/Avoid
198124SN/ASimpleThread::serialize(ostream &os)
1996221Snate@binkert.org{
2006221Snate@binkert.org    ThreadState::serialize(os);
2016221Snate@binkert.org    regs.serialize(os);
202124SN/A    // thread_num and cpu_id are deterministic from the config
203124SN/A}
204124SN/A
205124SN/A
2065606Snate@binkert.orgvoid
2075606Snate@binkert.orgSimpleThread::unserialize(Checkpoint *cp, const std::string &section)
2089749Sandreas@sandberg.pp.se{
2099749Sandreas@sandberg.pp.se    ThreadState::unserialize(cp, section);
2105606Snate@binkert.org    regs.unserialize(cp, section);
211124SN/A    // thread_num and cpu_id are deterministic from the config
2121400SN/A}
2135606Snate@binkert.org
214124SN/A#if FULL_SYSTEM
215124SN/Avoid
216124SN/ASimpleThread::dumpFuncProfile()
217124SN/A{
2186221Snate@binkert.org    std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
2196221Snate@binkert.org    profile->dump(tc, *os);
2205606Snate@binkert.org}
2216221Snate@binkert.org#endif
2225606Snate@binkert.org
223124SN/Avoid
224124SN/ASimpleThread::activate(int delay)
2251191SN/A{
2265529Snate@binkert.org    if (status() == ThreadContext::Active)
2278634Schris.emmons@arm.com        return;
22811359Sandreas@sandberg.pp.se
2298634Schris.emmons@arm.com    lastActivate = curTick;
2301191SN/A
2315529Snate@binkert.org    if (status() == ThreadContext::Unallocated) {
2321191SN/A        cpu->activateWhenReady(tid);
2335529Snate@binkert.org        return;
2341191SN/A    }
2351191SN/A
23612085Sspwilson2@wisc.edu    _status = ThreadContext::Active;
23712085Sspwilson2@wisc.edu
2385606Snate@binkert.org    // status() == Suspended
2391191SN/A    cpu->activateContext(tid, delay);
2401191SN/A}
2418876Sandreas.hansson@arm.com
2428876Sandreas.hansson@arm.comvoid
2438876Sandreas.hansson@arm.comSimpleThread::suspend()
2449433SAndreas.Sandberg@ARM.com{
24511221Sandreas.sandberg@arm.com    if (status() == ThreadContext::Suspended)
24611221Sandreas.sandberg@arm.com        return;
24711221Sandreas.sandberg@arm.com
24811221Sandreas.sandberg@arm.com    lastActivate = curTick;
24911221Sandreas.sandberg@arm.com    lastSuspend = curTick;
25011221Sandreas.sandberg@arm.com/*
2518876Sandreas.hansson@arm.com#if FULL_SYSTEM
2525810Sgblack@eecs.umich.edu    // Don't change the status from active if there are pending interrupts
2538779Sgblack@eecs.umich.edu    if (cpu->check_interrupts()) {
2548779Sgblack@eecs.umich.edu        assert(status() == ThreadContext::Active);
25512127Sspwilson2@wisc.edu        return;
25612127Sspwilson2@wisc.edu    }
25712127Sspwilson2@wisc.edu#endif
2588779Sgblack@eecs.umich.edu*/
2595529Snate@binkert.org    _status = ThreadContext::Suspended;
2609384SAndreas.Sandberg@arm.com    cpu->suspendContext(tid);
2619384SAndreas.Sandberg@arm.com}
2629384SAndreas.Sandberg@arm.com
2639384SAndreas.Sandberg@arm.comvoid
2649384SAndreas.Sandberg@arm.comSimpleThread::deallocate()
2651917SN/A{
2661191SN/A    if (status() == ThreadContext::Unallocated)
2671191SN/A        return;
2681191SN/A
2691191SN/A    _status = ThreadContext::Unallocated;
2701191SN/A    cpu->deallocateContext(tid);
2711191SN/A}
2721191SN/A
2731191SN/Avoid
2741191SN/ASimpleThread::halt()
2759086Sandreas.hansson@arm.com{
2769086Sandreas.hansson@arm.com    if (status() == ThreadContext::Halted)
2779086Sandreas.hansson@arm.com        return;
2781191SN/A
2791191SN/A    _status = ThreadContext::Halted;
2801129SN/A    cpu->haltContext(tid);
28111148Smitch.hayenga@arm.com}
28210529Smorr@cs.wisc.edu
28311148Smitch.hayenga@arm.com
28411148Smitch.hayenga@arm.comvoid
28511148Smitch.hayenga@arm.comSimpleThread::regStats(const string &name)
28611148Smitch.hayenga@arm.com{
28711148Smitch.hayenga@arm.com#if FULL_SYSTEM
28811148Smitch.hayenga@arm.com    if (kernelStats)
28911148Smitch.hayenga@arm.com        kernelStats->regStats(name + ".kern");
29010529Smorr@cs.wisc.edu#endif
29110529Smorr@cs.wisc.edu}
29210529Smorr@cs.wisc.edu
29311148Smitch.hayenga@arm.comvoid
29410529Smorr@cs.wisc.eduSimpleThread::copyArchRegs(ThreadContext *src_tc)
29511148Smitch.hayenga@arm.com{
29611148Smitch.hayenga@arm.com    TheISA::copyRegs(src_tc, tc);
29711148Smitch.hayenga@arm.com}
29811325Ssteve.reinhardt@amd.com
29910529Smorr@cs.wisc.edu#if FULL_SYSTEM
30010529Smorr@cs.wisc.eduVirtualPort*
30110529Smorr@cs.wisc.eduSimpleThread::getVirtPort(ThreadContext *src_tc)
30210529Smorr@cs.wisc.edu{
30311148Smitch.hayenga@arm.com    if (!src_tc)
30411148Smitch.hayenga@arm.com        return virtPort;
30510529Smorr@cs.wisc.edu
30611148Smitch.hayenga@arm.com    VirtualPort *vp;
30711148Smitch.hayenga@arm.com    Port *mem_port;
30810529Smorr@cs.wisc.edu
30910529Smorr@cs.wisc.edu    vp = new VirtualPort("tc-vport", src_tc);
31011148Smitch.hayenga@arm.com    mem_port = system->physmem->getPort("functional");
31110529Smorr@cs.wisc.edu    mem_port->setPeer(vp);
31210529Smorr@cs.wisc.edu    vp->setPeer(mem_port);
31310529Smorr@cs.wisc.edu    return vp;
31410529Smorr@cs.wisc.edu}
31510529Smorr@cs.wisc.edu
31612406Sgabeblack@google.comvoid
31710529Smorr@cs.wisc.eduSimpleThread::delVirtPort(VirtualPort *vp)
31811148Smitch.hayenga@arm.com{
31911148Smitch.hayenga@arm.com    if (vp != virtPort) {
32011148Smitch.hayenga@arm.com        delete vp->getPeer();
32110529Smorr@cs.wisc.edu        delete vp;
32211148Smitch.hayenga@arm.com    }
32310529Smorr@cs.wisc.edu}
32410529Smorr@cs.wisc.edu
32510529Smorr@cs.wisc.edu
32610529Smorr@cs.wisc.edu#endif
32710529Smorr@cs.wisc.edu
32810529Smorr@cs.wisc.edu