CheckerCPU: Make CheckerCPU runtime selectable instead of compile selectable
[gem5.git] / src / cpu / o3 / thread_context_impl.hh
index 735827ebcd19a27177b2054bc48ef159e11d1451..13bfe32dfeb36671eeba94efd59ff54b03553045 100755 (executable)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2010-2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2004-2006 The Regents of The University of Michigan
  * All rights reserved.
  *
  *          Korey Sewell
  */
 
-#include "arch/regfile.hh"
+#include "arch/kernel_stats.hh"
+#include "arch/registers.hh"
+#include "config/the_isa.hh"
 #include "cpu/o3/thread_context.hh"
 #include "cpu/quiesce_event.hh"
+#include "debug/O3CPU.hh"
 
-#if FULL_SYSTEM
 template <class Impl>
-VirtualPort *
-O3ThreadContext<Impl>::getVirtPort()
+FSTranslatingPortProxy&
+O3ThreadContext<Impl>::getVirtProxy()
 {
-    return thread->getVirtPort();
+    return thread->getVirtProxy();
 }
 
 template <class Impl>
@@ -47,18 +61,14 @@ O3ThreadContext<Impl>::dumpFuncProfile()
 {
     thread->dumpFuncProfile();
 }
-#endif
 
 template <class Impl>
 void
 O3ThreadContext<Impl>::takeOverFrom(ThreadContext *old_context)
 {
     // some things should already be set up
-#if FULL_SYSTEM
     assert(getSystemPtr() == old_context->getSystemPtr());
-#else
     assert(getProcessPtr() == old_context->getProcessPtr());
-#endif
 
     // copy over functional state
     setStatus(old_context->status());
@@ -66,26 +76,25 @@ O3ThreadContext<Impl>::takeOverFrom(ThreadContext *old_context)
     setContextId(old_context->contextId());
     setThreadId(old_context->threadId());
 
-#if !FULL_SYSTEM
-    thread->funcExeInst = old_context->readFuncExeInst();
-#else
-    EndQuiesceEvent *other_quiesce = old_context->getQuiesceEvent();
-    if (other_quiesce) {
-        // Point the quiesce event's TC at this TC so that it wakes up
-        // the proper CPU.
-        other_quiesce->tc = this;
+    if (FullSystem) {
+        EndQuiesceEvent *other_quiesce = old_context->getQuiesceEvent();
+        if (other_quiesce) {
+            // Point the quiesce event's TC at this TC so that it wakes up
+            // the proper CPU.
+            other_quiesce->tc = this;
+        }
+        if (thread->quiesceEvent) {
+            thread->quiesceEvent->tc = this;
+        }
+
+        // Transfer kernel stats from one CPU to the other.
+        thread->kernelStats = old_context->getKernelStats();
+        cpu->lockFlag = false;
+    } else {
+        thread->funcExeInst = old_context->readFuncExeInst();
     }
-    if (thread->quiesceEvent) {
-        thread->quiesceEvent->tc = this;
-    }
-
-    // Transfer kernel stats from one CPU to the other.
-    thread->kernelStats = old_context->getKernelStats();
-//    storeCondFailures = 0;
-    cpu->lockFlag = false;
-#endif
 
-    old_context->setStatus(ThreadContext::Unallocated);
+    old_context->setStatus(ThreadContext::Halted);
 
     thread->inSyscall = false;
     thread->trapPending = false;
@@ -101,15 +110,7 @@ O3ThreadContext<Impl>::activate(int delay)
     if (thread->status() == ThreadContext::Active)
         return;
 
-#if FULL_SYSTEM
-    thread->lastActivate = curTick;
-#endif
-
-    if (thread->status() == ThreadContext::Unallocated) {
-        cpu->activateWhenReady(thread->threadId());
-        return;
-    }
-
+    thread->lastActivate = curTick();
     thread->setStatus(ThreadContext::Active);
 
     // status() == Suspended
@@ -126,37 +127,13 @@ O3ThreadContext<Impl>::suspend(int delay)
     if (thread->status() == ThreadContext::Suspended)
         return;
 
-#if FULL_SYSTEM
-    thread->lastActivate = curTick;
-    thread->lastSuspend = curTick;
-#endif
-/*
-#if FULL_SYSTEM
-    // Don't change the status from active if there are pending interrupts
-    if (cpu->checkInterrupts()) {
-        assert(status() == ThreadContext::Active);
-        return;
-    }
-#endif
-*/
+    thread->lastActivate = curTick();
+    thread->lastSuspend = curTick();
+
     thread->setStatus(ThreadContext::Suspended);
     cpu->suspendContext(thread->threadId());
 }
 
-template <class Impl>
-void
-O3ThreadContext<Impl>::deallocate(int delay)
-{
-    DPRINTF(O3CPU, "Calling deallocate on Thread Context %d delay %d\n",
-            threadId(), delay);
-
-    if (thread->status() == ThreadContext::Unallocated)
-        return;
-
-    thread->setStatus(ThreadContext::Unallocated);
-    cpu->deallocateContext(thread->threadId(), true, delay);
-}
-
 template <class Impl>
 void
 O3ThreadContext<Impl>::halt(int delay)
@@ -175,35 +152,28 @@ template <class Impl>
 void
 O3ThreadContext<Impl>::regStats(const std::string &name)
 {
-#if FULL_SYSTEM
-    thread->kernelStats = new TheISA::Kernel::Statistics(cpu->system);
-    thread->kernelStats->regStats(name + ".kern");
-#endif
+    if (FullSystem) {
+        thread->kernelStats = new TheISA::Kernel::Statistics(cpu->system);
+        thread->kernelStats->regStats(name + ".kern");
+    }
 }
 
 template <class Impl>
 void
 O3ThreadContext<Impl>::serialize(std::ostream &os)
 {
-#if FULL_SYSTEM
-    if (thread->kernelStats)
+    if (FullSystem && thread->kernelStats)
         thread->kernelStats->serialize(os);
-#endif
-
 }
 
 template <class Impl>
 void
 O3ThreadContext<Impl>::unserialize(Checkpoint *cp, const std::string &section)
 {
-#if FULL_SYSTEM
-    if (thread->kernelStats)
+    if (FullSystem && thread->kernelStats)
         thread->kernelStats->unserialize(cp, section);
-#endif
-
 }
 
-#if FULL_SYSTEM
 template <class Impl>
 Tick
 O3ThreadContext<Impl>::readLastActivate()
@@ -231,109 +201,48 @@ O3ThreadContext<Impl>::profileSample()
 {
     thread->profileSample();
 }
-#endif
-
-template <class Impl>
-TheISA::MachInst
-O3ThreadContext<Impl>:: getInst()
-{
-    return thread->getInst();
-}
 
 template <class Impl>
 void
 O3ThreadContext<Impl>::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->threadId();
-    PhysRegIndex renamed_reg;
-
-    // First loop through the integer registers.
-    for (int i = 0; i < TheISA::NumIntRegs; ++i) {
-        renamed_reg = cpu->renameMap[tid].lookup(i);
-
-        DPRINTF(O3CPU, "Copying over register %i, had data %lli, "
-                "now has data %lli.\n",
-                renamed_reg, cpu->readIntReg(renamed_reg),
-                tc->readIntReg(i));
-
-        cpu->setIntReg(renamed_reg, tc->readIntReg(i));
-    }
-
-    // Then loop through the floating point registers.
-    for (int i = 0; i < TheISA::NumFloatRegs; ++i) {
-        renamed_reg = cpu->renameMap[tid].lookup(i + TheISA::FP_Base_DepTag);
-        cpu->setFloatRegBits(renamed_reg,
-                             tc->readFloatRegBits(i));
-    }
+    // Prevent squashing
+    thread->inSyscall = true;
+    TheISA::copyRegs(tc, this);
+    thread->inSyscall = false;
 
-    // Copy the misc regs.
-    TheISA::copyMiscRegs(tc, this);
-
-    // Then finally set the PC, the next PC, the nextNPC, the micropc, and the
-    // next micropc.
-    cpu->setPC(tc->readPC(), tid);
-    cpu->setNextPC(tc->readNextPC(), tid);
-    cpu->setNextNPC(tc->readNextNPC(), tid);
-    cpu->setMicroPC(tc->readMicroPC(), tid);
-    cpu->setNextMicroPC(tc->readNextMicroPC(), tid);
-#if !FULL_SYSTEM
-    this->thread->funcExeInst = tc->readFuncExeInst();
-#endif
+    if (!FullSystem)
+        this->thread->funcExeInst = tc->readFuncExeInst();
 }
 
 template <class Impl>
 void
 O3ThreadContext<Impl>::clearArchRegs()
