cpu: re-organizes the branch predictor structure.
[gem5.git] / src / cpu / simple_thread.cc
index 1edcbf35256ca740971f603e9f894c200f0e1ce6..36603a1c167cd10f908e8ef1578d916d1384f5d8 100644 (file)
 #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 "arch/kernel_stats.hh"
+#include "arch/stacktrace.hh"
+#include "arch/utility.hh"
 #include "base/callback.hh"
 #include "base/cprintf.hh"
 #include "base/output.hh"
 #include "base/trace.hh"
+#include "config/the_isa.hh"
+#include "cpu/base.hh"
 #include "cpu/profile.hh"
 #include "cpu/quiesce_event.hh"
+#include "cpu/simple_thread.hh"
+#include "cpu/thread_context.hh"
+#include "mem/fs_translating_port_proxy.hh"
+#include "mem/se_translating_port_proxy.hh"
+#include "params/BaseCPU.hh"
+#include "sim/faults.hh"
+#include "sim/full_system.hh"
+#include "sim/process.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,
-                           TheISA::ITB *_itb, TheISA::DTB *_dtb,
-                           bool use_kernel_stats)
-    : ThreadState(_cpu, -1, _thread_num), cpu(_cpu), system(_sys), itb(_itb),
-      dtb(_dtb)
+                           Process *_process, TheISA::TLB *_itb,
+                           TheISA::TLB *_dtb, TheISA::ISA *_isa)
+    : ThreadState(_cpu, _thread_num, _process), isa(_isa),
+      predicate(false), system(_sys),
+      itb(_itb), dtb(_dtb)
+{
+    clearArchRegs();
+    tc = new ProxyThreadContext<SimpleThread>(this);
+}
 
+SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
+                           TheISA::TLB *_itb, TheISA::TLB *_dtb,
+                           TheISA::ISA *_isa, bool use_kernel_stats)
+    : ThreadState(_cpu, _thread_num, NULL), isa(_isa), system(_sys), itb(_itb),
+      dtb(_dtb)
 {
     tc = new ProxyThreadContext<SimpleThread>(this);
 
     quiesceEvent = new EndQuiesceEvent(tc);
 
-    regs.clear();
+    clearArchRegs();
 
-    if (cpu->params->profile) {
+    if (baseCpu->params()->profile) {
         profile = new FunctionProfile(system->kernelSymtab);
         Callback *cb =
             new MakeCallback<SimpleThread,
@@ -86,104 +97,24 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
     profileNode = &dummyNode;
     profilePC = 3;
 
-    if (use_kernel_stats) {
+    if (use_kernel_stats)
         kernelStats = new TheISA::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)
-    : ThreadState(_cpu, -1, _thread_num, _process, _asid),
-      cpu(_cpu)
-{
-    regs.clear();
-    tc = new ProxyThreadContext<SimpleThread>(this);
-}
-
-#endif
-
-SimpleThread::SimpleThread()
-#if FULL_SYSTEM
-    : ThreadState(NULL, -1, -1)
-#else
-    : ThreadState(NULL, -1, -1, NULL, -1)
-#endif
-{
-    tc = new ProxyThreadContext<SimpleThread>(this);
-    regs.clear();
 }
 
 SimpleThread::~SimpleThread()
 {
-#if FULL_SYSTEM
-    delete physPort;
-    delete virtPort;
-#endif
     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
-
-    copyState(oldContext);
-#if FULL_SYSTEM
-    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;
-    }
-
-    TheISA::Kernel::Statistics *stats = oldContext->getKernelStats();
-    if (stats) {
-        kernelStats = stats;
-    }
-#endif
+    ::takeOverFrom(*tc, *oldContext);
+    decoder.takeOverFrom(oldContext->getDecoderPtr());
 
+    kernelStats = oldContext->getKernelStats();
+    funcExeInst = oldContext->readFuncExeInst();
     storeCondFailures = 0;
-
-    oldContext->setStatus(ThreadContext::Unallocated);
-}
-
-void
-SimpleThread::copyTC(ThreadContext *context)
-{
-    copyState(context);
-
-#if FULL_SYSTEM
-    EndQuiesceEvent *quiesce = context->getQuiesceEvent();
-    if (quiesce) {
-        quiesceEvent = quiesce;
-    }
-    TheISA::Kernel::Statistics *stats = context->getKernelStats();
-    if (stats) {
-        kernelStats = stats;
-    }
-#endif
 }
 
 void
@@ -192,19 +123,18 @@ SimpleThread::copyState(ThreadContext *oldContext)
     // copy over functional state
     _status = oldContext->status();
     copyArchRegs(oldContext);
-    cpuId = oldContext->readCpuId();
-#if !FULL_SYSTEM
-    funcExeInst = oldContext->readFuncExeInst();
-#endif
-    inst = oldContext->getInst();
+    if (FullSystem)
+        funcExeInst = oldContext->readFuncExeInst();
+
+    _threadId = oldContext->threadId();
+    _contextId = oldContext->contextId();
 }
 
 void
 SimpleThread::serialize(ostream &os)
 {
     ThreadState::serialize(os);
-    regs.serialize(os);
-    // thread_num and cpu_id are deterministic from the config
+    ::serialize(*tc, os);
 }
 
 
@@ -212,36 +142,32 @@ void
 SimpleThread::unserialize(Checkpoint *cp, const std::string &section)
 {
     ThreadState::unserialize(cp, section);
-    regs.unserialize(cp, section);
-    // thread_num and cpu_id are deterministic from the config
+    ::unserialize(*tc, cp, section);
+}
+
+void
+SimpleThread::startup()
+{
+    isa->startup(tc);
 }
 
-#if FULL_SYSTEM
 void
 SimpleThread::dumpFuncProfile()
 {
-    std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
+    std::ostream *os = simout.create(csprintf("profile.%s.dat",
+                                              baseCpu->name()));
     profile->dump(tc, *os);
 }
-#endif
 
 void
-SimpleThread::activate(int delay)
+SimpleThread::activate()
 {
     if (status() == ThreadContext::Active)
         return;
 
-    lastActivate = curTick;
-
-    if (status() == ThreadContext::Unallocated) {
-        cpu->activateWhenReady(tid);
-        return;
-    }
-
+    lastActivate = curTick();
     _status = ThreadContext::Active;
-
-    // status() == Suspended
-    cpu->activateContext(tid, delay);
+    baseCpu->activateContext(_threadId);
 }
 
 void
@@ -250,30 +176,12 @@ 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
-*/
+    lastActivate = curTick();
+    lastSuspend = curTick();
     _status = ThreadContext::Suspended;
-    cpu->suspendContext(tid);
+    baseCpu->suspendContext(_threadId);
 }
 
