/* * Copyright (c) 2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer; * redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution; * neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 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. */ #ifndef __CPU_CHECKER_EXEC_CONTEXT_HH__ #define __CPU_CHECKER_EXEC_CONTEXT_HH__ #include "cpu/checker/cpu.hh" #include "cpu/cpu_exec_context.hh" #include "cpu/exec_context.hh" class EndQuiesceEvent; namespace Kernel { class Statistics; }; template class CheckerExecContext : public ExecContext { public: CheckerExecContext(XC *actual_xc, CheckerCPU *checker_cpu) : actualXC(actual_xc), checkerXC(checker_cpu->cpuXC), checkerCPU(checker_cpu) { } private: XC *actualXC; CPUExecContext *checkerXC; CheckerCPU *checkerCPU; public: BaseCPU *getCpuPtr() { return actualXC->getCpuPtr(); } void setCpuId(int id) { actualXC->setCpuId(id); checkerXC->setCpuId(id); } int readCpuId() { return actualXC->readCpuId(); } FunctionalMemory *getMemPtr() { return actualXC->getMemPtr(); } #if FULL_SYSTEM System *getSystemPtr() { return actualXC->getSystemPtr(); } PhysicalMemory *getPhysMemPtr() { return actualXC->getPhysMemPtr(); } AlphaITB *getITBPtr() { return actualXC->getITBPtr(); } AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); } Kernel::Statistics *getKernelStats() { return actualXC->getKernelStats(); } #else Process *getProcessPtr() { return actualXC->getProcessPtr(); } #endif Status status() const { return actualXC->status(); } void setStatus(Status new_status) { actualXC->setStatus(new_status); checkerXC->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); checkerXC->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); checkerXC->copyArchRegs(xc); } void clearArchRegs() { actualXC->clearArchRegs(); checkerXC->clearArchRegs(); } // // New accessors for new decoder. // uint64_t readIntReg(int reg_idx) { return actualXC->readIntReg(reg_idx); } float readFloatRegSingle(int reg_idx) { return actualXC->readFloatRegSingle(reg_idx); } double readFloatRegDouble(int reg_idx) { return actualXC->readFloatRegDouble(reg_idx); } uint64_t readFloatRegInt(int reg_idx) { return actualXC->readFloatRegInt(reg_idx); } void setIntReg(int reg_idx, uint64_t val) { actualXC->setIntReg(reg_idx, val); checkerXC->setIntReg(reg_idx, val); } void setFloatRegSingle(int reg_idx, float val) { actualXC->setFloatRegSingle(reg_idx, val); checkerXC->setFloatRegSingle(reg_idx, val); } void setFloatRegDouble(int reg_idx, double val) { actualXC->setFloatRegDouble(reg_idx, val); checkerXC->setFloatRegSingle(reg_idx, val); } void setFloatRegInt(int reg_idx, uint64_t val) { actualXC->setFloatRegInt(reg_idx, val); checkerXC->setFloatRegInt(reg_idx, val); } uint64_t readPC() { return actualXC->readPC(); } void setPC(uint64_t val) { actualXC->setPC(val); checkerXC->setPC(val); checkerCPU->recordPCChange(val); } uint64_t readNextPC() { return actualXC->readNextPC(); } void setNextPC(uint64_t val) { actualXC->setNextPC(val); checkerXC->setNextPC(val); checkerCPU->recordNextPCChange(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) { checkerXC->setMiscReg(misc_reg, val); return actualXC->setMiscReg(misc_reg, val); } Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) { checkerXC->setMiscRegWithEffect(misc_reg, val); return actualXC->setMiscRegWithEffect(misc_reg, val); } unsigned readStCondFailures() { return actualXC->readStCondFailures(); } void setStCondFailures(unsigned sc_failures) { checkerXC->setStCondFailures(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) { checkerXC->setSyscallArg(i, val); actualXC->setSyscallArg(i, val); } void setSyscallReturn(SyscallReturn return_value) { checkerXC->setSyscallReturn(return_value); actualXC->setSyscallReturn(return_value); } Counter readFuncExeInst() { return actualXC->readFuncExeInst(); } #endif }; #endif // __CPU_CHECKER_EXEC_CONTEXT_HH__