/*
+ * 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,
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
// 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 §ion)
+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
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);
}
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);
}
-