thread_state.hh revision 2292
12459SN/A
22459SN/A#ifndef __CPU_O3_THREAD_STATE_HH__
32459SN/A#define __CPU_O3_THREAD_STATE_HH__
42459SN/A
52459SN/A#include "arch/faults.hh"
62459SN/A#include "arch/isa_traits.hh"
72459SN/A#include "cpu/exec_context.hh"
82459SN/A#include "cpu/thread_state.hh"
92459SN/A
102459SN/Aclass Event;
112459SN/Aclass Process;
122459SN/A
132459SN/A#if FULL_SYSTEM
142459SN/Aclass EndQuiesceEvent;
152459SN/Aclass FunctionProfile;
162459SN/Aclass ProfileNode;
172459SN/A#else
182459SN/Aclass Process;
192459SN/Aclass FunctionalMemory;
202459SN/A#endif
212459SN/A
222459SN/A// In the new CPU case this may be quite small...It depends on what I define
232459SN/A// ThreadState to be.  Currently it's only the state that exists within
242459SN/A// ExecContext basically.  Leaves the interface and manipulation up to the
252459SN/A// CPU.  Not sure this is useful/flexible...probably can be if I can avoid
262459SN/A// including state here that parts of the pipeline can't modify directly,
272665SN/A// or at least don't let them.  The only problem is for state that's needed
282665SN/A// per thread, per structure.  I.e. rename table, memreqs.
292665SN/A// On the other hand, it might be nice to not have to pay the extra pointer
302459SN/A// lookup to get frequently used state such as a memreq (that isn't used much
312459SN/A// elsewhere)...
326329Sgblack@eecs.umich.edu
336329Sgblack@eecs.umich.edu// Maybe this ozone thread state should only really have committed state?
342459SN/A// I need to think about why I'm using this and what it's useful for.  Clearly
356329Sgblack@eecs.umich.edu// has benefits for SMT; basically serves same use as CPUExecContext.
366329Sgblack@eecs.umich.edu// Makes the ExecContext proxy easier.  Gives organization/central access point
376320SN/A// to state of a thread that can be accessed normally (i.e. not in-flight
386329Sgblack@eecs.umich.edu// stuff within a OoO processor).  Does this need an XC proxy within it?
392459SN/Atemplate <class Impl>
402459SN/Astruct O3ThreadState : public ThreadState {
412459SN/A    typedef ExecContext::Status Status;
426329Sgblack@eecs.umich.edu    typedef typename Impl::FullCPU FullCPU;
436329Sgblack@eecs.umich.edu
446329Sgblack@eecs.umich.edu    Status _status;
456329Sgblack@eecs.umich.edu
466329Sgblack@eecs.umich.edu    // Current instruction?
476329Sgblack@eecs.umich.edu    TheISA::MachInst inst;
486329Sgblack@eecs.umich.edu  private:
496329Sgblack@eecs.umich.edu    FullCPU *cpu;
506329Sgblack@eecs.umich.edu  public:
516329Sgblack@eecs.umich.edu
526329Sgblack@eecs.umich.edu    bool inSyscall;
536329Sgblack@eecs.umich.edu
546329Sgblack@eecs.umich.edu    bool trapPending;
556329Sgblack@eecs.umich.edu
566329Sgblack@eecs.umich.edu#if FULL_SYSTEM
576329Sgblack@eecs.umich.edu    O3ThreadState(FullCPU *_cpu, int _thread_num, FunctionalMemory *_mem)
586329Sgblack@eecs.umich.edu        : ThreadState(-1, _thread_num, _mem),
596329Sgblack@eecs.umich.edu          inSyscall(0), trapPending(0)
606329Sgblack@eecs.umich.edu    { }
616329Sgblack@eecs.umich.edu#else
626329Sgblack@eecs.umich.edu    O3ThreadState(FullCPU *_cpu, int _thread_num, Process *_process, int _asid)
636329Sgblack@eecs.umich.edu        : ThreadState(-1, _thread_num, NULL, _process, _asid),
646329Sgblack@eecs.umich.edu          cpu(_cpu), inSyscall(0), trapPending(0)
656329Sgblack@eecs.umich.edu    { }
666329Sgblack@eecs.umich.edu
676329Sgblack@eecs.umich.edu    O3ThreadState(FullCPU *_cpu, int _thread_num, FunctionalMemory *_mem,
686329Sgblack@eecs.umich.edu                  int _asid)
696329Sgblack@eecs.umich.edu        : ThreadState(-1, _thread_num, _mem, NULL, _asid),
706329Sgblack@eecs.umich.edu          cpu(_cpu), inSyscall(0), trapPending(0)
716329Sgblack@eecs.umich.edu    { }
726329Sgblack@eecs.umich.edu#endif
736329Sgblack@eecs.umich.edu
746329Sgblack@eecs.umich.edu    ExecContext *xcProxy;
756320SN/A
766320SN/A    ExecContext *getXCProxy() { return xcProxy; }
776320SN/A
782459SN/A    Status status() const { return _status; }
792459SN/A
802459SN/A    void setStatus(Status new_status) { _status = new_status; }
81
82#if !FULL_SYSTEM
83
84    Fault dummyTranslation(MemReqPtr &req)
85    {
86#if 0
87        assert((req->vaddr >> 48 & 0xffff) == 0);
88#endif
89
90        // put the asid in the upper 16 bits of the paddr
91        req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16);
92        req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16;
93        return NoFault;
94    }
95    Fault translateInstReq(MemReqPtr &req)
96    {
97        return dummyTranslation(req);
98    }
99    Fault translateDataReadReq(MemReqPtr &req)
100    {
101        return dummyTranslation(req);
102    }
103    Fault translateDataWriteReq(MemReqPtr &req)
104    {
105        return dummyTranslation(req);
106    }
107
108    bool validInstAddr(Addr addr)
109    { return process->validInstAddr(addr); }
110
111    bool validDataAddr(Addr addr)
112    { return process->validDataAddr(addr); }
113#else
114    Fault translateInstReq(MemReqPtr &req)
115    {
116        return cpu->itb->translate(req);
117    }
118
119    Fault translateDataReadReq(MemReqPtr &req)
120    {
121        return cpu->dtb->translate(req, false);
122    }
123
124    Fault translateDataWriteReq(MemReqPtr &req)
125    {
126        return cpu->dtb->translate(req, true);
127    }
128#endif
129
130    bool misspeculating() { return false; }
131
132    void setInst(TheISA::MachInst _inst) { inst = _inst; }
133
134    Counter readFuncExeInst() { return funcExeInst; }
135
136    void setFuncExeInst(Counter new_val) { funcExeInst = new_val; }
137
138#if !FULL_SYSTEM
139    void syscall() { process->syscall(xcProxy); }
140#endif
141};
142
143#endif // __CPU_O3_THREAD_STATE_HH__
144