Reorganization/renaming of CPUExecContext. Now it is called SimpleThread in order...
authorKevin Lim <ktlim@umich.edu>
Wed, 7 Jun 2006 19:29:53 +0000 (15:29 -0400)
committerKevin Lim <ktlim@umich.edu>
Wed, 7 Jun 2006 19:29:53 +0000 (15:29 -0400)
Following with the previous check-in, ExecContext now refers only to the interface provided to the ISA in order to access CPU state.  ThreadContext refers to the interface provided to all objects outside the CPU in order to access thread state.  SimpleThread provides all thread state and the interface to access it, and is suitable for simple execution models such as the SimpleCPU.

src/SConscript:
    Include thread state file.
src/arch/alpha/ev5.cc:
src/cpu/checker/cpu.cc:
src/cpu/checker/cpu.hh:
src/cpu/checker/thread_context.hh:
src/cpu/memtest/memtest.cc:
src/cpu/memtest/memtest.hh:
src/cpu/o3/cpu.cc:
src/cpu/ozone/cpu_impl.hh:
src/cpu/simple/atomic.cc:
src/cpu/simple/base.cc:
src/cpu/simple/base.hh:
src/cpu/simple/timing.cc:
    Rename CPUExecContext to SimpleThread.
src/cpu/base_dyn_inst.hh:
    Make thread member variables protected..
src/cpu/o3/alpha_cpu.hh:
src/cpu/o3/cpu.hh:
    Make various members of ThreadState protected.
src/cpu/o3/alpha_cpu_impl.hh:
    Push generation of TranslatingPort into the CPU itself.
    Make various members of ThreadState protected.
src/cpu/o3/thread_state.hh:
    Pull a lot of common code into the base ThreadState class.
src/cpu/ozone/thread_state.hh:
    Rename CPUExecContext to SimpleThread, move a lot of common code into base ThreadState class.
src/cpu/thread_state.hh:
    Push a lot of common code into base ThreadState class.  This goes along with renaming CPUExecContext to SimpleThread, and making it derive from ThreadState.
src/cpu/simple_thread.cc:
    Rename CPUExecContext to SimpleThread, make it derive from ThreadState.  This helps push a lot of common code/state into a single class that can be used by all CPUs.
src/cpu/simple_thread.hh:
    Rename CPUExecContext to SimpleThread, make it derive from ThreadState.
src/kern/system_events.cc:
    Rename cpu_exec_context to thread_context.
src/sim/process.hh:
    Remove unused forward declaration.

--HG--
rename : src/cpu/cpu_exec_context.cc => src/cpu/simple_thread.cc
rename : src/cpu/cpu_exec_context.hh => src/cpu/simple_thread.hh
extra : convert_revision : 2ed617aa80b64016cb9270f75352607cca032733

27 files changed:
src/SConscript
src/arch/alpha/ev5.cc
src/cpu/base_dyn_inst.hh
src/cpu/checker/cpu.cc
src/cpu/checker/cpu.hh
src/cpu/checker/thread_context.hh
src/cpu/cpu_exec_context.cc [deleted file]
src/cpu/cpu_exec_context.hh [deleted file]
src/cpu/memtest/memtest.cc
src/cpu/memtest/memtest.hh
src/cpu/o3/alpha_cpu.hh
src/cpu/o3/alpha_cpu_impl.hh
src/cpu/o3/cpu.cc
src/cpu/o3/cpu.hh
src/cpu/o3/thread_state.hh
src/cpu/ozone/cpu_impl.hh
src/cpu/ozone/thread_state.hh
src/cpu/simple/atomic.cc
src/cpu/simple/base.cc
src/cpu/simple/base.hh
src/cpu/simple/timing.cc
src/cpu/simple_thread.cc [new file with mode: 0644]
src/cpu/simple_thread.hh [new file with mode: 0644]
src/cpu/thread_state.cc [new file with mode: 0644]
src/cpu/thread_state.hh
src/kern/system_events.cc
src/sim/process.hh

index 3fc9d4c2fb3ee92cfdd96b30f191ebf990f2ef4a..d29ecb7bbb71b84519350cf53a1507588c262f18 100644 (file)
@@ -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
         
