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(®s, 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(®s, 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(®s, 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 §ion) 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