simple_thread.cc revision 9377
19380SAndreas.Sandberg@ARM.com/* 29380SAndreas.Sandberg@ARM.com * Copyright (c) 2001-2006 The Regents of The University of Michigan 39380SAndreas.Sandberg@ARM.com * All rights reserved. 49380SAndreas.Sandberg@ARM.com * 59380SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without 69380SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are 79380SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright 89380SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer; 99380SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright 109380SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the 119380SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution; 129380SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its 139380SAndreas.Sandberg@ARM.com * contributors may be used to endorse or promote products derived from 149380SAndreas.Sandberg@ARM.com * this software without specific prior written permission. 159380SAndreas.Sandberg@ARM.com * 169380SAndreas.Sandberg@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179380SAndreas.Sandberg@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189380SAndreas.Sandberg@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 199380SAndreas.Sandberg@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 209380SAndreas.Sandberg@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 219380SAndreas.Sandberg@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 229380SAndreas.Sandberg@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239380SAndreas.Sandberg@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249380SAndreas.Sandberg@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259380SAndreas.Sandberg@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 269380SAndreas.Sandberg@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279380SAndreas.Sandberg@ARM.com * 289380SAndreas.Sandberg@ARM.com * Authors: Steve Reinhardt 299380SAndreas.Sandberg@ARM.com * Nathan Binkert 309380SAndreas.Sandberg@ARM.com * Lisa Hsu 319380SAndreas.Sandberg@ARM.com * Kevin Lim 329380SAndreas.Sandberg@ARM.com */ 339380SAndreas.Sandberg@ARM.com 349380SAndreas.Sandberg@ARM.com#include <string> 359380SAndreas.Sandberg@ARM.com 369380SAndreas.Sandberg@ARM.com#include "arch/isa_traits.hh" 379380SAndreas.Sandberg@ARM.com#include "arch/kernel_stats.hh" 389380SAndreas.Sandberg@ARM.com#include "arch/stacktrace.hh" 399380SAndreas.Sandberg@ARM.com#include "arch/utility.hh" 409380SAndreas.Sandberg@ARM.com#include "base/callback.hh" 419380SAndreas.Sandberg@ARM.com#include "base/cprintf.hh" 4211682Sandreas.hansson@arm.com#include "base/output.hh" 4313916Sodanrc@yahoo.com.br#include "base/trace.hh" 4411682Sandreas.hansson@arm.com#include "config/the_isa.hh" 459380SAndreas.Sandberg@ARM.com#include "cpu/base.hh" 469380SAndreas.Sandberg@ARM.com#include "cpu/profile.hh" 479380SAndreas.Sandberg@ARM.com#include "cpu/quiesce_event.hh" 489380SAndreas.Sandberg@ARM.com#include "cpu/simple_thread.hh" 499380SAndreas.Sandberg@ARM.com#include "cpu/thread_context.hh" 509380SAndreas.Sandberg@ARM.com#include "mem/fs_translating_port_proxy.hh" 519380SAndreas.Sandberg@ARM.com#include "mem/se_translating_port_proxy.hh" 529380SAndreas.Sandberg@ARM.com#include "params/BaseCPU.hh" 539380SAndreas.Sandberg@ARM.com#include "sim/full_system.hh" 549380SAndreas.Sandberg@ARM.com#include "sim/process.hh" 559380SAndreas.Sandberg@ARM.com#include "sim/serialize.hh" 569380SAndreas.Sandberg@ARM.com#include "sim/sim_exit.hh" 579380SAndreas.Sandberg@ARM.com#include "sim/system.hh" 589380SAndreas.Sandberg@ARM.com 599380SAndreas.Sandberg@ARM.comusing namespace std; 609380SAndreas.Sandberg@ARM.com 619380SAndreas.Sandberg@ARM.com// constructor 629826Sandreas.hansson@arm.comSimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys, 6313916Sodanrc@yahoo.com.br Process *_process, TheISA::TLB *_itb, 649380SAndreas.Sandberg@ARM.com TheISA::TLB *_dtb) 659380SAndreas.Sandberg@ARM.com : ThreadState(_cpu, _thread_num, _process), system(_sys), itb(_itb), 669380SAndreas.Sandberg@ARM.com dtb(_dtb) 679380SAndreas.Sandberg@ARM.com{ 689380SAndreas.Sandberg@ARM.com clearArchRegs(); 699380SAndreas.Sandberg@ARM.com tc = new ProxyThreadContext<SimpleThread>(this); 709380SAndreas.Sandberg@ARM.com} 719380SAndreas.Sandberg@ARM.com 729380SAndreas.Sandberg@ARM.comSimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys, 739380SAndreas.Sandberg@ARM.com TheISA::TLB *_itb, TheISA::TLB *_dtb, 749380SAndreas.Sandberg@ARM.com bool use_kernel_stats) 759380SAndreas.Sandberg@ARM.com : ThreadState(_cpu, _thread_num, NULL), system(_sys), itb(_itb), dtb(_dtb) 769380SAndreas.Sandberg@ARM.com{ 779380SAndreas.Sandberg@ARM.com tc = new ProxyThreadContext<SimpleThread>(this); 789380SAndreas.Sandberg@ARM.com 799380SAndreas.Sandberg@ARM.com quiesceEvent = new EndQuiesceEvent(tc); 809380SAndreas.Sandberg@ARM.com 819380SAndreas.Sandberg@ARM.com clearArchRegs(); 829380SAndreas.Sandberg@ARM.com 839380SAndreas.Sandberg@ARM.com if (baseCpu->params()->profile) { 849380SAndreas.Sandberg@ARM.com profile = new FunctionProfile(system->kernelSymtab); 859380SAndreas.Sandberg@ARM.com Callback *cb = 869380SAndreas.Sandberg@ARM.com new MakeCallback<SimpleThread, 879380SAndreas.Sandberg@ARM.com &SimpleThread::dumpFuncProfile>(this); 889380SAndreas.Sandberg@ARM.com registerExitCallback(cb); 899380SAndreas.Sandberg@ARM.com } 909380SAndreas.Sandberg@ARM.com 919380SAndreas.Sandberg@ARM.com // let's fill with a dummy node for now so we don't get a segfault 929380SAndreas.Sandberg@ARM.com // on the first cycle when there's no node available. 939380SAndreas.Sandberg@ARM.com static ProfileNode dummyNode; 949380SAndreas.Sandberg@ARM.com profileNode = &dummyNode; 959447SAndreas.Sandberg@ARM.com profilePC = 3; 969447SAndreas.Sandberg@ARM.com 979447SAndreas.Sandberg@ARM.com if (use_kernel_stats) 989447SAndreas.Sandberg@ARM.com kernelStats = new TheISA::Kernel::Statistics(system); 999447SAndreas.Sandberg@ARM.com} 1009447SAndreas.Sandberg@ARM.com 1019447SAndreas.Sandberg@ARM.comSimpleThread::SimpleThread() 102 : ThreadState(NULL, -1, NULL) 103{ 104 tc = new ProxyThreadContext<SimpleThread>(this); 105} 106 107SimpleThread::~SimpleThread() 108{ 109 delete tc; 110} 111 112void 113SimpleThread::takeOverFrom(ThreadContext *oldContext) 114{ 115 // some things should already be set up 116 if (FullSystem) 117 assert(system == oldContext->getSystemPtr()); 118 assert(process == oldContext->getProcessPtr()); 119 120 copyState(oldContext); 121 if (FullSystem) { 122 EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent(); 123 if (quiesce) { 124 // Point the quiesce event's TC at this TC so that it wakes up 125 // the proper CPU. 126 quiesce->tc = tc; 127 } 128 if (quiesceEvent) { 129 quiesceEvent->tc = tc; 130 } 131 132 TheISA::Kernel::Statistics *stats = oldContext->getKernelStats(); 133 if (stats) { 134 kernelStats = stats; 135 } 136 } 137 138 storeCondFailures = 0; 139 140 oldContext->setStatus(ThreadContext::Halted); 141} 142 143void 144SimpleThread::copyTC(ThreadContext *context) 145{ 146 copyState(context); 147 148 if (FullSystem) { 149 EndQuiesceEvent *quiesce = context->getQuiesceEvent(); 150 if (quiesce) { 151 quiesceEvent = quiesce; 152 } 153 TheISA::Kernel::Statistics *stats = context->getKernelStats(); 154 if (stats) { 155 kernelStats = stats; 156 } 157 } 158} 159 160void 161SimpleThread::copyState(ThreadContext *oldContext) 162{ 163 // copy over functional state 164 _status = oldContext->status(); 165 copyArchRegs(oldContext); 166 if (FullSystem) 167 funcExeInst = oldContext->readFuncExeInst(); 168 169 _threadId = oldContext->threadId(); 170 _contextId = oldContext->contextId(); 171} 172 173void 174SimpleThread::serialize(ostream &os) 175{ 176 ThreadState::serialize(os); 177 SERIALIZE_ARRAY(floatRegs.i, TheISA::NumFloatRegs); 178 SERIALIZE_ARRAY(intRegs, TheISA::NumIntRegs); 179 _pcState.serialize(os); 180 // thread_num and cpu_id are deterministic from the config 181 182 // 183 // Now must serialize all the ISA dependent state 184 // 185 isa.serialize(baseCpu, os); 186} 187 188 189void 190SimpleThread::unserialize(Checkpoint *cp, const std::string §ion) 191{ 192 ThreadState::unserialize(cp, section); 193 UNSERIALIZE_ARRAY(floatRegs.i, TheISA::NumFloatRegs); 194 UNSERIALIZE_ARRAY(intRegs, TheISA::NumIntRegs); 195 _pcState.unserialize(cp, section); 196 // thread_num and cpu_id are deterministic from the config 197 198 // 199 // Now must unserialize all the ISA dependent state 200 // 201 isa.unserialize(baseCpu, cp, section); 202} 203 204void 205SimpleThread::dumpFuncProfile() 206{ 207 std::ostream *os = simout.create(csprintf("profile.%s.dat", 208 baseCpu->name())); 209 profile->dump(tc, *os); 210} 211 212void 213SimpleThread::activate(Cycles delay) 214{ 215 if (status() == ThreadContext::Active) 216 return; 217 218 lastActivate = curTick(); 219 220// if (status() == ThreadContext::Unallocated) { 221// cpu->activateWhenReady(_threadId); 222// return; 223// } 224 225 _status = ThreadContext::Active; 226 227 // status() == Suspended 228 baseCpu->activateContext(_threadId, delay); 229} 230 231void 232SimpleThread::suspend() 233{ 234 if (status() == ThreadContext::Suspended) 235 return; 236 237 lastActivate = curTick(); 238 lastSuspend = curTick(); 239 _status = ThreadContext::Suspended; 240 baseCpu->suspendContext(_threadId); 241} 242 243 244void 245SimpleThread::halt() 246{ 247 if (status() == ThreadContext::Halted) 248 return; 249 250 _status = ThreadContext::Halted; 251 baseCpu->haltContext(_threadId); 252} 253 254 255void 256SimpleThread::regStats(const string &name) 257{ 258 if (FullSystem && kernelStats) 259 kernelStats->regStats(name + ".kern"); 260} 261 262void 263SimpleThread::copyArchRegs(ThreadContext *src_tc) 264{ 265 TheISA::copyRegs(src_tc, tc); 266} 267 268