index 50ce6b78a88f6043741bc592924022f33df70626..c419762b757fb063f673182ad4d85a7171081151 100644 (file)
@@ -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);
index 0657be32478cdd61255ad26c6f9410272851c0ef..e69e00d6cc934abf75c6473c35b970e2dda8c913 100644 (file)
@@ -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) {
index 7ae7047e86e9d94846354cb5b0ad9a3ac2da39ff..2d2f67e6bef9d0707ef7d09e712abf2f4608577d 100644 (file)
@@ -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 &section)
 /*
     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();
         }
     }
index 484f4cf04fed1a71ce0839f16c2605adbb0bda32..f733becd404ab6659b993753daf69556a2ef374c 100644 (file)
@@ -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;
index 48890584d98d9b09ea49f956336ecd09d2ba9650..d3eb9cf0c04ddc8d625e601cfe8dcc7e71e75d59 100644 (file)
  * 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/cpu_exec_context.cc b/src/cpu/cpu_exec_context.cc
deleted file mode 100644 (file)
index 1e8071c..0000000
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (c) 2001-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.
- *
- * Authors: Steve Reinhardt
- *          Nathan Binkert
- *          Lisa Hsu
- *          Kevin Lim
- */
-
-#include <string>
-
-#include "arch/isa_traits.hh"
-#include "cpu/base.hh"
-#include "cpu/cpu_exec_context.hh"
-#include "cpu/thread_context.hh"
-
-#if FULL_SYSTEM
-#include "base/callback.hh"
-#include "base/cprintf.hh"
-#include "base/output.hh"
-#include "base/trace.hh"
-#include "cpu/profile.hh"
-#include "cpu/quiesce_event.hh"
-#include "kern/kernel_stats.hh"
-#include "sim/serialize.hh"
-#include "sim/sim_exit.hh"
-#include "arch/stacktrace.hh"
-#else
-#include "sim/process.hh"
-#include "sim/system.hh"
-#include "mem/translating_port.hh"
-#endif
-
-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)
-
-{
-    tc = new ProxyThreadContext<CPUExecContext>(this);
-
-    quiesceEvent = new EndQuiesceEvent(tc);
-
-    regs.clear();
-
-    if (cpu->params->profile) {
-        profile = new FunctionProfile(system->kernelSymtab);
-        Callback *cb =
-            new MakeCallback<CPUExecContext,
-            &CPUExecContext::dumpFuncProfile>(this);
-        registerExitCallback(cb);
-    }
-
-    // let's fill with a dummy node for now so we don't get a segfault
-    // on the first cycle when there's no node available.
-    static ProfileNode dummyNode;
-    profileNode = &dummyNode;
-    profilePC = 3;
-
-
-    if (use_kernel_stats) {
-        kernelStats = new Kernel::Statistics(system);
-    } else {
-        kernelStats = NULL;
-    }
-    Port *mem_port;
-    physPort = new FunctionalPort(csprintf("%s-%d-funcport",
-                                           cpu->name(), thread_num));
-    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));
-    mem_port = system->physmem->getPort("functional");
-    mem_port->setPeer(virtPort);
-    virtPort->setPeer(mem_port);
-}
-#else
-CPUExecContext::CPUExecContext(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)
-{
-    /* Use this port to for syscall emulation writes to memory. */
-    Port *mem_port;
-    port = new TranslatingPort(csprintf("%s-%d-funcport",
-                                        cpu->name(), thread_num),
-                               process->pTable, false);
-    mem_port = memobj->getPort("functional");
-    mem_port->setPeer(port);
-    port->setPeer(mem_port);
-
-    regs.clear();
-    tc = new ProxyThreadContext<CPUExecContext>(this);
-}
-
-CPUExecContext::CPUExecContext(RegFile *regFile)
-    : cpu(NULL), thread_num(-1), process(NULL), asid(-1),
-      func_exe_inst(0), storeCondFailures(0)
-{
-    regs = *regFile;
-    tc = new ProxyThreadContext<CPUExecContext>(this);
-}
-
-#endif
-
-CPUExecContext::~CPUExecContext()
-{
-    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)
-{
-    // some things should already be set up
-#if FULL_SYSTEM
-    assert(system == oldContext->getSystemPtr());
-#else
-    assert(process == oldContext->getProcessPtr());
-#endif
-
-    // copy over functional state
-    _status = oldContext->status();
-    copyArchRegs(oldContext);
-    cpu_id = oldContext->readCpuId();
-#if !FULL_SYSTEM
-    func_exe_inst = oldContext->readFuncExeInst();
-#else
-    EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent();
-    if (quiesce) {
-        // Point the quiesce event's TC at this TC so that it wakes up
-        // the proper CPU.
-        quiesce->tc = tc;
-    }
-    if (quiesceEvent) {
-        quiesceEvent->tc = tc;
-    }
-#endif
-
-    storeCondFailures = 0;
-
-    oldContext->setStatus(ThreadContext::Unallocated);
-}
-
-void
-CPUExecContext::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(inst);
-
-#if FULL_SYSTEM
-    Tick quiesceEndTick = 0;
-    if (quiesceEvent->scheduled())
-        quiesceEndTick = quiesceEvent->when();
-    SERIALIZE_SCALAR(quiesceEndTick);
-    if (kernelStats)
-        kernelStats->serialize(os);
-#endif
-}
-
-
-void
-CPUExecContext::unserialize(Checkpoint *cp, const std::string &section)
-{
-    UNSERIALIZE_ENUM(_status);
-    regs.unserialize(cp, section);
-    // thread_num and cpu_id are deterministic from the config
-    UNSERIALIZE_SCALAR(func_exe_inst);
-    UNSERIALIZE_SCALAR(inst);
-
-#if FULL_SYSTEM
-    Tick quiesceEndTick;
-    UNSERIALIZE_SCALAR(quiesceEndTick);
-    if (quiesceEndTick)
-        quiesceEvent->schedule(quiesceEndTick);
-    if (kernelStats)
-        kernelStats->unserialize(cp, section);
-#endif
-}
-
-
-void
-CPUExecContext::activate(int delay)
-{
-    if (status() == ThreadContext::Active)
-        return;
-
-    lastActivate = curTick;
-
-    if (status() == ThreadContext::Unallocated) {
-        cpu->activateWhenReady(thread_num);
-        return;
-    }
-
-    _status = ThreadContext::Active;
-
-    // status() == Suspended
-    cpu->activateContext(thread_num, delay);
-}
-
-void
-CPUExecContext::suspend()
-{
-    if (status() == ThreadContext::Suspended)
-        return;
-
-    lastActivate = curTick;
-    lastSuspend = curTick;
-/*
-#if FULL_SYSTEM
-    // Don't change the status from active if there are pending interrupts
-    if (cpu->check_interrupts()) {
-        assert(status() == ThreadContext::Active);
-        return;
-    }
-#endif
-*/
-    _status = ThreadContext::Suspended;
-    cpu->suspendContext(thread_num);
-}
-
-void
-CPUExecContext::deallocate()
-{
-    if (status() == ThreadContext::Unallocated)
-        return;
-
-    _status = ThreadContext::Unallocated;
-    cpu->deallocateContext(thread_num);
-}
-
-void
-CPUExecContext::halt()
-{
-    if (status() == ThreadContext::Halted)
-        return;
-
-    _status = ThreadContext::Halted;
-    cpu->haltContext(thread_num);
-}
-
-
-void
-CPUExecContext::regStats(const string &name)
-{
-#if FULL_SYSTEM
-    if (kernelStats)
-        kernelStats->regStats(name + ".kern");
-#endif
-}
-
-void
-CPUExecContext::copyArchRegs(ThreadContext *src_tc)
-{
-    TheISA::copyRegs(src_tc, tc);
-}
-
-#if FULL_SYSTEM
-VirtualPort*
-CPUExecContext::getVirtPort(ThreadContext *src_tc)
-{
-    if (!src_tc)
-        return virtPort;
-
-    VirtualPort *vp;
-    Port *mem_port;
-
-    vp = new VirtualPort("tc-vport", src_tc);
-    mem_port = system->physmem->getPort("functional");
-    mem_port->setPeer(vp);
-    vp->setPeer(mem_port);
-    return vp;
-}
-
-void
-CPUExecContext::delVirtPort(VirtualPort *vp)
-{
-//    assert(!vp->nullThreadContext());
-    delete vp->getPeer();
-    delete vp;
-}
-
-
-#endif
-
diff --git a/src/cpu/cpu_exec_context.hh b/src/cpu/cpu_exec_context.hh
deleted file mode 100644 (file)
index 01b5cbb..0000000
+++ /dev/null
@@ -1,543 +0,0 @@
-/*
- * Copyright (c) 2001-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.
- *
- * Authors: Steve Reinhardt
- *          Nathan Binkert
- */
-
-#ifndef __CPU_CPU_EXEC_CONTEXT_HH__
-#define __CPU_CPU_EXEC_CONTEXT_HH__
-
-#include "arch/isa_traits.hh"
-#include "config/full_system.hh"
-#include "cpu/thread_context.hh"
-#include "mem/physical.hh"
-#include "mem/request.hh"
-#include "sim/byteswap.hh"
-#include "sim/eventq.hh"
-#include "sim/host.hh"
-#include "sim/serialize.hh"
-
-class BaseCPU;
-
-#if FULL_SYSTEM
-
-#include "sim/system.hh"
-#include "arch/tlb.hh"
-
-class FunctionProfile;
-class ProfileNode;
-class FunctionalPort;
-class PhysicalPort;
-
-
-namespace Kernel {
-    class Statistics;
-};
-
-#else // !FULL_SYSTEM
-
-#include "sim/process.hh"
-#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.
-//
-
-class CPUExecContext
-{
-  protected:
-    typedef TheISA::RegFile RegFile;
-    typedef TheISA::MachInst MachInst;
-    typedef TheISA::MiscRegFile MiscRegFile;
-    typedef TheISA::MiscReg MiscReg;
-    typedef TheISA::FloatReg FloatReg;
-    typedef TheISA::FloatRegBits FloatRegBits;
-  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
-    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;
-
-    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
-#if FULL_SYSTEM
-    CPUExecContext(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);
-#endif
-    virtual ~CPUExecContext();
-
-    virtual void takeOverFrom(ThreadContext *oldContext);
-
-    void regStats(const std::string &name);
-
-    void serialize(std::ostream &os);
-    void unserialize(Checkpoint *cp, const std::string &section);
-
-    BaseCPU *getCpuPtr() { return 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(); }
-
-    Fault translateInstReq(RequestPtr &req)
-    {
-        return itb->translate(req, tc);
-    }
-
-    Fault translateDataReadReq(RequestPtr &req)
-    {
-        return dtb->translate(req, tc, false);
-    }
-
-    Fault translateDataWriteReq(RequestPtr &req)
-    {
-        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 delVirtPort(VirtualPort *vp);
-
-#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);
-    }
-
-    Fault translateDataReadReq(RequestPtr &req)
-    {
-        return process->pTable->translate(req);
-    }
-
-    Fault translateDataWriteReq(RequestPtr &req)
-    {
-        return process->pTable->translate(req);
-    }
-
-#endif
-
-/*
-    template <class T>
-    Fault read(RequestPtr &req, T &data)
-    {
-#if FULL_SYSTEM && THE_ISA == ALPHA_ISA
-        if (req->flags & LOCKED) {
-            req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr);
-            req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true);
-        }
-#endif
-
-        Fault error;
-        error = mem->prot_read(req->paddr, data, req->size);
-        data = LittleEndianGuest::gtoh(data);
-        return error;
-    }
-
-    template <class T>
-    Fault write(RequestPtr &req, T &data)
-    {
-#if FULL_SYSTEM && THE_ISA == ALPHA_ISA
-        ExecContext *xc;
-
-        // If this is a store conditional, act appropriately
-        if (req->flags & LOCKED) {
-            xc = req->xc;
-
-            if (req->flags & UNCACHEABLE) {
-                // Don't update result register (see stq_c in isa_desc)
-                req->result = 2;
-                xc->setStCondFailures(0);//Needed? [RGD]
-            } else {
-                bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag);
-                Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag);
-                req->result = lock_flag;
-                if (!lock_flag ||
-                    ((lock_addr & ~0xf) != (req->paddr & ~0xf))) {
-                    xc->setMiscReg(TheISA::Lock_Flag_DepTag, false);
-                    xc->setStCondFailures(xc->readStCondFailures() + 1);
-                    if (((xc->readStCondFailures()) % 100000) == 0) {
-                        std::cerr << "Warning: "
-                                  << xc->readStCondFailures()
-                                  << " consecutive store conditional failures "
-                                  << "on cpu " << req->xc->readCpuId()
-                                  << std::endl;
-                    }
-                    return NoFault;
-                }
-                else xc->setStCondFailures(0);
-            }
-        }
-
-        // Need to clear any locked flags on other proccessors for
-        // this address.  Only do this for succsful Store Conditionals
-        // and all other stores (WH64?).  Unsuccessful Store
-        // Conditionals would have returned above, and wouldn't fall
-        // through.
-        for (int i = 0; i < system->execContexts.size(); i++){
-            xc = system->execContexts[i];
-            if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) ==
-                (req->paddr & ~0xf)) {
-                xc->setMiscReg(TheISA::Lock_Flag_DepTag, false);
-            }
-        }
-
-#endif
-        return mem->prot_write(req->paddr, (T)htog(data), req->size);
-    }
-*/
-    virtual bool misspeculating();
-
-
-    MachInst getInst() { return inst; }
-
-    void setInst(MachInst new_inst)
-    {
-        inst = new_inst;
-    }
-
-    Fault instRead(RequestPtr &req)
-    {
-        panic("instRead not implemented");
-        // return funcPhysMem->read(req, inst);
-        return NoFault;
-    }
-
-    void setCpuId(int id) { cpu_id = id; }
-
-    int readCpuId() { return cpu_id; }
-
-    void copyArchRegs(ThreadContext *tc);
-
-    //
-    // New accessors for new decoder.
-    //
-    uint64_t readIntReg(int reg_idx)
-    {
-        return regs.readIntReg(reg_idx);
-    }
-
-    FloatReg readFloatReg(int reg_idx, int width)
-    {
-        return regs.readFloatReg(reg_idx, width);
-    }
-
-    FloatReg readFloatReg(int reg_idx)
-    {
-        return regs.readFloatReg(reg_idx);
-    }
-
-    FloatRegBits readFloatRegBits(int reg_idx, int width)
-    {
-        return regs.readFloatRegBits(reg_idx, width);
-    }
-
-    FloatRegBits readFloatRegBits(int reg_idx)
-    {
-        return regs.readFloatRegBits(reg_idx);
-    }
-
-    void setIntReg(int reg_idx, uint64_t val)
-    {
-        regs.setIntReg(reg_idx, val);
-    }
-
-    void setFloatReg(int reg_idx, FloatReg val, int width)
-    {
-        regs.setFloatReg(reg_idx, val, width);
-    }
-
-    void setFloatReg(int reg_idx, FloatReg val)
-    {
-        regs.setFloatReg(reg_idx, val);
-    }
-
-    void setFloatRegBits(int reg_idx, FloatRegBits val, int width)
-    {
-        regs.setFloatRegBits(reg_idx, val, width);
-    }
-
-    void setFloatRegBits(int reg_idx, FloatRegBits val)
-    {
-        regs.setFloatRegBits(reg_idx, val);
-    }
-
-    uint64_t readPC()
-    {
-        return regs.readPC();
-    }
-
-    void setPC(uint64_t val)
-    {
-        regs.setPC(val);
-    }
-
-    uint64_t readNextPC()
-    {
-        return regs.readNextPC();
-    }
-
-    void setNextPC(uint64_t val)
-    {
-        regs.setNextPC(val);
-    }
-
-    uint64_t readNextNPC()
-    {
-        return regs.readNextNPC();
-    }
-
-    void setNextNPC(uint64_t val)
-    {
-        regs.setNextNPC(val);
-    }
-
-
-    MiscReg readMiscReg(int misc_reg)
-    {
-        return regs.readMiscReg(misc_reg);
-    }
-
-    MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
-    {
-        return regs.readMiscRegWithEffect(misc_reg, fault, tc);
-    }
-
-    Fault setMiscReg(int misc_reg, const MiscReg &val)
-    {
-        return regs.setMiscReg(misc_reg, val);
-    }
-
-    Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
-    {
-        return regs.setMiscRegWithEffect(misc_reg, val, tc);
-    }
-
-    unsigned readStCondFailures() { return storeCondFailures; }
-
-    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
-    TheISA::IntReg getSyscallArg(int i)
-    {
-        return regs.readIntReg(TheISA::ArgumentReg0 + i);
-    }
-
-    // used to shift args for indirect syscall
-    void setSyscallArg(int i, TheISA::IntReg val)
-    {
-        regs.setIntReg(TheISA::ArgumentReg0 + i, val);
-    }
-
-    void setSyscallReturn(SyscallReturn return_value)
-    {
-        TheISA::setSyscallReturn(return_value, &regs);
-    }
-
-    void syscall(int64_t callnum)
-    {
-        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,
-            RegFile::ContextVal val)
-    {
-        regs.changeContext(param, val);
-    }
-};
-
-
-// for non-speculative execution context, spec_mode is always false
-inline bool
-CPUExecContext::misspeculating()
-{
-    return false;
-}
-
-#endif // __CPU_CPU_EXEC_CONTEXT_HH__
index 62e539250b6d9d5ad250d8744e8a3f332d719a4b..7ea9eaefcce8016b06ba4d0c4158bf17e9230f31 100644 (file)
@@ -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
index 9976000e91abb9dcc48e02b570d7beb390c70111..42fb235db43a6ada9a9d4b4343b029244c3b0078 100644 (file)
@@ -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
 