-void
-SimpleThread::deallocate()
-{
-    if (status() == ThreadContext::Unallocated)
-        return;
-
-    _status = ThreadContext::Unallocated;
-    cpu->deallocateContext(tid);
-}
 
 void
 SimpleThread::halt()
@@ -282,17 +190,15 @@ SimpleThread::halt()
         return;
 
     _status = ThreadContext::Halted;
-    cpu->haltContext(tid);
+    baseCpu->haltContext(_threadId);
 }
 
 
 void
 SimpleThread::regStats(const string &name)
 {
-#if FULL_SYSTEM
-    if (kernelStats)
+    if (FullSystem && kernelStats)
         kernelStats->regStats(name + ".kern");
-#endif
 }
 
 void
@@ -301,29 +207,18 @@ SimpleThread::copyArchRegs(ThreadContext *src_tc)
     TheISA::copyRegs(src_tc, tc);
 }
 
-#if FULL_SYSTEM
-VirtualPort*
-SimpleThread::getVirtPort(ThreadContext *src_tc)
+// The following methods are defined in src/arch/alpha/ev5.cc for
+// Alpha.
+#if THE_ISA != ALPHA_ISA
+Fault
+SimpleThread::hwrei()
 {
-    if (!src_tc)
-        return virtPort;
-
-    VirtualPort *vp = new VirtualPort("tc-vport", src_tc);
-    Port *mem_port = getMemFuncPort();
-
-    mem_port->setPeer(vp);
-    vp->setPeer(mem_port);
-    return vp;
+    return NoFault;
 }
 
-void
-SimpleThread::delVirtPort(VirtualPort *vp)
+bool
+SimpleThread::simPalCheck(int palFunc)
 {
-    if (vp != virtPort) {
-        delete vp->getPeer();
-        delete vp;
-    }
+    return true;
 }
-
 #endif
-