simple_thread.cc revision 2526
13918Ssaidi@eecs.umich.edu/*
22632Sstever@eecs.umich.edu * Copyright (c) 2001-2006 The Regents of The University of Michigan
32632Sstever@eecs.umich.edu * All rights reserved.
42632Sstever@eecs.umich.edu *
52632Sstever@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
62632Sstever@eecs.umich.edu * modification, are permitted provided that the following conditions are
72632Sstever@eecs.umich.edu * met: redistributions of source code must retain the above copyright
82632Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
92632Sstever@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
102632Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
112632Sstever@eecs.umich.edu * documentation and/or other materials provided with the distribution;
122632Sstever@eecs.umich.edu * neither the name of the copyright holders nor the names of its
132632Sstever@eecs.umich.edu * contributors may be used to endorse or promote products derived from
142632Sstever@eecs.umich.edu * this software without specific prior written permission.
152632Sstever@eecs.umich.edu *
162632Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172632Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182632Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192632Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202632Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212632Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222632Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232632Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242632Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252632Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262632Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272632Sstever@eecs.umich.edu */
282632Sstever@eecs.umich.edu
292632Sstever@eecs.umich.edu#include <string>
302632Sstever@eecs.umich.edu
312022SN/A#include "arch/isa_traits.hh"
322022SN/A#include "cpu/base.hh"
332022SN/A#include "cpu/cpu_exec_context.hh"
342022SN/A#include "cpu/exec_context.hh"
352022SN/A
362022SN/A#if FULL_SYSTEM
372022SN/A#include "base/callback.hh"
382022SN/A#include "base/cprintf.hh"
392022SN/A#include "base/output.hh"
402482SN/A#include "base/trace.hh"
412022SN/A#include "cpu/profile.hh"
422224SN/A#include "kern/kernel_stats.hh"
432224SN/A#include "sim/serialize.hh"
442516SN/A#include "sim/sim_exit.hh"
452516SN/A#include "arch/stacktrace.hh"
462224SN/A#else
472224SN/A#include "sim/process.hh"
482224SN/A#include "sim/system.hh"
492022SN/A#include "mem/translating_port.hh"
502224SN/A#endif
512469SN/A
522516SN/Ausing namespace std;
532516SN/A
542516SN/A// constructor
552516SN/A#if FULL_SYSTEM
562516SN/ACPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
572516SN/A                         AlphaITB *_itb, AlphaDTB *_dtb)
582516SN/A    : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num),
592516SN/A      cpu_id(-1), lastActivate(0), lastSuspend(0), system(_sys), itb(_itb),
602516SN/A      dtb(_dtb), memctrl(_sys->memctrl), profile(NULL),
612516SN/A      quiesceEvent(this), func_exe_inst(0), storeCondFailures(0)
622516SN/A{
632516SN/A    proxy = new ProxyExecContext<CPUExecContext>(this);
642516SN/A
652516SN/A    regs.clear();
662516SN/A
672516SN/A    if (cpu->params->profile) {
682516SN/A        profile = new FunctionProfile(system->kernelSymtab);
692516SN/A        Callback *cb =
703042Sgblack@eecs.umich.edu            new MakeCallback<CPUExecContext,
712516SN/A            &CPUExecContext::dumpFuncProfile>(this);
722516SN/A        registerExitCallback(cb);
732516SN/A    }
742516SN/A
752516SN/A    // let's fill with a dummy node for now so we don't get a segfault
762516SN/A    // on the first cycle when there's no node available.
772022SN/A    static ProfileNode dummyNode;
782482SN/A    profileNode = &dummyNode;
792482SN/A    profilePC = 3;
802482SN/A}
812482SN/A#else
822516SN/ACPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num,
832482SN/A                         Process *_process, int _asid, MemObject* memobj)
842482SN/A    : _status(ExecContext::Unallocated),
852482SN/A      cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0),
862516SN/A      lastSuspend(0), process(_process), asid(_asid),
872516SN/A      func_exe_inst(0), storeCondFailures(0)
882516SN/A{
892482SN/A    /* Use this port to for syscall emulation writes to memory. */
903273Sgblack@eecs.umich.edu    Port *mem_port;
912482SN/A    port = new TranslatingPort(process->pTable, false);
922482SN/A    mem_port = memobj->getPort("functional");
932482SN/A    mem_port->setPeer(port);
942482SN/A    port->setPeer(mem_port);
952591SN/A
962591SN/A    regs.clear();
972591SN/A    proxy = new ProxyExecContext<CPUExecContext>(this);
982591SN/A}
992591SN/A
1002591SN/ACPUExecContext::CPUExecContext(RegFile *regFile)
1012591SN/A    : cpu(NULL), thread_num(-1), process(NULL), asid(-1),
1022591SN/A      func_exe_inst(0), storeCondFailures(0)
1032591SN/A{
1042591SN/A    regs = *regFile;
1053273Sgblack@eecs.umich.edu    proxy = new ProxyExecContext<CPUExecContext>(this);
1062591SN/A}
1072591SN/A
1082591SN/A#endif
1092591SN/A
1102482SN/ACPUExecContext::~CPUExecContext()
1112482SN/A{
1122516SN/A    delete proxy;
1132482SN/A}
1142482SN/A
1152482SN/A#if FULL_SYSTEM
1162516SN/Avoid
1172516SN/ACPUExecContext::dumpFuncProfile()
1182516SN/A{
1192482SN/A    std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
1203273Sgblack@eecs.umich.edu    profile->dump(proxy, *os);
1212516SN/A}
1222516SN/A
1232516SN/ACPUExecContext::EndQuiesceEvent::EndQuiesceEvent(CPUExecContext *_cpuXC)
1242516SN/A    : Event(&mainEventQueue), cpuXC(_cpuXC)
1252516SN/A{
1262516SN/A}
1272516SN/A
1282516SN/Avoid
1292516SN/ACPUExecContext::EndQuiesceEvent::process()
1302516SN/A{
1312516SN/A    cpuXC->activate();
1322516SN/A}
1332516SN/A
1342516SN/Aconst char*
1352944Sgblack@eecs.umich.eduCPUExecContext::EndQuiesceEvent::description()
1362482SN/A{
1372482SN/A    return "End Quiesce Event.";
1382516SN/A}
1392516SN/A
1402482SN/Avoid
1412022SN/ACPUExecContext::profileClear()
1422022SN/A{
1432516SN/A    if (profile)
1442516SN/A        profile->clear();
1457741Sgblack@eecs.umich.edu}
1462516SN/A
1472516SN/Avoid
1482516SN/ACPUExecContext::profileSample()
1492516SN/A{
1502516SN/A    if (profile)
1512516SN/A        profile->sample(profileNode, profilePC);
1522022SN/A}
1532516SN/A
1547741Sgblack@eecs.umich.edu#endif
1557741Sgblack@eecs.umich.edu
1562516SN/Avoid
1572516SN/ACPUExecContext::takeOverFrom(ExecContext *oldContext)
1587741Sgblack@eecs.umich.edu{
1592516SN/A    // some things should already be set up
1602944Sgblack@eecs.umich.edu#if FULL_SYSTEM
1612516SN/A    assert(system == oldContext->getSystemPtr());
1622944Sgblack@eecs.umich.edu#else
1632516SN/A    assert(process == oldContext->getProcessPtr());
1642516SN/A#endif
1652516SN/A
1662516SN/A    // copy over functional state
1672516SN/A    _status = oldContext->status();
1687741Sgblack@eecs.umich.edu    copyArchRegs(oldContext);
1697741Sgblack@eecs.umich.edu    cpu_id = oldContext->readCpuId();
1702516SN/A#if !FULL_SYSTEM
1712516SN/A    func_exe_inst = oldContext->readFuncExeInst();
1727741Sgblack@eecs.umich.edu#endif
1737741Sgblack@eecs.umich.edu
1747741Sgblack@eecs.umich.edu    storeCondFailures = 0;
1752516SN/A
1767741Sgblack@eecs.umich.edu    oldContext->setStatus(ExecContext::Unallocated);
1772516SN/A}
1782944Sgblack@eecs.umich.edu
1792516SN/Avoid
1802944Sgblack@eecs.umich.eduCPUExecContext::serialize(ostream &os)
1812944Sgblack@eecs.umich.edu{
1827741Sgblack@eecs.umich.edu    SERIALIZE_ENUM(_status);
1832516SN/A    regs.serialize(os);
1842944Sgblack@eecs.umich.edu    // thread_num and cpu_id are deterministic from the config
1852516SN/A    SERIALIZE_SCALAR(func_exe_inst);
1862944Sgblack@eecs.umich.edu    SERIALIZE_SCALAR(inst);
1872516SN/A
1882516SN/A#if FULL_SYSTEM
1892516SN/A    Tick quiesceEndTick = 0;
1902516SN/A    if (quiesceEvent.scheduled())
1912516SN/A        quiesceEndTick = quiesceEvent.when();
1922516SN/A    SERIALIZE_SCALAR(quiesceEndTick);
1937741Sgblack@eecs.umich.edu
1947741Sgblack@eecs.umich.edu#endif
1952022SN/A}
1962516SN/A
1972516SN/A
1987741Sgblack@eecs.umich.eduvoid
1992944Sgblack@eecs.umich.eduCPUExecContext::unserialize(Checkpoint *cp, const std::string &section)
2002944Sgblack@eecs.umich.edu{
2012944Sgblack@eecs.umich.edu    UNSERIALIZE_ENUM(_status);
2027741Sgblack@eecs.umich.edu    regs.unserialize(cp, section);
2032944Sgblack@eecs.umich.edu    // thread_num and cpu_id are deterministic from the config
2042944Sgblack@eecs.umich.edu    UNSERIALIZE_SCALAR(func_exe_inst);
2052516SN/A    UNSERIALIZE_SCALAR(inst);
2062516SN/A
2072516SN/A#if FULL_SYSTEM
2087741Sgblack@eecs.umich.edu    Tick quiesceEndTick;
2097741Sgblack@eecs.umich.edu    UNSERIALIZE_SCALAR(quiesceEndTick);
2102516SN/A    if (quiesceEndTick)
2112516SN/A        quiesceEvent.schedule(quiesceEndTick);
2122516SN/A#endif
2132516SN/A}
2147741Sgblack@eecs.umich.edu
2152944Sgblack@eecs.umich.edu
2162944Sgblack@eecs.umich.eduvoid
2172944Sgblack@eecs.umich.eduCPUExecContext::activate(int delay)
2187741Sgblack@eecs.umich.edu{
2192944Sgblack@eecs.umich.edu    if (status() == ExecContext::Active)
2202944Sgblack@eecs.umich.edu        return;
2217741Sgblack@eecs.umich.edu
2222944Sgblack@eecs.umich.edu    lastActivate = curTick;
2232944Sgblack@eecs.umich.edu
2242516SN/A    _status = ExecContext::Active;
2252516SN/A    cpu->activateContext(thread_num, delay);
2262516SN/A}
2277741Sgblack@eecs.umich.edu
2287741Sgblack@eecs.umich.eduvoid
2292516SN/ACPUExecContext::suspend()
2302516SN/A{
2312516SN/A    if (status() == ExecContext::Suspended)
2322516SN/A        return;
2332516SN/A
2342944Sgblack@eecs.umich.edu    lastActivate = curTick;
2352516SN/A    lastSuspend = curTick;
2362022SN/A/*
2372022SN/A#if FULL_SYSTEM
2382022SN/A    // Don't change the status from active if there are pending interrupts
2392482SN/A    if (cpu->check_interrupts()) {
2402482SN/A        assert(status() == ExecContext::Active);
2412482SN/A        return;
2422482SN/A    }
2432482SN/A#endif
2442482SN/A*/
2452482SN/A    _status = ExecContext::Suspended;
2462482SN/A    cpu->suspendContext(thread_num);
2472482SN/A}
2482482SN/A
2497741Sgblack@eecs.umich.eduvoid
2507741Sgblack@eecs.umich.eduCPUExecContext::deallocate()
2512561SN/A{
2522022SN/A    if (status() == ExecContext::Unallocated)
2532482SN/A        return;
2542482SN/A
2552482SN/A    _status = ExecContext::Unallocated;
2562482SN/A    cpu->deallocateContext(thread_num);
2572482SN/A}
2582482SN/A
2592516SN/Avoid
2602516SN/ACPUExecContext::halt()
2612516SN/A{
2623792Sgblack@eecs.umich.edu    if (status() == ExecContext::Halted)
2633792Sgblack@eecs.umich.edu        return;
2643792Sgblack@eecs.umich.edu
2652022SN/A    _status = ExecContext::Halted;
2662022SN/A    cpu->haltContext(thread_num);
2672516SN/A}
2682482SN/A
2692526SN/A
2703792Sgblack@eecs.umich.eduvoid
2712482SN/ACPUExecContext::regStats(const string &name)
2722482SN/A{
2732516SN/A}
2742482SN/A
2752482SN/Avoid
2762482SN/ACPUExecContext::copyArchRegs(ExecContext *xc)
2772516SN/A{
2782516SN/A    TheISA::copyRegs(xc, proxy);
2792516SN/A}
2802944Sgblack@eecs.umich.edu
2812646Ssaidi@eecs.umich.edu