index 588b11724530adfdc4e92c766a7a0f2f94e5f404..3449454bd298aa9372a541c4fba23a07db3266ab 100644 (file)
@@ -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;
                 }
             }
index 7f3d916401e6a6cc0c0f44371ab55e8b949a15d9..2debe074b4fbede0825ee1f88afce1a796465639 100644 (file)
@@ -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",
index f523766cc95c1f7db329f1c89b4570d5a1badae4..c5f78d63dd171299b9777c9a7fddc3075c25567c 100644 (file)
@@ -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
index 69f52f147eae92016b8c23caac9dc9fb86a853d5..8e482f1e526f9f045f84bc6e93d181e45aa8e028 100644 (file)
@@ -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
 
index 7322161e649eaedee590367bbd2e1b3c6096cf2f..38d37ec96ed2e5617d08bb6a4e4c2428775b350d 100644 (file)
@@ -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); }
index 0763a30b3b6bdffa9135c82195d3b677e4d123ef..76e2318aa740e607ff5fb25eae70f6ae0dd6a02f 100644 (file)
@@ -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());
index c91297e735a551aa58c3c2b44a12de636c3eae79..e6256e4e367befa1c836909c895c09df07d71c61 100644 (file)
@@ -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__
index 91ac0b6a56c75056e80f73ab1bfa4f8be78a197a..071193f02e01a4154c658ba91b9d81be6ada515a 100644 (file)
@@ -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) {
index d36aa93a20d1a00b5ef50c6e8da4da67b7c49266..c1ecf396764744bce32ab863a3ea780e1fb75868 100644 (file)
 #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 &section)
 {
     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
 }
 
index bc17ece563bea6eb5fb16ed76b3742fdb0fd4513..39bc86050ebee726b0f996daa8dd21e5ed092058 100644 (file)
@@ -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; }
 };
 