-{}
+{
+    cpu->isa[thread->threadId()].clear();
+}
 
 template <class Impl>
 uint64_t
 O3ThreadContext<Impl>::readIntReg(int reg_idx)
 {
-    reg_idx = TheISA::flattenIntIndex(this, reg_idx);
+    reg_idx = cpu->isa[thread->threadId()].flattenIntIndex(reg_idx);
     return cpu->readArchIntReg(reg_idx, thread->threadId());
 }
 
-template <class Impl>
-TheISA::FloatReg
-O3ThreadContext<Impl>::readFloatReg(int reg_idx, int width)
-{
-    reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
-    switch(width) {
-      case 32:
-        return cpu->readArchFloatRegSingle(reg_idx, thread->threadId());
-      case 64:
-        return cpu->readArchFloatRegDouble(reg_idx, thread->threadId());
-      default:
-        panic("Unsupported width!");
-        return 0;
-    }
-}
-
 template <class Impl>
 TheISA::FloatReg
 O3ThreadContext<Impl>::readFloatReg(int reg_idx)
 {
-    reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
-    return cpu->readArchFloatRegSingle(reg_idx, thread->threadId());
-}
-
-template <class Impl>
-TheISA::FloatRegBits
-O3ThreadContext<Impl>::readFloatRegBits(int reg_idx, int width)
-{
-    DPRINTF(Fault, "Reading floatint register through the TC!\n");
-    reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
-    return cpu->readArchFloatRegInt(reg_idx, thread->threadId());
+    reg_idx = cpu->isa[thread->threadId()].flattenFloatIndex(reg_idx);
+    return cpu->readArchFloatReg(reg_idx, thread->threadId());
 }
 
 template <class Impl>
 TheISA::FloatRegBits
 O3ThreadContext<Impl>::readFloatRegBits(int reg_idx)
 {
-    reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
+    reg_idx = cpu->isa[thread->threadId()].flattenFloatIndex(reg_idx);
     return cpu->readArchFloatRegInt(reg_idx, thread->threadId());
 }
 
