simple_thread.cc revision 223
11761SN/A/*
22SN/A * Copyright (c) 2003 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262665Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
282SN/A
292SN/A#include <string>
302SN/A
312SN/A#include "cpu/base_cpu.hh"
322SN/A#include "cpu/exec_context.hh"
336986Snate@binkert.org
342SN/A#ifdef FULL_SYSTEM
352SN/A#include "sim/system.hh"
362SN/A#else
376661Snate@binkert.org#include "sim/prog.hh"
382SN/A#endif
396987Snate@binkert.org
406987Snate@binkert.orgusing namespace std;
416984Snate@binkert.org
426984Snate@binkert.org// constructor
432SN/A#ifdef FULL_SYSTEM
446984Snate@binkert.orgExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
456984Snate@binkert.org                         AlphaItb *_itb, AlphaDtb *_dtb,
466984Snate@binkert.org                         FunctionalMemory *_mem)
476984Snate@binkert.org    : _status(ExecContext::Unallocated),
486984Snate@binkert.org      kernelStats(this, _cpu), cpu(_cpu), thread_num(_thread_num),
496984Snate@binkert.org      cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys),
506984Snate@binkert.org      memCtrl(_sys->memCtrl), physmem(_sys->physmem),
516661Snate@binkert.org      func_exe_insn(0), storeCondFailures(0)
526984Snate@binkert.org{
536984Snate@binkert.org    memset(&regs, 0, sizeof(RegFile));
546984Snate@binkert.org}
556984Snate@binkert.org#else
566984Snate@binkert.orgExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
576984Snate@binkert.org                         Process *_process, int _asid)
586984Snate@binkert.org    : _status(ExecContext::Unallocated),
596984Snate@binkert.org      cpu(_cpu), thread_num(_thread_num), cpu_id(-1),
606984Snate@binkert.org      process(_process), mem(process->getMemory()), asid(_asid),
616984Snate@binkert.org      func_exe_insn(0), storeCondFailures(0)
626984Snate@binkert.org{
636984Snate@binkert.org}
646984Snate@binkert.org
656984Snate@binkert.orgExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
666984Snate@binkert.org                         FunctionalMemory *_mem, int _asid)
676984Snate@binkert.org    : cpu(_cpu), thread_num(_thread_num), process(0), mem(_mem), asid(_asid),
686661Snate@binkert.org      func_exe_insn(0), storeCondFailures(0)
696984Snate@binkert.org{
706984Snate@binkert.org}
716984Snate@binkert.org#endif
726984Snate@binkert.org
736984Snate@binkert.org
746984Snate@binkert.orgvoid
756661Snate@binkert.orgExecContext::takeOverFrom(ExecContext *oldContext)
766986Snate@binkert.org{
776986Snate@binkert.org    // some things should already be set up
786986Snate@binkert.org    assert(mem == oldContext->mem);
796986Snate@binkert.org#ifdef FULL_SYSTEM
806986Snate@binkert.org    assert(system == oldContext->system);
816986Snate@binkert.org#else
826986Snate@binkert.org    assert(process == oldContext->process);
836986Snate@binkert.org#endif
846986Snate@binkert.org
856986Snate@binkert.org    // copy over functional state
866986Snate@binkert.org    _status = oldContext->_status;
876986Snate@binkert.org#ifdef FULL_SYSTEM
886987Snate@binkert.org    kernelStats = oldContext->kernelStats;
896986Snate@binkert.org#endif
906986Snate@binkert.org    regs = oldContext->regs;
916986Snate@binkert.org    cpu_id = oldContext->cpu_id;
926986Snate@binkert.org    func_exe_insn = oldContext->func_exe_insn;
936986Snate@binkert.org
946986Snate@binkert.org    storeCondFailures = 0;
956986Snate@binkert.org
966986Snate@binkert.org    oldContext->_status = ExecContext::Unallocated;
976986Snate@binkert.org}
986986Snate@binkert.org
996986Snate@binkert.org
1006986Snate@binkert.orgvoid
1016986Snate@binkert.orgExecContext::serialize(ostream &os)
1026986Snate@binkert.org{
1036986Snate@binkert.org    SERIALIZE_ENUM(_status);
1046986Snate@binkert.org    regs.serialize(os);
1056986Snate@binkert.org    // thread_num and cpu_id are deterministic from the config
1066986Snate@binkert.org    SERIALIZE_SCALAR(func_exe_insn);
1076986Snate@binkert.org}
1086986Snate@binkert.org
1096987Snate@binkert.org
1106986Snate@binkert.orgvoid
1116986Snate@binkert.orgExecContext::unserialize(const IniFile *db, const std::string &section)
1126986Snate@binkert.org{
1136986Snate@binkert.org    UNSERIALIZE_ENUM(_status);
1146986Snate@binkert.org    regs.unserialize(db, section);
1156986Snate@binkert.org    // thread_num and cpu_id are deterministic from the config
1166661Snate@binkert.org    UNSERIALIZE_SCALAR(func_exe_insn);
1176984Snate@binkert.org}
1186984Snate@binkert.org
1196984Snate@binkert.org
1206984Snate@binkert.orgvoid
1216984Snate@binkert.orgExecContext::setStatus(Status new_status)
1226661Snate@binkert.org{
1236984Snate@binkert.org#ifdef FULL_SYSTEM
1246661Snate@binkert.org    if (status() == new_status)
1256984Snate@binkert.org        return;
1266991Snate@binkert.org
1276991Snate@binkert.org    // Don't change the status from active if there are pending interrupts
1286984Snate@binkert.org    if (new_status == Suspended && cpu->check_interrupts()) {
1296661Snate@binkert.org        assert(status() == Active);
1306984Snate@binkert.org        return;
1316984Snate@binkert.org    }
1326661Snate@binkert.org#endif
1336984Snate@binkert.org
1346984Snate@binkert.org    _status = new_status;
1356991Snate@binkert.org    cpu->execCtxStatusChg(thread_num);
1366984Snate@binkert.org}
1376991Snate@binkert.org
1386661Snate@binkert.orgvoid
1396984Snate@binkert.orgExecContext::regStats(const string &name)
1406984Snate@binkert.org{
1416984Snate@binkert.org#ifdef FULL_SYSTEM
1426991Snate@binkert.org    kernelStats.regStats(name + ".kern");
1432SN/A#endif
1446984Snate@binkert.org}
1456984Snate@binkert.org