X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=cpu%2Fexec_context.hh;h=6a17951f95bd693473bec2006cf58136026f452b;hb=5aa71721193c49016ffa69934b44ce38672e4eed;hp=ddfc53684e3aae2dc8e580abb96568422eb02adf;hpb=11eaf2f2ab5b01868c696830f015b014a5c57580;p=gem5.git diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index ddfc53684..6a17951f9 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2001-2005 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,28 +26,33 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __EXEC_CONTEXT_HH__ -#define __EXEC_CONTEXT_HH__ +#ifndef __CPU_EXEC_CONTEXT_HH__ +#define __CPU_EXEC_CONTEXT_HH__ +#include "config/full_system.hh" +#include "mem/functional/functional.hh" +#include "mem/mem_req.hh" #include "sim/host.hh" -#include "targetarch/mem_req.hh" +#include "sim/serialize.hh" +#include "targetarch/byte_swap.hh" // forward declaration: see functional_memory.hh class FunctionalMemory; class PhysicalMemory; class BaseCPU; -#ifdef FULL_SYSTEM +#if FULL_SYSTEM +#include "sim/system.hh" #include "targetarch/alpha_memory.hh" -class MemoryController; -#include "kern/tru64/kernel_stats.hh" -#include "sim/system.hh" +class MemoryController; +class StaticInstBase; +namespace Kernel { class Binning; class Statistics; } #else // !FULL_SYSTEM -#include "sim/prog.hh" +#include "sim/process.hh" #endif // FULL_SYSTEM @@ -60,19 +65,46 @@ class MemoryController; class ExecContext { public: - enum Status { Unallocated, Active, Suspended, Halted }; + enum Status + { + /// Initialized but not running yet. All CPUs start in + /// this state, but most transition to Active on cycle 1. + /// In MP or SMT systems, non-primary contexts will stay + /// in this state until a thread is assigned to them. + Unallocated, + + /// Running. Instructions should be executed only when + /// the context is in this state. + Active, + + /// Temporarily inactive. Entered while waiting for + /// synchronization, etc. + Suspended, + + /// Permanently shut down. Entered when target executes + /// m5exit pseudo-instruction. When all contexts enter + /// this state, the simulation will terminate. + Halted + }; private: Status _status; public: Status status() const { return _status; } - void setStatus(Status new_status); -#ifdef FULL_SYSTEM - public: - KernelStats kernelStats; -#endif + /// Set the status to Active. Optional delay indicates number of + /// cycles to wait before beginning execution. + void activate(int delay = 1); + + /// Set the status to Suspended. + void suspend(); + + /// Set the status to Unallocated. + void deallocate(); + + /// Set the status to Halted. + void halt(); public: RegFile regs; // correct-path register context @@ -80,23 +112,34 @@ class ExecContext // pointer to CPU associated with this context BaseCPU *cpu; + // Current instruction + MachInst inst; + // Index of hardware thread context on the CPU that this represents. int thread_num; -#ifdef FULL_SYSTEM + // ID of this context w.r.t. the System or Process object to which + // it belongs. For full-system mode, this is the system CPU ID. + int cpu_id; +#if FULL_SYSTEM FunctionalMemory *mem; - AlphaItb *itb; - AlphaDtb *dtb; - int cpu_id; + AlphaITB *itb; + AlphaDTB *dtb; System *system; // the following two fields are redundant, since we can always // look them up through the system pointer, but we'll leave them // here for now for convenience - MemoryController *memCtrl; + MemoryController *memctrl; PhysicalMemory *physmem; + Kernel::Binning *kernelBinning; + Kernel::Statistics *kernelStats; + bool bin; + bool fnbin; + void execute(const StaticInstBase *inst); + #else Process *process; @@ -109,12 +152,24 @@ class ExecContext #endif + /** + * Temporary storage to pass the source address from copy_load to + * copy_store. + * @todo Remove this temporary when we have a better way to do it. + */ + Addr copySrcAddr; + /** + * Temp storage for the physical source address of a copy. + * @todo Remove this temporary when we have a better way to do it. + */ + Addr copySrcPhysAddr; + /* * number of executed instructions, for matching with syscall trace * points in EIO files. */ - Counter func_exe_insn; + Counter func_exe_inst; // // Count failed store conditionals so we can warn of apparent @@ -122,41 +177,44 @@ class ExecContext unsigned storeCondFailures; // constructor: initialize context from given process structure -#ifdef FULL_SYSTEM +#if FULL_SYSTEM ExecContext(BaseCPU *_cpu, int _thread_num, System *_system, - AlphaItb *_itb, AlphaDtb *_dtb, FunctionalMemory *_dem, - int _cpu_id); + AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem); #else ExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid); ExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem, int _asid); #endif - virtual ~ExecContext() {} + virtual ~ExecContext(); + + virtual void takeOverFrom(ExecContext *oldContext); void regStats(const std::string &name); -#ifdef FULL_SYSTEM + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + +#if FULL_SYSTEM bool validInstAddr(Addr addr) { return true; } bool validDataAddr(Addr addr) { return true; } - int getInstAsid() { return ITB_ASN_ASN(regs.ipr[TheISA::IPR_ITB_ASN]); } - int getDataAsid() { return DTB_ASN_ASN(regs.ipr[TheISA::IPR_DTB_ASN]); } + int getInstAsid() { return regs.instAsid(); } + int getDataAsid() { return regs.dataAsid(); } - Fault translateInstReq(MemReqPtr req) + Fault translateInstReq(MemReqPtr &req) { return itb->translate(req); } - Fault translateDataReadReq(MemReqPtr req) + Fault translateDataReadReq(MemReqPtr &req) { return dtb->translate(req, false); } - Fault translateDataWriteReq(MemReqPtr req) + Fault translateDataWriteReq(MemReqPtr &req) { return dtb->translate(req, true); } - #else bool validInstAddr(Addr addr) { return process->validInstAddr(addr); } @@ -167,7 +225,7 @@ class ExecContext int getInstAsid() { return asid; } int getDataAsid() { return asid; } - Fault dummyTranslation(MemReqPtr req) + Fault dummyTranslation(MemReqPtr &req) { #if 0 assert((req->vaddr >> 48 & 0xffff) == 0); @@ -178,15 +236,15 @@ class ExecContext req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16; return No_Fault; } - Fault translateInstReq(MemReqPtr req) + Fault translateInstReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault translateDataReadReq(MemReqPtr req) + Fault translateDataReadReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault translateDataWriteReq(MemReqPtr req) + Fault translateDataWriteReq(MemReqPtr &req) { return dummyTranslation(req); } @@ -194,22 +252,26 @@ class ExecContext #endif template - Fault read(MemReqPtr req, T& data) + Fault read(MemReqPtr &req, T &data) { -#if defined(TARGET_ALPHA) && defined(FULL_SYSTEM) +#if FULL_SYSTEM && defined(TARGET_ALPHA) if (req->flags & LOCKED) { MiscRegFile *cregs = &req->xc->regs.miscRegs; cregs->lock_addr = req->paddr; cregs->lock_flag = true; } #endif - return mem->read(req, data); + + Fault error; + error = mem->read(req, data); + data = gtoh(data); + return error; } template - Fault write(MemReqPtr req, T& data) + Fault write(MemReqPtr &req, T &data) { -#if defined(TARGET_ALPHA) && defined(FULL_SYSTEM) +#if FULL_SYSTEM && defined(TARGET_ALPHA) MiscRegFile *cregs; @@ -218,7 +280,7 @@ class ExecContext cregs = &req->xc->regs.miscRegs; if (req->flags & UNCACHEABLE) { - // Don't update result register (see machine.def) + // Don't update result register (see stq_c in isa_desc) req->result = 2; req->xc->storeCondFailures = 0;//Needed? [RGD] } else { @@ -239,26 +301,37 @@ class ExecContext } } - // Need to clear any locked flags on other proccessors for this - // address - // Only do this for succsful Store Conditionals and all other - // stores (WH64?) - // Unsuccesful Store Conditionals would have returned above, - // and wouldn't fall through - for (int i = 0; i < system->xcvec.size(); i++){ - cregs = &system->xcvec[i]->regs.miscRegs; + // Need to clear any locked flags on other proccessors for + // this address. Only do this for succsful Store Conditionals + // and all other stores (WH64?). Unsuccessful Store + // Conditionals would have returned above, and wouldn't fall + // through. + for (int i = 0; i < system->execContexts.size(); i++){ + cregs = &system->execContexts[i]->regs.miscRegs; if ((cregs->lock_addr & ~0xf) == (req->paddr & ~0xf)) { cregs->lock_flag = false; } } #endif - return mem->write(req, data); + return mem->write(req, (T)htog(data)); } virtual bool misspeculating(); + MachInst getInst() { return inst; } + + void setInst(MachInst new_inst) + { + inst = new_inst; + } + + Fault instRead(MemReqPtr &req) + { + return mem->read(req, inst); + } + // // New accessors for new decoder. // @@ -332,15 +405,54 @@ class ExecContext regs.miscRegs.fpcr = val; } -#ifdef FULL_SYSTEM +#if FULL_SYSTEM uint64_t readIpr(int idx, Fault &fault); Fault setIpr(int idx, uint64_t val); + int readIntrFlag() { return regs.intrflag; } + void setIntrFlag(int val) { regs.intrflag = val; } Fault hwrei(); + bool inPalMode() { return AlphaISA::PcPAL(regs.pc); } void ev5_trap(Fault fault); bool simPalCheck(int palFunc); #endif -#ifndef FULL_SYSTEM + /** Meant to be more generic trap function to be + * called when an instruction faults. + * @param fault The fault generated by executing the instruction. + * @todo How to do this properly so it's dependent upon ISA only? + */ + + void trap(Fault fault); + +#if !FULL_SYSTEM + IntReg getSyscallArg(int i) + { + return regs.intRegFile[ArgumentReg0 + i]; + } + + // used to shift args for indirect syscall + void setSyscallArg(int i, IntReg val) + { + regs.intRegFile[ArgumentReg0 + i] = val; + } + + void setSyscallReturn(SyscallReturn return_value) + { + // check for error condition. Alpha syscall convention is to + // indicate success/failure in reg a3 (r19) and put the + // return value itself in the standard return value reg (v0). + const int RegA3 = 19; // only place this is used + if (return_value.successful()) { + // no error + regs.intRegFile[RegA3] = 0; + regs.intRegFile[ReturnValueReg] = return_value.value(); + } else { + // got an error, return details + regs.intRegFile[RegA3] = (IntReg) -1; + regs.intRegFile[ReturnValueReg] = -return_value.value(); + } + } + void syscall() { process->syscall(this); @@ -356,4 +468,4 @@ ExecContext::misspeculating() return false; } -#endif // __EXEC_CONTEXT_HH__ +#endif // __CPU_EXEC_CONTEXT_HH__