X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcpu%2Fexec_context.hh;h=951c9c2b3e14d0c6f0ccda935d3c6cfd9d865348;hb=8faeec44a69ee56ca9252cd36a2bb8e22d02bddd;hp=5b601bb30a8919ae2cfe26f66c45edd1fa3934ad;hpb=4a5b51b516853c9fcaabc44caacdd7e8e93dc0ef;p=gem5.git diff --git a/src/cpu/exec_context.hh b/src/cpu/exec_context.hh index 5b601bb30..951c9c2b3 100644 --- a/src/cpu/exec_context.hh +++ b/src/cpu/exec_context.hh @@ -1,5 +1,18 @@ /* - * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2014 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2015 Advanced Micro Devices, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,394 +37,261 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Kevin Lim + * Andreas Sandberg */ #ifndef __CPU_EXEC_CONTEXT_HH__ #define __CPU_EXEC_CONTEXT_HH__ -#include "config/full_system.hh" -#include "mem/request.hh" -#include "sim/faults.hh" -#include "sim/host.hh" -#include "sim/serialize.hh" -#include "sim/byteswap.hh" - -// @todo: Figure out a more architecture independent way to obtain the ITB and -// DTB pointers. -class AlphaDTB; -class AlphaITB; -class BaseCPU; -class EndQuiesceEvent; -class Event; -class TranslatingPort; -class FunctionalPort; -class VirtualPort; -class Process; -class System; -namespace Kernel { - class Statistics; -}; +#include "arch/registers.hh" +#include "base/types.hh" +#include "config/the_isa.hh" +#include "cpu/base.hh" +#include "cpu/static_inst_fwd.hh" +#include "cpu/translation.hh" -class ExecContext -{ - protected: - typedef TheISA::RegFile RegFile; - typedef TheISA::MachInst MachInst; +/** + * The ExecContext is an abstract base class the provides the + * interface used by the ISA to manipulate the state of the CPU model. + * + * Register accessor methods in this class typically provide the index + * of the instruction's operand (e.g., 0 or 1), not the architectural + * register index, to simplify the implementation of register + * renaming. The architectural register index can be found by + * indexing into the instruction's own operand index table. + * + * @note The methods in this class typically take a raw pointer to the + * StaticInst is provided instead of a ref-counted StaticInstPtr to + * reduce overhead as an argument. This is fine as long as the + * implementation doesn't copy the pointer into any long-term storage + * (which is pretty hard to imagine they would have reason to do). + */ +class ExecContext { + public: typedef TheISA::IntReg IntReg; + typedef TheISA::PCState PCState; typedef TheISA::FloatReg FloatReg; typedef TheISA::FloatRegBits FloatRegBits; - typedef TheISA::MiscRegFile MiscRegFile; typedef TheISA::MiscReg MiscReg; - public: - 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 - }; - - virtual ~ExecContext() { }; - - virtual BaseCPU *getCpuPtr() = 0; - - virtual void setCpuId(int id) = 0; - - virtual int readCpuId() = 0; - -#if FULL_SYSTEM - virtual System *getSystemPtr() = 0; - - virtual AlphaITB *getITBPtr() = 0; - - virtual AlphaDTB * getDTBPtr() = 0; - - virtual Kernel::Statistics *getKernelStats() = 0; - - virtual FunctionalPort *getPhysPort() = 0; - - virtual VirtualPort *getVirtPort(ExecContext *xc = NULL) = 0; - - virtual void delVirtPort(VirtualPort *vp) = 0; -#else - virtual TranslatingPort *getMemPort() = 0; - - virtual Process *getProcessPtr() = 0; -#endif - - virtual Status status() const = 0; - - virtual void setStatus(Status new_status) = 0; - - /// Set the status to Active. Optional delay indicates number of - /// cycles to wait before beginning execution. - virtual void activate(int delay = 1) = 0; - - /// Set the status to Suspended. - virtual void suspend() = 0; - - /// Set the status to Unallocated. - virtual void deallocate() = 0; - - /// Set the status to Halted. - virtual void halt() = 0; - -#if FULL_SYSTEM - virtual void dumpFuncProfile() = 0; -#endif - - virtual void takeOverFrom(ExecContext *old_context) = 0; - - virtual void regStats(const std::string &name) = 0; - - virtual void serialize(std::ostream &os) = 0; - virtual void unserialize(Checkpoint *cp, const std::string §ion) = 0; - -#if FULL_SYSTEM - virtual EndQuiesceEvent *getQuiesceEvent() = 0; - - // Not necessarily the best location for these... - // Having an extra function just to read these is obnoxious - virtual Tick readLastActivate() = 0; - virtual Tick readLastSuspend() = 0; - - virtual void profileClear() = 0; - virtual void profileSample() = 0; -#endif - - virtual int getThreadNum() = 0; - - // Also somewhat obnoxious. Really only used for the TLB fault. - // However, may be quite useful in SPARC. - virtual TheISA::MachInst getInst() = 0; - - virtual void copyArchRegs(ExecContext *xc) = 0; - - virtual void clearArchRegs() = 0; - - // - // New accessors for new decoder. - // - virtual uint64_t readIntReg(int reg_idx) = 0; - - virtual FloatReg readFloatReg(int reg_idx, int width) = 0; - - virtual FloatReg readFloatReg(int reg_idx) = 0; - - virtual FloatRegBits readFloatRegBits(int reg_idx, int width) = 0; - - virtual FloatRegBits readFloatRegBits(int reg_idx) = 0; - - virtual void setIntReg(int reg_idx, uint64_t val) = 0; - - virtual void setFloatReg(int reg_idx, FloatReg val, int width) = 0; - - virtual void setFloatReg(int reg_idx, FloatReg val) = 0; - - virtual void setFloatRegBits(int reg_idx, FloatRegBits val) = 0; - - virtual void setFloatRegBits(int reg_idx, FloatRegBits val, int width) = 0; - - virtual uint64_t readPC() = 0; - - virtual void setPC(uint64_t val) = 0; - - virtual uint64_t readNextPC() = 0; - - virtual void setNextPC(uint64_t val) = 0; - - virtual uint64_t readNextNPC() = 0; - - virtual void setNextNPC(uint64_t val) = 0; - - virtual MiscReg readMiscReg(int misc_reg) = 0; - - virtual MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) = 0; - - virtual Fault setMiscReg(int misc_reg, const MiscReg &val) = 0; - - virtual Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) = 0; - - // Also not necessarily the best location for these two. Hopefully will go - // away once we decide upon where st cond failures goes. - virtual unsigned readStCondFailures() = 0; - - virtual void setStCondFailures(unsigned sc_failures) = 0; - -#if FULL_SYSTEM - virtual bool inPalMode() = 0; -#endif - - // Only really makes sense for old CPU model. Still could be useful though. - virtual bool misspeculating() = 0; - -#if !FULL_SYSTEM - virtual IntReg getSyscallArg(int i) = 0; - - // used to shift args for indirect syscall - virtual void setSyscallArg(int i, IntReg val) = 0; - virtual void setSyscallReturn(SyscallReturn return_value) = 0; + typedef TheISA::CCReg CCReg; - - // Same with st cond failures. - virtual Counter readFuncExeInst() = 0; -#endif - - virtual void changeRegFileContext(RegFile::ContextParam param, - RegFile::ContextVal val) = 0; -}; - -template -class ProxyExecContext : public ExecContext -{ public: - ProxyExecContext(XC *actual_xc) - { actualXC = actual_xc; } - - private: - XC *actualXC; - - public: - - BaseCPU *getCpuPtr() { return actualXC->getCpuPtr(); } - - void setCpuId(int id) { actualXC->setCpuId(id); } - - int readCpuId() { return actualXC->readCpuId(); } - -#if FULL_SYSTEM - System *getSystemPtr() { return actualXC->getSystemPtr(); } - - AlphaITB *getITBPtr() { return actualXC->getITBPtr(); } - - AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); } - - Kernel::Statistics *getKernelStats() { return actualXC->getKernelStats(); } - - FunctionalPort *getPhysPort() { return actualXC->getPhysPort(); } - - VirtualPort *getVirtPort(ExecContext *xc = NULL) { return actualXC->getVirtPort(xc); } - - void delVirtPort(VirtualPort *vp) { return actualXC->delVirtPort(vp); } -#else - TranslatingPort *getMemPort() { return actualXC->getMemPort(); } - - Process *getProcessPtr() { return actualXC->getProcessPtr(); } -#endif - - Status status() const { return actualXC->status(); } - - void setStatus(Status new_status) { actualXC->setStatus(new_status); } - - /// Set the status to Active. Optional delay indicates number of - /// cycles to wait before beginning execution. - void activate(int delay = 1) { actualXC->activate(delay); } - - /// Set the status to Suspended. - void suspend() { actualXC->suspend(); } - - /// Set the status to Unallocated. - void deallocate() { actualXC->deallocate(); } - - /// Set the status to Halted. - void halt() { actualXC->halt(); } - -#if FULL_SYSTEM - void dumpFuncProfile() { actualXC->dumpFuncProfile(); } -#endif - - void takeOverFrom(ExecContext *oldContext) - { actualXC->takeOverFrom(oldContext); } - - void regStats(const std::string &name) { actualXC->regStats(name); } - - void serialize(std::ostream &os) { actualXC->serialize(os); } - void unserialize(Checkpoint *cp, const std::string §ion) - { actualXC->unserialize(cp, section); } - -#if FULL_SYSTEM - EndQuiesceEvent *getQuiesceEvent() { return actualXC->getQuiesceEvent(); } - - Tick readLastActivate() { return actualXC->readLastActivate(); } - Tick readLastSuspend() { return actualXC->readLastSuspend(); } - - void profileClear() { return actualXC->profileClear(); } - void profileSample() { return actualXC->profileSample(); } -#endif - - int getThreadNum() { return actualXC->getThreadNum(); } - - // @todo: Do I need this? - MachInst getInst() { return actualXC->getInst(); } - - // @todo: Do I need this? - void copyArchRegs(ExecContext *xc) { actualXC->copyArchRegs(xc); } - - void clearArchRegs() { actualXC->clearArchRegs(); } - - // - // New accessors for new decoder. - // - uint64_t readIntReg(int reg_idx) - { return actualXC->readIntReg(reg_idx); } - - FloatReg readFloatReg(int reg_idx, int width) - { return actualXC->readFloatReg(reg_idx, width); } - - FloatReg readFloatReg(int reg_idx) - { return actualXC->readFloatReg(reg_idx); } - - FloatRegBits readFloatRegBits(int reg_idx, int width) - { return actualXC->readFloatRegBits(reg_idx, width); } - - FloatRegBits readFloatRegBits(int reg_idx) - { return actualXC->readFloatRegBits(reg_idx); } - - void setIntReg(int reg_idx, uint64_t val) - { actualXC->setIntReg(reg_idx, val); } - - void setFloatReg(int reg_idx, FloatReg val, int width) - { actualXC->setFloatReg(reg_idx, val, width); } - - void setFloatReg(int reg_idx, FloatReg val) - { actualXC->setFloatReg(reg_idx, val); } - - void setFloatRegBits(int reg_idx, FloatRegBits val, int width) - { actualXC->setFloatRegBits(reg_idx, val, width); } - - void setFloatRegBits(int reg_idx, FloatRegBits val) - { actualXC->setFloatRegBits(reg_idx, val); } - - uint64_t readPC() { return actualXC->readPC(); } - - void setPC(uint64_t val) { actualXC->setPC(val); } - - uint64_t readNextPC() { return actualXC->readNextPC(); } - - void setNextPC(uint64_t val) { actualXC->setNextPC(val); } - - uint64_t readNextNPC() { return actualXC->readNextNPC(); } - - void setNextNPC(uint64_t val) { actualXC->setNextNPC(val); } - - MiscReg readMiscReg(int misc_reg) - { return actualXC->readMiscReg(misc_reg); } - - MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) - { return actualXC->readMiscRegWithEffect(misc_reg, fault); } - - Fault setMiscReg(int misc_reg, const MiscReg &val) - { return actualXC->setMiscReg(misc_reg, val); } - - Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) - { return actualXC->setMiscRegWithEffect(misc_reg, val); } - - unsigned readStCondFailures() - { return actualXC->readStCondFailures(); } - - void setStCondFailures(unsigned sc_failures) - { actualXC->setStCondFailures(sc_failures); } -#if FULL_SYSTEM - bool inPalMode() { return actualXC->inPalMode(); } -#endif - - // @todo: Fix this! - bool misspeculating() { return actualXC->misspeculating(); } - -#if !FULL_SYSTEM - IntReg getSyscallArg(int i) { return actualXC->getSyscallArg(i); } - - // used to shift args for indirect syscall - void setSyscallArg(int i, IntReg val) - { actualXC->setSyscallArg(i, val); } + /** + * @{ + * @name Integer Register Interfaces + * + */ + + /** Reads an integer register. */ + virtual IntReg readIntRegOperand(const StaticInst *si, int idx) = 0; + + /** Sets an integer register to a value. */ + virtual void setIntRegOperand(const StaticInst *si, + int idx, IntReg val) = 0; + + /** @} */ + + + /** + * @{ + * @name Floating Point Register Interfaces + */ + + /** Reads a floating point register of single register width. */ + virtual FloatReg readFloatRegOperand(const StaticInst *si, int idx) = 0; + + /** Reads a floating point register in its binary format, instead + * of by value. */ + virtual FloatRegBits readFloatRegOperandBits(const StaticInst *si, + int idx) = 0; + + /** Sets a floating point register of single width to a value. */ + virtual void setFloatRegOperand(const StaticInst *si, + int idx, FloatReg val) = 0; + + /** Sets the bits of a floating point register of single width + * to a binary value. */ + virtual void setFloatRegOperandBits(const StaticInst *si, + int idx, FloatRegBits val) = 0; + + /** @} */ + + /** + * @{ + * @name Condition Code Registers + */ + virtual CCReg readCCRegOperand(const StaticInst *si, int idx) = 0; + virtual void setCCRegOperand(const StaticInst *si, int idx, CCReg val) = 0; + /** @} */ + + /** + * @{ + * @name Misc Register Interfaces + */ + virtual MiscReg readMiscRegOperand(const StaticInst *si, int idx) = 0; + virtual void setMiscRegOperand(const StaticInst *si, + int idx, const MiscReg &val) = 0; + + /** + * Reads a miscellaneous register, handling any architectural + * side effects due to reading that register. + */ + virtual MiscReg readMiscReg(int misc_reg) = 0; - void setSyscallReturn(SyscallReturn return_value) - { actualXC->setSyscallReturn(return_value); } + /** + * Sets a miscellaneous register, handling any architectural + * side effects due to writing that register. + */ + virtual void setMiscReg(int misc_reg, const MiscReg &val) = 0; + + /** @} */ + + /** + * @{ + * @name PC Control + */ + virtual PCState pcState() const = 0; + virtual void pcState(const PCState &val) = 0; + /** @} */ + + /** + * @{ + * @name Memory Interface + */ + /** + * Record the effective address of the instruction. + * + * @note Only valid for memory ops. + */ + virtual void setEA(Addr EA) = 0; + /** + * Get the effective address of the instruction. + * + * @note Only valid for memory ops. + */ + virtual Addr getEA() const = 0; + + /** + * Perform an atomic memory read operation. Must be overridden + * for exec contexts that support atomic memory mode. Not pure + * virtual since exec contexts that only support timing memory + * mode need not override (though in that case this function + * should never be called). + */ + virtual Fault readMem(Addr addr, uint8_t *data, unsigned int size, + unsigned int flags) + { + panic("ExecContext::readMem() should be overridden\n"); + } + /** + * Initiate a timing memory read operation. Must be overridden + * for exec contexts that support timing memory mode. Not pure + * virtual since exec contexts that only support atomic memory + * mode need not override (though in that case this function + * should never be called). + */ + virtual Fault initiateMemRead(Addr addr, unsigned int size, + unsigned int flags) + { + panic("ExecContext::initiateMemRead() should be overridden\n"); + } - Counter readFuncExeInst() { return actualXC->readFuncExeInst(); } + /** + * For atomic-mode contexts, perform an atomic memory write operation. + * For timing-mode contexts, initiate a timing memory write operation. + */ + virtual Fault writeMem(uint8_t *data, unsigned int size, Addr addr, + unsigned int flags, uint64_t *res) = 0; + + /** + * Sets the number of consecutive store conditional failures. + */ + virtual void setStCondFailures(unsigned int sc_failures) = 0; + + /** + * Returns the number of consecutive store conditional failures. + */ + virtual unsigned int readStCondFailures() const = 0; + + /** @} */ + + /** + * @{ + * @name SysCall Emulation Interfaces + */ + + /** + * Executes a syscall specified by the callnum. + */ + virtual void syscall(int64_t callnum) = 0; + + /** @} */ + + /** Returns a pointer to the ThreadContext. */ + virtual ThreadContext *tcBase() = 0; + + /** + * @{ + * @name Alpha-Specific Interfaces + */ + + /** + * Somewhat Alpha-specific function that handles returning from an + * error or interrupt. + */ + virtual Fault hwrei() = 0; + + /** + * Check for special simulator handling of specific PAL calls. If + * return value is false, actual PAL call will be suppressed. + */ + virtual bool simPalCheck(int palFunc) = 0; + + /** @} */ + + /** + * @{ + * @name ARM-Specific Interfaces + */ + + virtual bool readPredicate() = 0; + virtual void setPredicate(bool val) = 0; + + /** @} */ + + /** + * @{ + * @name X86-Specific Interfaces + */ + + /** + * Invalidate a page in the DTLB and ITLB. + */ + virtual void demapPage(Addr vaddr, uint64_t asn) = 0; + virtual void armMonitor(Addr address) = 0; + virtual bool mwait(PacketPtr pkt) = 0; + virtual void mwaitAtomic(ThreadContext *tc) = 0; + virtual AddressMonitor *getAddrMonitor() = 0; + + /** @} */ + + /** + * @{ + * @name MIPS-Specific Interfaces + */ + +#if THE_ISA == MIPS_ISA + virtual MiscReg readRegOtherThread(int regIdx, + ThreadID tid = InvalidThreadID) = 0; + virtual void setRegOtherThread(int regIdx, MiscReg val, + ThreadID tid = InvalidThreadID) = 0; #endif - void changeRegFileContext(RegFile::ContextParam param, - RegFile::ContextVal val) - { - actualXC->changeRegFileContext(param, val); - } + /** @} */ }; -#endif +#endif // __CPU_EXEC_CONTEXT_HH__