simple_thread.cc revision 2526
17860SN/A/* 27860SN/A * Copyright (c) 2001-2006 The Regents of The University of Michigan 37860SN/A * All rights reserved. 48825Snilay@cs.wisc.edu * 57935SN/A * Redistribution and use in source and binary forms, with or without 67935SN/A * modification, are permitted provided that the following conditions are 77935SN/A * met: redistributions of source code must retain the above copyright 87860SN/A * notice, this list of conditions and the following disclaimer; 97860SN/A * redistributions in binary form must reproduce the above copyright 107860SN/A * notice, this list of conditions and the following disclaimer in the 117860SN/A * documentation and/or other materials provided with the distribution; 128825Snilay@cs.wisc.edu * neither the name of the copyright holders nor the names of its 139348SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from 148825Snilay@cs.wisc.edu * this software without specific prior written permission. 158825Snilay@cs.wisc.edu * 168825Snilay@cs.wisc.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179449SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189449SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 198464SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 208721SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 218825Snilay@cs.wisc.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 228825Snilay@cs.wisc.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237935SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247935SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257935SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267935SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277935SN/A */ 287935SN/A 297935SN/A#include <string> 308893Ssaidi@eecs.umich.edu 317860SN/A#include "arch/isa_traits.hh" 327860SN/A#include "cpu/base.hh" 337860SN/A#include "cpu/cpu_exec_context.hh" 349449SAli.Saidi@ARM.com#include "cpu/exec_context.hh" 357860SN/A 367860SN/A#if FULL_SYSTEM 377860SN/A#include "base/callback.hh" 387860SN/A#include "base/cprintf.hh" 398210SN/A#include "base/output.hh" 408210SN/A#include "base/trace.hh" 417860SN/A#include "cpu/profile.hh" 427860SN/A#include "kern/kernel_stats.hh" 437860SN/A#include "sim/serialize.hh" 447860SN/A#include "sim/sim_exit.hh" 457860SN/A#include "arch/stacktrace.hh" 467860SN/A#else 477860SN/A#include "sim/process.hh" 487860SN/A#include "sim/system.hh" 497860SN/A#include "mem/translating_port.hh" 507860SN/A#endif 517860SN/A 527860SN/Ausing namespace std; 537860SN/A 547860SN/A// constructor 557860SN/A#if FULL_SYSTEM 567860SN/ACPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, 577860SN/A AlphaITB *_itb, AlphaDTB *_dtb) 587860SN/A : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num), 597860SN/A cpu_id(-1), lastActivate(0), lastSuspend(0), system(_sys), itb(_itb), 607860SN/A dtb(_dtb), memctrl(_sys->memctrl), profile(NULL), 617860SN/A quiesceEvent(this), func_exe_inst(0), storeCondFailures(0) 628825Snilay@cs.wisc.edu{ 637860SN/A proxy = new ProxyExecContext<CPUExecContext>(this); 647860SN/A 657860SN/A regs.clear(); 667860SN/A 677860SN/A if (cpu->params->profile) { 687860SN/A profile = new FunctionProfile(system->kernelSymtab); 697860SN/A Callback *cb = 707860SN/A new MakeCallback<CPUExecContext, 717860SN/A &CPUExecContext::dumpFuncProfile>(this); 727860SN/A registerExitCallback(cb); 737860SN/A } 747860SN/A 757860SN/A // let's fill with a dummy node for now so we don't get a segfault 767860SN/A // on the first cycle when there's no node available. 777860SN/A static ProfileNode dummyNode; 787860SN/A profileNode = &dummyNode; 797860SN/A profilePC = 3; 808825Snilay@cs.wisc.edu} 819449SAli.Saidi@ARM.com#else 827860SN/ACPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, 837860SN/A Process *_process, int _asid, MemObject* memobj) 847860SN/A : _status(ExecContext::Unallocated), 857860SN/A cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0), 867860SN/A lastSuspend(0), process(_process), asid(_asid), 877860SN/A func_exe_inst(0), storeCondFailures(0) 887860SN/A{ 897860SN/A /* Use this port to for syscall emulation writes to memory. */ 907860SN/A Port *mem_port; 917860SN/A port = new TranslatingPort(process->pTable, false); 927860SN/A mem_port = memobj->getPort("functional"); 938825Snilay@cs.wisc.edu mem_port->setPeer(port); 947860SN/A port->setPeer(mem_port); 957860SN/A 967860SN/A regs.clear(); 977860SN/A proxy = new ProxyExecContext<CPUExecContext>(this); 987860SN/A} 997860SN/A 1007860SN/ACPUExecContext::CPUExecContext(RegFile *regFile) 1018825Snilay@cs.wisc.edu : cpu(NULL), thread_num(-1), process(NULL), asid(-1), 1027860SN/A func_exe_inst(0), storeCondFailures(0) 1037860SN/A{ 1047860SN/A regs = *regFile; 1057860SN/A proxy = new ProxyExecContext<CPUExecContext>(this); 1067860SN/A} 1077860SN/A 1087860SN/A#endif 1097860SN/A 1107860SN/ACPUExecContext::~CPUExecContext() 1117860SN/A{ 1127860SN/A delete proxy; 1137860SN/A} 1147860SN/A 1157860SN/A#if FULL_SYSTEM 1167860SN/Avoid 1177860SN/ACPUExecContext::dumpFuncProfile() 1188521SN/A{ 1199449SAli.Saidi@ARM.com std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); 1207860SN/A profile->dump(proxy, *os); 1217860SN/A} 1227860SN/A 1237860SN/ACPUExecContext::EndQuiesceEvent::EndQuiesceEvent(CPUExecContext *_cpuXC) 1247860SN/A : Event(&mainEventQueue), cpuXC(_cpuXC) 1257860SN/A{ 1267860SN/A} 1277860SN/A 1287860SN/Avoid 1297860SN/ACPUExecContext::EndQuiesceEvent::process() 1307860SN/A{ 1318893Ssaidi@eecs.umich.edu cpuXC->activate(); 1327860SN/A} 1337860SN/A 1349348SAli.Saidi@ARM.comconst char* 1357860SN/ACPUExecContext::EndQuiesceEvent::description() 1369348SAli.Saidi@ARM.com{ 1378150SN/A return "End Quiesce Event."; 1387860SN/A} 1399348SAli.Saidi@ARM.com 1407860SN/Avoid 1418835SAli.Saidi@ARM.comCPUExecContext::profileClear() 1429348SAli.Saidi@ARM.com{ 1437860SN/A if (profile) 1448835SAli.Saidi@ARM.com profile->clear(); 1457860SN/A} 1467860SN/A 1477860SN/Avoid 1487860SN/ACPUExecContext::profileSample() 1498893Ssaidi@eecs.umich.edu{ 1507860SN/A if (profile) 1517860SN/A profile->sample(profileNode, profilePC); 1527860SN/A} 1538825Snilay@cs.wisc.edu 1547860SN/A#endif 1558825Snilay@cs.wisc.edu 1568825Snilay@cs.wisc.eduvoid 1578825Snilay@cs.wisc.eduCPUExecContext::takeOverFrom(ExecContext *oldContext) 1588825Snilay@cs.wisc.edu{ 1599348SAli.Saidi@ARM.com // some things should already be set up 1609265SAli.Saidi@ARM.com#if FULL_SYSTEM 1618825Snilay@cs.wisc.edu assert(system == oldContext->getSystemPtr()); 1628893Ssaidi@eecs.umich.edu#else 1637860SN/A assert(process == oldContext->getProcessPtr()); 1647860SN/A#endif 1657860SN/A 1667860SN/A // copy over functional state 1677860SN/A _status = oldContext->status(); 1687860SN/A copyArchRegs(oldContext); 1697860SN/A cpu_id = oldContext->readCpuId(); 1707860SN/A#if !FULL_SYSTEM 1717860SN/A func_exe_inst = oldContext->readFuncExeInst(); 1727860SN/A#endif 1737860SN/A 1747860SN/A storeCondFailures = 0; 1757860SN/A 1767860SN/A oldContext->setStatus(ExecContext::Unallocated); 1777860SN/A} 1787860SN/A 1797860SN/Avoid 1807860SN/ACPUExecContext::serialize(ostream &os) 1817860SN/A{ 1827860SN/A SERIALIZE_ENUM(_status); 1837860SN/A regs.serialize(os); 1847860SN/A // thread_num and cpu_id are deterministic from the config 1857860SN/A SERIALIZE_SCALAR(func_exe_inst); 1867860SN/A SERIALIZE_SCALAR(inst); 1877860SN/A 1887860SN/A#if FULL_SYSTEM 1897860SN/A Tick quiesceEndTick = 0; 1907860SN/A if (quiesceEvent.scheduled()) 1917860SN/A quiesceEndTick = quiesceEvent.when(); 1927860SN/A SERIALIZE_SCALAR(quiesceEndTick); 1937860SN/A 1947860SN/A#endif 1957860SN/A} 1967860SN/A 1977860SN/A 1987860SN/Avoid 1997860SN/ACPUExecContext::unserialize(Checkpoint *cp, const std::string §ion) 2007860SN/A{ 2017860SN/A UNSERIALIZE_ENUM(_status); 2027860SN/A regs.unserialize(cp, section); 2037860SN/A // thread_num and cpu_id are deterministic from the config 2047860SN/A UNSERIALIZE_SCALAR(func_exe_inst); 2057860SN/A UNSERIALIZE_SCALAR(inst); 2067860SN/A 2077860SN/A#if FULL_SYSTEM 2087860SN/A Tick quiesceEndTick; 2097860SN/A UNSERIALIZE_SCALAR(quiesceEndTick); 2107860SN/A if (quiesceEndTick) 2117860SN/A quiesceEvent.schedule(quiesceEndTick); 2127860SN/A#endif 2137860SN/A} 2147860SN/A 2157860SN/A 2167860SN/Avoid 2177860SN/ACPUExecContext::activate(int delay) 2187860SN/A{ 2197860SN/A if (status() == ExecContext::Active) 2207860SN/A return; 2217860SN/A 2227860SN/A lastActivate = curTick; 2237860SN/A 2247860SN/A _status = ExecContext::Active; 2257860SN/A cpu->activateContext(thread_num, delay); 2267860SN/A} 2277860SN/A 2287860SN/Avoid 2297860SN/ACPUExecContext::suspend() 2307860SN/A{ 2317860SN/A if (status() == ExecContext::Suspended) 2327860SN/A return; 2337860SN/A 2347860SN/A lastActivate = curTick; 2357860SN/A lastSuspend = curTick; 2367860SN/A/* 2377860SN/A#if FULL_SYSTEM 2387860SN/A // Don't change the status from active if there are pending interrupts 2397860SN/A if (cpu->check_interrupts()) { 2407860SN/A assert(status() == ExecContext::Active); 2417860SN/A return; 2427860SN/A } 2437860SN/A#endif 2447860SN/A*/ 2457860SN/A _status = ExecContext::Suspended; 2467860SN/A cpu->suspendContext(thread_num); 2477860SN/A} 2487860SN/A 2497860SN/Avoid 2507860SN/ACPUExecContext::deallocate() 2517860SN/A{ 2527860SN/A if (status() == ExecContext::Unallocated) 2537860SN/A return; 2547860SN/A 2557860SN/A _status = ExecContext::Unallocated; 2567860SN/A cpu->deallocateContext(thread_num); 2577860SN/A} 2587860SN/A 2597860SN/Avoid 2607860SN/ACPUExecContext::halt() 2617860SN/A{ 2627860SN/A if (status() == ExecContext::Halted) 2637860SN/A return; 2647860SN/A 2657860SN/A _status = ExecContext::Halted; 2667860SN/A cpu->haltContext(thread_num); 2677860SN/A} 2687860SN/A 2697860SN/A 2707860SN/Avoid 2717860SN/ACPUExecContext::regStats(const string &name) 2727860SN/A{ 2737860SN/A} 2747860SN/A 2757860SN/Avoid 2767860SN/ACPUExecContext::copyArchRegs(ExecContext *xc) 2777860SN/A{ 2787860SN/A TheISA::copyRegs(xc, proxy); 2797860SN/A} 2807860SN/A 2817860SN/A