@@ -341,7 +250,7 @@ template <class Impl>
 void
 O3ThreadContext<Impl>::setIntReg(int reg_idx, uint64_t val)
 {
-    reg_idx = TheISA::flattenIntIndex(this, reg_idx);
+    reg_idx = cpu->isa[thread->threadId()].flattenIntIndex(reg_idx);
     cpu->setArchIntReg(reg_idx, val, thread->threadId());
 
     // Squash if we're not already in a state update mode.
@@ -350,58 +259,23 @@ O3ThreadContext<Impl>::setIntReg(int reg_idx, uint64_t val)
     }
 }
 
-template <class Impl>
-void
-O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val, int width)
-{
-    reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
-    switch(width) {
-      case 32:
-        cpu->setArchFloatRegSingle(reg_idx, val, thread->threadId());
-        break;
-      case 64:
-        cpu->setArchFloatRegDouble(reg_idx, val, thread->threadId());
-        break;
-    }
-
-    // Squash if we're not already in a state update mode.
-    if (!thread->trapPending && !thread->inSyscall) {
-        cpu->squashFromTC(thread->threadId());
-    }
-}
-
 template <class Impl>
 void
 O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val)
 {
-    reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
-    cpu->setArchFloatRegSingle(reg_idx, val, thread->threadId());
+    reg_idx = cpu->isa[thread->threadId()].flattenFloatIndex(reg_idx);
+    cpu->setArchFloatReg(reg_idx, val, thread->threadId());
 
     if (!thread->trapPending && !thread->inSyscall) {
         cpu->squashFromTC(thread->threadId());
     }
 }
 
