cpu: Mark ExecContext::tcBase() as const
[gem5.git] / src / cpu / simple_thread.cc
index 2541bdee1e2831300345917fc531b02fa5503cca..c4785cfa33f7d03da951b90fd1317209e9ee098a 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2018 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) 2001-2006 The Regents of The University of Michigan
  * All rights reserved.
  *
  *          Kevin Lim
  */
 
+#include "cpu/simple_thread.hh"
+
 #include <string>
 
 #include "arch/isa_traits.hh"
-#include "arch/utility.hh"
-#include "config/the_isa.hh"
-#include "cpu/base.hh"
-#include "cpu/simple_thread.hh"
-#include "cpu/thread_context.hh"
-#include "params/BaseCPU.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/thread_context.hh"
 #include "mem/fs_translating_port_proxy.hh"
-#include "sim/serialize.hh"
-#include "sim/sim_exit.hh"
-#else
 #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 "sim/system.hh"
-#endif
 
 using namespace std;
 
 // constructor
-#if FULL_SYSTEM
 SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
-                           TheISA::TLB *_itb, TheISA::TLB *_dtb,
-                           bool use_kernel_stats)
-    : ThreadState(_cpu, _thread_num),
-      cpu(_cpu), system(_sys), itb(_itb), dtb(_dtb)
+                           Process *_process, BaseTLB *_itb,
+                           BaseTLB *_dtb, BaseISA *_isa)
+    : ThreadState(_cpu, _thread_num, _process),
+      isa(dynamic_cast<TheISA::ISA *>(_isa)),
+      predicate(true), memAccPredicate(true),
+      comInstEventQueue("instruction-based event queue"),
+      system(_sys), itb(_itb), dtb(_dtb), decoder(TheISA::Decoder(isa))
+{
+    assert(isa);
+    clearArchRegs();
+    quiesceEvent = new EndQuiesceEvent(this);
+}
 
+SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
+                           BaseTLB *_itb, BaseTLB *_dtb,
+                           BaseISA *_isa, bool use_kernel_stats)
+    : ThreadState(_cpu, _thread_num, NULL),
+      isa(dynamic_cast<TheISA::ISA *>(_isa)),
+      predicate(true), memAccPredicate(true),
+      comInstEventQueue("instruction-based event queue"),
+      system(_sys), itb(_itb), dtb(_dtb), decoder(TheISA::Decoder(isa))
 {
-    tc = new ProxyThreadContext<SimpleThread>(this);
+    assert(isa);
 
-    quiesceEvent = new EndQuiesceEvent(tc);
+    quiesceEvent = new EndQuiesceEvent(this);
 
     clearArchRegs();
 
-    if (cpu->params()->profile) {
+    if (baseCpu->params()->profile) {
         profile = new FunctionProfile(system->kernelSymtab);
         Callback *cb =
             new MakeCallback<SimpleThread,
@@ -91,83 +117,18 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
     profilePC = 3;
 
     if (use_kernel_stats)
-        kernelStats = new TheISA::Kernel::Statistics(system);
-}
-#else
-SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process,
-                           TheISA::TLB *_itb, TheISA::TLB *_dtb)
-    : ThreadState(_cpu, _thread_num, _process),
-      cpu(_cpu), itb(_itb), dtb(_dtb)
-{
-    clearArchRegs();
-    tc = new ProxyThreadContext<SimpleThread>(this);
-}
-
-#endif
-
-SimpleThread::SimpleThread()
-#if FULL_SYSTEM
-    : ThreadState(NULL, -1)
-#else
-    : ThreadState(NULL, -1, NULL)
-#endif
-{
-    tc = new ProxyThreadContext<SimpleThread>(this);
-}
-
-SimpleThread::~SimpleThread()
-{
-    delete tc;
+        kernelStats = new TheISA::Kernel::Statistics();
 }
 
 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(*this, *oldContext);
+    decoder.takeOverFrom(oldContext->getDecoderPtr());
 
+    kernelStats = oldContext->getKernelStats();
+    funcExeInst = oldContext->readFuncExeInst();
     storeCondFailures = 0;
-
-    oldContext->setStatus(ThreadContext::Halted);
-}
-
-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
@@ -176,71 +137,51 @@ SimpleThread::copyState(ThreadContext *oldContext)
     // copy over functional state
     _status = oldContext->status();
     copyArchRegs(oldContext);
