simple_thread.cc revision 2420
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#include "mem/translating_port.hh" 47#endif 48 49using namespace std; 50 51// constructor 52#if FULL_SYSTEM 53ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, 54 AlphaITB *_itb, AlphaDTB *_dtb, 55 Memory *_mem) 56 : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num), 57 cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys), 58 memctrl(_sys->memctrl), physmem(_sys->physmem), 59 kernelBinning(system->kernelBinning), bin(kernelBinning->bin), 60 fnbin(kernelBinning->fnbin), profile(NULL), 61 func_exe_inst(0), storeCondFailures(0) 62{ 63 kernelStats = new Kernel::Statistics(this); 64 memset(®s, 0, sizeof(RegFile)); 65 66 if (cpu->params->profile) { 67 profile = new FunctionProfile(system->kernelSymtab); 68 Callback *cb = 69 new MakeCallback<ExecContext, &ExecContext::dumpFuncProfile>(this); 70 registerExitCallback(cb); 71 } 72 73 // let's fill with a dummy node for now so we don't get a segfault 74 // on the first cycle when there's no node available. 75 static ProfileNode dummyNode; 76 profileNode = &dummyNode; 77 profilePC = 3; 78} 79#else 80ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, 81 Process *_process, int _asid, Port *mem_port) 82 : _status(ExecContext::Unallocated), 83 cpu(_cpu), thread_num(_thread_num), cpu_id(-1), 84 process(_process), 85 asid(_asid), 86 func_exe_inst(0), storeCondFailures(0) 87{ 88 port = new TranslatingPort(mem_port, process->pTable); 89 memset(®s, 0, sizeof(RegFile)); 90} 91#endif 92 93ExecContext::~ExecContext() 94{ 95#if FULL_SYSTEM 96 delete kernelStats; 97#endif 98} 99 100#if FULL_SYSTEM 101void 102ExecContext::dumpFuncProfile() 103{ 104 std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); 105 profile->dump(this, *os); 106} 107#endif 108 109void 110ExecContext::takeOverFrom(ExecContext *oldContext) 111{ 112 // some things should already be set up 113// assert(mem == oldContext->mem); 114#if FULL_SYSTEM 115 assert(system == oldContext->system); 116#else 117 assert(process == oldContext->process); 118#endif 119 120 // copy over functional state 121 _status = oldContext->_status; 122 regs = oldContext->regs; 123 cpu_id = oldContext->cpu_id; 124 func_exe_inst = oldContext->func_exe_inst; 125 126 storeCondFailures = 0; 127 128 oldContext->_status = ExecContext::Unallocated; 129} 130 131void 132ExecContext::serialize(ostream &os) 133{ 134 SERIALIZE_ENUM(_status); 135 regs.serialize(os); 136 // thread_num and cpu_id are deterministic from the config 137 SERIALIZE_SCALAR(func_exe_inst); 138 SERIALIZE_SCALAR(inst); 139 140#if FULL_SYSTEM 141 kernelStats->serialize(os); 142#endif 143} 144 145 146void 147ExecContext::unserialize(Checkpoint *cp, const std::string §ion) 148{ 149 UNSERIALIZE_ENUM(_status); 150 regs.unserialize(cp, section); 151 // thread_num and cpu_id are deterministic from the config 152 UNSERIALIZE_SCALAR(func_exe_inst); 153 UNSERIALIZE_SCALAR(inst); 154 155#if FULL_SYSTEM 156 kernelStats->unserialize(cp, section); 157#endif 158} 159 160 161void 162ExecContext::activate(int delay) 163{ 164 if (status() == Active) 165 return; 166 167 _status = Active; 168 cpu->activateContext(thread_num, delay); 169} 170 171void 172ExecContext::suspend() 173{ 174 if (status() == Suspended) 175 return; 176 177#if FULL_SYSTEM 178 // Don't change the status from active if there are pending interrupts 179 if (cpu->check_interrupts()) { 180 assert(status() == Active); 181 return; 182 } 183#endif 184 185 _status = Suspended; 186 cpu->suspendContext(thread_num); 187} 188 189void 190ExecContext::deallocate() 191{ 192 if (status() == Unallocated) 193 return; 194 195 _status = Unallocated; 196 cpu->deallocateContext(thread_num); 197} 198 199void 200ExecContext::halt() 201{ 202 if (status() == Halted) 203 return; 204 205 _status = Halted; 206 cpu->haltContext(thread_num); 207} 208 209 210void 211ExecContext::regStats(const string &name) 212{ 213#if FULL_SYSTEM 214 kernelStats->regStats(name + ".kern"); 215#endif 216} 217 218void 219ExecContext::trap(Fault fault) 220{ 221 //TheISA::trap(fault); //One possible way to do it... 222 223 /** @todo: Going to hack it for now. Do a true fixup later. */ 224#if FULL_SYSTEM 225 ev5_trap(fault); 226#else 227 fatal("fault (%d) detected @ PC 0x%08p", fault, readPC()); 228#endif 229} 230