diff options
-rw-r--r-- | src/SConscript | 3 | ||||
-rw-r--r-- | src/arch/alpha/ev5.cc | 10 | ||||
-rw-r--r-- | src/cpu/base_dyn_inst.hh | 4 | ||||
-rw-r--r-- | src/cpu/checker/cpu.cc | 118 | ||||
-rw-r--r-- | src/cpu/checker/cpu.hh | 54 | ||||
-rw-r--r-- | src/cpu/checker/thread_context.hh | 25 | ||||
-rw-r--r-- | src/cpu/memtest/memtest.cc | 6 | ||||
-rw-r--r-- | src/cpu/memtest/memtest.hh | 2 | ||||
-rw-r--r-- | src/cpu/o3/alpha_cpu.hh | 34 | ||||
-rw-r--r-- | src/cpu/o3/alpha_cpu_impl.hh | 117 | ||||
-rw-r--r-- | src/cpu/o3/cpu.cc | 12 | ||||
-rw-r--r-- | src/cpu/o3/cpu.hh | 6 | ||||
-rw-r--r-- | src/cpu/o3/thread_state.hh | 31 | ||||
-rw-r--r-- | src/cpu/ozone/cpu_impl.hh | 6 | ||||
-rw-r--r-- | src/cpu/ozone/thread_state.hh | 21 | ||||
-rw-r--r-- | src/cpu/simple/atomic.cc | 12 | ||||
-rw-r--r-- | src/cpu/simple/base.cc | 116 | ||||
-rw-r--r-- | src/cpu/simple/base.hh | 63 | ||||
-rw-r--r-- | src/cpu/simple/timing.cc | 12 | ||||
-rw-r--r-- | src/cpu/simple_thread.cc (renamed from src/cpu/cpu_exec_context.cc) | 117 | ||||
-rw-r--r-- | src/cpu/simple_thread.hh (renamed from src/cpu/cpu_exec_context.hh) | 256 | ||||
-rw-r--r-- | src/cpu/thread_state.cc | 46 | ||||
-rw-r--r-- | src/cpu/thread_state.hh | 128 | ||||
-rw-r--r-- | src/kern/system_events.cc | 2 | ||||
-rw-r--r-- | src/sim/process.hh | 1 |
25 files changed, 604 insertions, 598 deletions
diff --git a/src/SConscript b/src/SConscript index 3fc9d4c2f..d29ecb7bb 100644 --- a/src/SConscript +++ b/src/SConscript @@ -83,7 +83,6 @@ base_sources = Split(''' cpu/activity.cc cpu/base.cc - cpu/cpu_exec_context.cc cpu/cpuevent.cc cpu/exetrace.cc cpu/op_class.cc @@ -91,6 +90,8 @@ base_sources = Split(''' cpu/quiesce_event.cc cpu/static_inst.cc cpu/sampler/sampler.cc + cpu/simple_thread.cc + cpu/thread_state.cc encumbered/cpu/full/fu_pool.cc diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 50ce6b78a..c419762b7 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -37,7 +37,7 @@ #include "base/stats/events.hh" #include "config/full_system.hh" #include "cpu/base.hh" -#include "cpu/cpu_exec_context.hh" +#include "cpu/simple_thread.hh" #include "cpu/thread_context.hh" #include "kern/kernel_stats.hh" #include "sim/debug.hh" @@ -135,12 +135,12 @@ AlphaISA::zeroRegisters(CPU *cpu) // Insure ISA semantics // (no longer very clean due to the change in setIntReg() in the // cpu model. Consider changing later.) - cpu->cpuXC->setIntReg(ZeroReg, 0); - cpu->cpuXC->setFloatReg(ZeroReg, 0.0); + cpu->thread->setIntReg(ZeroReg, 0); + cpu->thread->setFloatReg(ZeroReg, 0.0); } Fault -CPUExecContext::hwrei() +SimpleThread::hwrei() { if (!inPalMode()) return new UnimplementedOpcodeFault; @@ -562,7 +562,7 @@ AlphaISA::copyIprs(ThreadContext *src, ThreadContext *dest) * If return value is false, actual PAL call will be suppressed. */ bool -CPUExecContext::simPalCheck(int palFunc) +SimpleThread::simPalCheck(int palFunc) { if (kernelStats) kernelStats->callpal(palFunc, tc); diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index 0657be324..e69e00d6c 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -650,7 +650,7 @@ BaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags) req = new Request(); req->setVirt(asid, addr, sizeof(T), flags, this->PC); - req->setThreadContext(thread->cpuId, threadNumber); + req->setThreadContext(thread->readCpuId(), threadNumber); if ((req->getVaddr() & (TheISA::VMPageSize - 1)) + req->getSize() > TheISA::VMPageSize) { @@ -705,7 +705,7 @@ BaseDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res) req = new Request(); req->setVirt(asid, addr, sizeof(T), flags, this->PC); - req->setThreadContext(thread->cpuId, threadNumber); + req->setThreadContext(thread->readCpuId(), threadNumber); if ((req->getVaddr() & (TheISA::VMPageSize - 1)) + req->getSize() > TheISA::VMPageSize) { diff --git a/src/cpu/checker/cpu.cc b/src/cpu/checker/cpu.cc index 7ae7047e8..2d2f67e6b 100644 --- a/src/cpu/checker/cpu.cc +++ b/src/cpu/checker/cpu.cc @@ -33,7 +33,7 @@ #include "cpu/base.hh" #include "cpu/base_dyn_inst.hh" #include "cpu/checker/cpu.hh" -#include "cpu/cpu_exec_context.hh" +#include "cpu/simple_thread.hh" #include "cpu/thread_context.hh" #include "cpu/static_inst.hh" #include "sim/byteswap.hh" @@ -62,7 +62,7 @@ CheckerCPU::init() } CheckerCPU::CheckerCPU(Params *p) - : BaseCPU(p), cpuXC(NULL), tc(NULL) + : BaseCPU(p), thread(NULL), tc(NULL) { memReq = NULL; @@ -94,21 +94,21 @@ CheckerCPU::setMemory(MemObject *mem) { memPtr = mem; #if !FULL_SYSTEM - cpuXC = new CPUExecContext(this, /* thread_num */ 0, process, - /* asid */ 0, mem); + thread = new SimpleThread(this, /* thread_num */ 0, process, + /* asid */ 0, mem); - cpuXC->setStatus(ThreadContext::Suspended); - tc = cpuXC->getTC(); + thread->setStatus(ThreadContext::Suspended); + tc = thread->getTC(); threadContexts.push_back(tc); #else if (systemPtr) { - cpuXC = new CPUExecContext(this, 0, systemPtr, itb, dtb, memPtr, false); + thread = new SimpleThread(this, 0, systemPtr, itb, dtb, memPtr, false); - cpuXC->setStatus(ThreadContext::Suspended); - tc = cpuXC->getTC(); + thread->setStatus(ThreadContext::Suspended); + tc = thread->getTC(); threadContexts.push_back(tc); - delete cpuXC->kernelStats; - cpuXC->kernelStats = NULL; + delete thread->kernelStats; + thread->kernelStats = NULL; } #endif } @@ -120,13 +120,13 @@ CheckerCPU::setSystem(System *system) systemPtr = system; if (memPtr) { - cpuXC = new CPUExecContext(this, 0, systemPtr, itb, dtb, memPtr, false); + thread = new SimpleThread(this, 0, systemPtr, itb, dtb, memPtr, false); - cpuXC->setStatus(ThreadContext::Suspended); - tc = cpuXC->getTC(); + thread->setStatus(ThreadContext::Suspended); + tc = thread->getTC(); threadContexts.push_back(tc); - delete cpuXC->kernelStats; - cpuXC->kernelStats = NULL; + delete thread->kernelStats; + thread->kernelStats = NULL; } } #endif @@ -150,7 +150,7 @@ CheckerCPU::serialize(ostream &os) BaseCPU::serialize(os); SERIALIZE_SCALAR(inst); nameOut(os, csprintf("%s.xc", name())); - cpuXC->serialize(os); + thread->serialize(os); cacheCompletionEvent.serialize(os); */ } @@ -161,7 +161,7 @@ CheckerCPU::unserialize(Checkpoint *cp, const string §ion) /* BaseCPU::unserialize(cp, section); UNSERIALIZE_SCALAR(inst); - cpuXC->unserialize(cp, csprintf("%s.xc", section)); + thread->unserialize(cp, csprintf("%s.xc", section)); */ } @@ -184,7 +184,7 @@ CheckerCPU::read(Addr addr, T &data, unsigned flags) // need to fill in CPU & thread IDs here memReq = new Request(); - memReq->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC()); + memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC()); // translate to physical address translateDataReadReq(memReq); @@ -254,10 +254,10 @@ CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) // need to fill in CPU & thread IDs here memReq = new Request(); - memReq->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC()); + memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC()); // translate to physical address - cpuXC->translateDataWriteReq(memReq); + thread->translateDataWriteReq(memReq); // Can compare the write data and result only if it's cacheable, // not a store conditional, or is a store conditional that @@ -356,9 +356,9 @@ bool CheckerCPU::translateInstReq(Request *req) { #if FULL_SYSTEM - return (cpuXC->translateInstReq(req) == NoFault); + return (thread->translateInstReq(req) == NoFault); #else - cpuXC->translateInstReq(req); + thread->translateInstReq(req); return true; #endif } @@ -366,7 +366,7 @@ CheckerCPU::translateInstReq(Request *req) void CheckerCPU::translateDataReadReq(Request *req) { - cpuXC->translateDataReadReq(req); + thread->translateDataReadReq(req); if (req->getVaddr() != unverifiedReq->getVaddr()) { warn("%lli: Request virtual addresses do not match! Inst: %#x, " @@ -386,7 +386,7 @@ CheckerCPU::translateDataReadReq(Request *req) void CheckerCPU::translateDataWriteReq(Request *req) { - cpuXC->translateDataWriteReq(req); + thread->translateDataWriteReq(req); if (req->getVaddr() != unverifiedReq->getVaddr()) { warn("%lli: Request virtual addresses do not match! Inst: %#x, " @@ -475,9 +475,9 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst) Fault fault = NoFault; // maintain $r0 semantics - cpuXC->setIntReg(ZeroReg, 0); + thread->setIntReg(ZeroReg, 0); #ifdef TARGET_ALPHA - cpuXC->setFloatRegDouble(ZeroReg, 0.0); + thread->setFloatRegDouble(ZeroReg, 0.0); #endif // TARGET_ALPHA // Check if any recent PC changes match up with anything we @@ -485,14 +485,14 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst) // PC-based events have occurred in both the checker and CPU. if (changedPC) { DPRINTF(Checker, "Changed PC recently to %#x\n", - cpuXC->readPC()); + thread->readPC()); if (willChangePC) { - if (newPC == cpuXC->readPC()) { + if (newPC == thread->readPC()) { DPRINTF(Checker, "Changed PC matches expected PC\n"); } else { warn("%lli: Changed PC does not match expected PC, " "changed: %#x, expected: %#x", - curTick, cpuXC->readPC(), newPC); + curTick, thread->readPC(), newPC); handleError(); } willChangePC = false; @@ -501,7 +501,7 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst) } if (changedNextPC) { DPRINTF(Checker, "Changed NextPC recently to %#x\n", - cpuXC->readNextPC()); + thread->readNextPC()); changedNextPC = false; } @@ -513,13 +513,13 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst) #define IFETCH_FLAGS(pc) 0 #endif - uint64_t fetch_PC = cpuXC->readPC() & ~3; + uint64_t fetch_PC = thread->readPC() & ~3; // set up memory request for instruction fetch memReq = new Request(inst->threadNumber, fetch_PC, sizeof(uint32_t), - IFETCH_FLAGS(cpuXC->readPC()), - fetch_PC, cpuXC->readCpuId(), inst->threadNumber); + IFETCH_FLAGS(thread->readPC()), + fetch_PC, thread->readCpuId(), inst->threadNumber); bool succeeded = translateInstReq(memReq); @@ -531,12 +531,12 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst) // translate this instruction; in the SMT case it's // possible that its ITB entry was kicked out. warn("%lli: Instruction PC %#x was not found in the ITB!", - curTick, cpuXC->readPC()); + curTick, thread->readPC()); handleError(); // go to the next instruction - cpuXC->setPC(cpuXC->readNextPC()); - cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst)); + thread->setPC(thread->readNextPC()); + thread->setNextPC(thread->readNextPC() + sizeof(MachInst)); return; } else { @@ -567,10 +567,10 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst) validateInst(inst); curStaticInst = StaticInst::decode(makeExtMI(machInst, - cpuXC->readPC())); + thread->readPC())); #if FULL_SYSTEM - cpuXC->setInst(machInst); + thread->setInst(machInst); #endif // FULL_SYSTEM fault = inst->getFault(); @@ -585,7 +585,7 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst) // that the instruction is properly marked as a fault. if (fault == NoFault) { - cpuXC->func_exe_inst++; + thread->funcExeInst++; fault = curStaticInst->execute(this, NULL); @@ -601,21 +601,21 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst) #if FULL_SYSTEM fault->invoke(xcProxy); willChangePC = true; - newPC = cpuXC->readPC(); + newPC = thread->readPC(); DPRINTF(Checker, "Fault, PC is now %#x\n", newPC); #else // !FULL_SYSTEM - fatal("fault (%d) detected @ PC 0x%08p", fault, cpuXC->readPC()); + fatal("fault (%d) detected @ PC 0x%08p", fault, thread->readPC()); #endif // FULL_SYSTEM } else { #if THE_ISA != MIPS_ISA // go to the next instruction - cpuXC->setPC(cpuXC->readNextPC()); - cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst)); + thread->setPC(thread->readNextPC()); + thread->setNextPC(thread->readNextPC() + sizeof(MachInst)); #else // go to the next instruction - cpuXC->setPC(cpuXC->readNextPC()); - cpuXC->setNextPC(cpuXC->readNextNPC()); - cpuXC->setNextNPC(cpuXC->readNextNPC() + sizeof(MachInst)); + thread->setPC(thread->readNextPC()); + thread->setNextPC(thread->readNextNPC()); + thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst)); #endif } @@ -627,13 +627,13 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst) Addr oldpc; int count = 0; do { - oldpc = cpuXC->readPC(); + oldpc = thread->readPC(); system->pcEventQueue.service(xcProxy); count++; - } while (oldpc != cpuXC->readPC()); + } while (oldpc != thread->readPC()); if (count > 1) { willChangePC = true; - newPC = cpuXC->readPC(); + newPC = thread->readPC(); DPRINTF(Checker, "PC Event, PC is now %#x\n", newPC); } #endif @@ -677,9 +677,9 @@ template <class DynInstPtr> void Checker<DynInstPtr>::validateInst(DynInstPtr &inst) { - if (inst->readPC() != cpuXC->readPC()) { + if (inst->readPC() != thread->readPC()) { warn("%lli: PCs do not match! Inst: %#x, checker: %#x", - curTick, inst->readPC(), cpuXC->readPC()); + curTick, inst->readPC(), thread->readPC()); if (changedPC) { warn("%lli: Changed PCs recently, may not be an error", curTick); @@ -710,11 +710,11 @@ Checker<DynInstPtr>::validateExecution(DynInstPtr &inst) // instruction and write it to the register. RegIndex idx = inst->destRegIdx(0); if (idx < TheISA::FP_Base_DepTag) { - cpuXC->setIntReg(idx, inst->readIntResult()); + thread->setIntReg(idx, inst->readIntResult()); } else if (idx < TheISA::Fpcr_DepTag) { - cpuXC->setFloatRegBits(idx, inst->readIntResult()); + thread->setFloatRegBits(idx, inst->readIntResult()); } else { - cpuXC->setMiscReg(idx, inst->readIntResult()); + thread->setMiscReg(idx, inst->readIntResult()); } } else if (result.integer != inst->readIntResult()) { warn("%lli: Instruction results do not match! (Values may not " @@ -724,10 +724,10 @@ Checker<DynInstPtr>::validateExecution(DynInstPtr &inst) } } - if (inst->readNextPC() != cpuXC->readNextPC()) { + if (inst->readNextPC() != thread->readNextPC()) { warn("%lli: Instruction next PCs do not match! Inst: %#x, " "checker: %#x", - curTick, inst->readNextPC(), cpuXC->readNextPC()); + curTick, inst->readNextPC(), thread->readNextPC()); handleError(); } @@ -741,12 +741,12 @@ Checker<DynInstPtr>::validateExecution(DynInstPtr &inst) miscRegIdxs.pop(); if (inst->tcBase()->readMiscReg(misc_reg_idx) != - cpuXC->readMiscReg(misc_reg_idx)) { + thread->readMiscReg(misc_reg_idx)) { warn("%lli: Misc reg idx %i (side effect) does not match! " "Inst: %#x, checker: %#x", curTick, misc_reg_idx, inst->tcBase()->readMiscReg(misc_reg_idx), - cpuXC->readMiscReg(misc_reg_idx)); + thread->readMiscReg(misc_reg_idx)); handleError(); } } diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh index 484f4cf04..f733becd4 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -38,7 +38,7 @@ #include "config/full_system.hh" #include "cpu/base.hh" #include "cpu/base_dyn_inst.hh" -#include "cpu/cpu_exec_context.hh" +#include "cpu/simple_thread.hh" #include "cpu/pc_event.hh" #include "cpu/static_inst.hh" #include "sim/eventq.hh" @@ -77,7 +77,7 @@ class Sampler; * instructions marked as "IsUnverifiable", the checker assumes that * the value from the main CPU's execution is correct and simply * copies that value. It provides a CheckerThreadContext (see - * checker/exec_context.hh) that provides hooks for updating the + * checker/thread_context.hh) that provides hooks for updating the * Checker's state through any ThreadContext accesses. This allows the * checker to be able to correctly verify instructions, even with * external accesses to the ThreadContext that change state. @@ -129,8 +129,8 @@ class CheckerCPU : public BaseCPU Port *dcachePort; public: - // execution context - CPUExecContext *cpuXC; + // Primary thread being run. + SimpleThread *thread; ThreadContext *tc; @@ -213,43 +213,43 @@ class CheckerCPU : public BaseCPU uint64_t readIntReg(const StaticInst *si, int idx) { - return cpuXC->readIntReg(si->srcRegIdx(idx)); + return thread->readIntReg(si->srcRegIdx(idx)); } FloatReg readFloatReg(const StaticInst *si, int idx, int width) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return cpuXC->readFloatReg(reg_idx, width); + return thread->readFloatReg(reg_idx, width); } FloatReg readFloatReg(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return cpuXC->readFloatReg(reg_idx); + return thread->readFloatReg(reg_idx); } FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return cpuXC->readFloatRegBits(reg_idx, width); + return thread->readFloatRegBits(reg_idx, width); } FloatRegBits readFloatRegBits(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return cpuXC->readFloatRegBits(reg_idx); + return thread->readFloatRegBits(reg_idx); } void setIntReg(const StaticInst *si, int idx, uint64_t val) { - cpuXC->setIntReg(si->destRegIdx(idx), val); + thread->setIntReg(si->destRegIdx(idx), val); result.integer = val; } void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - cpuXC->setFloatReg(reg_idx, val, width); + thread->setFloatReg(reg_idx, val, width); switch(width) { case 32: result.fp = val; @@ -263,7 +263,7 @@ class CheckerCPU : public BaseCPU void setFloatReg(const StaticInst *si, int idx, FloatReg val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - cpuXC->setFloatReg(reg_idx, val); + thread->setFloatReg(reg_idx, val); result.fp = val; } @@ -271,46 +271,46 @@ class CheckerCPU : public BaseCPU int width) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - cpuXC->setFloatRegBits(reg_idx, val, width); + thread->setFloatRegBits(reg_idx, val, width); result.integer = val; } void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - cpuXC->setFloatRegBits(reg_idx, val); + thread->setFloatRegBits(reg_idx, val); result.integer = val; } - uint64_t readPC() { return cpuXC->readPC(); } + uint64_t readPC() { return thread->readPC(); } - uint64_t readNextPC() { return cpuXC->readNextPC(); } + uint64_t readNextPC() { return thread->readNextPC(); } void setNextPC(uint64_t val) { - cpuXC->setNextPC(val); + thread->setNextPC(val); } MiscReg readMiscReg(int misc_reg) { - return cpuXC->readMiscReg(misc_reg); + return thread->readMiscReg(misc_reg); } MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) { - return cpuXC->readMiscRegWithEffect(misc_reg, fault); + return thread->readMiscRegWithEffect(misc_reg, fault); } Fault setMiscReg(int misc_reg, const MiscReg &val) { result.integer = val; miscRegIdxs.push(misc_reg); - return cpuXC->setMiscReg(misc_reg, val); + return thread->setMiscReg(misc_reg, val); } Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) { miscRegIdxs.push(misc_reg); - return cpuXC->setMiscRegWithEffect(misc_reg, val); + return thread->setMiscRegWithEffect(misc_reg, val); } void recordPCChange(uint64_t val) { changedPC = true; } @@ -321,12 +321,12 @@ class CheckerCPU : public BaseCPU void translateDataReadReq(Request *req); #if FULL_SYSTEM - Fault hwrei() { return cpuXC->hwrei(); } - int readIntrFlag() { return cpuXC->readIntrFlag(); } - void setIntrFlag(int val) { cpuXC->setIntrFlag(val); } - bool inPalMode() { return cpuXC->inPalMode(); } + Fault hwrei() { return thread->hwrei(); } + int readIntrFlag() { return thread->readIntrFlag(); } + void setIntrFlag(int val) { thread->setIntrFlag(val); } + bool inPalMode() { return thread->inPalMode(); } void ev5_trap(Fault fault) { fault->invoke(xcProxy); } - bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); } + bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } #else // Assume that the normal CPU's call to syscall was successful. // The checker's state would have already been updated by the syscall. @@ -341,7 +341,7 @@ class CheckerCPU : public BaseCPU bool checkFlags(Request *req); ThreadContext *tcBase() { return tc; } - CPUExecContext *cpuXCBase() { return cpuXC; } + SimpleThread *threadBase() { return thread; } Result unverifiedResult; Request *unverifiedReq; diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh index 48890584d..d3eb9cf0c 100644 --- a/src/cpu/checker/thread_context.hh +++ b/src/cpu/checker/thread_context.hh @@ -26,11 +26,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __CPU_CHECKER_EXEC_CONTEXT_HH__ -#define __CPU_CHECKER_EXEC_CONTEXT_HH__ +#ifndef __CPU_CHECKER_THREAD_CONTEXT_HH__ +#define __CPU_CHECKER_THREAD_CONTEXT_HH__ #include "cpu/checker/cpu.hh" -#include "cpu/cpu_exec_context.hh" +#include "cpu/simple_thread.hh" #include "cpu/thread_context.hh" class EndQuiesceEvent; @@ -41,23 +41,30 @@ namespace Kernel { /** * Derived ThreadContext class for use with the Checker. The template * parameter is the ThreadContext class used by the specific CPU being - * verified. This CheckerThreadContext is then used by the main CPU in - * place of its usual ThreadContext class. It handles updating the - * checker's state any time state is updated through the ThreadContext. + * verified. This CheckerThreadContext is then used by the main CPU + * in place of its usual ThreadContext class. It handles updating the + * checker's state any time state is updated externally through the + * ThreadContext. */ template <class TC> class CheckerThreadContext : public ThreadContext { public: CheckerThreadContext(TC *actual_tc, - CheckerCPU *checker_cpu) - : actualTC(actual_tc), checkerTC(checker_cpu->cpuXC), + CheckerCPU *checker_cpu) + : actualTC(actual_tc), checkerTC(checker_cpu->thread), checkerCPU(checker_cpu) { } private: + /** The main CPU's ThreadContext, or class that implements the + * ThreadContext interface. */ TC *actualTC; - CPUExecContext *checkerTC; + /** The checker's own SimpleThread. Will be updated any time + * anything uses this ThreadContext to externally update a + * thread's state. */ + SimpleThread *checkerTC; + /** Pointer to the checker CPU. */ CheckerCPU *checkerCPU; public: diff --git a/src/cpu/memtest/memtest.cc b/src/cpu/memtest/memtest.cc index 62e539250..7ea9eaefc 100644 --- a/src/cpu/memtest/memtest.cc +++ b/src/cpu/memtest/memtest.cc @@ -38,7 +38,7 @@ #include "base/misc.hh" #include "base/statistics.hh" -#include "cpu/cpu_exec_context.hh" +#include "cpu/simple_thread.hh" #include "cpu/memtest/memtest.hh" #include "mem/cache/base_cache.hh" #include "sim/builder.hh" @@ -81,7 +81,7 @@ MemTest::MemTest(const string &name, vector<string> cmd; cmd.push_back("/bin/ls"); vector<string> null_vec; - cpuXC = new CPUExecContext(NULL, 0, mainMem, 0); + thread = new SimpleThread(NULL, 0, mainMem, 0); blockSize = cacheInterface->getBlockSize(); blockAddrMask = blockSize - 1; @@ -271,7 +271,7 @@ MemTest::tick() req->data = new uint8_t[req->size]; req->paddr &= ~(req->size - 1); req->time = curTick; - req->xc = cpuXC->getProxy(); + req->xc = thread->getProxy(); if (cmd < percentReads) { // read diff --git a/src/cpu/memtest/memtest.hh b/src/cpu/memtest/memtest.hh index 9976000e9..42fb235db 100644 --- a/src/cpu/memtest/memtest.hh +++ b/src/cpu/memtest/memtest.hh @@ -86,7 +86,7 @@ class MemTest : public SimObject MemInterface *cacheInterface; FunctionalMemory *mainMem; FunctionalMemory *checkMem; - CPUExecContext *cpuXC; + SimpleThread *thread; unsigned size; // size of testing memory region diff --git a/src/cpu/o3/alpha_cpu.hh b/src/cpu/o3/alpha_cpu.hh index 588b11724..3449454bd 100644 --- a/src/cpu/o3/alpha_cpu.hh +++ b/src/cpu/o3/alpha_cpu.hh @@ -96,7 +96,7 @@ class AlphaFullCPU : public FullO3CPU<Impl> /** Reads this CPU's ID. */ virtual int readCpuId() { return cpu->cpu_id; } - virtual TranslatingPort *getMemPort() { return thread->port; } + virtual TranslatingPort *getMemPort() { return thread->getMemPort(); } #if FULL_SYSTEM /** Returns a pointer to the system. */ @@ -116,7 +116,7 @@ class AlphaFullCPU : public FullO3CPU<Impl> { return thread->kernelStats; } #else /** Returns a pointer to this thread's process. */ - virtual Process *getProcessPtr() { return thread->process; } + virtual Process *getProcessPtr() { return thread->getProcessPtr(); } #endif /** Returns this thread's status. */ virtual Status status() const { return thread->status(); } @@ -170,7 +170,7 @@ class AlphaFullCPU : public FullO3CPU<Impl> virtual void profileSample(); #endif /** Returns this thread's ID number. */ - virtual int getThreadNum() { return thread->tid; } + virtual int getThreadNum() { return thread->readTid(); } /** Returns the instruction this thread is currently committing. * Only used when an instruction faults. @@ -207,14 +207,14 @@ class AlphaFullCPU : public FullO3CPU<Impl> /** Reads this thread's PC. */ virtual uint64_t readPC() - { return cpu->readPC(thread->tid); } + { return cpu->readPC(thread->readTid()); } /** Sets this thread's PC. */ virtual void setPC(uint64_t val); /** Reads this thread's next PC. */ virtual uint64_t readNextPC() - { return cpu->readNextPC(thread->tid); } + { return cpu->readNextPC(thread->readTid()); } /** Sets this thread's next PC. */ virtual void setNextPC(uint64_t val); @@ -230,12 +230,12 @@ class AlphaFullCPU : public FullO3CPU<Impl> /** Reads a miscellaneous register. */ virtual MiscReg readMiscReg(int misc_reg) - { return cpu->readMiscReg(misc_reg, thread->tid); } + { return cpu->readMiscReg(misc_reg, thread->readTid()); } /** Reads a misc. register, including any side-effects the * read might have as defined by the architecture. */ virtual MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) - { return cpu->readMiscRegWithEffect(misc_reg, fault, thread->tid); } + { return cpu->readMiscRegWithEffect(misc_reg, fault, thread->readTid()); } /** Sets a misc. register. */ virtual Fault setMiscReg(int misc_reg, const MiscReg &val); @@ -257,7 +257,7 @@ class AlphaFullCPU : public FullO3CPU<Impl> /** Returns if the thread is currently in PAL mode, based on * the PC's value. */ virtual bool inPalMode() - { return TheISA::PcPAL(cpu->readPC(thread->tid)); } + { return TheISA::PcPAL(cpu->readPC(thread->readTid())); } #endif // Only really makes sense for old CPU model. Lots of code // outside the CPU still checks this function, so it will @@ -279,7 +279,7 @@ class AlphaFullCPU : public FullO3CPU<Impl> /** Executes a syscall in SE mode. */ virtual void syscall(int64_t callnum) - { return cpu->syscall(callnum, thread->tid); } + { return cpu->syscall(callnum, thread->readTid()); } /** Reads the funcExeInst counter. */ virtual Counter readFuncExeInst() { return thread->funcExeInst; } @@ -323,21 +323,21 @@ class AlphaFullCPU : public FullO3CPU<Impl> Fault translateInstReq(RequestPtr &req) { int tid = req->getThreadNum(); - return this->thread[tid]->process->pTable->translate(req); + return this->thread[tid]->getProcessPtr()->pTable->translate(req); } /** Translates data read request in syscall emulation mode. */ Fault translateDataReadReq(RequestPtr &req) { int tid = req->getThreadNum(); - return this->thread[tid]->process->pTable->translate(req); + return this->thread[tid]->getProcessPtr()->pTable->translate(req); } /** Translates data write request in syscall emulation mode. */ Fault translateDataWriteReq(RequestPtr &req) { int tid = req->getThreadNum(); - return this->thread[tid]->process->pTable->translate(req); + return this->thread[tid]->getProcessPtr()->pTable->translate(req); } #endif @@ -492,14 +492,14 @@ class AlphaFullCPU : public FullO3CPU<Impl> #if FULL_SYSTEM // @todo: Fix this LL/SC hack. - if (req->flags & LOCKED) { - if (req->flags & UNCACHEABLE) { - req->result = 2; + if (req->getFlags() & LOCKED) { + if (req->getFlags() & UNCACHEABLE) { + req->setScResult(2); } else { if (this->lockFlag) { - req->result = 1; + req->setScResult(1); } else { - req->result = 0; + req->setScResult(0); return NoFault; } } diff --git a/src/cpu/o3/alpha_cpu_impl.hh b/src/cpu/o3/alpha_cpu_impl.hh index 7f3d91640..2debe074b 100644 --- a/src/cpu/o3/alpha_cpu_impl.hh +++ b/src/cpu/o3/alpha_cpu_impl.hh @@ -32,7 +32,7 @@ #include "base/cprintf.hh" #include "base/statistics.hh" #include "base/timebuf.hh" -#include "cpu/checker/exec_context.hh" +#include "cpu/checker/thread_context.hh" #include "sim/sim_events.hh" #include "sim/stats.hh" @@ -77,6 +77,20 @@ AlphaFullCPU<Impl>::AlphaFullCPU(Params *params) i, params->mem); this->thread[i]->setStatus(ThreadContext::Suspended); + +#if !FULL_SYSTEM + /* Use this port to for syscall emulation writes to memory. */ + Port *mem_port; + TranslatingPort *trans_port; + trans_port = new TranslatingPort(csprintf("%s-%d-funcport", + name(), i), + params->workload[i]->pTable, + false); + mem_port = params->mem->getPort("functional"); + mem_port->setPeer(trans_port); + trans_port->setPeer(mem_port); + this->thread[i]->setMemPort(trans_port); +#endif //usedTids[i] = true; //threadMap[i] = i; } else { @@ -108,10 +122,25 @@ AlphaFullCPU<Impl>::AlphaFullCPU(Params *params) #if FULL_SYSTEM // Setup quiesce event. - this->thread[i]->quiesceEvent = - new EndQuiesceEvent(tc); - this->thread[i]->lastActivate = 0; - this->thread[i]->lastSuspend = 0; + this->thread[i]->quiesceEvent = new EndQuiesceEvent(tc); + + Port *mem_port; + FunctionalPort *phys_port; + VirtualPort *virt_port; + phys_port = new FunctionalPort(csprintf("%s-%d-funcport", + cpu->name(), tid)); + mem_port = system->physmem->getPort("functional"); + mem_port->setPeer(phys_port); + phys_port->setPeer(mem_port); + + virt_port = new VirtualPort(csprintf("%s-%d-vport", + cpu->name(), tid)); + mem_port = system->physmem->getPort("functional"); + mem_port->setPeer(virt_port); + virt_port->setPeer(mem_port); + + this->thread[i]->setPhysPort(phys_port); + this->thread[i]->setVirtPort(virt_port); #endif // Give the thread the TC. this->thread[i]->tc = tc; @@ -120,9 +149,8 @@ AlphaFullCPU<Impl>::AlphaFullCPU(Params *params) this->threadContexts.push_back(tc); } - for (int i=0; i < this->numThreads; i++) { - this->thread[i]->funcExeInst = 0; + this->thread[i]->setFuncExeInst(0); } // Sets CPU pointers. These must be set at this level because the CPU @@ -218,14 +246,14 @@ AlphaFullCPU<Impl>::AlphaTC::activate(int delay) #endif if (thread->status() == ThreadContext::Unallocated) { - cpu->activateWhenReady(thread->tid); + cpu->activateWhenReady(thread->readTid()); return; } thread->setStatus(ThreadContext::Active); // status() == Suspended - cpu->activateContext(thread->tid, delay); + cpu->activateContext(thread->readTid(), delay); } template <class Impl> @@ -251,7 +279,7 @@ AlphaFullCPU<Impl>::AlphaTC::suspend() #endif */ thread->setStatus(ThreadContext::Suspended); - cpu->suspendContext(thread->tid); + cpu->suspendContext(thread->readTid()); } template <class Impl> @@ -264,7 +292,7 @@ AlphaFullCPU<Impl>::AlphaTC::deallocate() return; thread->setStatus(ThreadContext::Unallocated); - cpu->deallocateContext(thread->tid); + cpu->deallocateContext(thread->readTid()); } template <class Impl> @@ -277,7 +305,7 @@ AlphaFullCPU<Impl>::AlphaTC::halt() return; thread->setStatus(ThreadContext::Halted); - cpu->haltContext(thread->tid); + cpu->haltContext(thread->readTid()); } template <class Impl> @@ -349,7 +377,7 @@ template <class Impl> TheISA::MachInst AlphaFullCPU<Impl>::AlphaTC:: getInst() { - return thread->inst; + return thread->getInst(); } template <class Impl> @@ -358,7 +386,7 @@ AlphaFullCPU<Impl>::AlphaTC::copyArchRegs(ThreadContext *tc) { // This function will mess things up unless the ROB is empty and // there are no instructions in the pipeline. - unsigned tid = thread->tid; + unsigned tid = thread->readTid(); PhysRegIndex renamed_reg; // First loop through the integer registers. @@ -400,7 +428,7 @@ template <class Impl> uint64_t AlphaFullCPU<Impl>::AlphaTC::readIntReg(int reg_idx) { - return cpu->readArchIntReg(reg_idx, thread->tid); + return cpu->readArchIntReg(reg_idx, thread->readTid()); } template <class Impl> @@ -409,9 +437,9 @@ AlphaFullCPU<Impl>::AlphaTC::readFloatReg(int reg_idx, int width) { switch(width) { case 32: - return cpu->readArchFloatRegSingle(reg_idx, thread->tid); + return cpu->readArchFloatRegSingle(reg_idx, thread->readTid()); case 64: - return cpu->readArchFloatRegDouble(reg_idx, thread->tid); + return cpu->readArchFloatRegDouble(reg_idx, thread->readTid()); default: panic("Unsupported width!"); return 0; @@ -422,7 +450,7 @@ template <class Impl> FloatReg AlphaFullCPU<Impl>::AlphaTC::readFloatReg(int reg_idx) { - return cpu->readArchFloatRegSingle(reg_idx, thread->tid); + return cpu->readArchFloatRegSingle(reg_idx, thread->readTid()); } template <class Impl> @@ -430,25 +458,25 @@ FloatRegBits AlphaFullCPU<Impl>::AlphaTC::readFloatRegBits(int reg_idx, int width) { DPRINTF(Fault, "Reading floatint register through the TC!\n"); - return cpu->readArchFloatRegInt(reg_idx, thread->tid); + return cpu->readArchFloatRegInt(reg_idx, thread->readTid()); } template <class Impl> FloatRegBits AlphaFullCPU<Impl>::AlphaTC::readFloatRegBits(int reg_idx) { - return cpu->readArchFloatRegInt(reg_idx, thread->tid); + return cpu->readArchFloatRegInt(reg_idx, thread->readTid()); } template <class Impl> void AlphaFullCPU<Impl>::AlphaTC::setIntReg(int reg_idx, uint64_t val) { - cpu->setArchIntReg(reg_idx, val, thread->tid); + cpu->setArchIntReg(reg_idx, val, thread->readTid()); // Squash if we're not already in a state update mode. if (!thread->trapPending && !thread->inSyscall) { - cpu->squashFromTC(thread->tid); + cpu->squashFromTC(thread->readTid()); } } @@ -458,16 +486,16 @@ AlphaFullCPU<Impl>::AlphaTC::setFloatReg(int reg_idx, FloatReg val, int width) { switch(width) { case 32: - cpu->setArchFloatRegSingle(reg_idx, val, thread->tid); + cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid()); break; case 64: - cpu->setArchFloatRegDouble(reg_idx, val, thread->tid); + cpu->setArchFloatRegDouble(reg_idx, val, thread->readTid()); break; } // Squash if we're not already in a state update mode. if (!thread->trapPending && !thread->inSyscall) { - cpu->squashFromTC(thread->tid); + cpu->squashFromTC(thread->readTid()); } } @@ -475,10 +503,10 @@ template <class Impl> void AlphaFullCPU<Impl>::AlphaTC::setFloatReg(int reg_idx, FloatReg val) { - cpu->setArchFloatRegSingle(reg_idx, val, thread->tid); + cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid()); if (!thread->trapPending && !thread->inSyscall) { - cpu->squashFromTC(thread->tid); + cpu->squashFromTC(thread->readTid()); } } @@ -488,11 +516,11 @@ AlphaFullCPU<Impl>::AlphaTC::setFloatRegBits(int reg_idx, FloatRegBits val, int width) { DPRINTF(Fault, "Setting floatint register through the TC!\n"); - cpu->setArchFloatRegInt(reg_idx, val, thread->tid); + cpu->setArchFloatRegInt(reg_idx, val, thread->readTid()); // Squash if we're not already in a state update mode. if (!thread->trapPending && !thread->inSyscall) { - cpu->squashFromTC(thread->tid); + cpu->squashFromTC(thread->readTid()); } } @@ -500,11 +528,11 @@ template <class Impl> void AlphaFullCPU<Impl>::AlphaTC::setFloatRegBits(int reg_idx, FloatRegBits val) { - cpu->setArchFloatRegInt(reg_idx, val, thread->tid); + cpu->setArchFloatRegInt(reg_idx, val, thread->readTid()); // Squash if we're not already in a state update mode. if (!thread->trapPending && !thread->inSyscall) { - cpu->squashFromTC(thread->tid); + cpu->squashFromTC(thread->readTid()); } } @@ -512,11 +540,11 @@ template <class Impl> void AlphaFullCPU<Impl>::AlphaTC::setPC(uint64_t val) { - cpu->setPC(val, thread->tid); + cpu->setPC(val, thread->readTid()); // Squash if we're not already in a state update mode. if (!thread->trapPending && !thread->inSyscall) { - cpu->squashFromTC(thread->tid); + cpu->squashFromTC(thread->readTid()); } } @@ -524,11 +552,11 @@ template <class Impl> void AlphaFullCPU<Impl>::AlphaTC::setNextPC(uint64_t val) { - cpu->setNextPC(val, thread->tid); + cpu->setNextPC(val, thread->readTid()); // Squash if we're not already in a state update mode. if (!thread->trapPending && !thread->inSyscall) { - cpu->squashFromTC(thread->tid); + cpu->squashFromTC(thread->readTid()); } } @@ -536,11 +564,11 @@ template <class Impl> Fault AlphaFullCPU<Impl>::AlphaTC::setMiscReg(int misc_reg, const MiscReg &val) { - Fault ret_fault = cpu->setMiscReg(misc_reg, val, thread->tid); + Fault ret_fault = cpu->setMiscReg(misc_reg, val, thread->readTid()); // Squash if we're not already in a state update mode. if (!thread->trapPending && !thread->inSyscall) { - cpu->squashFromTC(thread->tid); + cpu->squashFromTC(thread->readTid()); } return ret_fault; @@ -551,11 +579,12 @@ Fault AlphaFullCPU<Impl>::AlphaTC::setMiscRegWithEffect(int misc_reg, const MiscReg &val) { - Fault ret_fault = cpu->setMiscRegWithEffect(misc_reg, val, thread->tid); + Fault ret_fault = cpu->setMiscRegWithEffect(misc_reg, val, + thread->readTid()); // Squash if we're not already in a state update mode. if (!thread->trapPending && !thread->inSyscall) { - cpu->squashFromTC(thread->tid); + cpu->squashFromTC(thread->readTid()); } return ret_fault; @@ -567,21 +596,21 @@ template <class Impl> TheISA::IntReg AlphaFullCPU<Impl>::AlphaTC::getSyscallArg(int i) { - return cpu->getSyscallArg(i, thread->tid); + return cpu->getSyscallArg(i, thread->readTid()); } template <class Impl> void AlphaFullCPU<Impl>::AlphaTC::setSyscallArg(int i, IntReg val) { - cpu->setSyscallArg(i, val, thread->tid); + cpu->setSyscallArg(i, val, thread->readTid()); } template <class Impl> void AlphaFullCPU<Impl>::AlphaTC::setSyscallReturn(SyscallReturn return_value) { - cpu->setSyscallReturn(return_value, thread->tid); + cpu->setSyscallReturn(return_value, thread->readTid()); } #endif // FULL_SYSTEM @@ -749,8 +778,8 @@ AlphaFullCPU<Impl>::processInterrupts() this->setMiscReg(IPR_INTID, ipl, 0); // Checker needs to know these two registers were updated. if (this->checker) { - this->checker->cpuXCBase()->setMiscReg(IPR_ISR, summary); - this->checker->cpuXCBase()->setMiscReg(IPR_INTID, ipl); + this->checker->threadBase()->setMiscReg(IPR_ISR, summary); + this->checker->threadBase()->setMiscReg(IPR_INTID, ipl); } this->trap(Fault(new InterruptFault), 0); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index f523766cc..c5f78d63d 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -38,7 +38,7 @@ #include "cpu/activity.hh" #include "cpu/checker/cpu.hh" -#include "cpu/cpu_exec_context.hh" +#include "cpu/simple_thread.hh" #include "cpu/thread_context.hh" #include "cpu/o3/alpha_dyn_inst.hh" #include "cpu/o3/alpha_impl.hh" @@ -245,12 +245,6 @@ FullO3CPU<Impl>::FullO3CPU(Params *params) } rename.setFreeList(&freeList); - // Setup the page table for whichever stages need it. -#if !FULL_SYSTEM -// fetch.setPageTable(pTable); -// iew.setPageTable(pTable); -#endif - // Setup the ROB for whichever stages need it. commit.setROB(&rob); @@ -427,12 +421,12 @@ FullO3CPU<Impl>::insertThread(unsigned tid) { DPRINTF(FullCPU,"[tid:%i] Initializing thread data"); // Will change now that the PC and thread state is internal to the CPU - // and not in the CPUExecContext. + // and not in the ThreadContext. #if 0 #if FULL_SYSTEM ThreadContext *src_tc = system->threadContexts[tid]; #else - CPUExecContext *src_tc = thread[tid]; + ThreadContext *src_tc = thread[tid]; #endif //Bind Int Regs to Rename Map diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index 69f52f147..8e482f1e5 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -43,7 +43,7 @@ #include "config/full_system.hh" #include "cpu/activity.hh" #include "cpu/base.hh" -#include "cpu/cpu_exec_context.hh" +#include "cpu/simple_thread.hh" #include "cpu/o3/comm.hh" #include "cpu/o3/cpu_policy.hh" #include "cpu/o3/scoreboard.hh" @@ -237,11 +237,11 @@ class FullO3CPU : public BaseFullCPU #else /** Get instruction asid. */ int getInstAsid(unsigned tid) - { return thread[tid]->asid; } + { return thread[tid]->getInstAsid(); } /** Get data asid. */ int getDataAsid(unsigned tid) - { return thread[tid]->asid; } + { return thread[tid]->getDataAsid(); } #endif diff --git a/src/cpu/o3/thread_state.hh b/src/cpu/o3/thread_state.hh index 7322161e6..38d37ec96 100644 --- a/src/cpu/o3/thread_state.hh +++ b/src/cpu/o3/thread_state.hh @@ -58,14 +58,6 @@ struct O3ThreadState : public ThreadState { typedef ThreadContext::Status Status; typedef typename Impl::FullCPU FullCPU; - /** Current status of the thread. */ - Status _status; - - /** Current instruction the thread is committing. Only set and - * used for DTB faults currently. - */ - TheISA::MachInst inst; - private: /** Pointer to the CPU. */ FullCPU *cpu; @@ -81,8 +73,8 @@ struct O3ThreadState : public ThreadState { bool trapPending; #if FULL_SYSTEM - O3ThreadState(FullCPU *_cpu, int _thread_num, FunctionalMemory *_mem) - : ThreadState(-1, _thread_num, _mem), + O3ThreadState(FullCPU *_cpu, int _thread_num, ) + : ThreadState(-1, _thread_num), inSyscall(0), trapPending(0) { } #else @@ -99,25 +91,6 @@ struct O3ThreadState : public ThreadState { /** Returns a pointer to the TC of this thread. */ ThreadContext *getTC() { return tc; } - /** Returns the status of this thread. */ - Status status() const { return _status; } - - /** Sets the status of this thread. */ - void setStatus(Status new_status) { _status = new_status; } - - /** Sets the current instruction being committed. */ - void setInst(TheISA::MachInst _inst) { inst = _inst; } - - /** Reads the number of instructions functionally executed and - * committed. - */ - Counter readFuncExeInst() { return funcExeInst; } - - /** Sets the total number of instructions functionally executed - * and committed. - */ - void setFuncExeInst(Counter new_val) { funcExeInst = new_val; } - #if !FULL_SYSTEM /** Handles the syscall. */ void syscall(int64_t callnum) { process->syscall(callnum, tc); } diff --git a/src/cpu/ozone/cpu_impl.hh b/src/cpu/ozone/cpu_impl.hh index 0763a30b3..76e2318aa 100644 --- a/src/cpu/ozone/cpu_impl.hh +++ b/src/cpu/ozone/cpu_impl.hh @@ -36,7 +36,7 @@ #include "base/trace.hh" #include "config/full_system.hh" #include "cpu/base.hh" -#include "cpu/checker/exec_context.hh" +#include "cpu/checker/thread_context.hh" #include "cpu/thread_context.hh" #include "cpu/exetrace.hh" #include "cpu/ozone/cpu.hh" @@ -670,8 +670,8 @@ OzoneCPU<Impl>::processInterrupts() thread.setMiscReg(IPR_INTID, ipl); // @todo: Make this more transparent if (checker) { - checker->cpuXCBase()->setMiscReg(IPR_ISR, summary); - checker->cpuXCBase()->setMiscReg(IPR_INTID, ipl); + checker->threadBase()->setMiscReg(IPR_ISR, summary); + checker->threadBase()->setMiscReg(IPR_INTID, ipl); } Fault fault = new InterruptFault; fault->invoke(thread.getTC()); diff --git a/src/cpu/ozone/thread_state.hh b/src/cpu/ozone/thread_state.hh index c91297e73..e6256e4e3 100644 --- a/src/cpu/ozone/thread_state.hh +++ b/src/cpu/ozone/thread_state.hh @@ -49,7 +49,7 @@ class FunctionalMemory; // Maybe this ozone thread state should only really have committed state? // I need to think about why I'm using this and what it's useful for. Clearly -// has benefits for SMT; basically serves same use as CPUExecContext. +// has benefits for SMT; basically serves same use as SimpleThread. // Makes the ExecContext proxy easier. Gives organization/central access point // to state of a thread that can be accessed normally (i.e. not in-flight // stuff within a OoO processor). Does this need an TC proxy within it? @@ -83,18 +83,11 @@ struct OzoneThreadState : public ThreadState { } #endif - Status _status; - - Status status() const { return _status; } - - void setStatus(Status new_status) { _status = new_status; } - RenameTable<Impl> renameTable; + Addr PC; - Addr nextPC; - // Current instruction - TheISA::MachInst inst; + Addr nextPC; TheISA::RegFile regs; @@ -169,14 +162,6 @@ struct OzoneThreadState : public ThreadState { void setNextPC(uint64_t val) { nextPC = val; } - - bool misspeculating() { return false; } - - void setInst(TheISA::MachInst _inst) { inst = _inst; } - - Counter readFuncExeInst() { return funcExeInst; } - - void setFuncExeInst(Counter new_val) { funcExeInst = new_val; } }; #endif // __CPU_OZONE_THREAD_STATE_HH__ diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 91ac0b6a5..071193f02 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -196,7 +196,7 @@ void AtomicSimpleCPU::activateContext(int thread_num, int delay) { assert(thread_num == 0); - assert(cpuXC); + assert(thread); assert(_status == Idle); assert(!tickEvent.scheduled()); @@ -211,7 +211,7 @@ void AtomicSimpleCPU::suspendContext(int thread_num) { assert(thread_num == 0); - assert(cpuXC); + assert(thread); assert(_status == Running); @@ -229,14 +229,14 @@ template <class T> Fault AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags) { - data_read_req->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC()); + data_read_req->setVirt(0, addr, sizeof(T), flags, thread->readPC()); if (traceData) { traceData->setAddr(addr); } // translate to physical address - Fault fault = cpuXC->translateDataReadReq(data_read_req); + Fault fault = thread->translateDataReadReq(data_read_req); // Now do the access. if (fault == NoFault) { @@ -304,14 +304,14 @@ template <class T> Fault AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) { - data_write_req->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC()); + data_write_req->setVirt(0, addr, sizeof(T), flags, thread->readPC()); if (traceData) { traceData->setAddr(addr); } // translate to physical address - Fault fault = cpuXC->translateDataWriteReq(data_write_req); + Fault fault = thread->translateDataWriteReq(data_write_req); // Now do the access. if (fault == NoFault) { diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index d36aa93a2..c1ecf3967 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -38,18 +38,18 @@ #include "base/stats/events.hh" #include "base/trace.hh" #include "cpu/base.hh" -#include "cpu/cpu_exec_context.hh" -#include "cpu/thread_context.hh" #include "cpu/exetrace.hh" #include "cpu/profile.hh" #include "cpu/sampler/sampler.hh" #include "cpu/simple/base.hh" +#include "cpu/simple_thread.hh" #include "cpu/smt.hh" #include "cpu/static_inst.hh" +#include "cpu/thread_context.hh" #include "kern/kernel_stats.hh" #include "mem/packet_impl.hh" -#include "sim/byteswap.hh" #include "sim/builder.hh" +#include "sim/byteswap.hh" #include "sim/debug.hh" #include "sim/host.hh" #include "sim/sim_events.hh" @@ -70,18 +70,18 @@ using namespace std; using namespace TheISA; BaseSimpleCPU::BaseSimpleCPU(Params *p) - : BaseCPU(p), mem(p->mem), cpuXC(NULL) + : BaseCPU(p), mem(p->mem), thread(NULL) { #if FULL_SYSTEM - cpuXC = new CPUExecContext(this, 0, p->system, p->itb, p->dtb); + thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb); #else - cpuXC = new CPUExecContext(this, /* thread_num */ 0, p->process, + thread = new SimpleThread(this, /* thread_num */ 0, p->process, /* asid */ 0, mem); #endif // !FULL_SYSTEM - cpuXC->setStatus(ThreadContext::Suspended); + thread->setStatus(ThreadContext::Suspended); - tc = cpuXC->getTC(); + tc = thread->getTC(); numInst = 0; startNumInst = 0; @@ -180,7 +180,7 @@ BaseSimpleCPU::serialize(ostream &os) BaseCPU::serialize(os); SERIALIZE_SCALAR(inst); nameOut(os, csprintf("%s.xc", name())); - cpuXC->serialize(os); + thread->serialize(os); } void @@ -188,7 +188,7 @@ BaseSimpleCPU::unserialize(Checkpoint *cp, const string §ion) { BaseCPU::unserialize(cp, section); UNSERIALIZE_SCALAR(inst); - cpuXC->unserialize(cp, csprintf("%s.xc", section)); + thread->unserialize(cp, csprintf("%s.xc", section)); } void @@ -217,16 +217,16 @@ BaseSimpleCPU::copySrcTranslate(Addr src) memReq->reset(src & ~(blk_size - 1), blk_size); // translate to physical address - Fault fault = cpuXC->translateDataReadReq(req); + Fault fault = thread->translateDataReadReq(req); if (fault == NoFault) { - cpuXC->copySrcAddr = src; - cpuXC->copySrcPhysAddr = memReq->paddr + offset; + thread->copySrcAddr = src; + thread->copySrcPhysAddr = memReq->paddr + offset; } else { assert(!fault->isAlignmentFault()); - cpuXC->copySrcAddr = 0; - cpuXC->copySrcPhysAddr = 0; + thread->copySrcAddr = 0; + thread->copySrcPhysAddr = 0; } return fault; #else @@ -243,7 +243,7 @@ BaseSimpleCPU::copy(Addr dest) // Only support block sizes of 64 atm. assert(blk_size == 64); uint8_t data[blk_size]; - //assert(cpuXC->copySrcAddr); + //assert(thread->copySrcAddr); int offset = dest & (blk_size - 1); // Make sure block doesn't span page @@ -256,19 +256,19 @@ BaseSimpleCPU::copy(Addr dest) memReq->reset(dest & ~(blk_size -1), blk_size); // translate to physical address - Fault fault = cpuXC->translateDataWriteReq(req); + Fault fault = thread->translateDataWriteReq(req); if (fault == NoFault) { Addr dest_addr = memReq->paddr + offset; // Need to read straight from memory since we have more than 8 bytes. - memReq->paddr = cpuXC->copySrcPhysAddr; - cpuXC->mem->read(memReq, data); + memReq->paddr = thread->copySrcPhysAddr; + thread->mem->read(memReq, data); memReq->paddr = dest_addr; - cpuXC->mem->write(memReq, data); + thread->mem->write(memReq, data); if (dcacheInterface) { memReq->cmd = Copy; memReq->completionEvent = NULL; - memReq->paddr = cpuXC->copySrcPhysAddr; + memReq->paddr = thread->copySrcPhysAddr; memReq->dest = dest_addr; memReq->size = 64; memReq->time = curTick; @@ -300,9 +300,9 @@ BaseSimpleCPU::post_interrupt(int int_num, int index) { BaseCPU::post_interrupt(int_num, index); - if (cpuXC->status() == ThreadContext::Suspended) { + if (thread->status() == ThreadContext::Suspended) { DPRINTF(IPI,"Suspended Processor awoke\n"); - cpuXC->activate(); + thread->activate(); } } #endif // FULL_SYSTEM @@ -311,15 +311,15 @@ void BaseSimpleCPU::checkForInterrupts() { #if FULL_SYSTEM - if (checkInterrupts && check_interrupts() && !cpuXC->inPalMode()) { + if (checkInterrupts && check_interrupts() && !thread->inPalMode()) { int ipl = 0; int summary = 0; checkInterrupts = false; - if (cpuXC->readMiscReg(IPR_SIRR)) { + if (thread->readMiscReg(IPR_SIRR)) { for (int i = INTLEVEL_SOFTWARE_MIN; i < INTLEVEL_SOFTWARE_MAX; i++) { - if (cpuXC->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { + if (thread->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { // See table 4-19 of 21164 hardware reference ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; summary |= (ULL(1) << i); @@ -327,7 +327,7 @@ BaseSimpleCPU::checkForInterrupts() } } - uint64_t interrupts = cpuXC->cpu->intr_status(); + uint64_t interrupts = thread->cpu->intr_status(); for (int i = INTLEVEL_EXTERNAL_MIN; i < INTLEVEL_EXTERNAL_MAX; i++) { if (interrupts & (ULL(1) << i)) { @@ -337,17 +337,17 @@ BaseSimpleCPU::checkForInterrupts() } } - if (cpuXC->readMiscReg(IPR_ASTRR)) + if (thread->readMiscReg(IPR_ASTRR)) panic("asynchronous traps not implemented\n"); - if (ipl && ipl > cpuXC->readMiscReg(IPR_IPLR)) { - cpuXC->setMiscReg(IPR_ISR, summary); - cpuXC->setMiscReg(IPR_INTID, ipl); + if (ipl && ipl > thread->readMiscReg(IPR_IPLR)) { + thread->setMiscReg(IPR_ISR, summary); + thread->setMiscReg(IPR_INTID, ipl); Fault(new InterruptFault)->invoke(tc); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - cpuXC->readMiscReg(IPR_IPLR), ipl, summary); + thread->readMiscReg(IPR_IPLR), ipl, summary); } } #endif @@ -358,14 +358,14 @@ Fault BaseSimpleCPU::setupFetchRequest(Request *req) { // set up memory request for instruction fetch - DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",cpuXC->readPC(), - cpuXC->readNextPC(),cpuXC->readNextNPC()); + DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",thread->readPC(), + thread->readNextPC(),thread->readNextNPC()); - req->setVirt(0, cpuXC->readPC() & ~3, sizeof(MachInst), - (FULL_SYSTEM && (cpuXC->readPC() & 1)) ? PHYSICAL : 0, - cpuXC->readPC()); + req->setVirt(0, thread->readPC() & ~3, sizeof(MachInst), + (FULL_SYSTEM && (thread->readPC() & 1)) ? PHYSICAL : 0, + thread->readPC()); - Fault fault = cpuXC->translateInstReq(req); + Fault fault = thread->translateInstReq(req); return fault; } @@ -375,33 +375,33 @@ void BaseSimpleCPU::preExecute() { // maintain $r0 semantics - cpuXC->setIntReg(ZeroReg, 0); + thread->setIntReg(ZeroReg, 0); #if THE_ISA == ALPHA_ISA - cpuXC->setFloatReg(ZeroReg, 0.0); + thread->setFloatReg(ZeroReg, 0.0); #endif // ALPHA_ISA // keep an instruction count numInst++; numInsts++; - cpuXC->func_exe_inst++; + thread->funcExeInst++; // check for instruction-count-based events comInstEventQueue[0]->serviceEvents(numInst); // decode the instruction inst = gtoh(inst); - curStaticInst = StaticInst::decode(makeExtMI(inst, cpuXC->readPC())); + curStaticInst = StaticInst::decode(makeExtMI(inst, thread->readPC())); traceData = Trace::getInstRecord(curTick, tc, this, curStaticInst, - cpuXC->readPC()); + thread->readPC()); DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n", curStaticInst->getName(), curStaticInst->getOpcode(), curStaticInst->machInst); #if FULL_SYSTEM - cpuXC->setInst(inst); + thread->setInst(inst); #endif // FULL_SYSTEM } @@ -410,17 +410,17 @@ BaseSimpleCPU::postExecute() { #if FULL_SYSTEM if (system->kernelBinning->fnbin) { - assert(cpuXC->getKernelStats()); + assert(thread->getKernelStats()); system->kernelBinning->execute(tc, inst); } - if (cpuXC->profile) { + if (thread->profile) { bool usermode = - (cpuXC->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; - cpuXC->profilePC = usermode ? 1 : cpuXC->readPC(); - ProfileNode *node = cpuXC->profile->consume(tc, inst); + (thread->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; + thread->profilePC = usermode ? 1 : thread->readPC(); + ProfileNode *node = thread->profile->consume(tc, inst); if (node) - cpuXC->profileNode = node; + thread->profileNode = node; } #endif @@ -433,7 +433,7 @@ BaseSimpleCPU::postExecute() comLoadEventQueue[0]->serviceEvents(numLoad); } - traceFunctions(cpuXC->readPC()); + traceFunctions(thread->readPC()); if (traceData) { traceData->finalize(); @@ -448,17 +448,17 @@ BaseSimpleCPU::advancePC(Fault fault) #if FULL_SYSTEM fault->invoke(tc); #else // !FULL_SYSTEM - fatal("fault (%s) detected @ PC %08p", fault->name(), cpuXC->readPC()); + fatal("fault (%s) detected @ PC %08p", fault->name(), thread->readPC()); #endif // FULL_SYSTEM } else { // go to the next instruction - cpuXC->setPC(cpuXC->readNextPC()); + thread->setPC(thread->readNextPC()); #if THE_ISA == ALPHA_ISA - cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst)); + thread->setNextPC(thread->readNextPC() + sizeof(MachInst)); #else - cpuXC->setNextPC(cpuXC->readNextNPC()); - cpuXC->setNextNPC(cpuXC->readNextNPC() + sizeof(MachInst)); + thread->setNextPC(thread->readNextNPC()); + thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst)); #endif } @@ -466,9 +466,9 @@ BaseSimpleCPU::advancePC(Fault fault) #if FULL_SYSTEM Addr oldpc; do { - oldpc = cpuXC->readPC(); + oldpc = thread->readPC(); system->pcEventQueue.service(tc); - } while (oldpc != cpuXC->readPC()); + } while (oldpc != thread->readPC()); #endif } diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index bc17ece56..39bc86050 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -36,7 +36,7 @@ #include "base/statistics.hh" #include "config/full_system.hh" #include "cpu/base.hh" -#include "cpu/cpu_exec_context.hh" +#include "cpu/simple_thread.hh" #include "cpu/pc_event.hh" #include "cpu/sampler/sampler.hh" #include "cpu/static_inst.hh" @@ -108,9 +108,12 @@ class BaseSimpleCPU : public BaseCPU virtual ~BaseSimpleCPU(); public: - // execution context - CPUExecContext *cpuXC; + /** SimpleThread object, provides all the architectural state. */ + SimpleThread *thread; + /** ThreadContext object, provides an interface for external + * objects to modify this thread's state. + */ ThreadContext *tc; #if FULL_SYSTEM @@ -217,103 +220,103 @@ class BaseSimpleCPU : public BaseCPU uint64_t readIntReg(const StaticInst *si, int idx) { - return cpuXC->readIntReg(si->srcRegIdx(idx)); + return thread->readIntReg(si->srcRegIdx(idx)); } FloatReg readFloatReg(const StaticInst *si, int idx, int width) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return cpuXC->readFloatReg(reg_idx, width); + return thread->readFloatReg(reg_idx, width); } FloatReg readFloatReg(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return cpuXC->readFloatReg(reg_idx); + return thread->readFloatReg(reg_idx); } FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return cpuXC->readFloatRegBits(reg_idx, width); + return thread->readFloatRegBits(reg_idx, width); } FloatRegBits readFloatRegBits(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return cpuXC->readFloatRegBits(reg_idx); + return thread->readFloatRegBits(reg_idx); } void setIntReg(const StaticInst *si, int idx, uint64_t val) { - cpuXC->setIntReg(si->destRegIdx(idx), val); + thread->setIntReg(si->destRegIdx(idx), val); } void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - cpuXC->setFloatReg(reg_idx, val, width); + thread->setFloatReg(reg_idx, val, width); } void setFloatReg(const StaticInst *si, int idx, FloatReg val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - cpuXC->setFloatReg(reg_idx, val); + thread->setFloatReg(reg_idx, val); } void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val, int width) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - cpuXC->setFloatRegBits(reg_idx, val, width); + thread->setFloatRegBits(reg_idx, val, width); } void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - cpuXC->setFloatRegBits(reg_idx, val); + thread->setFloatRegBits(reg_idx, val); } - uint64_t readPC() { return cpuXC->readPC(); } - uint64_t readNextPC() { return cpuXC->readNextPC(); } - uint64_t readNextNPC() { return cpuXC->readNextNPC(); } + uint64_t readPC() { return thread->readPC(); } + uint64_t readNextPC() { return thread->readNextPC(); } + uint64_t readNextNPC() { return thread->readNextNPC(); } - void setPC(uint64_t val) { cpuXC->setPC(val); } - void setNextPC(uint64_t val) { cpuXC->setNextPC(val); } - void setNextNPC(uint64_t val) { cpuXC->setNextNPC(val); } + void setPC(uint64_t val) { thread->setPC(val); } + void setNextPC(uint64_t val) { thread->setNextPC(val); } + void setNextNPC(uint64_t val) { thread->setNextNPC(val); } MiscReg readMiscReg(int misc_reg) { - return cpuXC->readMiscReg(misc_reg); + return thread->readMiscReg(misc_reg); } MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) { - return cpuXC->readMiscRegWithEffect(misc_reg, fault); + return thread->readMiscRegWithEffect(misc_reg, fault); } Fault setMiscReg(int misc_reg, const MiscReg &val) { - return cpuXC->setMiscReg(misc_reg, val); + return thread->setMiscReg(misc_reg, val); } Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) { - return cpuXC->setMiscRegWithEffect(misc_reg, val); + return thread->setMiscRegWithEffect(misc_reg, val); } #if FULL_SYSTEM - Fault hwrei() { return cpuXC->hwrei(); } - int readIntrFlag() { return cpuXC->readIntrFlag(); } - void setIntrFlag(int val) { cpuXC->setIntrFlag(val); } - bool inPalMode() { return cpuXC->inPalMode(); } + Fault hwrei() { return thread->hwrei(); } + int readIntrFlag() { return thread->readIntrFlag(); } + void setIntrFlag(int val) { thread->setIntrFlag(val); } + bool inPalMode() { return thread->inPalMode(); } void ev5_trap(Fault fault) { fault->invoke(tc); } - bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); } + bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } #else - void syscall(int64_t callnum) { cpuXC->syscall(callnum); } + void syscall(int64_t callnum) { thread->syscall(callnum); } #endif - bool misspeculating() { return cpuXC->misspeculating(); } + bool misspeculating() { return thread->misspeculating(); } ThreadContext *tcBase() { return tc; } }; diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 00c6de037..c99db8fbf 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -141,7 +141,7 @@ void TimingSimpleCPU::activateContext(int thread_num, int delay) { assert(thread_num == 0); - assert(cpuXC); + assert(thread); assert(_status == Idle); @@ -158,7 +158,7 @@ void TimingSimpleCPU::suspendContext(int thread_num) { assert(thread_num == 0); - assert(cpuXC); + assert(thread); assert(_status == Running); @@ -177,14 +177,14 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags) // need to fill in CPU & thread IDs here Request *data_read_req = new Request(); - data_read_req->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC()); + data_read_req->setVirt(0, addr, sizeof(T), flags, thread->readPC()); if (traceData) { traceData->setAddr(data_read_req->getVaddr()); } // translate to physical address - Fault fault = cpuXC->translateDataReadReq(data_read_req); + Fault fault = thread->translateDataReadReq(data_read_req); // Now do the access. if (fault == NoFault) { @@ -257,10 +257,10 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) { // need to fill in CPU & thread IDs here Request *data_write_req = new Request(); - data_write_req->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC()); + data_write_req->setVirt(0, addr, sizeof(T), flags, thread->readPC()); // translate to physical address - Fault fault = cpuXC->translateDataWriteReq(data_write_req); + Fault fault = thread->translateDataWriteReq(data_write_req); // Now do the access. if (fault == NoFault) { Packet *data_write_pkt = diff --git a/src/cpu/cpu_exec_context.cc b/src/cpu/simple_thread.cc index 1e8071ca8..219167e4e 100644 --- a/src/cpu/cpu_exec_context.cc +++ b/src/cpu/simple_thread.cc @@ -35,7 +35,7 @@ #include "arch/isa_traits.hh" #include "cpu/base.hh" -#include "cpu/cpu_exec_context.hh" +#include "cpu/simple_thread.hh" #include "cpu/thread_context.hh" #if FULL_SYSTEM @@ -59,15 +59,14 @@ using namespace std; // constructor #if FULL_SYSTEM -CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, - AlphaITB *_itb, AlphaDTB *_dtb, - bool use_kernel_stats) - : _status(ThreadContext::Unallocated), cpu(_cpu), thread_num(_thread_num), - cpu_id(-1), lastActivate(0), lastSuspend(0), system(_sys), itb(_itb), - dtb(_dtb), profile(NULL), func_exe_inst(0), storeCondFailures(0) +SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys, + AlphaITB *_itb, AlphaDTB *_dtb, + bool use_kernel_stats) + : ThreadState(-1, _thread_num), cpu(_cpu), system(_sys), itb(_itb), + dtb(_dtb) { - tc = new ProxyThreadContext<CPUExecContext>(this); + tc = new ProxyThreadContext<SimpleThread>(this); quiesceEvent = new EndQuiesceEvent(tc); @@ -76,8 +75,8 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, if (cpu->params->profile) { profile = new FunctionProfile(system->kernelSymtab); Callback *cb = - new MakeCallback<CPUExecContext, - &CPUExecContext::dumpFuncProfile>(this); + new MakeCallback<SimpleThread, + &SimpleThread::dumpFuncProfile>(this); registerExitCallback(cb); } @@ -87,7 +86,6 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, profileNode = &dummyNode; profilePC = 3; - if (use_kernel_stats) { kernelStats = new Kernel::Statistics(system); } else { @@ -95,79 +93,52 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, } Port *mem_port; physPort = new FunctionalPort(csprintf("%s-%d-funcport", - cpu->name(), thread_num)); + cpu->name(), tid)); mem_port = system->physmem->getPort("functional"); mem_port->setPeer(physPort); physPort->setPeer(mem_port); virtPort = new VirtualPort(csprintf("%s-%d-vport", - cpu->name(), thread_num)); + cpu->name(), tid)); mem_port = system->physmem->getPort("functional"); mem_port->setPeer(virtPort); virtPort->setPeer(mem_port); } #else -CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, +SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid, MemObject* memobj) - : _status(ThreadContext::Unallocated), - cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0), - lastSuspend(0), process(_process), asid(_asid), - func_exe_inst(0), storeCondFailures(0) + : ThreadState(-1, _thread_num, memobj, _process, _asid), + cpu(_cpu) { /* Use this port to for syscall emulation writes to memory. */ Port *mem_port; port = new TranslatingPort(csprintf("%s-%d-funcport", - cpu->name(), thread_num), + cpu->name(), tid), process->pTable, false); mem_port = memobj->getPort("functional"); mem_port->setPeer(port); port->setPeer(mem_port); regs.clear(); - tc = new ProxyThreadContext<CPUExecContext>(this); + tc = new ProxyThreadContext<SimpleThread>(this); } -CPUExecContext::CPUExecContext(RegFile *regFile) - : cpu(NULL), thread_num(-1), process(NULL), asid(-1), - func_exe_inst(0), storeCondFailures(0) +SimpleThread::SimpleThread(RegFile *regFile) + : ThreadState(-1, -1, NULL, NULL, -1), cpu(NULL) { regs = *regFile; - tc = new ProxyThreadContext<CPUExecContext>(this); + tc = new ProxyThreadContext<SimpleThread>(this); } #endif -CPUExecContext::~CPUExecContext() +SimpleThread::~SimpleThread() { delete tc; } -#if FULL_SYSTEM void -CPUExecContext::dumpFuncProfile() -{ - std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); - profile->dump(tc, *os); -} - -void -CPUExecContext::profileClear() -{ - if (profile) - profile->clear(); -} - -void -CPUExecContext::profileSample() -{ - if (profile) - profile->sample(profileNode, profilePC); -} - -#endif - -void -CPUExecContext::takeOverFrom(ThreadContext *oldContext) +SimpleThread::takeOverFrom(ThreadContext *oldContext) { // some things should already be set up #if FULL_SYSTEM @@ -179,9 +150,9 @@ CPUExecContext::takeOverFrom(ThreadContext *oldContext) // copy over functional state _status = oldContext->status(); copyArchRegs(oldContext); - cpu_id = oldContext->readCpuId(); + cpuId = oldContext->readCpuId(); #if !FULL_SYSTEM - func_exe_inst = oldContext->readFuncExeInst(); + funcExeInst = oldContext->readFuncExeInst(); #else EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent(); if (quiesce) { @@ -200,12 +171,12 @@ CPUExecContext::takeOverFrom(ThreadContext *oldContext) } void -CPUExecContext::serialize(ostream &os) +SimpleThread::serialize(ostream &os) { SERIALIZE_ENUM(_status); regs.serialize(os); // thread_num and cpu_id are deterministic from the config - SERIALIZE_SCALAR(func_exe_inst); + SERIALIZE_SCALAR(funcExeInst); SERIALIZE_SCALAR(inst); #if FULL_SYSTEM @@ -220,12 +191,12 @@ CPUExecContext::serialize(ostream &os) void -CPUExecContext::unserialize(Checkpoint *cp, const std::string §ion) +SimpleThread::unserialize(Checkpoint *cp, const std::string §ion) { UNSERIALIZE_ENUM(_status); regs.unserialize(cp, section); // thread_num and cpu_id are deterministic from the config - UNSERIALIZE_SCALAR(func_exe_inst); + UNSERIALIZE_SCALAR(funcExeInst); UNSERIALIZE_SCALAR(inst); #if FULL_SYSTEM @@ -238,9 +209,17 @@ CPUExecContext::unserialize(Checkpoint *cp, const std::string §ion) #endif } +#if FULL_SYSTEM +void +SimpleThread::dumpFuncProfile() +{ + std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); + profile->dump(tc, *os); +} +#endif void -CPUExecContext::activate(int delay) +SimpleThread::activate(int delay) { if (status() == ThreadContext::Active) return; @@ -248,18 +227,18 @@ CPUExecContext::activate(int delay) lastActivate = curTick; if (status() == ThreadContext::Unallocated) { - cpu->activateWhenReady(thread_num); + cpu->activateWhenReady(tid); return; } _status = ThreadContext::Active; // status() == Suspended - cpu->activateContext(thread_num, delay); + cpu->activateContext(tid, delay); } void -CPUExecContext::suspend() +SimpleThread::suspend() { if (status() == ThreadContext::Suspended) return; @@ -276,32 +255,32 @@ CPUExecContext::suspend() #endif */ _status = ThreadContext::Suspended; - cpu->suspendContext(thread_num); + cpu->suspendContext(tid); } void -CPUExecContext::deallocate() +SimpleThread::deallocate() { if (status() == ThreadContext::Unallocated) return; _status = ThreadContext::Unallocated; - cpu->deallocateContext(thread_num); + cpu->deallocateContext(tid); } void -CPUExecContext::halt() +SimpleThread::halt() { if (status() == ThreadContext::Halted) return; _status = ThreadContext::Halted; - cpu->haltContext(thread_num); + cpu->haltContext(tid); } void -CPUExecContext::regStats(const string &name) +SimpleThread::regStats(const string &name) { #if FULL_SYSTEM if (kernelStats) @@ -310,14 +289,14 @@ CPUExecContext::regStats(const string &name) } void -CPUExecContext::copyArchRegs(ThreadContext *src_tc) +SimpleThread::copyArchRegs(ThreadContext *src_tc) { TheISA::copyRegs(src_tc, tc); } #if FULL_SYSTEM VirtualPort* -CPUExecContext::getVirtPort(ThreadContext *src_tc) +SimpleThread::getVirtPort(ThreadContext *src_tc) { if (!src_tc) return virtPort; @@ -333,7 +312,7 @@ CPUExecContext::getVirtPort(ThreadContext *src_tc) } void -CPUExecContext::delVirtPort(VirtualPort *vp) +SimpleThread::delVirtPort(VirtualPort *vp) { // assert(!vp->nullThreadContext()); delete vp->getPeer(); diff --git a/src/cpu/cpu_exec_context.hh b/src/cpu/simple_thread.hh index 01b5cbb15..de65e9891 100644 --- a/src/cpu/cpu_exec_context.hh +++ b/src/cpu/simple_thread.hh @@ -29,12 +29,13 @@ * Nathan Binkert */ -#ifndef __CPU_CPU_EXEC_CONTEXT_HH__ -#define __CPU_CPU_EXEC_CONTEXT_HH__ +#ifndef __CPU_SIMPLE_THREAD_HH__ +#define __CPU_SIMPLE_THREAD_HH__ #include "arch/isa_traits.hh" #include "config/full_system.hh" #include "cpu/thread_context.hh" +#include "cpu/thread_state.hh" #include "mem/physical.hh" #include "mem/request.hh" #include "sim/byteswap.hh" @@ -54,7 +55,6 @@ class ProfileNode; class FunctionalPort; class PhysicalPort; - namespace Kernel { class Statistics; }; @@ -65,16 +65,25 @@ namespace Kernel { #include "mem/page_table.hh" class TranslatingPort; - #endif // FULL_SYSTEM -// -// The CPUExecContext object represents a functional context for -// instruction execution. It incorporates everything required for -// architecture-level functional simulation of a single thread. -// +/** + * The SimpleThread object provides a combination of the ThreadState + * object and the ThreadContext interface. It implements the + * ThreadContext interface so that a ProxyThreadContext class can be + * made using SimpleThread as the template parameter (see + * thread_context.hh). It adds to the ThreadState object by adding all + * the objects needed for simple functional execution, including a + * simple architectural register file, and pointers to the ITB and DTB + * in full system mode. For CPU models that do not need more advanced + * ways to hold state (i.e. a separate physical register file, or + * separate fetch and commit PC's), this SimpleThread class provides + * all the necessary state for full architecture-level functional + * simulation. See the AtomicSimpleCPU or TimingSimpleCPU for + * examples. + */ -class CPUExecContext +class SimpleThread : public ThreadState { protected: typedef TheISA::RegFile RegFile; @@ -86,134 +95,35 @@ class CPUExecContext public: typedef ThreadContext::Status Status; - private: - Status _status; - - public: - Status status() const { return _status; } - - void setStatus(Status newStatus) { _status = newStatus; } - - /// 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(); - protected: RegFile regs; // correct-path register context public: - // pointer to CPU associated with this context + // pointer to CPU associated with this SimpleThread BaseCPU *cpu; - ProxyThreadContext<CPUExecContext> *tc; - - // Current instruction - MachInst inst; - - // Index of hardware thread context on the CPU that this represents. - int thread_num; - - // 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; - - Tick lastActivate; - Tick lastSuspend; + ProxyThreadContext<SimpleThread> *tc; System *system; - #if FULL_SYSTEM AlphaITB *itb; AlphaDTB *dtb; - - /** A functional port outgoing only for functional accesses to physical - * addresses.*/ - FunctionalPort *physPort; - - /** A functional port, outgoing only, for functional accesse to virtual - * addresses. That doen't require execution context information */ - VirtualPort *virtPort; - - FunctionProfile *profile; - ProfileNode *profileNode; - Addr profilePC; - void dumpFuncProfile(); - - EndQuiesceEvent *quiesceEvent; - - EndQuiesceEvent *getQuiesceEvent() { return quiesceEvent; } - - Tick readLastActivate() { return lastActivate; } - - Tick readLastSuspend() { return lastSuspend; } - - void profileClear(); - - void profileSample(); - - Kernel::Statistics *getKernelStats() { return kernelStats; } - - Kernel::Statistics *kernelStats; -#else - /// Port that syscalls can use to access memory (provides translation step). - TranslatingPort *port; - - Process *process; - - // Address space ID. Note that this is used for TIMING cache - // simulation only; all functional memory accesses should use - // one of the FunctionalMemory pointers above. - short asid; - #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_inst; - - // - // Count failed store conditionals so we can warn of apparent - // application deadlock situations. - unsigned storeCondFailures; - - // constructor: initialize context from given process structure + // constructor: initialize SimpleThread from given process structure #if FULL_SYSTEM - CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_system, - AlphaITB *_itb, AlphaDTB *_dtb, - bool use_kernel_stats = true); + SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system, + AlphaITB *_itb, AlphaDTB *_dtb, + bool use_kernel_stats = true); #else - CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid, - MemObject *memobj); - // Constructor to use XC to pass reg file around. Not used for anything - // else. - CPUExecContext(RegFile *regFile); + SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid, + MemObject *memobj); + // Constructor to use SimpleThread to pass reg file around. Not + // used for anything else. + SimpleThread(RegFile *regFile); #endif - virtual ~CPUExecContext(); + virtual ~SimpleThread(); virtual void takeOverFrom(ThreadContext *oldContext); @@ -222,19 +132,18 @@ class CPUExecContext void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); - BaseCPU *getCpuPtr() { return cpu; } + /*************************************************************** + * SimpleThread functions to provide CPU with access to various + * state, and to provide address translation methods. + **************************************************************/ + /** Returns the pointer to this SimpleThread's ThreadContext. Used + * when a ThreadContext must be passed to objects outside of the + * CPU. + */ ThreadContext *getTC() { return tc; } - int getThreadNum() { return thread_num; } - #if FULL_SYSTEM - System *getSystemPtr() { return system; } - - AlphaITB *getITBPtr() { return itb; } - - AlphaDTB *getDTBPtr() { return dtb; } - int getInstAsid() { return regs.instAsid(); } int getDataAsid() { return regs.dataAsid(); } @@ -253,23 +162,14 @@ class CPUExecContext return dtb->translate(req, tc, true); } - FunctionalPort *getPhysPort() { return physPort; } - - /** Return a virtual port. If no thread context is specified then a static - * port is returned. Otherwise a port is created and returned. It must be - * deleted by deleteVirtPort(). */ - VirtualPort *getVirtPort(ThreadContext *tc); + void dumpFuncProfile(); - void delVirtPort(VirtualPort *vp); + int readIntrFlag() { return regs.intrflag; } + void setIntrFlag(int val) { regs.intrflag = val; } + Fault hwrei(); + bool simPalCheck(int palFunc); #else - TranslatingPort *getMemPort() { return port; } - - Process *getProcessPtr() { return process; } - - int getInstAsid() { return asid; } - int getDataAsid() { return asid; } - Fault translateInstReq(RequestPtr &req) { return process->pTable->translate(req); @@ -284,9 +184,50 @@ class CPUExecContext { return process->pTable->translate(req); } +#endif + + /******************************************* + * ThreadContext interface functions. + ******************************************/ + + BaseCPU *getCpuPtr() { return cpu; } + + int getThreadNum() { return tid; } +#if FULL_SYSTEM + System *getSystemPtr() { return system; } + + AlphaITB *getITBPtr() { return itb; } + + AlphaDTB *getDTBPtr() { return dtb; } + + FunctionalPort *getPhysPort() { return physPort; } + + /** Return a virtual port. If no thread context is specified then a static + * port is returned. Otherwise a port is created and returned. It must be + * deleted by deleteVirtPort(). */ + VirtualPort *getVirtPort(ThreadContext *tc); + + void delVirtPort(VirtualPort *vp); #endif + Status status() const { return _status; } + + void setStatus(Status newStatus) { _status = newStatus; } + + /// 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(); + /* template <class T> Fault read(RequestPtr &req, T &data) @@ -358,14 +299,6 @@ class CPUExecContext */ virtual bool misspeculating(); - - MachInst getInst() { return inst; } - - void setInst(MachInst new_inst) - { - inst = new_inst; - } - Fault instRead(RequestPtr &req) { panic("instRead not implemented"); @@ -373,12 +306,10 @@ class CPUExecContext return NoFault; } - void setCpuId(int id) { cpu_id = id; } - - int readCpuId() { return cpu_id; } - void copyArchRegs(ThreadContext *tc); + void clearArchRegs() { regs.clear(); } + // // New accessors for new decoder. // @@ -462,7 +393,6 @@ class CPUExecContext regs.setNextNPC(val); } - MiscReg readMiscReg(int misc_reg) { return regs.readMiscReg(misc_reg); @@ -488,14 +418,8 @@ class CPUExecContext void setStCondFailures(unsigned sc_failures) { storeCondFailures = sc_failures; } - void clearArchRegs() { regs.clear(); } - #if FULL_SYSTEM - int readIntrFlag() { return regs.intrflag; } - void setIntrFlag(int val) { regs.intrflag = val; } - Fault hwrei(); bool inPalMode() { return AlphaISA::PcPAL(regs.readPC()); } - bool simPalCheck(int palFunc); #endif #if !FULL_SYSTEM @@ -519,10 +443,6 @@ class CPUExecContext { process->syscall(callnum, tc); } - - Counter readFuncExeInst() { return func_exe_inst; } - - void setFuncExeInst(Counter new_val) { func_exe_inst = new_val; } #endif void changeRegFileContext(RegFile::ContextParam param, @@ -535,7 +455,7 @@ class CPUExecContext // for non-speculative execution context, spec_mode is always false inline bool -CPUExecContext::misspeculating() +SimpleThread::misspeculating() { return false; } diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc new file mode 100644 index 000000000..9712ffa23 --- /dev/null +++ b/src/cpu/thread_state.cc @@ -0,0 +1,46 @@ +#include "base/output.hh" +#include "cpu/profile.hh" +#include "cpu/thread_state.hh" + +#if FULL_SYSTEM +ThreadState::ThreadState(int _cpuId, int _tid) + : cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0), + profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL), + funcExeInst(0), storeCondFailures(0) +#else +ThreadState::ThreadState(int _cpuId, int _tid, MemObject *mem, + Process *_process, short _asid) + : cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0), + process(_process), asid(_asid), + funcExeInst(0), storeCondFailures(0) +#endif +{ +#if !FULL_SYSTEM + /* Use this port to for syscall emulation writes to memory. */ + Port *mem_port; + port = new TranslatingPort(csprintf("%d-funcport", + tid), + process->pTable, false); + mem_port = mem->getPort("functional"); + mem_port->setPeer(port); + port->setPeer(mem_port); +#endif +} + +#if FULL_SYSTEM + +void +ThreadState::profileClear() +{ + if (profile) + profile->clear(); +} + +void +ThreadState::profileSample() +{ + if (profile) + profile->sample(profileNode, profilePC); +} + +#endif diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh index 6d64c94f7..d72697cb7 100644 --- a/src/cpu/thread_state.hh +++ b/src/cpu/thread_state.hh @@ -29,10 +29,13 @@ #ifndef __CPU_THREAD_STATE_HH__ #define __CPU_THREAD_STATE_HH__ +#include "arch/isa_traits.hh" #include "cpu/thread_context.hh" #if !FULL_SYSTEM +#include "mem/mem_object.hh" #include "mem/translating_port.hh" +#include "sim/process.hh" #endif #if FULL_SYSTEM @@ -42,9 +45,6 @@ class ProfileNode; namespace Kernel { class Statistics; }; -#else -class FunctionalMemory; -class Process; #endif /** @@ -54,56 +54,121 @@ class Process; * to hold more thread-specific stats within it. */ struct ThreadState { + typedef ThreadContext::Status Status; + #if FULL_SYSTEM - ThreadState(int _cpuId, int _tid) - : cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0), - profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL) + ThreadState(int _cpuId, int _tid); #else ThreadState(int _cpuId, int _tid, MemObject *mem, - Process *_process, short _asid) - : cpuId(_cpuId), tid(_tid), process(_process), asid(_asid) + Process *_process, short _asid); #endif - { - funcExeInst = 0; - storeCondFailures = 0; -#if !FULL_SYSTEM - /* Use this port to for syscall emulation writes to memory. */ - Port *mem_port; - port = new TranslatingPort(csprintf("%d-funcport", - tid), - process->pTable, false); - mem_port = mem->getPort("functional"); - mem_port->setPeer(port); - port->setPeer(mem_port); + + void setCpuId(int id) { cpuId = id; } + + int readCpuId() { return cpuId; } + + void setTid(int id) { tid = id; } + + int readTid() { return tid; } + + Tick readLastActivate() { return lastActivate; } + + Tick readLastSuspend() { return lastSuspend; } + +#if FULL_SYSTEM + void dumpFuncProfile(); + + EndQuiesceEvent *getQuiesceEvent() { return quiesceEvent; } + + void profileClear(); + + void profileSample(); + + Kernel::Statistics *getKernelStats() { return kernelStats; } + + void setPhysPort(FunctionalPort *port) { physPort = port; } + + void setVirtPort(VirtualPort *port) { virtPort = port; } +#else + Process *getProcessPtr() { return process; } + + TranslatingPort *getMemPort() { return port; } + + void setMemPort(TranslatingPort *_port) { port = _port; } + + int getInstAsid() { return asid; } + int getDataAsid() { return asid; } #endif - } - ThreadContext::Status status; + /** Sets the current instruction being committed. */ + void setInst(TheISA::MachInst _inst) { inst = _inst; } - int cpuId; + /** Returns the current instruction being committed. */ + TheISA::MachInst getInst() { return inst; } - // Index of hardware thread context on the CPU that this represents. - int tid; + /** Reads the number of instructions functionally executed and + * committed. + */ + Counter readFuncExeInst() { return funcExeInst; } + + /** Sets the total number of instructions functionally executed + * and committed. + */ + void setFuncExeInst(Counter new_val) { funcExeInst = new_val; } + + /** Returns the status of this thread. */ + Status status() const { return _status; } + /** Sets the status of this thread. */ + void setStatus(Status new_status) { _status = new_status; } + + /** Number of instructions committed. */ Counter numInst; + /** Stat for number instructions committed. */ Stats::Scalar<> numInsts; + /** Stat for number of memory references. */ Stats::Scalar<> numMemRefs; - // number of simulated loads + /** Number of simulated loads, used for tracking events based on + * the number of loads committed. + */ Counter numLoad; + + /** The number of simulated loads committed prior to this run. */ Counter startNumLoad; -#if FULL_SYSTEM + protected: + ThreadContext::Status _status; + + // 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 cpuId; + + // Index of hardware thread context on the CPU that this represents. + int tid; + + /** Last time activate was called on this thread. */ Tick lastActivate; + + /** Last time suspend was called on this thread. */ Tick lastSuspend; +#if FULL_SYSTEM + public: FunctionProfile *profile; ProfileNode *profileNode; Addr profilePC; - EndQuiesceEvent *quiesceEvent; Kernel::Statistics *kernelStats; + protected: + /** A functional port outgoing only for functional accesses to physical + * addresses.*/ + FunctionalPort *physPort; + + /** A functional port, outgoing only, for functional accesse to virtual + * addresses. That doen't require execution context information */ + VirtualPort *virtPort; #else TranslatingPort *port; @@ -113,9 +178,13 @@ struct ThreadState { // simulation only; all functional memory accesses should use // one of the FunctionalMemory pointers above. short asid; - #endif + /** Current instruction the thread is committing. Only set and + * used for DTB faults currently. + */ + TheISA::MachInst inst; + /** * Temporary storage to pass the source address from copy_load to * copy_store. @@ -128,6 +197,7 @@ struct ThreadState { */ Addr copySrcPhysAddr; + public: /* * number of executed instructions, for matching with syscall trace * points in EIO files. diff --git a/src/kern/system_events.cc b/src/kern/system_events.cc index aca75e27d..fe3805ce2 100644 --- a/src/kern/system_events.cc +++ b/src/kern/system_events.cc @@ -30,7 +30,7 @@ */ #include "cpu/base.hh" -#include "cpu/cpu_exec_context.hh" +#include "cpu/thread_context.hh" #include "kern/kernel_stats.hh" #include "kern/system_events.hh" #include "sim/system.hh" diff --git a/src/sim/process.hh b/src/sim/process.hh index 15d564455..edbc1e492 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -46,7 +46,6 @@ #include "base/statistics.hh" #include "sim/sim_object.hh" -class CPUExecContext; class ThreadContext; class SyscallDesc; class PageTable; |