index 00c6de0376d6a2e264b6155de4a02a92e54a06d7..c99db8fbfa378b97abc50f496b2522f06b2ec5f0 100644 (file)
@@ -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/simple_thread.cc b/src/cpu/simple_thread.cc
new file mode 100644 (file)
index 0000000..219167e
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2001-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.
+ *
+ * Authors: Steve Reinhardt
+ *          Nathan Binkert
+ *          Lisa Hsu
+ *          Kevin Lim
+ */
+
+#include <string>
+
+#include "arch/isa_traits.hh"
+#include "cpu/base.hh"
+#include "cpu/simple_thread.hh"
+#include "cpu/thread_context.hh"
+
+#if FULL_SYSTEM
+#include "base/callback.hh"
+#include "base/cprintf.hh"
+#include "base/output.hh"
+#include "base/trace.hh"
+#include "cpu/profile.hh"
+#include "cpu/quiesce_event.hh"
+#include "kern/kernel_stats.hh"
+#include "sim/serialize.hh"
+#include "sim/sim_exit.hh"
+#include "arch/stacktrace.hh"
+#else
+#include "sim/process.hh"
+#include "sim/system.hh"
+#include "mem/translating_port.hh"
+#endif
+
+using namespace std;
+
+// constructor
+#if FULL_SYSTEM
+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<SimpleThread>(this);
+
+    quiesceEvent = new EndQuiesceEvent(tc);
+
+    regs.clear();
+
+    if (cpu->params->profile) {
+        profile = new FunctionProfile(system->kernelSymtab);
+        Callback *cb =
+            new MakeCallback<SimpleThread,
+            &SimpleThread::dumpFuncProfile>(this);
+        registerExitCallback(cb);
+    }
+
+    // let's fill with a dummy node for now so we don't get a segfault
+    // on the first cycle when there's no node available.
+    static ProfileNode dummyNode;
+    profileNode = &dummyNode;
+    profilePC = 3;
+
+    if (use_kernel_stats) {
+        kernelStats = new Kernel::Statistics(system);
+    } else {
+        kernelStats = NULL;
+    }
+    Port *mem_port;
+    physPort = new FunctionalPort(csprintf("%s-%d-funcport",
+                                           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(), tid));
+    mem_port = system->physmem->getPort("functional");
+    mem_port->setPeer(virtPort);
+    virtPort->setPeer(mem_port);
+}
+#else
+SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num,
+                         Process *_process, int _asid, MemObject* memobj)
+    : 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(), tid),
+                               process->pTable, false);
+    mem_port = memobj->getPort("functional");
+    mem_port->setPeer(port);
+    port->setPeer(mem_port);
+
+    regs.clear();
+    tc = new ProxyThreadContext<SimpleThread>(this);
+}
+
+SimpleThread::SimpleThread(RegFile *regFile)
+    : ThreadState(-1, -1, NULL, NULL, -1), cpu(NULL)
+{
+    regs = *regFile;
+    tc = new ProxyThreadContext<SimpleThread>(this);
+}
+
+#endif
+
+SimpleThread::~SimpleThread()
+{
+    delete tc;
+}
+
+void
+SimpleThread::takeOverFrom(ThreadContext *oldContext)
+{
+    // some things should already be set up
+#if FULL_SYSTEM
+    assert(system == oldContext->getSystemPtr());
+#else
+    assert(process == oldContext->getProcessPtr());
+#endif
+
+    // copy over functional state
+    _status = oldContext->status();
+    copyArchRegs(oldContext);
+    cpuId = oldContext->readCpuId();
+#if !FULL_SYSTEM
+    funcExeInst = oldContext->readFuncExeInst();
+#else
+    EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent();
+    if (quiesce) {
+        // Point the quiesce event's TC at this TC so that it wakes up
+        // the proper CPU.
+        quiesce->tc = tc;
+    }
+    if (quiesceEvent) {
+        quiesceEvent->tc = tc;
+    }
+#endif
+
+    storeCondFailures = 0;
+
+    oldContext->setStatus(ThreadContext::Unallocated);
+}
+
+void
+SimpleThread::serialize(ostream &os)
+{
+    SERIALIZE_ENUM(_status);
+    regs.serialize(os);
+    // thread_num and cpu_id are deterministic from the config
+    SERIALIZE_SCALAR(funcExeInst);
+    SERIALIZE_SCALAR(inst);
+
+#if FULL_SYSTEM
+    Tick quiesceEndTick = 0;
+    if (quiesceEvent->scheduled())
+        quiesceEndTick = quiesceEvent->when();
+    SERIALIZE_SCALAR(quiesceEndTick);
+    if (kernelStats)
+        kernelStats->serialize(os);
+#endif
+}
+
+
+void
+SimpleThread::unserialize(Checkpoint *cp, const std::string &section)
+{
+    UNSERIALIZE_ENUM(_status);
+    regs.unserialize(cp, section);
+    // thread_num and cpu_id are deterministic from the config
+    UNSERIALIZE_SCALAR(funcExeInst);
+    UNSERIALIZE_SCALAR(inst);
+
+#if FULL_SYSTEM
+    Tick quiesceEndTick;
+    UNSERIALIZE_SCALAR(quiesceEndTick);
+    if (quiesceEndTick)
+        quiesceEvent->schedule(quiesceEndTick);
+    if (kernelStats)
+        kernelStats->unserialize(cp, section);
+#endif
+}
+
+#if FULL_SYSTEM
+void
+SimpleThread::dumpFuncProfile()
+{
+    std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
+    profile->dump(tc, *os);
+}
+#endif
+
+void
+SimpleThread::activate(int delay)
+{
+    if (status() == ThreadContext::Active)
+        return;
+
+    lastActivate = curTick;
+
+    if (status() == ThreadContext::Unallocated) {
+        cpu->activateWhenReady(tid);
+        return;
+    }
+
+    _status = ThreadContext::Active;
+
+    // status() == Suspended
+    cpu->activateContext(tid, delay);
+}
+
+void
+SimpleThread::suspend()
+{
+    if (status() == ThreadContext::Suspended)
+        return;
+
+    lastActivate = curTick;
+    lastSuspend = curTick;
+/*
+#if FULL_SYSTEM
+    // Don't change the status from active if there are pending interrupts
+    if (cpu->check_interrupts()) {
+        assert(status() == ThreadContext::Active);
+        return;
+    }
+#endif
+*/
+    _status = ThreadContext::Suspended;
+    cpu->suspendContext(tid);
+}
+
+void
+SimpleThread::deallocate()
+{
+    if (status() == ThreadContext::Unallocated)
+        return;
+
+    _status = ThreadContext::Unallocated;
+    cpu->deallocateContext(tid);
+}
+
+void
+SimpleThread::halt()
+{
+    if (status() == ThreadContext::Halted)
+        return;
+
+    _status = ThreadContext::Halted;
+    cpu->haltContext(tid);
+}
+
+
+void
+SimpleThread::regStats(const string &name)
+{
+#if FULL_SYSTEM
+    if (kernelStats)
+        kernelStats->regStats(name + ".kern");
+#endif
+}
+
+void
+SimpleThread::copyArchRegs(ThreadContext *src_tc)
+{
+    TheISA::copyRegs(src_tc, tc);
+}
+
+#if FULL_SYSTEM
+VirtualPort*
+SimpleThread::getVirtPort(ThreadContext *src_tc)
+{
+    if (!src_tc)
+        return virtPort;
+
+    VirtualPort *vp;
+    Port *mem_port;
+
+    vp = new VirtualPort("tc-vport", src_tc);
+    mem_port = system->physmem->getPort("functional");
+    mem_port->setPeer(vp);
+    vp->setPeer(mem_port);
+    return vp;
+}
+
+void
+SimpleThread::delVirtPort(VirtualPort *vp)
+{
+//    assert(!vp->nullThreadContext());
+    delete vp->getPeer();
+    delete vp;
+}
+
+
+#endif
+
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
new file mode 100644 (file)
index 0000000..de65e98
--- /dev/null
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2001-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.
+ *
+ * Authors: Steve Reinhardt
+ *          Nathan Binkert
+ */
+
+#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"
+#include "sim/eventq.hh"
+#include "sim/host.hh"
+#include "sim/serialize.hh"
+
+class BaseCPU;
+
+#if FULL_SYSTEM
+
+#include "sim/system.hh"
+#include "arch/tlb.hh"
+
+class FunctionProfile;
+class ProfileNode;
+class FunctionalPort;
+class PhysicalPort;
+
+namespace Kernel {
+    class Statistics;
+};
+
+#else // !FULL_SYSTEM
+
+#include "sim/process.hh"
+#include "mem/page_table.hh"
+class TranslatingPort;
+
+#endif // FULL_SYSTEM
+
+/**
+ * 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 SimpleThread : public ThreadState
+{
+  protected:
+    typedef TheISA::RegFile RegFile;
+    typedef TheISA::MachInst MachInst;
+    typedef TheISA::MiscRegFile MiscRegFile;
+    typedef TheISA::MiscReg MiscReg;
+    typedef TheISA::FloatReg FloatReg;
+    typedef TheISA::FloatRegBits FloatRegBits;
+  public:
+    typedef ThreadContext::Status Status;
+
+  protected:
+    RegFile regs;      // correct-path register context
+
+  public:
+    // pointer to CPU associated with this SimpleThread
+    BaseCPU *cpu;
+
+    ProxyThreadContext<SimpleThread> *tc;
+
+    System *system;
+
+#if FULL_SYSTEM
+    AlphaITB *itb;
+    AlphaDTB *dtb;
+#endif
+
+    // constructor: initialize SimpleThread from given process structure
+#if FULL_SYSTEM
+    SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
+                 AlphaITB *_itb, AlphaDTB *_dtb,
+                 bool use_kernel_stats = true);
+#else
+    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 ~SimpleThread();
+
+    virtual void takeOverFrom(ThreadContext *oldContext);
+
+    void regStats(const std::string &name);
+
+    void serialize(std::ostream &os);
+    void unserialize(Checkpoint *cp, const std::string &section);
+
+    /***************************************************************
+     *  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; }
+
+#if FULL_SYSTEM
+    int getInstAsid() { return regs.instAsid(); }
+    int getDataAsid() { return regs.dataAsid(); }
+
+    Fault translateInstReq(RequestPtr &req)
+    {
+        return itb->translate(req, tc);
+    }
+
+    Fault translateDataReadReq(RequestPtr &req)
+    {
+        return dtb->translate(req, tc, false);
+    }
+
+    Fault translateDataWriteReq(RequestPtr &req)
+    {
+        return dtb->translate(req, tc, true);
+    }
+
+    void dumpFuncProfile();
+
+    int readIntrFlag() { return regs.intrflag; }
+    void setIntrFlag(int val) { regs.intrflag = val; }
+    Fault hwrei();
+
+    bool simPalCheck(int palFunc);
+#else
+    Fault translateInstReq(RequestPtr &req)
+    {
+        return process->pTable->translate(req);
+    }
+
+    Fault translateDataReadReq(RequestPtr &req)
+    {
+        return process->pTable->translate(req);
+    }
+
+    Fault translateDataWriteReq(RequestPtr &req)
+    {
+        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)
+    {
+#if FULL_SYSTEM && THE_ISA == ALPHA_ISA
+        if (req->flags & LOCKED) {
+            req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr);
+            req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true);
+        }
+#endif
+
+        Fault error;
+        error = mem->prot_read(req->paddr, data, req->size);
+        data = LittleEndianGuest::gtoh(data);
+        return error;
+    }
+
+    template <class T>
+    Fault write(RequestPtr &req, T &data)
+    {
+#if FULL_SYSTEM && THE_ISA == ALPHA_ISA
+        ExecContext *xc;
+
+        // If this is a store conditional, act appropriately
+        if (req->flags & LOCKED) {
+            xc = req->xc;
+
+            if (req->flags & UNCACHEABLE) {
+                // Don't update result register (see stq_c in isa_desc)
+                req->result = 2;
+                xc->setStCondFailures(0);//Needed? [RGD]
+            } else {
+                bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag);
+                Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag);
+                req->result = lock_flag;
+                if (!lock_flag ||
+                    ((lock_addr & ~0xf) != (req->paddr & ~0xf))) {
+                    xc->setMiscReg(TheISA::Lock_Flag_DepTag, false);
+                    xc->setStCondFailures(xc->readStCondFailures() + 1);
+                    if (((xc->readStCondFailures()) % 100000) == 0) {
+                        std::cerr << "Warning: "
+                                  << xc->readStCondFailures()
+                                  << " consecutive store conditional failures "
+                                  << "on cpu " << req->xc->readCpuId()
+                                  << std::endl;
+                    }
+                    return NoFault;
+                }
+                else xc->setStCondFailures(0);
+            }
+        }
+
+        // Need to clear any locked flags on other proccessors for
+        // this address.  Only do this for succsful Store Conditionals
+        // and all other stores (WH64?).  Unsuccessful Store
+        // Conditionals would have returned above, and wouldn't fall
+        // through.
+        for (int i = 0; i < system->execContexts.size(); i++){
+            xc = system->execContexts[i];
+            if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) ==
+                (req->paddr & ~0xf)) {
+                xc->setMiscReg(TheISA::Lock_Flag_DepTag, false);
+            }
+        }
+
+#endif
+        return mem->prot_write(req->paddr, (T)htog(data), req->size);
+    }
+*/
+    virtual bool misspeculating();
+
+    Fault instRead(RequestPtr &req)
+    {
+        panic("instRead not implemented");
+        // return funcPhysMem->read(req, inst);
+        return NoFault;
+    }
+
+    void copyArchRegs(ThreadContext *tc);
+
+    void clearArchRegs() { regs.clear(); }
+
+    //
+    // New accessors for new decoder.
+    //
+    uint64_t readIntReg(int reg_idx)
+    {
+        return regs.readIntReg(reg_idx);
+    }
+
+    FloatReg readFloatReg(int reg_idx, int width)
+    {
+        return regs.readFloatReg(reg_idx, width);
+    }
+
+    FloatReg readFloatReg(int reg_idx)
+    {
+        return regs.readFloatReg(reg_idx);
+    }
+
+    FloatRegBits readFloatRegBits(int reg_idx, int width)
+    {
+        return regs.readFloatRegBits(reg_idx, width);
+    }
+
+    FloatRegBits readFloatRegBits(int reg_idx)
+    {
+        return regs.readFloatRegBits(reg_idx);
+    }
+
+    void setIntReg(int reg_idx, uint64_t val)
+    {
+        regs.setIntReg(reg_idx, val);
+    }
+
+    void setFloatReg(int reg_idx, FloatReg val, int width)
+    {
+        regs.setFloatReg(reg_idx, val, width);
+    }
+
+    void setFloatReg(int reg_idx, FloatReg val)
+    {
+        regs.setFloatReg(reg_idx, val);
+    }
+
+    void setFloatRegBits(int reg_idx, FloatRegBits val, int width)
+    {
+        regs.setFloatRegBits(reg_idx, val, width);
+    }
+
+    void setFloatRegBits(int reg_idx, FloatRegBits val)
+    {
+        regs.setFloatRegBits(reg_idx, val);
+    }
+
+    uint64_t readPC()
+    {
+        return regs.readPC();
+    }
+
+    void setPC(uint64_t val)
+    {
+        regs.setPC(val);
+    }
+
+    uint64_t readNextPC()
+    {
+        return regs.readNextPC();
+    }
+
+    void setNextPC(uint64_t val)
+    {
+        regs.setNextPC(val);
+    }
+
+    uint64_t readNextNPC()
+    {
+        return regs.readNextNPC();
+    }
+
+    void setNextNPC(uint64_t val)
+    {
+        regs.setNextNPC(val);
+    }
+
+    MiscReg readMiscReg(int misc_reg)
+    {
+        return regs.readMiscReg(misc_reg);
+    }
+
+    MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
+    {
+        return regs.readMiscRegWithEffect(misc_reg, fault, tc);
+    }
+
+    Fault setMiscReg(int misc_reg, const MiscReg &val)
+    {
+        return regs.setMiscReg(misc_reg, val);
+    }
+
+    Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+    {
+        return regs.setMiscRegWithEffect(misc_reg, val, tc);
+    }
+
+    unsigned readStCondFailures() { return storeCondFailures; }
+
+    void setStCondFailures(unsigned sc_failures)
+    { storeCondFailures = sc_failures; }
+
+#if FULL_SYSTEM
+    bool inPalMode() { return AlphaISA::PcPAL(regs.readPC()); }
+#endif
+
+#if !FULL_SYSTEM
+    TheISA::IntReg getSyscallArg(int i)
+    {
+        return regs.readIntReg(TheISA::ArgumentReg0 + i);
+    }
+
+    // used to shift args for indirect syscall
+    void setSyscallArg(int i, TheISA::IntReg val)
+    {
+        regs.setIntReg(TheISA::ArgumentReg0 + i, val);
+    }
+
+    void setSyscallReturn(SyscallReturn return_value)
+    {
+        TheISA::setSyscallReturn(return_value, &regs);
+    }
+
+    void syscall(int64_t callnum)
+    {
+        process->syscall(callnum, tc);
+    }
+#endif
+
+    void changeRegFileContext(RegFile::ContextParam param,
+            RegFile::ContextVal val)
+    {
+        regs.changeContext(param, val);
+    }
+};
+
+
+// for non-speculative execution context, spec_mode is always false
+inline bool
+SimpleThread::misspeculating()
+{
+    return false;
+}
+
+#endif // __CPU_CPU_EXEC_CONTEXT_HH__
diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc
new file mode 100644 (file)
index 0000000..9712ffa
--- /dev/null
@@ -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
index 6d64c94f775b264dd0de3fcd971cc6d0216c7b64..d72697cb79c8ed39e6a3ecaa0ee18a6d0786567c 100644 (file)
 #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.
index aca75e27d62c43de006cfeed467e32d176a170a2..fe3805ce26f27874af2ecf01dcb38a5ad390c00f 100644 (file)
@@ -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"
index 15d56445593bd644f7b6e9f77b3ea71a80c99eea..edbc1e492c2eb86d62017238dc827b546ac7335f 100644 (file)
@@ -46,7 +46,6 @@
 #include "base/statistics.hh"
 #include "sim/sim_object.hh"
 
-class CPUExecContext;
 class ThreadContext;
 class SyscallDesc;
 class PageTable;