/*
+ * Copyright (c) 2012 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) 2006 The Regents of The University of Michigan
* All rights reserved.
*
#include "base/output.hh"
#include "cpu/thread_context.hh"
#include "cpu/thread_state.hh"
+#include "sim/full_system.hh"
#include "sim/sim_exit.hh"
-class Event;
-class Process;
-
-#if FULL_SYSTEM
class EndQuiesceEvent;
-class FunctionProfile;
-class ProfileNode;
-#else
+class Event;
class FunctionalMemory;
+class FunctionProfile;
class Process;
-#endif
+class ProfileNode;
/**
* Class that has various thread state, such as the status, the
/** Pointer to the CPU. */
O3CPU *cpu;
public:
- /** Whether or not the thread is currently in syscall mode, and
- * thus able to be externally updated without squashing.
+ /* This variable controls if writes to a thread context should cause a all
+ * dynamic/speculative state to be thrown away. Nominally this is the
+ * desired behavior because the external thread context write has updated
+ * some state that could be used by an inflight instruction, however there
+ * are some cases like in a fault/trap handler where this behavior would
+ * lead to successive restarts and forward progress couldn't be made. This
+ * variable controls if the squashing will occur.
*/
- bool inSyscall;
+ bool noSquashFromTC;
/** Whether or not the thread is currently waiting on a trap, and
* thus able to be externally updated without squashing.
*/
bool trapPending;
-#if FULL_SYSTEM
- O3ThreadState(O3CPU *_cpu, int _thread_num)
- : ThreadState(-1, _thread_num),
- cpu(_cpu), inSyscall(0), trapPending(0)
+ O3ThreadState(O3CPU *_cpu, int _thread_num, Process *_process)
+ : ThreadState(_cpu, _thread_num, _process),
+ cpu(_cpu), noSquashFromTC(false), trapPending(false),
+ tc(nullptr)
{
- if (cpu->params->profile) {
- profile = new FunctionProfile(cpu->params->system->kernelSymtab);
+ if (!FullSystem)
+ return;
+
+ if (cpu->params()->profile) {
+ profile = new FunctionProfile(
+ cpu->params()->system->kernelSymtab);
Callback *cb =
new MakeCallback<O3ThreadState,
&O3ThreadState::dumpFuncProfile>(this);
profileNode = &dummyNode;
profilePC = 3;
}
-#else
- O3ThreadState(O3CPU *_cpu, int _thread_num, Process *_process, int _asid,
- MemObject *mem)
- : ThreadState(-1, _thread_num, _process, _asid, mem),
- cpu(_cpu), inSyscall(0), trapPending(0)
- { }
-#endif
+
+ void serialize(CheckpointOut &cp) const override
+ {
+ ThreadState::serialize(cp);
+ // Use the ThreadContext serialization helper to serialize the
+ // TC.
+ ::serialize(*tc, cp);
+ }
+
+ void unserialize(CheckpointIn &cp) override
+ {
+ // Prevent squashing - we don't have any instructions in
+ // flight that we need to squash since we just instantiated a
+ // clean system.
+ noSquashFromTC = true;
+ ThreadState::unserialize(cp);
+ // Use the ThreadContext serialization helper to unserialize
+ // the TC.
+ ::unserialize(*tc, cp);
+ noSquashFromTC = false;
+ }
/** Pointer to the ThreadContext of this thread. */
ThreadContext *tc;
/** Returns a pointer to the TC of this thread. */
ThreadContext *getTC() { return tc; }
-#if !FULL_SYSTEM
/** Handles the syscall. */
- void syscall(int64_t callnum) { process->syscall(callnum, tc); }
-#endif
+ void syscall(int64_t callnum, Fault *fault)
+ {
+ process->syscall(callnum, tc, fault);
+ }
-#if FULL_SYSTEM
void dumpFuncProfile()
{
- std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
- profile->dump(tc, *os);
+ OutputStream *os(
+ simout.create(csprintf("profile.%s.dat", cpu->name())));
+ profile->dump(tc, *os->stream());
+ simout.close(os);
}
-#endif
};
#endif // __CPU_O3_THREAD_STATE_HH__