-template <class Impl>
-void
-O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val,
-                                             int width)
-{
-    DPRINTF(Fault, "Setting floatint register through the TC!\n");
-    reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
-    cpu->setArchFloatRegInt(reg_idx, val, thread->threadId());
-
-    // Squash if we're not already in a state update mode.
-    if (!thread->trapPending && !thread->inSyscall) {
-        cpu->squashFromTC(thread->threadId());
-    }
-}
-
 template <class Impl>
 void
 O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
 {
-    reg_idx = TheISA::flattenFloatIndex(this, reg_idx);
+    reg_idx = cpu->isa[thread->threadId()].flattenFloatIndex(reg_idx);
     cpu->setArchFloatRegInt(reg_idx, val, thread->threadId());
 
     // Squash if we're not already in a state update mode.
@@ -412,9 +286,9 @@ O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
 
 template <class Impl>
 void
-O3ThreadContext<Impl>::setPC(uint64_t val)
+O3ThreadContext<Impl>::pcState(const TheISA::PCState &val)
 {
-    cpu->setPC(val, thread->threadId());
+    cpu->pcState(val, thread->threadId());
 
     // Squash if we're not already in a state update mode.
     if (!thread->trapPending && !thread->inSyscall) {
@@ -424,9 +298,9 @@ O3ThreadContext<Impl>::setPC(uint64_t val)
 
 template <class Impl>
 void
-O3ThreadContext<Impl>::setNextPC(uint64_t val)
+O3ThreadContext<Impl>::pcStateNoRecord(const TheISA::PCState &val)
 {
-    cpu->setNextPC(val, thread->threadId());
+    cpu->pcState(val, thread->threadId());
 
     // Squash if we're not already in a state update mode.
     if (!thread->trapPending && !thread->inSyscall) {
@@ -435,27 +309,17 @@ O3ThreadContext<Impl>::setNextPC(uint64_t val)
 }
 
 template <class Impl>
-void
-O3ThreadContext<Impl>::setMicroPC(uint64_t val)
+int
+O3ThreadContext<Impl>::flattenIntIndex(int reg)
 {
-    cpu->setMicroPC(val, thread->threadId());
-
-    // Squash if we're not already in a state update mode.
-    if (!thread->trapPending && !thread->inSyscall) {
-        cpu->squashFromTC(thread->threadId());
-    }
+    return cpu->isa[thread->threadId()].flattenIntIndex(reg);
 }
 
 template <class Impl>
-void
-O3ThreadContext<Impl>::setNextMicroPC(uint64_t val)
+int
+O3ThreadContext<Impl>::flattenFloatIndex(int reg)
 {
-    cpu->setNextMicroPC(val, thread->threadId());
-
-    // Squash if we're not already in a state update mode.
-    if (!thread->trapPending && !thread->inSyscall) {
-        cpu->squashFromTC(thread->threadId());
-    }
+    return cpu->isa[thread->threadId()].flattenFloatIndex(reg);
 }
 
 template <class Impl>
@@ -472,8 +336,7 @@ O3ThreadContext<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
 
 template <class Impl>
 void
-O3ThreadContext<Impl>::setMiscReg(int misc_reg,
-                                                const MiscReg &val)
+O3ThreadContext<Impl>::setMiscReg(int misc_reg, const MiscReg &val)
 {
     cpu->setMiscReg(misc_reg, val, thread->threadId());
 
@@ -483,28 +346,3 @@ O3ThreadContext<Impl>::setMiscReg(int misc_reg,
     }
 }
 
-#if !FULL_SYSTEM
-
-template <class Impl>
-TheISA::IntReg
-O3ThreadContext<Impl>::getSyscallArg(int i)
-{
-    return cpu->getSyscallArg(i, thread->threadId());
-}
-
-template <class Impl>
-void
-O3ThreadContext<Impl>::setSyscallArg(int i, IntReg val)
-{
-    cpu->setSyscallArg(i, val, thread->threadId());
-}
-
-template <class Impl>
-void
-O3ThreadContext<Impl>::setSyscallReturn(SyscallReturn return_value)
-{
-    cpu->setSyscallReturn(return_value, thread->threadId());
-}
-
-#endif // FULL_SYSTEM
-