simple_thread.cc revision 1858
16876Ssteve.reinhardt@amd.com/* 28922Swilliam.wang@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan 38922Swilliam.wang@arm.com * All rights reserved. 48922Swilliam.wang@arm.com * 58922Swilliam.wang@arm.com * Redistribution and use in source and binary forms, with or without 68922Swilliam.wang@arm.com * modification, are permitted provided that the following conditions are 78922Swilliam.wang@arm.com * met: redistributions of source code must retain the above copyright 88922Swilliam.wang@arm.com * notice, this list of conditions and the following disclaimer; 98922Swilliam.wang@arm.com * redistributions in binary form must reproduce the above copyright 108922Swilliam.wang@arm.com * notice, this list of conditions and the following disclaimer in the 118922Swilliam.wang@arm.com * documentation and/or other materials provided with the distribution; 128922Swilliam.wang@arm.com * neither the name of the copyright holders nor the names of its 138922Swilliam.wang@arm.com * contributors may be used to endorse or promote products derived from 146876Ssteve.reinhardt@amd.com * this software without specific prior written permission. 158717Snilay@cs.wisc.edu * 166876Ssteve.reinhardt@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176876Ssteve.reinhardt@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186876Ssteve.reinhardt@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196876Ssteve.reinhardt@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206876Ssteve.reinhardt@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216876Ssteve.reinhardt@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226876Ssteve.reinhardt@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236876Ssteve.reinhardt@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246876Ssteve.reinhardt@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256876Ssteve.reinhardt@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266876Ssteve.reinhardt@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276876Ssteve.reinhardt@amd.com */ 286876Ssteve.reinhardt@amd.com 296876Ssteve.reinhardt@amd.com#include <string> 306876Ssteve.reinhardt@amd.com 316876Ssteve.reinhardt@amd.com#include "cpu/base.hh" 326876Ssteve.reinhardt@amd.com#include "cpu/exec_context.hh" 336876Ssteve.reinhardt@amd.com 346876Ssteve.reinhardt@amd.com#if FULL_SYSTEM 356876Ssteve.reinhardt@amd.com#include "base/cprintf.hh" 366876Ssteve.reinhardt@amd.com#include "kern/kernel_stats.hh" 376876Ssteve.reinhardt@amd.com#include "sim/serialize.hh" 386876Ssteve.reinhardt@amd.com#include "sim/system.hh" 396876Ssteve.reinhardt@amd.com#else 406876Ssteve.reinhardt@amd.com#include "sim/process.hh" 416876Ssteve.reinhardt@amd.com#endif 427632SBrad.Beckmann@amd.com 438688Snilay@cs.wisc.eduusing namespace std; 448232Snate@binkert.org 458436SBrad.Beckmann@amd.com// constructor 467039Snate@binkert.org#if FULL_SYSTEM 476285Snate@binkert.orgExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, 488923Sandreas.hansson@arm.com AlphaITB *_itb, AlphaDTB *_dtb, 496285Snate@binkert.org FunctionalMemory *_mem) 506876Ssteve.reinhardt@amd.com : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num), 518922Swilliam.wang@arm.com cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys), 528922Swilliam.wang@arm.com memctrl(_sys->memctrl), physmem(_sys->physmem), 538922Swilliam.wang@arm.com kernelBinning(system->kernelBinning), bin(kernelBinning->bin), 548922Swilliam.wang@arm.com fnbin(kernelBinning->fnbin), func_exe_inst(0), storeCondFailures(0) 558923Sandreas.hansson@arm.com{ 568922Swilliam.wang@arm.com kernelStats = new Kernel::Statistics(this); 576876Ssteve.reinhardt@amd.com memset(®s, 0, sizeof(RegFile)); 586876Ssteve.reinhardt@amd.com} 596876Ssteve.reinhardt@amd.com#else 608922Swilliam.wang@arm.comExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, 618922Swilliam.wang@arm.com Process *_process, int _asid) 628922Swilliam.wang@arm.com : _status(ExecContext::Unallocated), 638922Swilliam.wang@arm.com cpu(_cpu), thread_num(_thread_num), cpu_id(-1), 648922Swilliam.wang@arm.com process(_process), mem(process->getMemory()), asid(_asid), 657039Snate@binkert.org func_exe_inst(0), storeCondFailures(0) 668922Swilliam.wang@arm.com{ 678922Swilliam.wang@arm.com memset(®s, 0, sizeof(RegFile)); 688922Swilliam.wang@arm.com} 698922Swilliam.wang@arm.com 708922Swilliam.wang@arm.comExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, 716876Ssteve.reinhardt@amd.com FunctionalMemory *_mem, int _asid) 726876Ssteve.reinhardt@amd.com : cpu(_cpu), thread_num(_thread_num), process(0), mem(_mem), asid(_asid), 737039Snate@binkert.org func_exe_inst(0), storeCondFailures(0) 747039Snate@binkert.org{ 756882SBrad.Beckmann@amd.com memset(®s, 0, sizeof(RegFile)); 766882SBrad.Beckmann@amd.com} 776882SBrad.Beckmann@amd.com#endif 786882SBrad.Beckmann@amd.com 796882SBrad.Beckmann@amd.comExecContext::~ExecContext() 808922Swilliam.wang@arm.com{ 818922Swilliam.wang@arm.com#if FULL_SYSTEM 826876Ssteve.reinhardt@amd.com delete kernelStats; 838922Swilliam.wang@arm.com#endif 848922Swilliam.wang@arm.com} 858922Swilliam.wang@arm.com 868922Swilliam.wang@arm.com 878839Sandreas.hansson@arm.comvoid 888839Sandreas.hansson@arm.comExecContext::takeOverFrom(ExecContext *oldContext) 898922Swilliam.wang@arm.com{ 908922Swilliam.wang@arm.com // some things should already be set up 918922Swilliam.wang@arm.com assert(mem == oldContext->mem); 928922Swilliam.wang@arm.com#if FULL_SYSTEM 938922Swilliam.wang@arm.com assert(system == oldContext->system); 948922Swilliam.wang@arm.com#else 958922Swilliam.wang@arm.com assert(process == oldContext->process); 968839Sandreas.hansson@arm.com#endif 978922Swilliam.wang@arm.com 988839Sandreas.hansson@arm.com // copy over functional state 998922Swilliam.wang@arm.com _status = oldContext->_status; 1008839Sandreas.hansson@arm.com regs = oldContext->regs; 1018922Swilliam.wang@arm.com cpu_id = oldContext->cpu_id; 1028922Swilliam.wang@arm.com func_exe_inst = oldContext->func_exe_inst; 1038922Swilliam.wang@arm.com 1048922Swilliam.wang@arm.com storeCondFailures = 0; 1058922Swilliam.wang@arm.com 1068922Swilliam.wang@arm.com oldContext->_status = ExecContext::Unallocated; 1078922Swilliam.wang@arm.com} 1088922Swilliam.wang@arm.com 1098922Swilliam.wang@arm.com#if FULL_SYSTEM 1108922Swilliam.wang@arm.comvoid 1118922Swilliam.wang@arm.comExecContext::execute(const StaticInstBase *inst) 1128922Swilliam.wang@arm.com{ 1138922Swilliam.wang@arm.com assert(kernelStats); 1148922Swilliam.wang@arm.com system->kernelBinning->execute(this, inst); 1157039Snate@binkert.org} 1166876Ssteve.reinhardt@amd.com#endif 1176882SBrad.Beckmann@amd.com 1187039Snate@binkert.orgvoid 1196882SBrad.Beckmann@amd.comExecContext::serialize(ostream &os) 1208922Swilliam.wang@arm.com{ 1218922Swilliam.wang@arm.com SERIALIZE_ENUM(_status); 1226882SBrad.Beckmann@amd.com regs.serialize(os); 1238922Swilliam.wang@arm.com // thread_num and cpu_id are deterministic from the config 1246882SBrad.Beckmann@amd.com SERIALIZE_SCALAR(func_exe_inst); 1256882SBrad.Beckmann@amd.com SERIALIZE_SCALAR(inst); 1268436SBrad.Beckmann@amd.com 1278436SBrad.Beckmann@amd.com#if FULL_SYSTEM 1288922Swilliam.wang@arm.com kernelStats->serialize(os); 1298914Sandreas.hansson@arm.com#endif 1308914Sandreas.hansson@arm.com} 1316882SBrad.Beckmann@amd.com 1328922Swilliam.wang@arm.com 1336882SBrad.Beckmann@amd.comvoid 1346882SBrad.Beckmann@amd.comExecContext::unserialize(Checkpoint *cp, const std::string §ion) 1356882SBrad.Beckmann@amd.com{ 1366882SBrad.Beckmann@amd.com UNSERIALIZE_ENUM(_status); 1376882SBrad.Beckmann@amd.com regs.unserialize(cp, section); 1386882SBrad.Beckmann@amd.com // thread_num and cpu_id are deterministic from the config 1396882SBrad.Beckmann@amd.com UNSERIALIZE_SCALAR(func_exe_inst); 1406882SBrad.Beckmann@amd.com UNSERIALIZE_SCALAR(inst); 1416882SBrad.Beckmann@amd.com 1426882SBrad.Beckmann@amd.com#if FULL_SYSTEM 1436882SBrad.Beckmann@amd.com kernelStats->unserialize(cp, section); 1448975Sandreas.hansson@arm.com#endif 1456882SBrad.Beckmann@amd.com} 1467039Snate@binkert.org 1477039Snate@binkert.org 1488161SBrad.Beckmann@amd.comvoid 1496882SBrad.Beckmann@amd.comExecContext::activate(int delay) 1506882SBrad.Beckmann@amd.com{ 1517039Snate@binkert.org if (status() == Active) 1526882SBrad.Beckmann@amd.com return; 1536882SBrad.Beckmann@amd.com 1546882SBrad.Beckmann@amd.com _status = Active; 1557039Snate@binkert.org cpu->activateContext(thread_num, delay); 1566882SBrad.Beckmann@amd.com} 1576882SBrad.Beckmann@amd.com 1586882SBrad.Beckmann@amd.comvoid 1597039Snate@binkert.orgExecContext::suspend() 1608975Sandreas.hansson@arm.com{ 1617039Snate@binkert.org if (status() == Suspended) 1626882SBrad.Beckmann@amd.com return; 1636882SBrad.Beckmann@amd.com 1646882SBrad.Beckmann@amd.com#if FULL_SYSTEM 1656882SBrad.Beckmann@amd.com // Don't change the status from active if there are pending interrupts 1668975Sandreas.hansson@arm.com if (cpu->check_interrupts()) { 1676882SBrad.Beckmann@amd.com assert(status() == Active); 1688161SBrad.Beckmann@amd.com return; 1697039Snate@binkert.org } 1706882SBrad.Beckmann@amd.com#endif 1718975Sandreas.hansson@arm.com 1726882SBrad.Beckmann@amd.com _status = Suspended; 1737039Snate@binkert.org cpu->suspendContext(thread_num); 1747039Snate@binkert.org} 1757039Snate@binkert.org 1766882SBrad.Beckmann@amd.comvoid 1776882SBrad.Beckmann@amd.comExecContext::deallocate() 1786882SBrad.Beckmann@amd.com{ 1796882SBrad.Beckmann@amd.com if (status() == Unallocated) 1806882SBrad.Beckmann@amd.com return; 1816882SBrad.Beckmann@amd.com 1826882SBrad.Beckmann@amd.com _status = Unallocated; 1836882SBrad.Beckmann@amd.com cpu->deallocateContext(thread_num); 1846882SBrad.Beckmann@amd.com} 1856882SBrad.Beckmann@amd.com 1866922SBrad.Beckmann@amd.comvoid 1876922SBrad.Beckmann@amd.comExecContext::halt() 1886922SBrad.Beckmann@amd.com{ 1896922SBrad.Beckmann@amd.com if (status() == Halted) 1906882SBrad.Beckmann@amd.com return; 1916882SBrad.Beckmann@amd.com 1926882SBrad.Beckmann@amd.com _status = Halted; 1938851Sandreas.hansson@arm.com cpu->haltContext(thread_num); 1948161SBrad.Beckmann@amd.com} 1956922SBrad.Beckmann@amd.com 1966922SBrad.Beckmann@amd.com 1976882SBrad.Beckmann@amd.comvoid 1988874Sandreas.hansson@arm.comExecContext::regStats(const string &name) 1996882SBrad.Beckmann@amd.com{ 2006882SBrad.Beckmann@amd.com#if FULL_SYSTEM 2018615Snilay@cs.wisc.edu kernelStats->regStats(name + ".kern"); 2028615Snilay@cs.wisc.edu#endif 2037906SBrad.Beckmann@amd.com} 2046882SBrad.Beckmann@amd.com 2058615Snilay@cs.wisc.eduvoid 2067023SBrad.Beckmann@amd.comExecContext::trap(Fault fault) 2077550SBrad.Beckmann@amd.com{ 2087023SBrad.Beckmann@amd.com //TheISA::trap(fault); //One possible way to do it... 2097023SBrad.Beckmann@amd.com 2107550SBrad.Beckmann@amd.com /** @todo: Going to hack it for now. Do a true fixup later. */ 2118161SBrad.Beckmann@amd.com#if FULL_SYSTEM 2126922SBrad.Beckmann@amd.com ev5_trap(fault); 2136882SBrad.Beckmann@amd.com#else 2147023SBrad.Beckmann@amd.com fatal("fault (%d) detected @ PC 0x%08p", fault, readPC()); 2157910SBrad.Beckmann@amd.com#endif 2167910SBrad.Beckmann@amd.com} 2177910SBrad.Beckmann@amd.com