simple_thread.cc revision 2519
18844SAli.Saidi@ARM.com/*
28844SAli.Saidi@ARM.com * Copyright (c) 2001-2006 The Regents of The University of Michigan
310585Sandreas.hansson@arm.com * All rights reserved.
410726Sandreas.hansson@arm.com *
510726Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
68844SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are
711138Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
811138Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
911138Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
1011138Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
1111138Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
1210726Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
1310726Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
1410036SAli.Saidi@ARM.com * this software without specific prior written permission.
1510036SAli.Saidi@ARM.com *
1610892Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1710409Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811138Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911138Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2011138Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2111138Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2211138Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2310535Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2411138Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2511138Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611138Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2711138Sandreas.hansson@arm.com */
2811138Sandreas.hansson@arm.com
2910827Sandreas.hansson@arm.com#include <string>
3010409Sandreas.hansson@arm.com
3111138Sandreas.hansson@arm.com#include "arch/isa_traits.hh"
3210892Sandreas.hansson@arm.com#include "cpu/base.hh"
3310409Sandreas.hansson@arm.com#include "cpu/cpu_exec_context.hh"
3411138Sandreas.hansson@arm.com#include "cpu/exec_context.hh"
3511138Sandreas.hansson@arm.com
3611138Sandreas.hansson@arm.com#if FULL_SYSTEM
3711138Sandreas.hansson@arm.com#include "base/callback.hh"
3811138Sandreas.hansson@arm.com#include "base/cprintf.hh"
3910535Sandreas.hansson@arm.com#include "base/output.hh"
4011138Sandreas.hansson@arm.com#include "base/trace.hh"
4111138Sandreas.hansson@arm.com#include "cpu/profile.hh"
4210827Sandreas.hansson@arm.com#include "kern/kernel_stats.hh"
4310409Sandreas.hansson@arm.com#include "sim/serialize.hh"
4411138Sandreas.hansson@arm.com#include "sim/sim_exit.hh"
4510892Sandreas.hansson@arm.com#include "arch/stacktrace.hh"
4610513SAli.Saidi@ARM.com#else
4711138Sandreas.hansson@arm.com#include "sim/process.hh"
4811138Sandreas.hansson@arm.com#include "sim/system.hh"
4911138Sandreas.hansson@arm.com#include "mem/translating_port.hh"
5011138Sandreas.hansson@arm.com#endif
5111138Sandreas.hansson@arm.com
5210535Sandreas.hansson@arm.comusing namespace std;
5311138Sandreas.hansson@arm.com
5411138Sandreas.hansson@arm.com// constructor
5511138Sandreas.hansson@arm.com#if FULL_SYSTEM
5611138Sandreas.hansson@arm.comCPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
5711138Sandreas.hansson@arm.com                         AlphaITB *_itb, AlphaDTB *_dtb)
5810827Sandreas.hansson@arm.com    : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num),
5910513SAli.Saidi@ARM.com      cpu_id(-1), lastActivate(0), lastSuspend(0), system(_sys), itb(_itb),
6011138Sandreas.hansson@arm.com      dtb(_dtb), memctrl(_sys->memctrl), profile(NULL),
6111138Sandreas.hansson@arm.com      quiesceEvent(this), func_exe_inst(0), storeCondFailures(0)
6210892Sandreas.hansson@arm.com{
6310513SAli.Saidi@ARM.com    proxy = new ProxyExecContext<CPUExecContext>(this);
6411138Sandreas.hansson@arm.com
6511138Sandreas.hansson@arm.com    memset(&regs, 0, sizeof(RegFile));
6611138Sandreas.hansson@arm.com
6711138Sandreas.hansson@arm.com    if (cpu->params->profile) {
6811138Sandreas.hansson@arm.com        profile = new FunctionProfile(system->kernelSymtab);
6910585Sandreas.hansson@arm.com        Callback *cb =
7011138Sandreas.hansson@arm.com            new MakeCallback<CPUExecContext,
7110517SAli.Saidi@ARM.com            &CPUExecContext::dumpFuncProfile>(this);
7210517SAli.Saidi@ARM.com        registerExitCallback(cb);
7310517SAli.Saidi@ARM.com    }
7410517SAli.Saidi@ARM.com
7510517SAli.Saidi@ARM.com    // let's fill with a dummy node for now so we don't get a segfault
7610517SAli.Saidi@ARM.com    // on the first cycle when there's no node available.
7710517SAli.Saidi@ARM.com    static ProfileNode dummyNode;
7810517SAli.Saidi@ARM.com    profileNode = &dummyNode;
7910517SAli.Saidi@ARM.com    profilePC = 3;
8010517SAli.Saidi@ARM.com}
8110517SAli.Saidi@ARM.com#else
8210517SAli.Saidi@ARM.comCPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num,
8310517SAli.Saidi@ARM.com                         Process *_process, int _asid)
8410517SAli.Saidi@ARM.com    : _status(ExecContext::Unallocated),
8510517SAli.Saidi@ARM.com      cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0),
8610517SAli.Saidi@ARM.com      lastSuspend(0), process(_process), asid(_asid),
8710517SAli.Saidi@ARM.com      func_exe_inst(0), storeCondFailures(0)
8810517SAli.Saidi@ARM.com{
898844SAli.Saidi@ARM.com    /* Use this port to for syscall emulation writes to memory. */
9010513SAli.Saidi@ARM.com    Port *mem_port;
9110513SAli.Saidi@ARM.com    port = new TranslatingPort(process->pTable, false);
9210513SAli.Saidi@ARM.com    mem_port = process->system->physmem->getPort("functional");
9310513SAli.Saidi@ARM.com    mem_port->setPeer(port);
9410513SAli.Saidi@ARM.com    port->setPeer(mem_port);
9510535Sandreas.hansson@arm.com
9610628Sandreas.hansson@arm.com    memset(&regs, 0, sizeof(RegFile));
9710628Sandreas.hansson@arm.com    proxy = new ProxyExecContext<CPUExecContext>(this);
9810628Sandreas.hansson@arm.com}
9910628Sandreas.hansson@arm.com
10010628Sandreas.hansson@arm.comCPUExecContext::CPUExecContext(RegFile *regFile)
10110628Sandreas.hansson@arm.com    : cpu(NULL), thread_num(-1), process(NULL), asid(-1),
10210628Sandreas.hansson@arm.com      func_exe_inst(0), storeCondFailures(0)
10310628Sandreas.hansson@arm.com{
10410535Sandreas.hansson@arm.com    regs = *regFile;
10510535Sandreas.hansson@arm.com    proxy = new ProxyExecContext<CPUExecContext>(this);
10610535Sandreas.hansson@arm.com}
10710535Sandreas.hansson@arm.com
10810535Sandreas.hansson@arm.com#endif
10910535Sandreas.hansson@arm.com
11010535Sandreas.hansson@arm.comCPUExecContext::~CPUExecContext()
11110535Sandreas.hansson@arm.com{
11210535Sandreas.hansson@arm.com    delete proxy;
11310535Sandreas.hansson@arm.com}
11410535Sandreas.hansson@arm.com
11510535Sandreas.hansson@arm.com#if FULL_SYSTEM
11610535Sandreas.hansson@arm.comvoid
11710535Sandreas.hansson@arm.comCPUExecContext::dumpFuncProfile()
11810535Sandreas.hansson@arm.com{
11910535Sandreas.hansson@arm.com    std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
12010535Sandreas.hansson@arm.com    profile->dump(proxy, *os);
12110535Sandreas.hansson@arm.com}
12210535Sandreas.hansson@arm.com
12310535Sandreas.hansson@arm.comCPUExecContext::EndQuiesceEvent::EndQuiesceEvent(CPUExecContext *_cpuXC)
12410535Sandreas.hansson@arm.com    : Event(&mainEventQueue), cpuXC(_cpuXC)
12510628Sandreas.hansson@arm.com{
12610628Sandreas.hansson@arm.com}
12710628Sandreas.hansson@arm.com
12810628Sandreas.hansson@arm.comvoid
12910628Sandreas.hansson@arm.comCPUExecContext::EndQuiesceEvent::process()
13010628Sandreas.hansson@arm.com{
13110628Sandreas.hansson@arm.com    cpuXC->activate();
13210628Sandreas.hansson@arm.com}
13310628Sandreas.hansson@arm.com
13410628Sandreas.hansson@arm.comconst char*
13510628Sandreas.hansson@arm.comCPUExecContext::EndQuiesceEvent::description()
13610628Sandreas.hansson@arm.com{
13710628Sandreas.hansson@arm.com    return "End Quiesce Event.";
13810628Sandreas.hansson@arm.com}
13910628Sandreas.hansson@arm.com
14010628Sandreas.hansson@arm.comvoid
14110628Sandreas.hansson@arm.comCPUExecContext::profileClear()
14210628Sandreas.hansson@arm.com{
14310535Sandreas.hansson@arm.com    if (profile)
14410535Sandreas.hansson@arm.com        profile->clear();
14510726Sandreas.hansson@arm.com}
14610585Sandreas.hansson@arm.com
14710726Sandreas.hansson@arm.comvoid
14810535Sandreas.hansson@arm.comCPUExecContext::profileSample()
14910535Sandreas.hansson@arm.com{
15010535Sandreas.hansson@arm.com    if (profile)
15110535Sandreas.hansson@arm.com        profile->sample(profileNode, profilePC);
15210535Sandreas.hansson@arm.com}
15310535Sandreas.hansson@arm.com
15410535Sandreas.hansson@arm.com#endif
15510535Sandreas.hansson@arm.com
15610535Sandreas.hansson@arm.comvoid
15710535Sandreas.hansson@arm.comCPUExecContext::takeOverFrom(ExecContext *oldContext)
15810726Sandreas.hansson@arm.com{
15910726Sandreas.hansson@arm.com    // some things should already be set up
16010535Sandreas.hansson@arm.com#if FULL_SYSTEM
16110726Sandreas.hansson@arm.com    assert(system == oldContext->getSystemPtr());
16210585Sandreas.hansson@arm.com#else
16310726Sandreas.hansson@arm.com    assert(process == oldContext->getProcessPtr());
16410628Sandreas.hansson@arm.com#endif
16510628Sandreas.hansson@arm.com
16610628Sandreas.hansson@arm.com    // copy over functional state
16710628Sandreas.hansson@arm.com    _status = oldContext->status();
16810628Sandreas.hansson@arm.com    copyArchRegs(oldContext);
16910628Sandreas.hansson@arm.com    cpu_id = oldContext->readCpuId();
17010628Sandreas.hansson@arm.com#if !FULL_SYSTEM
17110628Sandreas.hansson@arm.com    func_exe_inst = oldContext->readFuncExeInst();
17210535Sandreas.hansson@arm.com#endif
17310535Sandreas.hansson@arm.com
17410535Sandreas.hansson@arm.com    storeCondFailures = 0;
17510535Sandreas.hansson@arm.com
17610535Sandreas.hansson@arm.com    oldContext->setStatus(ExecContext::Unallocated);
17710535Sandreas.hansson@arm.com}
17810535Sandreas.hansson@arm.com
17910535Sandreas.hansson@arm.comvoid
18010535Sandreas.hansson@arm.comCPUExecContext::serialize(ostream &os)
18110535Sandreas.hansson@arm.com{
18210535Sandreas.hansson@arm.com    SERIALIZE_ENUM(_status);
18310535Sandreas.hansson@arm.com    regs.serialize(os);
18410535Sandreas.hansson@arm.com    // thread_num and cpu_id are deterministic from the config
18510535Sandreas.hansson@arm.com    SERIALIZE_SCALAR(func_exe_inst);
18610535Sandreas.hansson@arm.com    SERIALIZE_SCALAR(inst);
18710535Sandreas.hansson@arm.com
18810535Sandreas.hansson@arm.com#if FULL_SYSTEM
18910535Sandreas.hansson@arm.com    Tick quiesceEndTick = 0;
19010535Sandreas.hansson@arm.com    if (quiesceEvent.scheduled())
19110535Sandreas.hansson@arm.com        quiesceEndTick = quiesceEvent.when();
19210535Sandreas.hansson@arm.com    SERIALIZE_SCALAR(quiesceEndTick);
19310628Sandreas.hansson@arm.com
19410628Sandreas.hansson@arm.com#endif
19510628Sandreas.hansson@arm.com}
19610628Sandreas.hansson@arm.com
19710628Sandreas.hansson@arm.com
19810628Sandreas.hansson@arm.comvoid
19910628Sandreas.hansson@arm.comCPUExecContext::unserialize(Checkpoint *cp, const std::string &section)
20010628Sandreas.hansson@arm.com{
20110628Sandreas.hansson@arm.com    UNSERIALIZE_ENUM(_status);
20210628Sandreas.hansson@arm.com    regs.unserialize(cp, section);
20310628Sandreas.hansson@arm.com    // thread_num and cpu_id are deterministic from the config
20410628Sandreas.hansson@arm.com    UNSERIALIZE_SCALAR(func_exe_inst);
20510628Sandreas.hansson@arm.com    UNSERIALIZE_SCALAR(inst);
20610628Sandreas.hansson@arm.com
20710628Sandreas.hansson@arm.com#if FULL_SYSTEM
20810628Sandreas.hansson@arm.com    Tick quiesceEndTick;
20910628Sandreas.hansson@arm.com    UNSERIALIZE_SCALAR(quiesceEndTick);
21010628Sandreas.hansson@arm.com    if (quiesceEndTick)
21110726Sandreas.hansson@arm.com        quiesceEvent.schedule(quiesceEndTick);
21210535Sandreas.hansson@arm.com#endif
21310535Sandreas.hansson@arm.com}
21410535Sandreas.hansson@arm.com
21510535Sandreas.hansson@arm.com
21610535Sandreas.hansson@arm.comvoid
21710535Sandreas.hansson@arm.comCPUExecContext::activate(int delay)
21810535Sandreas.hansson@arm.com{
21910535Sandreas.hansson@arm.com    if (status() == ExecContext::Active)
22010535Sandreas.hansson@arm.com        return;
22110535Sandreas.hansson@arm.com
22210535Sandreas.hansson@arm.com    lastActivate = curTick;
22310535Sandreas.hansson@arm.com
22410535Sandreas.hansson@arm.com    _status = ExecContext::Active;
22510535Sandreas.hansson@arm.com    cpu->activateContext(thread_num, delay);
22610535Sandreas.hansson@arm.com}
22710535Sandreas.hansson@arm.com
22810726Sandreas.hansson@arm.comvoid
22910726Sandreas.hansson@arm.comCPUExecContext::suspend()
23010535Sandreas.hansson@arm.com{
23110726Sandreas.hansson@arm.com    if (status() == ExecContext::Suspended)
23210726Sandreas.hansson@arm.com        return;
23310535Sandreas.hansson@arm.com
23410535Sandreas.hansson@arm.com    lastActivate = curTick;
23510726Sandreas.hansson@arm.com    lastSuspend = curTick;
23610726Sandreas.hansson@arm.com/*
23710726Sandreas.hansson@arm.com#if FULL_SYSTEM
23810535Sandreas.hansson@arm.com    // Don't change the status from active if there are pending interrupts
23910726Sandreas.hansson@arm.com    if (cpu->check_interrupts()) {
24010726Sandreas.hansson@arm.com        assert(status() == ExecContext::Active);
24110726Sandreas.hansson@arm.com        return;
24210535Sandreas.hansson@arm.com    }
24310726Sandreas.hansson@arm.com#endif
24410726Sandreas.hansson@arm.com*/
24510535Sandreas.hansson@arm.com    _status = ExecContext::Suspended;
24610535Sandreas.hansson@arm.com    cpu->suspendContext(thread_num);
24710726Sandreas.hansson@arm.com}
24810726Sandreas.hansson@arm.com
24910726Sandreas.hansson@arm.comvoid
25010726Sandreas.hansson@arm.comCPUExecContext::deallocate()
25110726Sandreas.hansson@arm.com{
25210726Sandreas.hansson@arm.com    if (status() == ExecContext::Unallocated)
25310726Sandreas.hansson@arm.com        return;
25410535Sandreas.hansson@arm.com
25510535Sandreas.hansson@arm.com    _status = ExecContext::Unallocated;
25610726Sandreas.hansson@arm.com    cpu->deallocateContext(thread_num);
25710535Sandreas.hansson@arm.com}
25810726Sandreas.hansson@arm.com
25910585Sandreas.hansson@arm.comvoid
26010535Sandreas.hansson@arm.comCPUExecContext::halt()
26110535Sandreas.hansson@arm.com{
26210535Sandreas.hansson@arm.com    if (status() == ExecContext::Halted)
26310535Sandreas.hansson@arm.com        return;
26410535Sandreas.hansson@arm.com
26510535Sandreas.hansson@arm.com    _status = ExecContext::Halted;
26610535Sandreas.hansson@arm.com    cpu->haltContext(thread_num);
26710535Sandreas.hansson@arm.com}
26810535Sandreas.hansson@arm.com
26910535Sandreas.hansson@arm.com
27010535Sandreas.hansson@arm.comvoid
27110535Sandreas.hansson@arm.comCPUExecContext::regStats(const string &name)
27210535Sandreas.hansson@arm.com{
27310535Sandreas.hansson@arm.com}
27410535Sandreas.hansson@arm.com
27510535Sandreas.hansson@arm.comvoid
27610535Sandreas.hansson@arm.comCPUExecContext::copyArchRegs(ExecContext *xc)
27710535Sandreas.hansson@arm.com{
27810535Sandreas.hansson@arm.com    TheISA::copyRegs(xc, proxy);
27910535Sandreas.hansson@arm.com}
28010535Sandreas.hansson@arm.com
28110535Sandreas.hansson@arm.com