* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Kevin Lim
*/
#ifndef __CPU_OZONE_THREAD_STATE_HH__
#define __CPU_OZONE_THREAD_STATE_HH__
#include "arch/faults.hh"
-#include "arch/isa_traits.hh"
-#include "cpu/exec_context.hh"
+#include "arch/types.hh"
+#include "arch/regfile.hh"
+#include "base/callback.hh"
+#include "base/output.hh"
+#include "cpu/thread_context.hh"
#include "cpu/thread_state.hh"
#include "sim/process.hh"
+#include "sim/sim_exit.hh"
class Event;
//class Process;
// Maybe this ozone thread state should only really have committed state?
// I need to think about why I'm using this and what it's useful for. Clearly
-// has benefits for SMT; basically serves same use as CPUExecContext.
+// has benefits for SMT; basically serves same use as SimpleThread.
// Makes the ExecContext proxy easier. Gives organization/central access point
// to state of a thread that can be accessed normally (i.e. not in-flight
-// stuff within a OoO processor). Does this need an XC proxy within it?
+// stuff within a OoO processor). Does this need an TC proxy within it?
template <class Impl>
struct OzoneThreadState : public ThreadState {
- typedef typename ExecContext::Status Status;
- typedef typename Impl::FullCPU FullCPU;
+ typedef typename ThreadContext::Status Status;
+ typedef typename Impl::CPUType CPUType;
typedef TheISA::MiscReg MiscReg;
#if FULL_SYSTEM
- OzoneThreadState(FullCPU *_cpu, int _thread_num, FunctionalMemory *_mem)
- : ThreadState(-1, _thread_num, _mem),
- inSyscall(0), trapPending(0)
+ OzoneThreadState(CPUType *_cpu, int _thread_num)
+ : ThreadState(-1, _thread_num),
+ cpu(_cpu), intrflag(0), inSyscall(0), trapPending(0)
{
- memset(®s, 0, sizeof(TheISA::RegFile));
+ if (cpu->params->profile) {
+ profile = new FunctionProfile(cpu->params->system->kernelSymtab);
+ Callback *cb =
+ new MakeCallback<OzoneThreadState,
+ &OzoneThreadState::dumpFuncProfile>(this);
+ registerExitCallback(cb);
+ }
+
+ // let's fill with a dummy node for now so we don't get a segfault
+ // on the first cycle when there's no node available.
+ static ProfileNode dummyNode;
+ profileNode = &dummyNode;
+ profilePC = 3;
+ miscRegFile.clear();
}
#else
- OzoneThreadState(FullCPU *_cpu, int _thread_num, Process *_process, int _asid)
- : ThreadState(-1, _thread_num, NULL, _process, _asid),
- cpu(_cpu), inSyscall(0), trapPending(0)
- {
- memset(®s, 0, sizeof(TheISA::RegFile));
- }
-
- OzoneThreadState(FullCPU *_cpu, int _thread_num, FunctionalMemory *_mem,
- int _asid)
- : ThreadState(-1, _thread_num, _mem, NULL, _asid),
+ OzoneThreadState(CPUType *_cpu, int _thread_num, Process *_process,
+ int _asid, MemObject *mem)
+ : ThreadState(-1, _thread_num, _process, _asid, mem),
cpu(_cpu), inSyscall(0), trapPending(0)
{
- memset(®s, 0, sizeof(TheISA::RegFile));
+ miscRegFile.clear();
}
#endif
- Status _status;
-
- Status status() const { return _status; }
-
- void setStatus(Status new_status) { _status = new_status; }
-
RenameTable<Impl> renameTable;
+
Addr PC;
+
Addr nextPC;
- // Current instruction
- TheISA::MachInst inst;
+ TheISA::MiscRegFile miscRegFile;
- TheISA::RegFile regs;
+ int intrflag;
- typename Impl::FullCPU *cpu;
+ typename Impl::CPUType *cpu;
bool inSyscall;
bool trapPending;
- ExecContext *xcProxy;
-
- ExecContext *getXCProxy() { return xcProxy; }
-
-#if !FULL_SYSTEM
- Fault translateInstReq(Request *req)
- {
- return process->pTable->translate(req);
- }
- Fault translateDataReadReq(Request *req)
- {
- return process->pTable->translate(req);
- }
- Fault translateDataWriteReq(Request *req)
- {
- return process->pTable->translate(req);
- }
-#else
- Fault translateInstReq(Request *req)
- {
- return cpu->itb->translate(req);
- }
-
- Fault translateDataReadReq(Request *req)
- {
- return cpu->dtb->translate(req, false);
- }
+ ThreadContext *tc;
- Fault translateDataWriteReq(Request *req)
- {
- return cpu->dtb->translate(req, true);
- }
-#endif
+ ThreadContext *getTC() { return tc; }
MiscReg readMiscReg(int misc_reg)
{
- return regs.readMiscReg(misc_reg);
+ return miscRegFile.readReg(misc_reg);
}
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
{
- return regs.readMiscRegWithEffect(misc_reg, fault, xcProxy);
+ return miscRegFile.readRegWithEffect(misc_reg, fault, tc);
}
Fault setMiscReg(int misc_reg, const MiscReg &val)
{
- return regs.setMiscReg(misc_reg, val);
+ return miscRegFile.setReg(misc_reg, val);
}
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{
- return regs.setMiscRegWithEffect(misc_reg, val, xcProxy);
+ return miscRegFile.setRegWithEffect(misc_reg, val, tc);
}
uint64_t readPC()
void setNextPC(uint64_t val)
{ nextPC = val; }
- bool misspeculating() { return false; }
-
- void setInst(TheISA::MachInst _inst) { inst = _inst; }
-
- Counter readFuncExeInst() { return funcExeInst; }
-
- void setFuncExeInst(Counter new_val) { funcExeInst = new_val; }
+#if FULL_SYSTEM
+ void dumpFuncProfile()
+ {
+ std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
+ profile->dump(xcProxy, *os);
+ }
+#endif
};
#endif // __CPU_OZONE_THREAD_STATE_HH__