simple_thread.cc revision 1070
19646SChris.Emmons@arm.com/* 210839Sandreas.sandberg@arm.com * Copyright (c) 2001-2004 The Regents of The University of Michigan 39646SChris.Emmons@arm.com * All rights reserved. 49646SChris.Emmons@arm.com * 59646SChris.Emmons@arm.com * Redistribution and use in source and binary forms, with or without 69646SChris.Emmons@arm.com * modification, are permitted provided that the following conditions are 79646SChris.Emmons@arm.com * met: redistributions of source code must retain the above copyright 89646SChris.Emmons@arm.com * notice, this list of conditions and the following disclaimer; 99646SChris.Emmons@arm.com * redistributions in binary form must reproduce the above copyright 109646SChris.Emmons@arm.com * notice, this list of conditions and the following disclaimer in the 119646SChris.Emmons@arm.com * documentation and/or other materials provided with the distribution; 129646SChris.Emmons@arm.com * neither the name of the copyright holders nor the names of its 139646SChris.Emmons@arm.com * contributors may be used to endorse or promote products derived from 149646SChris.Emmons@arm.com * this software without specific prior written permission. 159646SChris.Emmons@arm.com * 169646SChris.Emmons@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179646SChris.Emmons@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189646SChris.Emmons@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 199646SChris.Emmons@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 209646SChris.Emmons@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 219646SChris.Emmons@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 229646SChris.Emmons@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239646SChris.Emmons@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249646SChris.Emmons@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259646SChris.Emmons@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 269646SChris.Emmons@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279646SChris.Emmons@arm.com */ 289646SChris.Emmons@arm.com 299646SChris.Emmons@arm.com#include <string> 309646SChris.Emmons@arm.com 319646SChris.Emmons@arm.com#include "cpu/base_cpu.hh" 329646SChris.Emmons@arm.com#include "cpu/exec_context.hh" 339646SChris.Emmons@arm.com 349646SChris.Emmons@arm.com#ifdef FULL_SYSTEM 359646SChris.Emmons@arm.com#include "base/cprintf.hh" 369646SChris.Emmons@arm.com#include "kern/kernel_stats.hh" 379646SChris.Emmons@arm.com#include "sim/serialize.hh" 3811090Sandreas.sandberg@arm.com#include "sim/system.hh" 399646SChris.Emmons@arm.com#else 409646SChris.Emmons@arm.com#include "sim/process.hh" 4110839Sandreas.sandberg@arm.com#endif 4210839Sandreas.sandberg@arm.com 439646SChris.Emmons@arm.comusing namespace std; 449646SChris.Emmons@arm.com 459646SChris.Emmons@arm.com// constructor 4611090Sandreas.sandberg@arm.com#ifdef FULL_SYSTEM 479646SChris.Emmons@arm.comExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, 489646SChris.Emmons@arm.com AlphaITB *_itb, AlphaDTB *_dtb, 499646SChris.Emmons@arm.com FunctionalMemory *_mem) 509646SChris.Emmons@arm.com : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num), 519646SChris.Emmons@arm.com cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys), 5211090Sandreas.sandberg@arm.com memctrl(_sys->memctrl), physmem(_sys->physmem), 539646SChris.Emmons@arm.com kernelBinning(system->kernelBinning), bin(kernelBinning->bin), 549646SChris.Emmons@arm.com fnbin(kernelBinning->fnbin), func_exe_inst(0), storeCondFailures(0) 559646SChris.Emmons@arm.com{ 569646SChris.Emmons@arm.com kernelStats = new Kernel::Statistics(this); 579646SChris.Emmons@arm.com memset(®s, 0, sizeof(RegFile)); 589646SChris.Emmons@arm.com} 5911090Sandreas.sandberg@arm.com#else 6011090Sandreas.sandberg@arm.comExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, 6111090Sandreas.sandberg@arm.com Process *_process, int _asid) 6211090Sandreas.sandberg@arm.com : _status(ExecContext::Unallocated), 6311090Sandreas.sandberg@arm.com cpu(_cpu), thread_num(_thread_num), cpu_id(-1), 6411090Sandreas.sandberg@arm.com process(_process), mem(process->getMemory()), asid(_asid), 6511090Sandreas.sandberg@arm.com func_exe_inst(0), storeCondFailures(0) 6611090Sandreas.sandberg@arm.com{ 6711090Sandreas.sandberg@arm.com memset(®s, 0, sizeof(RegFile)); 6811090Sandreas.sandberg@arm.com} 6911090Sandreas.sandberg@arm.com 7011090Sandreas.sandberg@arm.comExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, 7111090Sandreas.sandberg@arm.com FunctionalMemory *_mem, int _asid) 7211090Sandreas.sandberg@arm.com : cpu(_cpu), thread_num(_thread_num), process(0), mem(_mem), asid(_asid), 739646SChris.Emmons@arm.com func_exe_inst(0), storeCondFailures(0) 749646SChris.Emmons@arm.com{ 7511090Sandreas.sandberg@arm.com memset(®s, 0, sizeof(RegFile)); 769646SChris.Emmons@arm.com} 779646SChris.Emmons@arm.com#endif 7811090Sandreas.sandberg@arm.com 7911090Sandreas.sandberg@arm.comExecContext::~ExecContext() 8011090Sandreas.sandberg@arm.com{ 8111090Sandreas.sandberg@arm.com#ifdef FULL_SYSTEM 8211090Sandreas.sandberg@arm.com delete kernelStats; 839646SChris.Emmons@arm.com#endif 8411090Sandreas.sandberg@arm.com} 8511090Sandreas.sandberg@arm.com 8611090Sandreas.sandberg@arm.com 8711090Sandreas.sandberg@arm.comvoid 889646SChris.Emmons@arm.comExecContext::takeOverFrom(ExecContext *oldContext) 899646SChris.Emmons@arm.com{ 9011090Sandreas.sandberg@arm.com // some things should already be set up 919646SChris.Emmons@arm.com assert(mem == oldContext->mem); 929646SChris.Emmons@arm.com#ifdef FULL_SYSTEM 939646SChris.Emmons@arm.com assert(system == oldContext->system); 949646SChris.Emmons@arm.com#else 959646SChris.Emmons@arm.com assert(process == oldContext->process); 969646SChris.Emmons@arm.com#endif 9711090Sandreas.sandberg@arm.com 9811091Sandreas.sandberg@arm.com // copy over functional state 9911091Sandreas.sandberg@arm.com _status = oldContext->_status; 10011091Sandreas.sandberg@arm.com regs = oldContext->regs; 10111091Sandreas.sandberg@arm.com cpu_id = oldContext->cpu_id; 10211091Sandreas.sandberg@arm.com func_exe_inst = oldContext->func_exe_inst; 10311091Sandreas.sandberg@arm.com 10411091Sandreas.sandberg@arm.com storeCondFailures = 0; 10511091Sandreas.sandberg@arm.com 10611091Sandreas.sandberg@arm.com oldContext->_status = ExecContext::Unallocated; 10711091Sandreas.sandberg@arm.com} 10811091Sandreas.sandberg@arm.com 10911091Sandreas.sandberg@arm.com#ifdef FULL_SYSTEM 11011090Sandreas.sandberg@arm.comvoid 11111090Sandreas.sandberg@arm.comExecContext::execute(const StaticInstBase *inst) 11211090Sandreas.sandberg@arm.com{ 11311090Sandreas.sandberg@arm.com assert(kernelStats); 11411090Sandreas.sandberg@arm.com system->kernelBinning->execute(this, inst); 11511090Sandreas.sandberg@arm.com} 11611090Sandreas.sandberg@arm.com#endif 11711090Sandreas.sandberg@arm.com 11811090Sandreas.sandberg@arm.comvoid 11911090Sandreas.sandberg@arm.comExecContext::serialize(ostream &os) 12011090Sandreas.sandberg@arm.com{ 12111090Sandreas.sandberg@arm.com SERIALIZE_ENUM(_status); 12211090Sandreas.sandberg@arm.com regs.serialize(os); 12311090Sandreas.sandberg@arm.com // thread_num and cpu_id are deterministic from the config 12411090Sandreas.sandberg@arm.com SERIALIZE_SCALAR(func_exe_inst); 12511090Sandreas.sandberg@arm.com SERIALIZE_SCALAR(inst); 12611090Sandreas.sandberg@arm.com 12711090Sandreas.sandberg@arm.com#ifdef FULL_SYSTEM 12811090Sandreas.sandberg@arm.com kernelStats->serialize(os); 12911090Sandreas.sandberg@arm.com#endif 13011090Sandreas.sandberg@arm.com} 13111090Sandreas.sandberg@arm.com 13211090Sandreas.sandberg@arm.com 13311090Sandreas.sandberg@arm.comvoid 13411090Sandreas.sandberg@arm.comExecContext::unserialize(Checkpoint *cp, const std::string §ion) 13511090Sandreas.sandberg@arm.com{ 13611090Sandreas.sandberg@arm.com UNSERIALIZE_ENUM(_status); 13711090Sandreas.sandberg@arm.com regs.unserialize(cp, section); 13811090Sandreas.sandberg@arm.com // thread_num and cpu_id are deterministic from the config 13911090Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(func_exe_inst); 14011090Sandreas.sandberg@arm.com UNSERIALIZE_SCALAR(inst); 14111090Sandreas.sandberg@arm.com 14211090Sandreas.sandberg@arm.com#ifdef FULL_SYSTEM 14311090Sandreas.sandberg@arm.com kernelStats->unserialize(cp, section); 14411090Sandreas.sandberg@arm.com#endif 14511090Sandreas.sandberg@arm.com} 14611090Sandreas.sandberg@arm.com 14711090Sandreas.sandberg@arm.com 14811090Sandreas.sandberg@arm.comvoid 14911090Sandreas.sandberg@arm.comExecContext::activate(int delay) 15011090Sandreas.sandberg@arm.com{ 15111090Sandreas.sandberg@arm.com if (status() == Active) 15211090Sandreas.sandberg@arm.com return; 15311090Sandreas.sandberg@arm.com 15411090Sandreas.sandberg@arm.com _status = Active; 15511090Sandreas.sandberg@arm.com cpu->activateContext(thread_num, delay); 15611090Sandreas.sandberg@arm.com} 15711090Sandreas.sandberg@arm.com 15811090Sandreas.sandberg@arm.comvoid 15911090Sandreas.sandberg@arm.comExecContext::suspend() 16011090Sandreas.sandberg@arm.com{ 16111090Sandreas.sandberg@arm.com if (status() == Suspended) 16211090Sandreas.sandberg@arm.com return; 16311090Sandreas.sandberg@arm.com 16411090Sandreas.sandberg@arm.com#ifdef FULL_SYSTEM 16511090Sandreas.sandberg@arm.com // Don't change the status from active if there are pending interrupts 16611090Sandreas.sandberg@arm.com if (cpu->check_interrupts()) { 16711090Sandreas.sandberg@arm.com assert(status() == Active); 16811090Sandreas.sandberg@arm.com return; 16911090Sandreas.sandberg@arm.com } 17011090Sandreas.sandberg@arm.com#endif 17111090Sandreas.sandberg@arm.com 17211090Sandreas.sandberg@arm.com _status = Suspended; 17311090Sandreas.sandberg@arm.com cpu->suspendContext(thread_num); 17411090Sandreas.sandberg@arm.com} 17511090Sandreas.sandberg@arm.com 17611090Sandreas.sandberg@arm.comvoid 17711090Sandreas.sandberg@arm.comExecContext::deallocate() 17811090Sandreas.sandberg@arm.com{ 17911090Sandreas.sandberg@arm.com if (status() == Unallocated) 18011090Sandreas.sandberg@arm.com return; 18111090Sandreas.sandberg@arm.com 18211090Sandreas.sandberg@arm.com _status = Unallocated; 18311090Sandreas.sandberg@arm.com cpu->deallocateContext(thread_num); 18411090Sandreas.sandberg@arm.com} 18511090Sandreas.sandberg@arm.com 18611090Sandreas.sandberg@arm.comvoid 18711090Sandreas.sandberg@arm.comExecContext::halt() 18811090Sandreas.sandberg@arm.com{ 18911090Sandreas.sandberg@arm.com if (status() == Halted) 19011090Sandreas.sandberg@arm.com return; 19111090Sandreas.sandberg@arm.com 19211090Sandreas.sandberg@arm.com _status = Halted; 19311090Sandreas.sandberg@arm.com cpu->haltContext(thread_num); 19411090Sandreas.sandberg@arm.com} 19511090Sandreas.sandberg@arm.com 19611090Sandreas.sandberg@arm.com 19711090Sandreas.sandberg@arm.comvoid 19811090Sandreas.sandberg@arm.comExecContext::regStats(const string &name) 19911090Sandreas.sandberg@arm.com{ 20011090Sandreas.sandberg@arm.com#ifdef FULL_SYSTEM 20111090Sandreas.sandberg@arm.com kernelStats->regStats(name + ".kern"); 20211090Sandreas.sandberg@arm.com#endif 20311090Sandreas.sandberg@arm.com} 20411090Sandreas.sandberg@arm.com 20511090Sandreas.sandberg@arm.comvoid 20611090Sandreas.sandberg@arm.comExecContext::trap(Fault fault) 20711090Sandreas.sandberg@arm.com{ 20811090Sandreas.sandberg@arm.com //TheISA::trap(fault); //One possible way to do it... 20911090Sandreas.sandberg@arm.com 21011090Sandreas.sandberg@arm.com /** @todo: Going to hack it for now. Do a true fixup later. */ 21111090Sandreas.sandberg@arm.com#ifdef FULL_SYSTEM 21211090Sandreas.sandberg@arm.com ev5_trap(fault); 2139646SChris.Emmons@arm.com#else 2149646SChris.Emmons@arm.com fatal("fault (%d) detected @ PC 0x%08p", fault, readPC()); 2159646SChris.Emmons@arm.com#endif 2169646SChris.Emmons@arm.com} 21711090Sandreas.sandberg@arm.com