simple_thread.cc revision 2526
17860SN/A/*
27860SN/A * Copyright (c) 2001-2006 The Regents of The University of Michigan
37860SN/A * All rights reserved.
48825Snilay@cs.wisc.edu *
57935SN/A * Redistribution and use in source and binary forms, with or without
67935SN/A * modification, are permitted provided that the following conditions are
77935SN/A * met: redistributions of source code must retain the above copyright
87860SN/A * notice, this list of conditions and the following disclaimer;
97860SN/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;
128825Snilay@cs.wisc.edu * neither the name of the copyright holders nor the names of its
139348SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from
148825Snilay@cs.wisc.edu * this software without specific prior written permission.
158825Snilay@cs.wisc.edu *
168825Snilay@cs.wisc.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
179449SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
189449SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
198464SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
208721SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
218825Snilay@cs.wisc.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
228825Snilay@cs.wisc.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
237935SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
247935SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
257935SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
267935SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
277935SN/A */
287935SN/A
297935SN/A#include <string>
308893Ssaidi@eecs.umich.edu
317860SN/A#include "arch/isa_traits.hh"
327860SN/A#include "cpu/base.hh"
337860SN/A#include "cpu/cpu_exec_context.hh"
349449SAli.Saidi@ARM.com#include "cpu/exec_context.hh"
357860SN/A
367860SN/A#if FULL_SYSTEM
377860SN/A#include "base/callback.hh"
387860SN/A#include "base/cprintf.hh"
398210SN/A#include "base/output.hh"
408210SN/A#include "base/trace.hh"
417860SN/A#include "cpu/profile.hh"
427860SN/A#include "kern/kernel_stats.hh"
437860SN/A#include "sim/serialize.hh"
447860SN/A#include "sim/sim_exit.hh"
457860SN/A#include "arch/stacktrace.hh"
467860SN/A#else
477860SN/A#include "sim/process.hh"
487860SN/A#include "sim/system.hh"
497860SN/A#include "mem/translating_port.hh"
507860SN/A#endif
517860SN/A
527860SN/Ausing namespace std;
537860SN/A
547860SN/A// constructor
557860SN/A#if FULL_SYSTEM
567860SN/ACPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
577860SN/A                         AlphaITB *_itb, AlphaDTB *_dtb)
587860SN/A    : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num),
597860SN/A      cpu_id(-1), lastActivate(0), lastSuspend(0), system(_sys), itb(_itb),
607860SN/A      dtb(_dtb), memctrl(_sys->memctrl), profile(NULL),
617860SN/A      quiesceEvent(this), func_exe_inst(0), storeCondFailures(0)
628825Snilay@cs.wisc.edu{
637860SN/A    proxy = new ProxyExecContext<CPUExecContext>(this);
647860SN/A
657860SN/A    regs.clear();
667860SN/A
677860SN/A    if (cpu->params->profile) {
687860SN/A        profile = new FunctionProfile(system->kernelSymtab);
697860SN/A        Callback *cb =
707860SN/A            new MakeCallback<CPUExecContext,
717860SN/A            &CPUExecContext::dumpFuncProfile>(this);
727860SN/A        registerExitCallback(cb);
737860SN/A    }
747860SN/A
757860SN/A    // let's fill with a dummy node for now so we don't get a segfault
767860SN/A    // on the first cycle when there's no node available.
777860SN/A    static ProfileNode dummyNode;
787860SN/A    profileNode = &dummyNode;
797860SN/A    profilePC = 3;
808825Snilay@cs.wisc.edu}
819449SAli.Saidi@ARM.com#else
827860SN/ACPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num,
837860SN/A                         Process *_process, int _asid, MemObject* memobj)
847860SN/A    : _status(ExecContext::Unallocated),
857860SN/A      cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0),
867860SN/A      lastSuspend(0), process(_process), asid(_asid),
877860SN/A      func_exe_inst(0), storeCondFailures(0)
887860SN/A{
897860SN/A    /* Use this port to for syscall emulation writes to memory. */
907860SN/A    Port *mem_port;
917860SN/A    port = new TranslatingPort(process->pTable, false);
927860SN/A    mem_port = memobj->getPort("functional");
938825Snilay@cs.wisc.edu    mem_port->setPeer(port);
947860SN/A    port->setPeer(mem_port);
957860SN/A
967860SN/A    regs.clear();
977860SN/A    proxy = new ProxyExecContext<CPUExecContext>(this);
987860SN/A}
997860SN/A
1007860SN/ACPUExecContext::CPUExecContext(RegFile *regFile)
1018825Snilay@cs.wisc.edu    : cpu(NULL), thread_num(-1), process(NULL), asid(-1),
1027860SN/A      func_exe_inst(0), storeCondFailures(0)
1037860SN/A{
1047860SN/A    regs = *regFile;
1057860SN/A    proxy = new ProxyExecContext<CPUExecContext>(this);
1067860SN/A}
1077860SN/A
1087860SN/A#endif
1097860SN/A
1107860SN/ACPUExecContext::~CPUExecContext()
1117860SN/A{
1127860SN/A    delete proxy;
1137860SN/A}
1147860SN/A
1157860SN/A#if FULL_SYSTEM
1167860SN/Avoid
1177860SN/ACPUExecContext::dumpFuncProfile()
1188521SN/A{
1199449SAli.Saidi@ARM.com    std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
1207860SN/A    profile->dump(proxy, *os);
1217860SN/A}
1227860SN/A
1237860SN/ACPUExecContext::EndQuiesceEvent::EndQuiesceEvent(CPUExecContext *_cpuXC)
1247860SN/A    : Event(&mainEventQueue), cpuXC(_cpuXC)
1257860SN/A{
1267860SN/A}
1277860SN/A
1287860SN/Avoid
1297860SN/ACPUExecContext::EndQuiesceEvent::process()
1307860SN/A{
1318893Ssaidi@eecs.umich.edu    cpuXC->activate();
1327860SN/A}
1337860SN/A
1349348SAli.Saidi@ARM.comconst char*
1357860SN/ACPUExecContext::EndQuiesceEvent::description()
1369348SAli.Saidi@ARM.com{
1378150SN/A    return "End Quiesce Event.";
1387860SN/A}
1399348SAli.Saidi@ARM.com
1407860SN/Avoid
1418835SAli.Saidi@ARM.comCPUExecContext::profileClear()
1429348SAli.Saidi@ARM.com{
1437860SN/A    if (profile)
1448835SAli.Saidi@ARM.com        profile->clear();
1457860SN/A}
1467860SN/A
1477860SN/Avoid
1487860SN/ACPUExecContext::profileSample()
1498893Ssaidi@eecs.umich.edu{
1507860SN/A    if (profile)
1517860SN/A        profile->sample(profileNode, profilePC);
1527860SN/A}
1538825Snilay@cs.wisc.edu
1547860SN/A#endif
1558825Snilay@cs.wisc.edu
1568825Snilay@cs.wisc.eduvoid
1578825Snilay@cs.wisc.eduCPUExecContext::takeOverFrom(ExecContext *oldContext)
1588825Snilay@cs.wisc.edu{
1599348SAli.Saidi@ARM.com    // some things should already be set up
1609265SAli.Saidi@ARM.com#if FULL_SYSTEM
1618825Snilay@cs.wisc.edu    assert(system == oldContext->getSystemPtr());
1628893Ssaidi@eecs.umich.edu#else
1637860SN/A    assert(process == oldContext->getProcessPtr());
1647860SN/A#endif
1657860SN/A
1667860SN/A    // copy over functional state
1677860SN/A    _status = oldContext->status();
1687860SN/A    copyArchRegs(oldContext);
1697860SN/A    cpu_id = oldContext->readCpuId();
1707860SN/A#if !FULL_SYSTEM
1717860SN/A    func_exe_inst = oldContext->readFuncExeInst();
1727860SN/A#endif
1737860SN/A
1747860SN/A    storeCondFailures = 0;
1757860SN/A
1767860SN/A    oldContext->setStatus(ExecContext::Unallocated);
1777860SN/A}
1787860SN/A
1797860SN/Avoid
1807860SN/ACPUExecContext::serialize(ostream &os)
1817860SN/A{
1827860SN/A    SERIALIZE_ENUM(_status);
1837860SN/A    regs.serialize(os);
1847860SN/A    // thread_num and cpu_id are deterministic from the config
1857860SN/A    SERIALIZE_SCALAR(func_exe_inst);
1867860SN/A    SERIALIZE_SCALAR(inst);
1877860SN/A
1887860SN/A#if FULL_SYSTEM
1897860SN/A    Tick quiesceEndTick = 0;
1907860SN/A    if (quiesceEvent.scheduled())
1917860SN/A        quiesceEndTick = quiesceEvent.when();
1927860SN/A    SERIALIZE_SCALAR(quiesceEndTick);
1937860SN/A
1947860SN/A#endif
1957860SN/A}
1967860SN/A
1977860SN/A
1987860SN/Avoid
1997860SN/ACPUExecContext::unserialize(Checkpoint *cp, const std::string &section)
2007860SN/A{
2017860SN/A    UNSERIALIZE_ENUM(_status);
2027860SN/A    regs.unserialize(cp, section);
2037860SN/A    // thread_num and cpu_id are deterministic from the config
2047860SN/A    UNSERIALIZE_SCALAR(func_exe_inst);
2057860SN/A    UNSERIALIZE_SCALAR(inst);
2067860SN/A
2077860SN/A#if FULL_SYSTEM
2087860SN/A    Tick quiesceEndTick;
2097860SN/A    UNSERIALIZE_SCALAR(quiesceEndTick);
2107860SN/A    if (quiesceEndTick)
2117860SN/A        quiesceEvent.schedule(quiesceEndTick);
2127860SN/A#endif
2137860SN/A}
2147860SN/A
2157860SN/A
2167860SN/Avoid
2177860SN/ACPUExecContext::activate(int delay)
2187860SN/A{
2197860SN/A    if (status() == ExecContext::Active)
2207860SN/A        return;
2217860SN/A
2227860SN/A    lastActivate = curTick;
2237860SN/A
2247860SN/A    _status = ExecContext::Active;
2257860SN/A    cpu->activateContext(thread_num, delay);
2267860SN/A}
2277860SN/A
2287860SN/Avoid
2297860SN/ACPUExecContext::suspend()
2307860SN/A{
2317860SN/A    if (status() == ExecContext::Suspended)
2327860SN/A        return;
2337860SN/A
2347860SN/A    lastActivate = curTick;
2357860SN/A    lastSuspend = curTick;
2367860SN/A/*
2377860SN/A#if FULL_SYSTEM
2387860SN/A    // Don't change the status from active if there are pending interrupts
2397860SN/A    if (cpu->check_interrupts()) {
2407860SN/A        assert(status() == ExecContext::Active);
2417860SN/A        return;
2427860SN/A    }
2437860SN/A#endif
2447860SN/A*/
2457860SN/A    _status = ExecContext::Suspended;
2467860SN/A    cpu->suspendContext(thread_num);
2477860SN/A}
2487860SN/A
2497860SN/Avoid
2507860SN/ACPUExecContext::deallocate()
2517860SN/A{
2527860SN/A    if (status() == ExecContext::Unallocated)
2537860SN/A        return;
2547860SN/A
2557860SN/A    _status = ExecContext::Unallocated;
2567860SN/A    cpu->deallocateContext(thread_num);
2577860SN/A}
2587860SN/A
2597860SN/Avoid
2607860SN/ACPUExecContext::halt()
2617860SN/A{
2627860SN/A    if (status() == ExecContext::Halted)
2637860SN/A        return;
2647860SN/A
2657860SN/A    _status = ExecContext::Halted;
2667860SN/A    cpu->haltContext(thread_num);
2677860SN/A}
2687860SN/A
2697860SN/A
2707860SN/Avoid
2717860SN/ACPUExecContext::regStats(const string &name)
2727860SN/A{
2737860SN/A}
2747860SN/A
2757860SN/Avoid
2767860SN/ACPUExecContext::copyArchRegs(ExecContext *xc)
2777860SN/A{
2787860SN/A    TheISA::copyRegs(xc, proxy);
2797860SN/A}
2807860SN/A
2817860SN/A