-#if !FULL_SYSTEM
-    funcExeInst = oldContext->readFuncExeInst();
-#endif
+    if (FullSystem)
+        funcExeInst = oldContext->readFuncExeInst();
 
     _threadId = oldContext->threadId();
     _contextId = oldContext->contextId();
 }
 
 void
-SimpleThread::serialize(ostream &os)
+SimpleThread::serialize(CheckpointOut &cp) const
 {
-    ThreadState::serialize(os);
-    SERIALIZE_ARRAY(floatRegs.i, TheISA::NumFloatRegs);
-    SERIALIZE_ARRAY(intRegs, TheISA::NumIntRegs);
-    _pcState.serialize(os);
-    // thread_num and cpu_id are deterministic from the config
-
-    // 
-    // Now must serialize all the ISA dependent state
-    //
-    isa.serialize(cpu, os);
+    ThreadState::serialize(cp);
+    ::serialize(*this, cp);
 }
 
 
 void
-SimpleThread::unserialize(Checkpoint *cp, const std::string &section)
+SimpleThread::unserialize(CheckpointIn &cp)
 {
-    ThreadState::unserialize(cp, section);
-    UNSERIALIZE_ARRAY(floatRegs.i, TheISA::NumFloatRegs);
-    UNSERIALIZE_ARRAY(intRegs, TheISA::NumIntRegs);
-    _pcState.unserialize(cp, section);
-    // thread_num and cpu_id are deterministic from the config
+    ThreadState::unserialize(cp);
+    ::unserialize(*this, cp);
+}
 
-    // 
-    // Now must unserialize all the ISA dependent state
-    //
-    isa.unserialize(cpu, cp, section);
+void
+SimpleThread::startup()
+{
+    isa->startup(this);
 }
 
-#if FULL_SYSTEM
 void
 SimpleThread::dumpFuncProfile()
 {
-    std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
-    profile->dump(tc, *os);
+    OutputStream *os(simout.create(csprintf("profile.%s.dat", baseCpu->name())));
+    profile->dump(this, *os->stream());
+    simout.close(os);
 }
-#endif
 
 void
-SimpleThread::activate(int delay)
+SimpleThread::activate()
 {
     if (status() == ThreadContext::Active)
         return;
 
     lastActivate = curTick();
-
-//    if (status() == ThreadContext::Unallocated) {
-//      cpu->activateWhenReady(_threadId);
-//      return;
-//   }
-
     _status = ThreadContext::Active;
-
-    // status() == Suspended
-    cpu->activateContext(_threadId, delay);
+    baseCpu->activateContext(_threadId);
 }
 
 void
@@ -251,17 +192,8 @@ SimpleThread::suspend()
 
     lastActivate = curTick();
     lastSuspend = curTick();
-/*
-#if FULL_SYSTEM
-    // Don't change the status from active if there are pending interrupts
-    if (cpu->checkInterrupts()) {
-        assert(status() == ThreadContext::Active);
-        return;
-    }
-#endif
-*/
     _status = ThreadContext::Suspended;
-    cpu->suspendContext(_threadId);
+    baseCpu->suspendContext(_threadId);
 }
 
 
@@ -272,22 +204,19 @@ SimpleThread::halt()
         return;
 
     _status = ThreadContext::Halted;
-    cpu->haltContext(_threadId);
+    baseCpu->haltContext(_threadId);
 }
 
 
 void
 SimpleThread::regStats(const string &name)
 {
-#if FULL_SYSTEM
-    if (kernelStats)
+    if (FullSystem && kernelStats)
         kernelStats->regStats(name + ".kern");
-#endif
 }
 
 void
 SimpleThread::copyArchRegs(ThreadContext *src_tc)
 {
-    TheISA::copyRegs(src_tc, tc);
+    TheISA::copyRegs(src_tc, this);
 }
-