simple_thread.cc revision 2132
12SN/A/* 21762SN/A * Copyright (c) 2001-2005 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 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292665Ssaidi@eecs.umich.edu#include <string> 302SN/A 312SN/A#include "cpu/base.hh" 321388SN/A#include "cpu/exec_context.hh" 332SN/A 342SN/A#if FULL_SYSTEM 352SN/A#include "base/callback.hh" 361191SN/A#include "base/cprintf.hh" 371191SN/A#include "base/output.hh" 381191SN/A#include "cpu/profile.hh" 391388SN/A#include "kern/kernel_stats.hh" 405529Snate@binkert.org#include "sim/serialize.hh" 411717SN/A#include "sim/sim_exit.hh" 422651Ssaidi@eecs.umich.edu#include "sim/system.hh" 432680Sktlim@umich.edu#include "targetarch/stacktrace.hh" 441977SN/A#else 455529Snate@binkert.org#include "sim/process.hh" 463144Shsul@eecs.umich.edu#endif 472190SN/A 4856SN/Ausing namespace std; 492190SN/A 502SN/A// constructor 512359SN/A#if FULL_SYSTEM 522359SN/AExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, 532359SN/A AlphaITB *_itb, AlphaDTB *_dtb, 542SN/A FunctionalMemory *_mem) 552SN/A : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num), 562SN/A cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys), 572SN/A memctrl(_sys->memctrl), physmem(_sys->physmem), 582SN/A kernelBinning(system->kernelBinning), bin(kernelBinning->bin), 592SN/A fnbin(kernelBinning->fnbin), profile(NULL), 602SN/A func_exe_inst(0), storeCondFailures(0) 612SN/A{ 622SN/A kernelStats = new Kernel::Statistics(this); 635606Snate@binkert.org memset(®s, 0, sizeof(RegFile)); 645606Snate@binkert.org 655606Snate@binkert.org if (cpu->params->profile) { 663126Sktlim@umich.edu profile = new FunctionProfile(system->kernelSymtab); 673126Sktlim@umich.edu Callback *cb = 685606Snate@binkert.org new MakeCallback<ExecContext, &ExecContext::dumpFuncProfile>(this); 693126Sktlim@umich.edu registerExitCallback(cb); 703126Sktlim@umich.edu } 712356SN/A 722356SN/A // let's fill with a dummy node for now so we don't get a segfault 732356SN/A // on the first cycle when there's no node available. 742367SN/A static ProfileNode dummyNode; 752356SN/A profileNode = &dummyNode; 765100Ssaidi@eecs.umich.edu profilePC = 3; 772367SN/A} 782356SN/A#else 792356SN/AExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, 802356SN/A Process *_process, int _asid) 812367SN/A : _status(ExecContext::Unallocated), 822367SN/A cpu(_cpu), thread_num(_thread_num), cpu_id(-1), 832367SN/A process(_process), mem(process->getMemory()), asid(_asid), 842367SN/A func_exe_inst(0), storeCondFailures(0) 852356SN/A{ 865606Snate@binkert.org memset(®s, 0, sizeof(RegFile)); 872356SN/A} 882356SN/A 892356SN/AExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, 905336Shines@cs.fsu.edu FunctionalMemory *_mem, int _asid) 912356SN/A : cpu(_cpu), thread_num(_thread_num), process(0), mem(_mem), asid(_asid), 924873Sstever@eecs.umich.edu func_exe_inst(0), storeCondFailures(0) 932356SN/A{ 942356SN/A memset(®s, 0, sizeof(RegFile)); 951858SN/A} 961400SN/A#endif 975647Sgblack@eecs.umich.edu 985529Snate@binkert.orgExecContext::~ExecContext() 993661Srdreslin@umich.edu{ 1002SN/A#if FULL_SYSTEM 1011400SN/A delete kernelStats; 1025529Snate@binkert.org#endif 1035529Snate@binkert.org} 1043661Srdreslin@umich.edu 1052SN/A#if FULL_SYSTEM 1062SN/Avoid 1072359SN/AExecContext::dumpFuncProfile() 1081062SN/A{ 1092SN/A std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); 1102SN/A profile->dump(this, *os); 1112SN/A} 1122SN/A#endif 1132SN/A 1142SN/Avoid 1152SN/AExecContext::takeOverFrom(ExecContext *oldContext) 1161354SN/A{ 1172SN/A // some things should already be set up 118503SN/A assert(mem == oldContext->mem); 1192SN/A#if FULL_SYSTEM 1202SN/A assert(system == oldContext->system); 1212SN/A#else 1222SN/A assert(process == oldContext->process); 1235606Snate@binkert.org#endif 1245606Snate@binkert.org 1255606Snate@binkert.org // copy over functional state 1265606Snate@binkert.org _status = oldContext->_status; 1275606Snate@binkert.org regs = oldContext->regs; 1285606Snate@binkert.org cpu_id = oldContext->cpu_id; 1295606Snate@binkert.org func_exe_inst = oldContext->func_exe_inst; 1302SN/A 1311400SN/A storeCondFailures = 0; 1325606Snate@binkert.org 1335606Snate@binkert.org oldContext->_status = ExecContext::Unallocated; 1342SN/A} 1352SN/A 1362SN/Avoid 1372SN/AExecContext::serialize(ostream &os) 1382SN/A{ 1395606Snate@binkert.org SERIALIZE_ENUM(_status); 1405606Snate@binkert.org regs.serialize(os); 1415606Snate@binkert.org // thread_num and cpu_id are deterministic from the config 1425606Snate@binkert.org SERIALIZE_SCALAR(func_exe_inst); 1432SN/A SERIALIZE_SCALAR(inst); 1442SN/A 145124SN/A#if FULL_SYSTEM 1461354SN/A kernelStats->serialize(os); 147124SN/A#endif 148124SN/A} 149124SN/A 150124SN/A 151124SN/Avoid 152124SN/AExecContext::unserialize(Checkpoint *cp, const std::string §ion) 1535606Snate@binkert.org{ 1545606Snate@binkert.org UNSERIALIZE_ENUM(_status); 1555606Snate@binkert.org regs.unserialize(cp, section); 1565606Snate@binkert.org // thread_num and cpu_id are deterministic from the config 1575606Snate@binkert.org UNSERIALIZE_SCALAR(func_exe_inst); 1585606Snate@binkert.org UNSERIALIZE_SCALAR(inst); 1595606Snate@binkert.org 160124SN/A#if FULL_SYSTEM 1611400SN/A kernelStats->unserialize(cp, section); 1625606Snate@binkert.org#endif 163124SN/A} 164124SN/A 165124SN/A 166124SN/Avoid 167124SN/AExecContext::activate(int delay) 1685606Snate@binkert.org{ 1695606Snate@binkert.org if (status() == Active) 1705606Snate@binkert.org return; 1715606Snate@binkert.org 172124SN/A _status = Active; 173124SN/A cpu->activateContext(thread_num, delay); 1741191SN/A} 1755529Snate@binkert.org 1761388SN/Avoid 1771191SN/AExecContext::suspend() 1785529Snate@binkert.org{ 1791191SN/A if (status() == Suspended) 1805529Snate@binkert.org return; 1811191SN/A 1821191SN/A#if FULL_SYSTEM 1835606Snate@binkert.org // Don't change the status from active if there are pending interrupts 1845606Snate@binkert.org if (cpu->check_interrupts()) { 1855606Snate@binkert.org assert(status() == Active); 1861191SN/A return; 1871191SN/A } 1881917SN/A#endif 1891917SN/A 1905529Snate@binkert.org _status = Suspended; 1915529Snate@binkert.org cpu->suspendContext(thread_num); 1921917SN/A} 1935529Snate@binkert.org 1941917SN/Avoid 1951191SN/AExecContext::deallocate() 1961191SN/A{ 1971191SN/A if (status() == Unallocated) 1981191SN/A return; 1991191SN/A 2001191SN/A _status = Unallocated; 2011191SN/A cpu->deallocateContext(thread_num); 2021191SN/A} 2031191SN/A 2041191SN/Avoid 2051191SN/AExecContext::halt() 2061129SN/A{ 2071129SN/A if (status() == Halted) 2081129SN/A return; 2095529Snate@binkert.org 2102680Sktlim@umich.edu _status = Halted; 2111129SN/A cpu->haltContext(thread_num); 212180SN/A} 2132SN/A 2141917SN/A 2151917SN/Avoid 2161917SN/AExecContext::regStats(const string &name) 2175529Snate@binkert.org{ 2185606Snate@binkert.org#if FULL_SYSTEM 2191917SN/A kernelStats->regStats(name + ".kern"); 2202356SN/A#endif 2215529Snate@binkert.org} 2225606Snate@binkert.org 2235606Snate@binkert.orgvoid 2245606Snate@binkert.orgExecContext::trap(Fault fault) 2252356SN/A{ 2261917SN/A //TheISA::trap(fault); //One possible way to do it... 2271917SN/A 2281917SN/A /** @todo: Going to hack it for now. Do a true fixup later. */ 2291917SN/A#if FULL_SYSTEM 2302SN/A ev5_trap(fault); 2312SN/A#else 232729SN/A fatal("fault (%d) detected @ PC 0x%08p", fault, readPC()); 233707SN/A#endif 234707SN/A} 235707SN/A