simple_thread.cc revision 1917
1/* 2 * Copyright (c) 2001-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <string> 30 31#include "cpu/base.hh" 32#include "cpu/exec_context.hh" 33 34#if FULL_SYSTEM 35#include "base/callback.hh" 36#include "base/cprintf.hh" 37#include "base/output.hh" 38#include "cpu/profile.hh" 39#include "kern/kernel_stats.hh" 40#include "sim/serialize.hh" 41#include "sim/sim_exit.hh" 42#include "sim/system.hh" 43#include "targetarch/stacktrace.hh" 44#else 45#include "sim/process.hh" 46#endif 47 48using namespace std; 49 50// constructor 51#if FULL_SYSTEM 52ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, 53 AlphaITB *_itb, AlphaDTB *_dtb, 54 FunctionalMemory *_mem) 55 : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num), 56 cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys), 57 memctrl(_sys->memctrl), physmem(_sys->physmem), 58 kernelBinning(system->kernelBinning), bin(kernelBinning->bin), 59 fnbin(kernelBinning->fnbin), profile(NULL), 60 func_exe_inst(0), storeCondFailures(0) 61{ 62 kernelStats = new Kernel::Statistics(this); 63 memset(®s, 0, sizeof(RegFile)); 64 65 if (cpu->params->profile) { 66 profile = new FunctionProfile(system->allSymtab); 67 Callback *cb = 68 new MakeCallback<ExecContext, &ExecContext::dumpFuncProfile>(this); 69 registerExitCallback(cb); 70 } 71 72 // let's fill with a dummy node for now so we don't get a segfault 73 // on the first cycle when there's no node available. 74 static ProfileNode dummyNode; 75 profileNode = &dummyNode; 76 profilePC = 3; 77} 78#else 79ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, 80 Process *_process, int _asid) 81 : _status(ExecContext::Unallocated), 82 cpu(_cpu), thread_num(_thread_num), cpu_id(-1), 83 process(_process), mem(process->getMemory()), asid(_asid), 84 func_exe_inst(0), storeCondFailures(0) 85{ 86 memset(®s, 0, sizeof(RegFile)); 87} 88 89ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, 90 FunctionalMemory *_mem, int _asid) 91 : cpu(_cpu), thread_num(_thread_num), process(0), mem(_mem), asid(_asid), 92 func_exe_inst(0), storeCondFailures(0) 93{ 94 memset(®s, 0, sizeof(RegFile)); 95} 96#endif 97 98ExecContext::~ExecContext() 99{ 100#if FULL_SYSTEM 101 delete kernelStats; 102#endif 103} 104 105#if FULL_SYSTEM 106void 107ExecContext::dumpFuncProfile() 108{ 109 std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); 110 profile->dump(this, *os); 111} 112#endif 113 114void 115ExecContext::takeOverFrom(ExecContext *oldContext) 116{ 117 // some things should already be set up 118 assert(mem == oldContext->mem); 119#if FULL_SYSTEM 120 assert(system == oldContext->system); 121#else 122 assert(process == oldContext->process); 123#endif 124 125 // copy over functional state 126 _status = oldContext->_status; 127 regs = oldContext->regs; 128 cpu_id = oldContext->cpu_id; 129 func_exe_inst = oldContext->func_exe_inst; 130 131 storeCondFailures = 0; 132 133 oldContext->_status = ExecContext::Unallocated; 134} 135 136void 137ExecContext::serialize(ostream &os) 138{ 139 SERIALIZE_ENUM(_status); 140 regs.serialize(os); 141 // thread_num and cpu_id are deterministic from the config 142 SERIALIZE_SCALAR(func_exe_inst); 143 SERIALIZE_SCALAR(inst); 144 145#if FULL_SYSTEM 146 kernelStats->serialize(os); 147#endif 148} 149 150 151void 152ExecContext::unserialize(Checkpoint *cp, const std::string §ion) 153{ 154 UNSERIALIZE_ENUM(_status); 155 regs.unserialize(cp, section); 156 // thread_num and cpu_id are deterministic from the config 157 UNSERIALIZE_SCALAR(func_exe_inst); 158 UNSERIALIZE_SCALAR(inst); 159 160#if FULL_SYSTEM 161 kernelStats->unserialize(cp, section); 162#endif 163} 164 165 166void 167ExecContext::activate(int delay) 168{ 169 if (status() == Active) 170 return; 171 172 _status = Active; 173 cpu->activateContext(thread_num, delay); 174} 175 176void 177ExecContext::suspend() 178{ 179 if (status() == Suspended) 180 return; 181 182#if FULL_SYSTEM 183 // Don't change the status from active if there are pending interrupts 184 if (cpu->check_interrupts()) { 185 assert(status() == Active); 186 return; 187 } 188#endif 189 190 _status = Suspended; 191 cpu->suspendContext(thread_num); 192} 193 194void 195ExecContext::deallocate() 196{ 197 if (status() == Unallocated) 198 return; 199 200 _status = Unallocated; 201 cpu->deallocateContext(thread_num); 202} 203 204void 205ExecContext::halt() 206{ 207 if (status() == Halted) 208 return; 209 210 _status = Halted; 211 cpu->haltContext(thread_num); 212} 213 214 215void 216ExecContext::regStats(const string &name) 217{ 218#if FULL_SYSTEM 219 kernelStats->regStats(name + ".kern"); 220#endif 221} 222 223void 224ExecContext::trap(Fault fault) 225{ 226 //TheISA::trap(fault); //One possible way to do it... 227 228 /** @todo: Going to hack it for now. Do a true fixup later. */ 229#if FULL_SYSTEM 230 ev5_trap(fault); 231#else 232 fatal("fault (%d) detected @ PC 0x%08p", fault, readPC()); 233#endif 234} 235