#define __CPU_SIMPLE_THREAD_HH__
#include "arch/isa_traits.hh"
+#include "arch/regfile.hh"
+#include "arch/syscallreturn.hh"
+#include "arch/tlb.hh"
#include "config/full_system.hh"
#include "cpu/thread_context.hh"
#include "cpu/thread_state.hh"
-#include "mem/physical.hh"
#include "mem/request.hh"
#include "sim/byteswap.hh"
#include "sim/eventq.hh"
#if FULL_SYSTEM
#include "sim/system.hh"
-#include "arch/tlb.hh"
class FunctionProfile;
class ProfileNode;
class FunctionalPort;
class PhysicalPort;
-namespace Kernel {
- class Statistics;
+namespace TheISA {
+ namespace Kernel {
+ class Statistics;
+ };
};
#else // !FULL_SYSTEM
typedef ThreadContext::Status Status;
protected:
- RegFile regs; // correct-path register context
+ RegFile regs; // correct-path register context
public:
// pointer to CPU associated with this SimpleThread
System *system;
-#if FULL_SYSTEM
- AlphaITB *itb;
- AlphaDTB *dtb;
-#endif
+ TheISA::ITB *itb;
+ TheISA::DTB *dtb;
// constructor: initialize SimpleThread from given process structure
#if FULL_SYSTEM
SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
- AlphaITB *_itb, AlphaDTB *_dtb,
+ TheISA::ITB *_itb, TheISA::DTB *_dtb,
bool use_kernel_stats = true);
#else
- SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid,
- MemObject *memobj);
- // Constructor to use SimpleThread to pass reg file around. Not
- // used for anything else.
- SimpleThread(RegFile *regFile);
+ SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process,
+ TheISA::ITB *_itb, TheISA::DTB *_dtb, int _asid);
#endif
+
+ SimpleThread();
+
virtual ~SimpleThread();
virtual void takeOverFrom(ThreadContext *oldContext);
void regStats(const std::string &name);
+ void copyTC(ThreadContext *context);
+
+ void copyState(ThreadContext *oldContext);
+
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string §ion);
*/
ThreadContext *getTC() { return tc; }
-#if FULL_SYSTEM
- int getInstAsid() { return regs.instAsid(); }
- int getDataAsid() { return regs.dataAsid(); }
-
Fault translateInstReq(RequestPtr &req)
{
return itb->translate(req, tc);
return dtb->translate(req, tc, true);
}
- void dumpFuncProfile();
-
- int readIntrFlag() { return regs.intrflag; }
- void setIntrFlag(int val) { regs.intrflag = val; }
- Fault hwrei();
-
- bool simPalCheck(int palFunc);
-#else
- Fault translateInstReq(RequestPtr &req)
+ void demapPage(Addr vaddr, uint64_t asn)
{
- return process->pTable->translate(req);
+ itb->demapPage(vaddr, asn);
+ dtb->demapPage(vaddr, asn);
}
- Fault translateDataReadReq(RequestPtr &req)
+ void demapInstPage(Addr vaddr, uint64_t asn)
{
- return process->pTable->translate(req);
+ itb->demapPage(vaddr, asn);
}
- Fault translateDataWriteReq(RequestPtr &req)
+ void demapDataPage(Addr vaddr, uint64_t asn)
{
- return process->pTable->translate(req);
+ dtb->demapPage(vaddr, asn);
}
+
+#if FULL_SYSTEM
+ int getInstAsid() { return regs.instAsid(); }
+ int getDataAsid() { return regs.dataAsid(); }
+
+ void dumpFuncProfile();
+
+ Fault hwrei();
+
+ bool simPalCheck(int palFunc);
+
#endif
/*******************************************
BaseCPU *getCpuPtr() { return cpu; }
- int getThreadNum() { return tid; }
+ TheISA::ITB *getITBPtr() { return itb; }
+
+ TheISA::DTB *getDTBPtr() { return dtb; }
#if FULL_SYSTEM
System *getSystemPtr() { return system; }
- AlphaITB *getITBPtr() { return itb; }
-
- AlphaDTB *getDTBPtr() { return dtb; }
-
FunctionalPort *getPhysPort() { return physPort; }
- /** Return a virtual port. If no thread context is specified then a static
- * port is returned. Otherwise a port is created and returned. It must be
- * deleted by deleteVirtPort(). */
- VirtualPort *getVirtPort(ThreadContext *tc);
-
- void delVirtPort(VirtualPort *vp);
+ /** Return a virtual port. This port cannot be cached locally in an object.
+ * After a CPU switch it may point to the wrong memory object which could
+ * mean stale data.
+ */
+ VirtualPort *getVirtPort() { return virtPort; }
#endif
Status status() const { return _status; }
/// Set the status to Halted.
void halt();
-/*
- template <class T>
- Fault read(RequestPtr &req, T &data)
- {
-#if FULL_SYSTEM && THE_ISA == ALPHA_ISA
- if (req->flags & LOCKED) {
- req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr);
- req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true);
- }
-#endif
-
- Fault error;
- error = mem->prot_read(req->paddr, data, req->size);
- data = LittleEndianGuest::gtoh(data);
- return error;
- }
-
- template <class T>
- Fault write(RequestPtr &req, T &data)
- {
-#if FULL_SYSTEM && THE_ISA == ALPHA_ISA
- ExecContext *xc;
-
- // If this is a store conditional, act appropriately
- if (req->flags & LOCKED) {
- xc = req->xc;
-
- if (req->flags & UNCACHEABLE) {
- // Don't update result register (see stq_c in isa_desc)
- req->result = 2;
- xc->setStCondFailures(0);//Needed? [RGD]
- } else {
- bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag);
- Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag);
- req->result = lock_flag;
- if (!lock_flag ||
- ((lock_addr & ~0xf) != (req->paddr & ~0xf))) {
- xc->setMiscReg(TheISA::Lock_Flag_DepTag, false);
- xc->setStCondFailures(xc->readStCondFailures() + 1);
- if (((xc->readStCondFailures()) % 100000) == 0) {
- std::cerr << "Warning: "
- << xc->readStCondFailures()
- << " consecutive store conditional failures "
- << "on cpu " << req->xc->readCpuId()
- << std::endl;
- }
- return NoFault;
- }
- else xc->setStCondFailures(0);
- }
- }
-
- // Need to clear any locked flags on other proccessors for
- // this address. Only do this for succsful Store Conditionals
- // and all other stores (WH64?). Unsuccessful Store
- // Conditionals would have returned above, and wouldn't fall
- // through.
- for (int i = 0; i < system->execContexts.size(); i++){
- xc = system->execContexts[i];
- if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) ==
- (req->paddr & ~0xf)) {
- xc->setMiscReg(TheISA::Lock_Flag_DepTag, false);
- }
- }
-
-#endif
- return mem->prot_write(req->paddr, (T)htog(data), req->size);
- }
-*/
virtual bool misspeculating();
Fault instRead(RequestPtr &req)
//
uint64_t readIntReg(int reg_idx)
{
- return regs.readIntReg(reg_idx);
+ int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
+ return regs.readIntReg(flatIndex);
}
FloatReg readFloatReg(int reg_idx, int width)
{
- return regs.readFloatReg(reg_idx, width);
+ int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx);
+ return regs.readFloatReg(flatIndex, width);
}
FloatReg readFloatReg(int reg_idx)
{
- return regs.readFloatReg(reg_idx);
+ int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx);
+ return regs.readFloatReg(flatIndex);
}
FloatRegBits readFloatRegBits(int reg_idx, int width)
{
- return regs.readFloatRegBits(reg_idx, width);
+ int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx);
+ return regs.readFloatRegBits(flatIndex, width);
}
FloatRegBits readFloatRegBits(int reg_idx)
{
- return regs.readFloatRegBits(reg_idx);
+ int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx);
+ return regs.readFloatRegBits(flatIndex);
}
void setIntReg(int reg_idx, uint64_t val)
{
- regs.setIntReg(reg_idx, val);
+ int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
+ regs.setIntReg(flatIndex, val);
}
void setFloatReg(int reg_idx, FloatReg val, int width)
{
- regs.setFloatReg(reg_idx, val, width);
+ int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx);
+ regs.setFloatReg(flatIndex, val, width);
}
void setFloatReg(int reg_idx, FloatReg val)
{
- regs.setFloatReg(reg_idx, val);
+ int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx);
+ regs.setFloatReg(flatIndex, val);
}
void setFloatRegBits(int reg_idx, FloatRegBits val, int width)
{
- regs.setFloatRegBits(reg_idx, val, width);
+ int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx);
+ regs.setFloatRegBits(flatIndex, val, width);
}
void setFloatRegBits(int reg_idx, FloatRegBits val)
{
- regs.setFloatRegBits(reg_idx, val);
+ int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx);
+ regs.setFloatRegBits(flatIndex, val);
}
uint64_t readPC()
regs.setPC(val);
}
+ uint64_t readMicroPC()
+ {
+ return microPC;
+ }
+
+ void setMicroPC(uint64_t val)
+ {
+ microPC = val;
+ }
+
uint64_t readNextPC()
{
return regs.readNextPC();
regs.setNextPC(val);
}
+ uint64_t readNextMicroPC()
+ {
+ return nextMicroPC;
+ }
+
+ void setNextMicroPC(uint64_t val)
+ {
+ nextMicroPC = val;
+ }
+
uint64_t readNextNPC()
{
return regs.readNextNPC();
regs.setNextNPC(val);
}
- MiscReg readMiscReg(int misc_reg)
+ MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid = 0)
{
- return regs.readMiscReg(misc_reg);
+ return regs.readMiscRegNoEffect(misc_reg);
}
- MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
+ MiscReg readMiscReg(int misc_reg, unsigned tid = 0)
{
- return regs.readMiscRegWithEffect(misc_reg, fault, tc);
+ return regs.readMiscReg(misc_reg, tc);
}
- Fault setMiscReg(int misc_reg, const MiscReg &val)
+ void setMiscRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid = 0)
{
- return regs.setMiscReg(misc_reg, val);
+ return regs.setMiscRegNoEffect(misc_reg, val);
}
- Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ void setMiscReg(int misc_reg, const MiscReg &val, unsigned tid = 0)
{
- return regs.setMiscRegWithEffect(misc_reg, val, tc);
+ return regs.setMiscReg(misc_reg, val, tc);
}
unsigned readStCondFailures() { return storeCondFailures; }
void setStCondFailures(unsigned sc_failures)
{ storeCondFailures = sc_failures; }
-#if FULL_SYSTEM
- bool inPalMode() { return AlphaISA::PcPAL(regs.readPC()); }
-#endif
-
#if !FULL_SYSTEM
TheISA::IntReg getSyscallArg(int i)
{
- return regs.readIntReg(TheISA::ArgumentReg0 + i);
+ assert(i < TheISA::NumArgumentRegs);
+ TheISA::IntReg val = regs.readIntReg(
+ TheISA::flattenIntIndex(getTC(), TheISA::ArgumentReg[i]));
+#if THE_ISA == SPARC_ISA
+ if (bits(this->readMiscRegNoEffect(
+ SparcISA::MISCREG_PSTATE), 3, 3)) {
+ val = bits(val, 31, 0);
+ }
+#endif
+ return val;
}
// used to shift args for indirect syscall
void setSyscallArg(int i, TheISA::IntReg val)
{
- regs.setIntReg(TheISA::ArgumentReg0 + i, val);
+ assert(i < TheISA::NumArgumentRegs);
+ regs.setIntReg(TheISA::flattenIntIndex(getTC(),
+ TheISA::ArgumentReg[i]), val);
}
void setSyscallReturn(SyscallReturn return_value)
{
- TheISA::setSyscallReturn(return_value, ®s);
+ TheISA::setSyscallReturn(return_value, getTC());
}
void syscall(int64_t callnum)
process->syscall(callnum, tc);
}
#endif
-
- void changeRegFileContext(RegFile::ContextParam param,
- RegFile::ContextVal val)
- {
- regs.changeContext(param, val);
- }
};