simple_thread.cc revision 2526
13918Ssaidi@eecs.umich.edu/* 22632Sstever@eecs.umich.edu * Copyright (c) 2001-2006 The Regents of The University of Michigan 32632Sstever@eecs.umich.edu * All rights reserved. 42632Sstever@eecs.umich.edu * 52632Sstever@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 62632Sstever@eecs.umich.edu * modification, are permitted provided that the following conditions are 72632Sstever@eecs.umich.edu * met: redistributions of source code must retain the above copyright 82632Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 92632Sstever@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 102632Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 112632Sstever@eecs.umich.edu * documentation and/or other materials provided with the distribution; 122632Sstever@eecs.umich.edu * neither the name of the copyright holders nor the names of its 132632Sstever@eecs.umich.edu * contributors may be used to endorse or promote products derived from 142632Sstever@eecs.umich.edu * this software without specific prior written permission. 152632Sstever@eecs.umich.edu * 162632Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172632Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182632Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192632Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202632Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212632Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222632Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232632Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242632Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252632Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262632Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272632Sstever@eecs.umich.edu */ 282632Sstever@eecs.umich.edu 292632Sstever@eecs.umich.edu#include <string> 302632Sstever@eecs.umich.edu 312022SN/A#include "arch/isa_traits.hh" 322022SN/A#include "cpu/base.hh" 332022SN/A#include "cpu/cpu_exec_context.hh" 342022SN/A#include "cpu/exec_context.hh" 352022SN/A 362022SN/A#if FULL_SYSTEM 372022SN/A#include "base/callback.hh" 382022SN/A#include "base/cprintf.hh" 392022SN/A#include "base/output.hh" 402482SN/A#include "base/trace.hh" 412022SN/A#include "cpu/profile.hh" 422224SN/A#include "kern/kernel_stats.hh" 432224SN/A#include "sim/serialize.hh" 442516SN/A#include "sim/sim_exit.hh" 452516SN/A#include "arch/stacktrace.hh" 462224SN/A#else 472224SN/A#include "sim/process.hh" 482224SN/A#include "sim/system.hh" 492022SN/A#include "mem/translating_port.hh" 502224SN/A#endif 512469SN/A 522516SN/Ausing namespace std; 532516SN/A 542516SN/A// constructor 552516SN/A#if FULL_SYSTEM 562516SN/ACPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, 572516SN/A AlphaITB *_itb, AlphaDTB *_dtb) 582516SN/A : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num), 592516SN/A cpu_id(-1), lastActivate(0), lastSuspend(0), system(_sys), itb(_itb), 602516SN/A dtb(_dtb), memctrl(_sys->memctrl), profile(NULL), 612516SN/A quiesceEvent(this), func_exe_inst(0), storeCondFailures(0) 622516SN/A{ 632516SN/A proxy = new ProxyExecContext<CPUExecContext>(this); 642516SN/A 652516SN/A regs.clear(); 662516SN/A 672516SN/A if (cpu->params->profile) { 682516SN/A profile = new FunctionProfile(system->kernelSymtab); 692516SN/A Callback *cb = 703042Sgblack@eecs.umich.edu new MakeCallback<CPUExecContext, 712516SN/A &CPUExecContext::dumpFuncProfile>(this); 722516SN/A registerExitCallback(cb); 732516SN/A } 742516SN/A 752516SN/A // let's fill with a dummy node for now so we don't get a segfault 762516SN/A // on the first cycle when there's no node available. 772022SN/A static ProfileNode dummyNode; 782482SN/A profileNode = &dummyNode; 792482SN/A profilePC = 3; 802482SN/A} 812482SN/A#else 822516SN/ACPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, 832482SN/A Process *_process, int _asid, MemObject* memobj) 842482SN/A : _status(ExecContext::Unallocated), 852482SN/A cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0), 862516SN/A lastSuspend(0), process(_process), asid(_asid), 872516SN/A func_exe_inst(0), storeCondFailures(0) 882516SN/A{ 892482SN/A /* Use this port to for syscall emulation writes to memory. */ 903273Sgblack@eecs.umich.edu Port *mem_port; 912482SN/A port = new TranslatingPort(process->pTable, false); 922482SN/A mem_port = memobj->getPort("functional"); 932482SN/A mem_port->setPeer(port); 942482SN/A port->setPeer(mem_port); 952591SN/A 962591SN/A regs.clear(); 972591SN/A proxy = new ProxyExecContext<CPUExecContext>(this); 982591SN/A} 992591SN/A 1002591SN/ACPUExecContext::CPUExecContext(RegFile *regFile) 1012591SN/A : cpu(NULL), thread_num(-1), process(NULL), asid(-1), 1022591SN/A func_exe_inst(0), storeCondFailures(0) 1032591SN/A{ 1042591SN/A regs = *regFile; 1053273Sgblack@eecs.umich.edu proxy = new ProxyExecContext<CPUExecContext>(this); 1062591SN/A} 1072591SN/A 1082591SN/A#endif 1092591SN/A 1102482SN/ACPUExecContext::~CPUExecContext() 1112482SN/A{ 1122516SN/A delete proxy; 1132482SN/A} 1142482SN/A 1152482SN/A#if FULL_SYSTEM 1162516SN/Avoid 1172516SN/ACPUExecContext::dumpFuncProfile() 1182516SN/A{ 1192482SN/A std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); 1203273Sgblack@eecs.umich.edu profile->dump(proxy, *os); 1212516SN/A} 1222516SN/A 1232516SN/ACPUExecContext::EndQuiesceEvent::EndQuiesceEvent(CPUExecContext *_cpuXC) 1242516SN/A : Event(&mainEventQueue), cpuXC(_cpuXC) 1252516SN/A{ 1262516SN/A} 1272516SN/A 1282516SN/Avoid 1292516SN/ACPUExecContext::EndQuiesceEvent::process() 1302516SN/A{ 1312516SN/A cpuXC->activate(); 1322516SN/A} 1332516SN/A 1342516SN/Aconst char* 1352944Sgblack@eecs.umich.eduCPUExecContext::EndQuiesceEvent::description() 1362482SN/A{ 1372482SN/A return "End Quiesce Event."; 1382516SN/A} 1392516SN/A 1402482SN/Avoid 1412022SN/ACPUExecContext::profileClear() 1422022SN/A{ 1432516SN/A if (profile) 1442516SN/A profile->clear(); 1457741Sgblack@eecs.umich.edu} 1462516SN/A 1472516SN/Avoid 1482516SN/ACPUExecContext::profileSample() 1492516SN/A{ 1502516SN/A if (profile) 1512516SN/A profile->sample(profileNode, profilePC); 1522022SN/A} 1532516SN/A 1547741Sgblack@eecs.umich.edu#endif 1557741Sgblack@eecs.umich.edu 1562516SN/Avoid 1572516SN/ACPUExecContext::takeOverFrom(ExecContext *oldContext) 1587741Sgblack@eecs.umich.edu{ 1592516SN/A // some things should already be set up 1602944Sgblack@eecs.umich.edu#if FULL_SYSTEM 1612516SN/A assert(system == oldContext->getSystemPtr()); 1622944Sgblack@eecs.umich.edu#else 1632516SN/A assert(process == oldContext->getProcessPtr()); 1642516SN/A#endif 1652516SN/A 1662516SN/A // copy over functional state 1672516SN/A _status = oldContext->status(); 1687741Sgblack@eecs.umich.edu copyArchRegs(oldContext); 1697741Sgblack@eecs.umich.edu cpu_id = oldContext->readCpuId(); 1702516SN/A#if !FULL_SYSTEM 1712516SN/A func_exe_inst = oldContext->readFuncExeInst(); 1727741Sgblack@eecs.umich.edu#endif 1737741Sgblack@eecs.umich.edu 1747741Sgblack@eecs.umich.edu storeCondFailures = 0; 1752516SN/A 1767741Sgblack@eecs.umich.edu oldContext->setStatus(ExecContext::Unallocated); 1772516SN/A} 1782944Sgblack@eecs.umich.edu 1792516SN/Avoid 1802944Sgblack@eecs.umich.eduCPUExecContext::serialize(ostream &os) 1812944Sgblack@eecs.umich.edu{ 1827741Sgblack@eecs.umich.edu SERIALIZE_ENUM(_status); 1832516SN/A regs.serialize(os); 1842944Sgblack@eecs.umich.edu // thread_num and cpu_id are deterministic from the config 1852516SN/A SERIALIZE_SCALAR(func_exe_inst); 1862944Sgblack@eecs.umich.edu SERIALIZE_SCALAR(inst); 1872516SN/A 1882516SN/A#if FULL_SYSTEM 1892516SN/A Tick quiesceEndTick = 0; 1902516SN/A if (quiesceEvent.scheduled()) 1912516SN/A quiesceEndTick = quiesceEvent.when(); 1922516SN/A SERIALIZE_SCALAR(quiesceEndTick); 1937741Sgblack@eecs.umich.edu 1947741Sgblack@eecs.umich.edu#endif 1952022SN/A} 1962516SN/A 1972516SN/A 1987741Sgblack@eecs.umich.eduvoid 1992944Sgblack@eecs.umich.eduCPUExecContext::unserialize(Checkpoint *cp, const std::string §ion) 2002944Sgblack@eecs.umich.edu{ 2012944Sgblack@eecs.umich.edu UNSERIALIZE_ENUM(_status); 2027741Sgblack@eecs.umich.edu regs.unserialize(cp, section); 2032944Sgblack@eecs.umich.edu // thread_num and cpu_id are deterministic from the config 2042944Sgblack@eecs.umich.edu UNSERIALIZE_SCALAR(func_exe_inst); 2052516SN/A UNSERIALIZE_SCALAR(inst); 2062516SN/A 2072516SN/A#if FULL_SYSTEM 2087741Sgblack@eecs.umich.edu Tick quiesceEndTick; 2097741Sgblack@eecs.umich.edu UNSERIALIZE_SCALAR(quiesceEndTick); 2102516SN/A if (quiesceEndTick) 2112516SN/A quiesceEvent.schedule(quiesceEndTick); 2122516SN/A#endif 2132516SN/A} 2147741Sgblack@eecs.umich.edu 2152944Sgblack@eecs.umich.edu 2162944Sgblack@eecs.umich.eduvoid 2172944Sgblack@eecs.umich.eduCPUExecContext::activate(int delay) 2187741Sgblack@eecs.umich.edu{ 2192944Sgblack@eecs.umich.edu if (status() == ExecContext::Active) 2202944Sgblack@eecs.umich.edu return; 2217741Sgblack@eecs.umich.edu 2222944Sgblack@eecs.umich.edu lastActivate = curTick; 2232944Sgblack@eecs.umich.edu 2242516SN/A _status = ExecContext::Active; 2252516SN/A cpu->activateContext(thread_num, delay); 2262516SN/A} 2277741Sgblack@eecs.umich.edu 2287741Sgblack@eecs.umich.eduvoid 2292516SN/ACPUExecContext::suspend() 2302516SN/A{ 2312516SN/A if (status() == ExecContext::Suspended) 2322516SN/A return; 2332516SN/A 2342944Sgblack@eecs.umich.edu lastActivate = curTick; 2352516SN/A lastSuspend = curTick; 2362022SN/A/* 2372022SN/A#if FULL_SYSTEM 2382022SN/A // Don't change the status from active if there are pending interrupts 2392482SN/A if (cpu->check_interrupts()) { 2402482SN/A assert(status() == ExecContext::Active); 2412482SN/A return; 2422482SN/A } 2432482SN/A#endif 2442482SN/A*/ 2452482SN/A _status = ExecContext::Suspended; 2462482SN/A cpu->suspendContext(thread_num); 2472482SN/A} 2482482SN/A 2497741Sgblack@eecs.umich.eduvoid 2507741Sgblack@eecs.umich.eduCPUExecContext::deallocate() 2512561SN/A{ 2522022SN/A if (status() == ExecContext::Unallocated) 2532482SN/A return; 2542482SN/A 2552482SN/A _status = ExecContext::Unallocated; 2562482SN/A cpu->deallocateContext(thread_num); 2572482SN/A} 2582482SN/A 2592516SN/Avoid 2602516SN/ACPUExecContext::halt() 2612516SN/A{ 2623792Sgblack@eecs.umich.edu if (status() == ExecContext::Halted) 2633792Sgblack@eecs.umich.edu return; 2643792Sgblack@eecs.umich.edu 2652022SN/A _status = ExecContext::Halted; 2662022SN/A cpu->haltContext(thread_num); 2672516SN/A} 2682482SN/A 2692526SN/A 2703792Sgblack@eecs.umich.eduvoid 2712482SN/ACPUExecContext::regStats(const string &name) 2722482SN/A{ 2732516SN/A} 2742482SN/A 2752482SN/Avoid 2762482SN/ACPUExecContext::copyArchRegs(ExecContext *xc) 2772516SN/A{ 2782516SN/A TheISA::copyRegs(xc, proxy); 2792516SN/A} 2802944Sgblack@eecs.umich.edu 2812646Ssaidi@eecs.umich.edu