simple_thread.cc revision 1858
16876Ssteve.reinhardt@amd.com/*
28922Swilliam.wang@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan
38922Swilliam.wang@arm.com * All rights reserved.
48922Swilliam.wang@arm.com *
58922Swilliam.wang@arm.com * Redistribution and use in source and binary forms, with or without
68922Swilliam.wang@arm.com * modification, are permitted provided that the following conditions are
78922Swilliam.wang@arm.com * met: redistributions of source code must retain the above copyright
88922Swilliam.wang@arm.com * notice, this list of conditions and the following disclaimer;
98922Swilliam.wang@arm.com * redistributions in binary form must reproduce the above copyright
108922Swilliam.wang@arm.com * notice, this list of conditions and the following disclaimer in the
118922Swilliam.wang@arm.com * documentation and/or other materials provided with the distribution;
128922Swilliam.wang@arm.com * neither the name of the copyright holders nor the names of its
138922Swilliam.wang@arm.com * contributors may be used to endorse or promote products derived from
146876Ssteve.reinhardt@amd.com * this software without specific prior written permission.
158717Snilay@cs.wisc.edu *
166876Ssteve.reinhardt@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176876Ssteve.reinhardt@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186876Ssteve.reinhardt@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196876Ssteve.reinhardt@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206876Ssteve.reinhardt@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216876Ssteve.reinhardt@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226876Ssteve.reinhardt@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236876Ssteve.reinhardt@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246876Ssteve.reinhardt@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256876Ssteve.reinhardt@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266876Ssteve.reinhardt@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276876Ssteve.reinhardt@amd.com */
286876Ssteve.reinhardt@amd.com
296876Ssteve.reinhardt@amd.com#include <string>
306876Ssteve.reinhardt@amd.com
316876Ssteve.reinhardt@amd.com#include "cpu/base.hh"
326876Ssteve.reinhardt@amd.com#include "cpu/exec_context.hh"
336876Ssteve.reinhardt@amd.com
346876Ssteve.reinhardt@amd.com#if FULL_SYSTEM
356876Ssteve.reinhardt@amd.com#include "base/cprintf.hh"
366876Ssteve.reinhardt@amd.com#include "kern/kernel_stats.hh"
376876Ssteve.reinhardt@amd.com#include "sim/serialize.hh"
386876Ssteve.reinhardt@amd.com#include "sim/system.hh"
396876Ssteve.reinhardt@amd.com#else
406876Ssteve.reinhardt@amd.com#include "sim/process.hh"
416876Ssteve.reinhardt@amd.com#endif
427632SBrad.Beckmann@amd.com
438688Snilay@cs.wisc.eduusing namespace std;
448232Snate@binkert.org
458436SBrad.Beckmann@amd.com// constructor
467039Snate@binkert.org#if FULL_SYSTEM
476285Snate@binkert.orgExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
488923Sandreas.hansson@arm.com                         AlphaITB *_itb, AlphaDTB *_dtb,
496285Snate@binkert.org                         FunctionalMemory *_mem)
506876Ssteve.reinhardt@amd.com    : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num),
518922Swilliam.wang@arm.com      cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys),
528922Swilliam.wang@arm.com      memctrl(_sys->memctrl), physmem(_sys->physmem),
538922Swilliam.wang@arm.com      kernelBinning(system->kernelBinning), bin(kernelBinning->bin),
548922Swilliam.wang@arm.com      fnbin(kernelBinning->fnbin), func_exe_inst(0), storeCondFailures(0)
558923Sandreas.hansson@arm.com{
568922Swilliam.wang@arm.com    kernelStats = new Kernel::Statistics(this);
576876Ssteve.reinhardt@amd.com    memset(&regs, 0, sizeof(RegFile));
586876Ssteve.reinhardt@amd.com}
596876Ssteve.reinhardt@amd.com#else
608922Swilliam.wang@arm.comExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
618922Swilliam.wang@arm.com                         Process *_process, int _asid)
628922Swilliam.wang@arm.com    : _status(ExecContext::Unallocated),
638922Swilliam.wang@arm.com      cpu(_cpu), thread_num(_thread_num), cpu_id(-1),
648922Swilliam.wang@arm.com      process(_process), mem(process->getMemory()), asid(_asid),
657039Snate@binkert.org      func_exe_inst(0), storeCondFailures(0)
668922Swilliam.wang@arm.com{
678922Swilliam.wang@arm.com    memset(&regs, 0, sizeof(RegFile));
688922Swilliam.wang@arm.com}
698922Swilliam.wang@arm.com
708922Swilliam.wang@arm.comExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
716876Ssteve.reinhardt@amd.com                         FunctionalMemory *_mem, int _asid)
726876Ssteve.reinhardt@amd.com    : cpu(_cpu), thread_num(_thread_num), process(0), mem(_mem), asid(_asid),
737039Snate@binkert.org      func_exe_inst(0), storeCondFailures(0)
747039Snate@binkert.org{
756882SBrad.Beckmann@amd.com    memset(&regs, 0, sizeof(RegFile));
766882SBrad.Beckmann@amd.com}
776882SBrad.Beckmann@amd.com#endif
786882SBrad.Beckmann@amd.com
796882SBrad.Beckmann@amd.comExecContext::~ExecContext()
808922Swilliam.wang@arm.com{
818922Swilliam.wang@arm.com#if FULL_SYSTEM
826876Ssteve.reinhardt@amd.com    delete kernelStats;
838922Swilliam.wang@arm.com#endif
848922Swilliam.wang@arm.com}
858922Swilliam.wang@arm.com
868922Swilliam.wang@arm.com
878839Sandreas.hansson@arm.comvoid
888839Sandreas.hansson@arm.comExecContext::takeOverFrom(ExecContext *oldContext)
898922Swilliam.wang@arm.com{
908922Swilliam.wang@arm.com    // some things should already be set up
918922Swilliam.wang@arm.com    assert(mem == oldContext->mem);
928922Swilliam.wang@arm.com#if FULL_SYSTEM
938922Swilliam.wang@arm.com    assert(system == oldContext->system);
948922Swilliam.wang@arm.com#else
958922Swilliam.wang@arm.com    assert(process == oldContext->process);
968839Sandreas.hansson@arm.com#endif
978922Swilliam.wang@arm.com
988839Sandreas.hansson@arm.com    // copy over functional state
998922Swilliam.wang@arm.com    _status = oldContext->_status;
1008839Sandreas.hansson@arm.com    regs = oldContext->regs;
1018922Swilliam.wang@arm.com    cpu_id = oldContext->cpu_id;
1028922Swilliam.wang@arm.com    func_exe_inst = oldContext->func_exe_inst;
1038922Swilliam.wang@arm.com
1048922Swilliam.wang@arm.com    storeCondFailures = 0;
1058922Swilliam.wang@arm.com
1068922Swilliam.wang@arm.com    oldContext->_status = ExecContext::Unallocated;
1078922Swilliam.wang@arm.com}
1088922Swilliam.wang@arm.com
1098922Swilliam.wang@arm.com#if FULL_SYSTEM
1108922Swilliam.wang@arm.comvoid
1118922Swilliam.wang@arm.comExecContext::execute(const StaticInstBase *inst)
1128922Swilliam.wang@arm.com{
1138922Swilliam.wang@arm.com    assert(kernelStats);
1148922Swilliam.wang@arm.com    system->kernelBinning->execute(this, inst);
1157039Snate@binkert.org}
1166876Ssteve.reinhardt@amd.com#endif
1176882SBrad.Beckmann@amd.com
1187039Snate@binkert.orgvoid
1196882SBrad.Beckmann@amd.comExecContext::serialize(ostream &os)
1208922Swilliam.wang@arm.com{
1218922Swilliam.wang@arm.com    SERIALIZE_ENUM(_status);
1226882SBrad.Beckmann@amd.com    regs.serialize(os);
1238922Swilliam.wang@arm.com    // thread_num and cpu_id are deterministic from the config
1246882SBrad.Beckmann@amd.com    SERIALIZE_SCALAR(func_exe_inst);
1256882SBrad.Beckmann@amd.com    SERIALIZE_SCALAR(inst);
1268436SBrad.Beckmann@amd.com
1278436SBrad.Beckmann@amd.com#if FULL_SYSTEM
1288922Swilliam.wang@arm.com    kernelStats->serialize(os);
1298914Sandreas.hansson@arm.com#endif
1308914Sandreas.hansson@arm.com}
1316882SBrad.Beckmann@amd.com
1328922Swilliam.wang@arm.com
1336882SBrad.Beckmann@amd.comvoid
1346882SBrad.Beckmann@amd.comExecContext::unserialize(Checkpoint *cp, const std::string &section)
1356882SBrad.Beckmann@amd.com{
1366882SBrad.Beckmann@amd.com    UNSERIALIZE_ENUM(_status);
1376882SBrad.Beckmann@amd.com    regs.unserialize(cp, section);
1386882SBrad.Beckmann@amd.com    // thread_num and cpu_id are deterministic from the config
1396882SBrad.Beckmann@amd.com    UNSERIALIZE_SCALAR(func_exe_inst);
1406882SBrad.Beckmann@amd.com    UNSERIALIZE_SCALAR(inst);
1416882SBrad.Beckmann@amd.com
1426882SBrad.Beckmann@amd.com#if FULL_SYSTEM
1436882SBrad.Beckmann@amd.com    kernelStats->unserialize(cp, section);
1448975Sandreas.hansson@arm.com#endif
1456882SBrad.Beckmann@amd.com}
1467039Snate@binkert.org
1477039Snate@binkert.org
1488161SBrad.Beckmann@amd.comvoid
1496882SBrad.Beckmann@amd.comExecContext::activate(int delay)
1506882SBrad.Beckmann@amd.com{
1517039Snate@binkert.org    if (status() == Active)
1526882SBrad.Beckmann@amd.com        return;
1536882SBrad.Beckmann@amd.com
1546882SBrad.Beckmann@amd.com    _status = Active;
1557039Snate@binkert.org    cpu->activateContext(thread_num, delay);
1566882SBrad.Beckmann@amd.com}
1576882SBrad.Beckmann@amd.com
1586882SBrad.Beckmann@amd.comvoid
1597039Snate@binkert.orgExecContext::suspend()
1608975Sandreas.hansson@arm.com{
1617039Snate@binkert.org    if (status() == Suspended)
1626882SBrad.Beckmann@amd.com        return;
1636882SBrad.Beckmann@amd.com
1646882SBrad.Beckmann@amd.com#if FULL_SYSTEM
1656882SBrad.Beckmann@amd.com    // Don't change the status from active if there are pending interrupts
1668975Sandreas.hansson@arm.com    if (cpu->check_interrupts()) {
1676882SBrad.Beckmann@amd.com        assert(status() == Active);
1688161SBrad.Beckmann@amd.com        return;
1697039Snate@binkert.org    }
1706882SBrad.Beckmann@amd.com#endif
1718975Sandreas.hansson@arm.com
1726882SBrad.Beckmann@amd.com    _status = Suspended;
1737039Snate@binkert.org    cpu->suspendContext(thread_num);
1747039Snate@binkert.org}
1757039Snate@binkert.org
1766882SBrad.Beckmann@amd.comvoid
1776882SBrad.Beckmann@amd.comExecContext::deallocate()
1786882SBrad.Beckmann@amd.com{
1796882SBrad.Beckmann@amd.com    if (status() == Unallocated)
1806882SBrad.Beckmann@amd.com        return;
1816882SBrad.Beckmann@amd.com
1826882SBrad.Beckmann@amd.com    _status = Unallocated;
1836882SBrad.Beckmann@amd.com    cpu->deallocateContext(thread_num);
1846882SBrad.Beckmann@amd.com}
1856882SBrad.Beckmann@amd.com
1866922SBrad.Beckmann@amd.comvoid
1876922SBrad.Beckmann@amd.comExecContext::halt()
1886922SBrad.Beckmann@amd.com{
1896922SBrad.Beckmann@amd.com    if (status() == Halted)
1906882SBrad.Beckmann@amd.com        return;
1916882SBrad.Beckmann@amd.com
1926882SBrad.Beckmann@amd.com    _status = Halted;
1938851Sandreas.hansson@arm.com    cpu->haltContext(thread_num);
1948161SBrad.Beckmann@amd.com}
1956922SBrad.Beckmann@amd.com
1966922SBrad.Beckmann@amd.com
1976882SBrad.Beckmann@amd.comvoid
1988874Sandreas.hansson@arm.comExecContext::regStats(const string &name)
1996882SBrad.Beckmann@amd.com{
2006882SBrad.Beckmann@amd.com#if FULL_SYSTEM
2018615Snilay@cs.wisc.edu    kernelStats->regStats(name + ".kern");
2028615Snilay@cs.wisc.edu#endif
2037906SBrad.Beckmann@amd.com}
2046882SBrad.Beckmann@amd.com
2058615Snilay@cs.wisc.eduvoid
2067023SBrad.Beckmann@amd.comExecContext::trap(Fault fault)
2077550SBrad.Beckmann@amd.com{
2087023SBrad.Beckmann@amd.com    //TheISA::trap(fault);    //One possible way to do it...
2097023SBrad.Beckmann@amd.com
2107550SBrad.Beckmann@amd.com    /** @todo: Going to hack it for now.  Do a true fixup later. */
2118161SBrad.Beckmann@amd.com#if FULL_SYSTEM
2126922SBrad.Beckmann@amd.com    ev5_trap(fault);
2136882SBrad.Beckmann@amd.com#else
2147023SBrad.Beckmann@amd.com    fatal("fault (%d) detected @ PC 0x%08p", fault, readPC());
2157910SBrad.Beckmann@amd.com#endif
2167910SBrad.Beckmann@amd.com}
2177910SBrad.Beckmann@amd.com