simple_thread.cc revision 1982
12810SN/A/*
210764Sandreas.hansson@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan
39663Suri.wiener@arm.com * All rights reserved.
49663Suri.wiener@arm.com *
59663Suri.wiener@arm.com * Redistribution and use in source and binary forms, with or without
69663Suri.wiener@arm.com * modification, are permitted provided that the following conditions are
79663Suri.wiener@arm.com * met: redistributions of source code must retain the above copyright
89663Suri.wiener@arm.com * notice, this list of conditions and the following disclaimer;
99663Suri.wiener@arm.com * redistributions in binary form must reproduce the above copyright
109663Suri.wiener@arm.com * notice, this list of conditions and the following disclaimer in the
119663Suri.wiener@arm.com * documentation and/or other materials provided with the distribution;
129663Suri.wiener@arm.com * neither the name of the copyright holders nor the names of its
139663Suri.wiener@arm.com * contributors may be used to endorse or promote products derived from
142810SN/A * this software without specific prior written permission.
152810SN/A *
162810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272810SN/A */
282810SN/A
292810SN/A#include <string>
302810SN/A
312810SN/A#include "cpu/base.hh"
322810SN/A#include "cpu/exec_context.hh"
332810SN/A
342810SN/A#if FULL_SYSTEM
352810SN/A#include "base/callback.hh"
362810SN/A#include "base/cprintf.hh"
372810SN/A#include "base/output.hh"
382810SN/A#include "cpu/profile.hh"
392810SN/A#include "kern/kernel_stats.hh"
402810SN/A#include "sim/serialize.hh"
412810SN/A#include "sim/sim_exit.hh"
422810SN/A#include "sim/system.hh"
432810SN/A#include "targetarch/stacktrace.hh"
442810SN/A#else
452810SN/A#include "sim/process.hh"
462810SN/A#endif
472810SN/A
4810764Sandreas.hansson@arm.comusing namespace std;
4910764Sandreas.hansson@arm.com
502810SN/A// constructor
514626SN/A#if FULL_SYSTEM
524626SN/AExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
535314SN/A                         AlphaITB *_itb, AlphaDTB *_dtb,
542810SN/A                         FunctionalMemory *_mem)
552810SN/A    : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num),
564626SN/A      cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys),
574626SN/A      memctrl(_sys->memctrl), physmem(_sys->physmem),
582810SN/A      kernelBinning(system->kernelBinning), bin(kernelBinning->bin),
592810SN/A      fnbin(kernelBinning->fnbin), profile(NULL),
602810SN/A      func_exe_inst(0), storeCondFailures(0)
613374SN/A{
629264Sdjordje.kovacevic@arm.com    kernelStats = new Kernel::Statistics(this);
632810SN/A    memset(&regs, 0, sizeof(RegFile));
645314SN/A
654626SN/A    if (cpu->params->profile) {
664626SN/A        profile = new FunctionProfile(system->kernelSymtab);
679725Sandreas.hansson@arm.com        Callback *cb =
689725Sandreas.hansson@arm.com            new MakeCallback<ExecContext, &ExecContext::dumpFuncProfile>(this);
699725Sandreas.hansson@arm.com        registerExitCallback(cb);
709725Sandreas.hansson@arm.com    }
719725Sandreas.hansson@arm.com
729725Sandreas.hansson@arm.com    // let's fill with a dummy node for now so we don't get a segfault
739725Sandreas.hansson@arm.com    // on the first cycle when there's no node available.
749725Sandreas.hansson@arm.com    static ProfileNode dummyNode;
759725Sandreas.hansson@arm.com    profileNode = &dummyNode;
769725Sandreas.hansson@arm.com    profilePC = 3;
779725Sandreas.hansson@arm.com}
789725Sandreas.hansson@arm.com#else
799725Sandreas.hansson@arm.comExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
809725Sandreas.hansson@arm.com                         Process *_process, int _asid)
819725Sandreas.hansson@arm.com    : _status(ExecContext::Unallocated),
829725Sandreas.hansson@arm.com      cpu(_cpu), thread_num(_thread_num), cpu_id(-1),
8311284Sandreas.hansson@arm.com      process(_process), mem(process->getMemory()), asid(_asid),
8411284Sandreas.hansson@arm.com      func_exe_inst(0), storeCondFailures(0)
8511284Sandreas.hansson@arm.com{
8611284Sandreas.hansson@arm.com    memset(&regs, 0, sizeof(RegFile));
8711284Sandreas.hansson@arm.com}
8811284Sandreas.hansson@arm.com
8911284Sandreas.hansson@arm.comExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
9011284Sandreas.hansson@arm.com                         FunctionalMemory *_mem, int _asid)
9111284Sandreas.hansson@arm.com    : cpu(_cpu), thread_num(_thread_num), process(0), mem(_mem), asid(_asid),
9211284Sandreas.hansson@arm.com      func_exe_inst(0), storeCondFailures(0)
9311284Sandreas.hansson@arm.com{
9411284Sandreas.hansson@arm.com    memset(&regs, 0, sizeof(RegFile));
9511284Sandreas.hansson@arm.com}
9611284Sandreas.hansson@arm.com#endif
9711284Sandreas.hansson@arm.com
9811284Sandreas.hansson@arm.comExecContext::~ExecContext()
9911284Sandreas.hansson@arm.com{
10011284Sandreas.hansson@arm.com#if FULL_SYSTEM
10111284Sandreas.hansson@arm.com    delete kernelStats;
10211284Sandreas.hansson@arm.com#endif
10311284Sandreas.hansson@arm.com}
10411284Sandreas.hansson@arm.com
10511284Sandreas.hansson@arm.com#if FULL_SYSTEM
10611284Sandreas.hansson@arm.comvoid
10711284Sandreas.hansson@arm.comExecContext::dumpFuncProfile()
1089725Sandreas.hansson@arm.com{
1099725Sandreas.hansson@arm.com    std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
1109725Sandreas.hansson@arm.com    profile->dump(this, *os);
1119725Sandreas.hansson@arm.com}
1129725Sandreas.hansson@arm.com#endif
1139725Sandreas.hansson@arm.com
1149725Sandreas.hansson@arm.comvoid
1152810SN/AExecContext::takeOverFrom(ExecContext *oldContext)
1164626SN/A{
1174626SN/A    // some things should already be set up
1184626SN/A    assert(mem == oldContext->mem);
1195875Ssteve.reinhardt@amd.com#if FULL_SYSTEM
1205875Ssteve.reinhardt@amd.com    assert(system == oldContext->system);
1215875Ssteve.reinhardt@amd.com#else
1225875Ssteve.reinhardt@amd.com    assert(process == oldContext->process);
1235875Ssteve.reinhardt@amd.com#endif
1245875Ssteve.reinhardt@amd.com
1255875Ssteve.reinhardt@amd.com    // copy over functional state
12610766Sandreas.hansson@arm.com    _status = oldContext->_status;
12710766Sandreas.hansson@arm.com    regs = oldContext->regs;
12810766Sandreas.hansson@arm.com    cpu_id = oldContext->cpu_id;
12910766Sandreas.hansson@arm.com    func_exe_inst = oldContext->func_exe_inst;
13010766Sandreas.hansson@arm.com
13110766Sandreas.hansson@arm.com    storeCondFailures = 0;
13210766Sandreas.hansson@arm.com
1334626SN/A    oldContext->_status = ExecContext::Unallocated;
1345318SN/A}
1355875Ssteve.reinhardt@amd.com
1367823Ssteve.reinhardt@amd.comvoid
1375875Ssteve.reinhardt@amd.comExecContext::serialize(ostream &os)
1384626SN/A{
1394626SN/A    SERIALIZE_ENUM(_status);
1404626SN/A    regs.serialize(os);
1414903SN/A    // thread_num and cpu_id are deterministic from the config
1424903SN/A    SERIALIZE_SCALAR(func_exe_inst);
1434903SN/A    SERIALIZE_SCALAR(inst);
14411284Sandreas.hansson@arm.com
1454903SN/A#if FULL_SYSTEM
1464903SN/A    kernelStats->serialize(os);
1474903SN/A#endif
14811284Sandreas.hansson@arm.com}
14911284Sandreas.hansson@arm.com
1505318SN/A
1515875Ssteve.reinhardt@amd.comvoid
15211357Sstephan.diestelhorst@arm.comExecContext::unserialize(Checkpoint *cp, const std::string &section)
15311357Sstephan.diestelhorst@arm.com{
15411357Sstephan.diestelhorst@arm.com    UNSERIALIZE_ENUM(_status);
15511357Sstephan.diestelhorst@arm.com    regs.unserialize(cp, section);
15611357Sstephan.diestelhorst@arm.com    // thread_num and cpu_id are deterministic from the config
1574903SN/A    UNSERIALIZE_SCALAR(func_exe_inst);
15811357Sstephan.diestelhorst@arm.com    UNSERIALIZE_SCALAR(inst);
1594908SN/A
1604920SN/A#if FULL_SYSTEM
1615314SN/A    kernelStats->unserialize(cp, section);
1625314SN/A#endif
1634903SN/A}
1644903SN/A
1652810SN/A
1662810SN/Avoid
1672810SN/AExecContext::activate(int delay)
1682810SN/A{
1692810SN/A    if (status() == Active)
1702810SN/A        return;
1712810SN/A
1724626SN/A    _status = Active;
1734626SN/A    cpu->activateContext(thread_num, delay);
1744626SN/A}
1754666SN/A
1764666SN/Avoid
1774666SN/AExecContext::suspend()
17810764Sandreas.hansson@arm.com{
17910764Sandreas.hansson@arm.com    if (status() == Suspended)
1804626SN/A        return;
18110764Sandreas.hansson@arm.com
18210764Sandreas.hansson@arm.com#if FULL_SYSTEM
1834626SN/A    // Don't change the status from active if there are pending interrupts
18410028SGiacomo.Gabrielli@arm.com    if (cpu->check_interrupts()) {
18510028SGiacomo.Gabrielli@arm.com        assert(status() == Active);
18610028SGiacomo.Gabrielli@arm.com        return;
1873374SN/A    }
1882810SN/A#endif
1894626SN/A
1905730SSteve.Reinhardt@amd.com    _status = Suspended;
1915730SSteve.Reinhardt@amd.com    cpu->suspendContext(thread_num);
1924903SN/A}
19311197Sandreas.hansson@arm.com
19411197Sandreas.hansson@arm.comvoid
19511197Sandreas.hansson@arm.comExecContext::deallocate()
1967667Ssteve.reinhardt@amd.com{
1977667Ssteve.reinhardt@amd.com    if (status() == Unallocated)
1987667Ssteve.reinhardt@amd.com        return;
1997667Ssteve.reinhardt@amd.com
2007667Ssteve.reinhardt@amd.com    _status = Unallocated;
20111284Sandreas.hansson@arm.com    cpu->deallocateContext(thread_num);
20211284Sandreas.hansson@arm.com}
2039725Sandreas.hansson@arm.com
20411284Sandreas.hansson@arm.comvoid
20511284Sandreas.hansson@arm.comExecContext::halt()
2067667Ssteve.reinhardt@amd.com{
2077667Ssteve.reinhardt@amd.com    if (status() == Halted)
2087667Ssteve.reinhardt@amd.com        return;
2097667Ssteve.reinhardt@amd.com
2107667Ssteve.reinhardt@amd.com    _status = Halted;
2117667Ssteve.reinhardt@amd.com    cpu->haltContext(thread_num);
2127667Ssteve.reinhardt@amd.com}
2137667Ssteve.reinhardt@amd.com
2147667Ssteve.reinhardt@amd.com
2154665SN/Avoid
2169725Sandreas.hansson@arm.comExecContext::regStats(const string &name)
2174668SN/A{
2184668SN/A#if FULL_SYSTEM
2194668SN/A    kernelStats->regStats(name + ".kern");
2204668SN/A#endif
2214668SN/A}
2222810SN/A
2232810SN/Avoid
2242810SN/AExecContext::trap(Fault fault)
2252810SN/A{
2262810SN/A    //TheISA::trap(fault);    //One possible way to do it...
2274626SN/A
2282810SN/A    /** @todo: Going to hack it for now.  Do a true fixup later. */
2292810SN/A#if FULL_SYSTEM
2302810SN/A    ev5_trap(fault);
2312810SN/A#else
2322810SN/A    fatal("fault (%d) detected @ PC 0x%08p", fault, readPC());
2332810SN/A#endif
2343374SN/A}
2359725Sandreas.hansson@arm.com