simple_thread.cc revision 2519
18844SAli.Saidi@ARM.com/* 28844SAli.Saidi@ARM.com * Copyright (c) 2001-2006 The Regents of The University of Michigan 310585Sandreas.hansson@arm.com * All rights reserved. 410726Sandreas.hansson@arm.com * 510726Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 68844SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are 711138Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 811138Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 911138Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 1011138Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 1111138Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 1210726Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 1310726Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 1410036SAli.Saidi@ARM.com * this software without specific prior written permission. 1510036SAli.Saidi@ARM.com * 1610892Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1710409Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1811138Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911138Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011138Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2111138Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2211138Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2310535Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411138Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511138Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611138Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711138Sandreas.hansson@arm.com */ 2811138Sandreas.hansson@arm.com 2910827Sandreas.hansson@arm.com#include <string> 3010409Sandreas.hansson@arm.com 3111138Sandreas.hansson@arm.com#include "arch/isa_traits.hh" 3210892Sandreas.hansson@arm.com#include "cpu/base.hh" 3310409Sandreas.hansson@arm.com#include "cpu/cpu_exec_context.hh" 3411138Sandreas.hansson@arm.com#include "cpu/exec_context.hh" 3511138Sandreas.hansson@arm.com 3611138Sandreas.hansson@arm.com#if FULL_SYSTEM 3711138Sandreas.hansson@arm.com#include "base/callback.hh" 3811138Sandreas.hansson@arm.com#include "base/cprintf.hh" 3910535Sandreas.hansson@arm.com#include "base/output.hh" 4011138Sandreas.hansson@arm.com#include "base/trace.hh" 4111138Sandreas.hansson@arm.com#include "cpu/profile.hh" 4210827Sandreas.hansson@arm.com#include "kern/kernel_stats.hh" 4310409Sandreas.hansson@arm.com#include "sim/serialize.hh" 4411138Sandreas.hansson@arm.com#include "sim/sim_exit.hh" 4510892Sandreas.hansson@arm.com#include "arch/stacktrace.hh" 4610513SAli.Saidi@ARM.com#else 4711138Sandreas.hansson@arm.com#include "sim/process.hh" 4811138Sandreas.hansson@arm.com#include "sim/system.hh" 4911138Sandreas.hansson@arm.com#include "mem/translating_port.hh" 5011138Sandreas.hansson@arm.com#endif 5111138Sandreas.hansson@arm.com 5210535Sandreas.hansson@arm.comusing namespace std; 5311138Sandreas.hansson@arm.com 5411138Sandreas.hansson@arm.com// constructor 5511138Sandreas.hansson@arm.com#if FULL_SYSTEM 5611138Sandreas.hansson@arm.comCPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, 5711138Sandreas.hansson@arm.com AlphaITB *_itb, AlphaDTB *_dtb) 5810827Sandreas.hansson@arm.com : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num), 5910513SAli.Saidi@ARM.com cpu_id(-1), lastActivate(0), lastSuspend(0), system(_sys), itb(_itb), 6011138Sandreas.hansson@arm.com dtb(_dtb), memctrl(_sys->memctrl), profile(NULL), 6111138Sandreas.hansson@arm.com quiesceEvent(this), func_exe_inst(0), storeCondFailures(0) 6210892Sandreas.hansson@arm.com{ 6310513SAli.Saidi@ARM.com proxy = new ProxyExecContext<CPUExecContext>(this); 6411138Sandreas.hansson@arm.com 6511138Sandreas.hansson@arm.com memset(®s, 0, sizeof(RegFile)); 6611138Sandreas.hansson@arm.com 6711138Sandreas.hansson@arm.com if (cpu->params->profile) { 6811138Sandreas.hansson@arm.com profile = new FunctionProfile(system->kernelSymtab); 6910585Sandreas.hansson@arm.com Callback *cb = 7011138Sandreas.hansson@arm.com new MakeCallback<CPUExecContext, 7110517SAli.Saidi@ARM.com &CPUExecContext::dumpFuncProfile>(this); 7210517SAli.Saidi@ARM.com registerExitCallback(cb); 7310517SAli.Saidi@ARM.com } 7410517SAli.Saidi@ARM.com 7510517SAli.Saidi@ARM.com // let's fill with a dummy node for now so we don't get a segfault 7610517SAli.Saidi@ARM.com // on the first cycle when there's no node available. 7710517SAli.Saidi@ARM.com static ProfileNode dummyNode; 7810517SAli.Saidi@ARM.com profileNode = &dummyNode; 7910517SAli.Saidi@ARM.com profilePC = 3; 8010517SAli.Saidi@ARM.com} 8110517SAli.Saidi@ARM.com#else 8210517SAli.Saidi@ARM.comCPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, 8310517SAli.Saidi@ARM.com Process *_process, int _asid) 8410517SAli.Saidi@ARM.com : _status(ExecContext::Unallocated), 8510517SAli.Saidi@ARM.com cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0), 8610517SAli.Saidi@ARM.com lastSuspend(0), process(_process), asid(_asid), 8710517SAli.Saidi@ARM.com func_exe_inst(0), storeCondFailures(0) 8810517SAli.Saidi@ARM.com{ 898844SAli.Saidi@ARM.com /* Use this port to for syscall emulation writes to memory. */ 9010513SAli.Saidi@ARM.com Port *mem_port; 9110513SAli.Saidi@ARM.com port = new TranslatingPort(process->pTable, false); 9210513SAli.Saidi@ARM.com mem_port = process->system->physmem->getPort("functional"); 9310513SAli.Saidi@ARM.com mem_port->setPeer(port); 9410513SAli.Saidi@ARM.com port->setPeer(mem_port); 9510535Sandreas.hansson@arm.com 9610628Sandreas.hansson@arm.com memset(®s, 0, sizeof(RegFile)); 9710628Sandreas.hansson@arm.com proxy = new ProxyExecContext<CPUExecContext>(this); 9810628Sandreas.hansson@arm.com} 9910628Sandreas.hansson@arm.com 10010628Sandreas.hansson@arm.comCPUExecContext::CPUExecContext(RegFile *regFile) 10110628Sandreas.hansson@arm.com : cpu(NULL), thread_num(-1), process(NULL), asid(-1), 10210628Sandreas.hansson@arm.com func_exe_inst(0), storeCondFailures(0) 10310628Sandreas.hansson@arm.com{ 10410535Sandreas.hansson@arm.com regs = *regFile; 10510535Sandreas.hansson@arm.com proxy = new ProxyExecContext<CPUExecContext>(this); 10610535Sandreas.hansson@arm.com} 10710535Sandreas.hansson@arm.com 10810535Sandreas.hansson@arm.com#endif 10910535Sandreas.hansson@arm.com 11010535Sandreas.hansson@arm.comCPUExecContext::~CPUExecContext() 11110535Sandreas.hansson@arm.com{ 11210535Sandreas.hansson@arm.com delete proxy; 11310535Sandreas.hansson@arm.com} 11410535Sandreas.hansson@arm.com 11510535Sandreas.hansson@arm.com#if FULL_SYSTEM 11610535Sandreas.hansson@arm.comvoid 11710535Sandreas.hansson@arm.comCPUExecContext::dumpFuncProfile() 11810535Sandreas.hansson@arm.com{ 11910535Sandreas.hansson@arm.com std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); 12010535Sandreas.hansson@arm.com profile->dump(proxy, *os); 12110535Sandreas.hansson@arm.com} 12210535Sandreas.hansson@arm.com 12310535Sandreas.hansson@arm.comCPUExecContext::EndQuiesceEvent::EndQuiesceEvent(CPUExecContext *_cpuXC) 12410535Sandreas.hansson@arm.com : Event(&mainEventQueue), cpuXC(_cpuXC) 12510628Sandreas.hansson@arm.com{ 12610628Sandreas.hansson@arm.com} 12710628Sandreas.hansson@arm.com 12810628Sandreas.hansson@arm.comvoid 12910628Sandreas.hansson@arm.comCPUExecContext::EndQuiesceEvent::process() 13010628Sandreas.hansson@arm.com{ 13110628Sandreas.hansson@arm.com cpuXC->activate(); 13210628Sandreas.hansson@arm.com} 13310628Sandreas.hansson@arm.com 13410628Sandreas.hansson@arm.comconst char* 13510628Sandreas.hansson@arm.comCPUExecContext::EndQuiesceEvent::description() 13610628Sandreas.hansson@arm.com{ 13710628Sandreas.hansson@arm.com return "End Quiesce Event."; 13810628Sandreas.hansson@arm.com} 13910628Sandreas.hansson@arm.com 14010628Sandreas.hansson@arm.comvoid 14110628Sandreas.hansson@arm.comCPUExecContext::profileClear() 14210628Sandreas.hansson@arm.com{ 14310535Sandreas.hansson@arm.com if (profile) 14410535Sandreas.hansson@arm.com profile->clear(); 14510726Sandreas.hansson@arm.com} 14610585Sandreas.hansson@arm.com 14710726Sandreas.hansson@arm.comvoid 14810535Sandreas.hansson@arm.comCPUExecContext::profileSample() 14910535Sandreas.hansson@arm.com{ 15010535Sandreas.hansson@arm.com if (profile) 15110535Sandreas.hansson@arm.com profile->sample(profileNode, profilePC); 15210535Sandreas.hansson@arm.com} 15310535Sandreas.hansson@arm.com 15410535Sandreas.hansson@arm.com#endif 15510535Sandreas.hansson@arm.com 15610535Sandreas.hansson@arm.comvoid 15710535Sandreas.hansson@arm.comCPUExecContext::takeOverFrom(ExecContext *oldContext) 15810726Sandreas.hansson@arm.com{ 15910726Sandreas.hansson@arm.com // some things should already be set up 16010535Sandreas.hansson@arm.com#if FULL_SYSTEM 16110726Sandreas.hansson@arm.com assert(system == oldContext->getSystemPtr()); 16210585Sandreas.hansson@arm.com#else 16310726Sandreas.hansson@arm.com assert(process == oldContext->getProcessPtr()); 16410628Sandreas.hansson@arm.com#endif 16510628Sandreas.hansson@arm.com 16610628Sandreas.hansson@arm.com // copy over functional state 16710628Sandreas.hansson@arm.com _status = oldContext->status(); 16810628Sandreas.hansson@arm.com copyArchRegs(oldContext); 16910628Sandreas.hansson@arm.com cpu_id = oldContext->readCpuId(); 17010628Sandreas.hansson@arm.com#if !FULL_SYSTEM 17110628Sandreas.hansson@arm.com func_exe_inst = oldContext->readFuncExeInst(); 17210535Sandreas.hansson@arm.com#endif 17310535Sandreas.hansson@arm.com 17410535Sandreas.hansson@arm.com storeCondFailures = 0; 17510535Sandreas.hansson@arm.com 17610535Sandreas.hansson@arm.com oldContext->setStatus(ExecContext::Unallocated); 17710535Sandreas.hansson@arm.com} 17810535Sandreas.hansson@arm.com 17910535Sandreas.hansson@arm.comvoid 18010535Sandreas.hansson@arm.comCPUExecContext::serialize(ostream &os) 18110535Sandreas.hansson@arm.com{ 18210535Sandreas.hansson@arm.com SERIALIZE_ENUM(_status); 18310535Sandreas.hansson@arm.com regs.serialize(os); 18410535Sandreas.hansson@arm.com // thread_num and cpu_id are deterministic from the config 18510535Sandreas.hansson@arm.com SERIALIZE_SCALAR(func_exe_inst); 18610535Sandreas.hansson@arm.com SERIALIZE_SCALAR(inst); 18710535Sandreas.hansson@arm.com 18810535Sandreas.hansson@arm.com#if FULL_SYSTEM 18910535Sandreas.hansson@arm.com Tick quiesceEndTick = 0; 19010535Sandreas.hansson@arm.com if (quiesceEvent.scheduled()) 19110535Sandreas.hansson@arm.com quiesceEndTick = quiesceEvent.when(); 19210535Sandreas.hansson@arm.com SERIALIZE_SCALAR(quiesceEndTick); 19310628Sandreas.hansson@arm.com 19410628Sandreas.hansson@arm.com#endif 19510628Sandreas.hansson@arm.com} 19610628Sandreas.hansson@arm.com 19710628Sandreas.hansson@arm.com 19810628Sandreas.hansson@arm.comvoid 19910628Sandreas.hansson@arm.comCPUExecContext::unserialize(Checkpoint *cp, const std::string §ion) 20010628Sandreas.hansson@arm.com{ 20110628Sandreas.hansson@arm.com UNSERIALIZE_ENUM(_status); 20210628Sandreas.hansson@arm.com regs.unserialize(cp, section); 20310628Sandreas.hansson@arm.com // thread_num and cpu_id are deterministic from the config 20410628Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(func_exe_inst); 20510628Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(inst); 20610628Sandreas.hansson@arm.com 20710628Sandreas.hansson@arm.com#if FULL_SYSTEM 20810628Sandreas.hansson@arm.com Tick quiesceEndTick; 20910628Sandreas.hansson@arm.com UNSERIALIZE_SCALAR(quiesceEndTick); 21010628Sandreas.hansson@arm.com if (quiesceEndTick) 21110726Sandreas.hansson@arm.com quiesceEvent.schedule(quiesceEndTick); 21210535Sandreas.hansson@arm.com#endif 21310535Sandreas.hansson@arm.com} 21410535Sandreas.hansson@arm.com 21510535Sandreas.hansson@arm.com 21610535Sandreas.hansson@arm.comvoid 21710535Sandreas.hansson@arm.comCPUExecContext::activate(int delay) 21810535Sandreas.hansson@arm.com{ 21910535Sandreas.hansson@arm.com if (status() == ExecContext::Active) 22010535Sandreas.hansson@arm.com return; 22110535Sandreas.hansson@arm.com 22210535Sandreas.hansson@arm.com lastActivate = curTick; 22310535Sandreas.hansson@arm.com 22410535Sandreas.hansson@arm.com _status = ExecContext::Active; 22510535Sandreas.hansson@arm.com cpu->activateContext(thread_num, delay); 22610535Sandreas.hansson@arm.com} 22710535Sandreas.hansson@arm.com 22810726Sandreas.hansson@arm.comvoid 22910726Sandreas.hansson@arm.comCPUExecContext::suspend() 23010535Sandreas.hansson@arm.com{ 23110726Sandreas.hansson@arm.com if (status() == ExecContext::Suspended) 23210726Sandreas.hansson@arm.com return; 23310535Sandreas.hansson@arm.com 23410535Sandreas.hansson@arm.com lastActivate = curTick; 23510726Sandreas.hansson@arm.com lastSuspend = curTick; 23610726Sandreas.hansson@arm.com/* 23710726Sandreas.hansson@arm.com#if FULL_SYSTEM 23810535Sandreas.hansson@arm.com // Don't change the status from active if there are pending interrupts 23910726Sandreas.hansson@arm.com if (cpu->check_interrupts()) { 24010726Sandreas.hansson@arm.com assert(status() == ExecContext::Active); 24110726Sandreas.hansson@arm.com return; 24210535Sandreas.hansson@arm.com } 24310726Sandreas.hansson@arm.com#endif 24410726Sandreas.hansson@arm.com*/ 24510535Sandreas.hansson@arm.com _status = ExecContext::Suspended; 24610535Sandreas.hansson@arm.com cpu->suspendContext(thread_num); 24710726Sandreas.hansson@arm.com} 24810726Sandreas.hansson@arm.com 24910726Sandreas.hansson@arm.comvoid 25010726Sandreas.hansson@arm.comCPUExecContext::deallocate() 25110726Sandreas.hansson@arm.com{ 25210726Sandreas.hansson@arm.com if (status() == ExecContext::Unallocated) 25310726Sandreas.hansson@arm.com return; 25410535Sandreas.hansson@arm.com 25510535Sandreas.hansson@arm.com _status = ExecContext::Unallocated; 25610726Sandreas.hansson@arm.com cpu->deallocateContext(thread_num); 25710535Sandreas.hansson@arm.com} 25810726Sandreas.hansson@arm.com 25910585Sandreas.hansson@arm.comvoid 26010535Sandreas.hansson@arm.comCPUExecContext::halt() 26110535Sandreas.hansson@arm.com{ 26210535Sandreas.hansson@arm.com if (status() == ExecContext::Halted) 26310535Sandreas.hansson@arm.com return; 26410535Sandreas.hansson@arm.com 26510535Sandreas.hansson@arm.com _status = ExecContext::Halted; 26610535Sandreas.hansson@arm.com cpu->haltContext(thread_num); 26710535Sandreas.hansson@arm.com} 26810535Sandreas.hansson@arm.com 26910535Sandreas.hansson@arm.com 27010535Sandreas.hansson@arm.comvoid 27110535Sandreas.hansson@arm.comCPUExecContext::regStats(const string &name) 27210535Sandreas.hansson@arm.com{ 27310535Sandreas.hansson@arm.com} 27410535Sandreas.hansson@arm.com 27510535Sandreas.hansson@arm.comvoid 27610535Sandreas.hansson@arm.comCPUExecContext::copyArchRegs(ExecContext *xc) 27710535Sandreas.hansson@arm.com{ 27810535Sandreas.hansson@arm.com TheISA::copyRegs(xc, proxy); 27910535Sandreas.hansson@arm.com} 28010535Sandreas.hansson@arm.com 28110535Sandreas.hansson@arm.com