summaryrefslogtreecommitdiff
path: root/src/cpu/ozone/cpu.hh
diff options
context:
space:
mode:
authorKevin Lim <ktlim@umich.edu>2006-05-31 11:34:42 -0400
committerKevin Lim <ktlim@umich.edu>2006-05-31 11:34:42 -0400
commitd4b73086b6b0856c28433b55c8dd5c7b56a1b6df (patch)
treeb54cb10579c6c5788fc09e7abd5d3a0ab1dd533c /src/cpu/ozone/cpu.hh
parentd77d39daee5c3ba8483d58911a1d5b12c4707040 (diff)
parent4a5b51b516853c9fcaabc44caacdd7e8e93dc0ef (diff)
downloadgem5-d4b73086b6b0856c28433b55c8dd5c7b56a1b6df.tar.xz
Merge ktlim@zizzer:/bk/newmem
into zamp.eecs.umich.edu:/z/ktlim2/clean/newmem --HG-- extra : convert_revision : 3d951bbeee0178de47e1bdbe704808544bfe732e
Diffstat (limited to 'src/cpu/ozone/cpu.hh')
-rw-r--r--src/cpu/ozone/cpu.hh713
1 files changed, 352 insertions, 361 deletions
diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh
index fa849bb09..5af2b02b2 100644
--- a/src/cpu/ozone/cpu.hh
+++ b/src/cpu/ozone/cpu.hh
@@ -26,15 +26,19 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __CPU_OOO_CPU_OOO_CPU_HH__
-#define __CPU_OOO_CPU_OOO_CPU_HH__
+#ifndef __CPU_OZONE_CPU_HH__
+#define __CPU_OZONE_CPU_HH__
+
+#include <set>
#include "base/statistics.hh"
+#include "base/timebuf.hh"
#include "config/full_system.hh"
#include "cpu/base.hh"
#include "cpu/exec_context.hh"
-#include "encumbered/cpu/full/fu_pool.hh"
-#include "cpu/ooo_cpu/ea_list.hh"
+#include "cpu/inst_seq.hh"
+#include "cpu/ozone/rename_table.hh"
+#include "cpu/ozone/thread_state.hh"
#include "cpu/pc_event.hh"
#include "cpu/static_inst.hh"
#include "mem/mem_interface.hh"
@@ -42,14 +46,21 @@
// forward declarations
#if FULL_SYSTEM
-class Processor;
+#include "arch/alpha/tlb.hh"
+
class AlphaITB;
class AlphaDTB;
class PhysicalMemory;
+class MemoryController;
+class Sampler;
class RemoteGDB;
class GDBListener;
+namespace Kernel {
+ class Statistics;
+};
+
#else
class Process;
@@ -57,12 +68,16 @@ class Process;
#endif // FULL_SYSTEM
class Checkpoint;
+class EndQuiesceEvent;
class MemInterface;
namespace Trace {
class InstRecord;
}
+template <class>
+class Checker;
+
/**
* Declaration of Out-of-Order CPU class. Basically it is a SimpleCPU with
* simple out-of-order capabilities added to it. It is still a 1 CPI machine
@@ -72,23 +87,177 @@ namespace Trace {
*/
template <class Impl>
-class OoOCPU : public BaseCPU
+class OzoneCPU : public BaseCPU
{
private:
+ typedef typename Impl::FrontEnd FrontEnd;
+ typedef typename Impl::BackEnd BackEnd;
typedef typename Impl::DynInst DynInst;
typedef typename Impl::DynInstPtr DynInstPtr;
+ typedef TheISA::MiscReg MiscReg;
+
+ public:
+ class OzoneXC : public ExecContext {
+ public:
+ OzoneCPU<Impl> *cpu;
+
+ OzoneThreadState<Impl> *thread;
+
+ BaseCPU *getCpuPtr();
+
+ void setCpuId(int id);
+
+ int readCpuId() { return thread->cpuId; }
+
+ FunctionalMemory *getMemPtr() { return thread->mem; }
+
+#if FULL_SYSTEM
+ System *getSystemPtr() { return cpu->system; }
+
+ PhysicalMemory *getPhysMemPtr() { return cpu->physmem; }
+
+ AlphaITB *getITBPtr() { return cpu->itb; }
+
+ AlphaDTB * getDTBPtr() { return cpu->dtb; }
+
+ Kernel::Statistics *getKernelStats() { return thread->kernelStats; }
+#else
+ Process *getProcessPtr() { return thread->process; }
+#endif
+
+ Status status() const { return thread->_status; }
+
+ void setStatus(Status new_status);
+
+ /// Set the status to Active. Optional delay indicates number of
+ /// cycles to wait before beginning execution.
+ void activate(int delay = 1);
+
+ /// Set the status to Suspended.
+ void suspend();
+
+ /// Set the status to Unallocated.
+ void deallocate();
+
+ /// Set the status to Halted.
+ void halt();
+
+#if FULL_SYSTEM
+ void dumpFuncProfile();
+#endif
+
+ void takeOverFrom(ExecContext *old_context);
+
+ void regStats(const std::string &name);
+
+ void serialize(std::ostream &os);
+ void unserialize(Checkpoint *cp, const std::string &section);
+
+#if FULL_SYSTEM
+ EndQuiesceEvent *getQuiesceEvent();
+
+ Tick readLastActivate();
+ Tick readLastSuspend();
+
+ void profileClear();
+ void profileSample();
+#endif
+
+ int getThreadNum();
+
+ // Also somewhat obnoxious. Really only used for the TLB fault.
+ TheISA::MachInst getInst();
+
+ void copyArchRegs(ExecContext *xc);
+
+ void clearArchRegs();
+
+ uint64_t readIntReg(int reg_idx);
+
+ float readFloatRegSingle(int reg_idx);
+
+ double readFloatRegDouble(int reg_idx);
+
+ uint64_t readFloatRegInt(int reg_idx);
+
+ void setIntReg(int reg_idx, uint64_t val);
+
+ void setFloatRegSingle(int reg_idx, float val);
+
+ void setFloatRegDouble(int reg_idx, double val);
+
+ void setFloatRegInt(int reg_idx, uint64_t val);
+
+ uint64_t readPC() { return thread->PC; }
+ void setPC(Addr val);
+
+ uint64_t readNextPC() { return thread->nextPC; }
+ void setNextPC(Addr val);
+
+ public:
+ // ISA stuff:
+ MiscReg readMiscReg(int misc_reg);
+
+ MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault);
+
+ Fault setMiscReg(int misc_reg, const MiscReg &val);
+
+ Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val);
+
+ unsigned readStCondFailures()
+ { return thread->storeCondFailures; }
+
+ void setStCondFailures(unsigned sc_failures)
+ { thread->storeCondFailures = sc_failures; }
+
+#if FULL_SYSTEM
+ bool inPalMode() { return cpu->inPalMode(); }
+#endif
+
+ bool misspeculating() { return false; }
+
+#if !FULL_SYSTEM
+ TheISA::IntReg getSyscallArg(int i)
+ { return thread->renameTable[TheISA::ArgumentReg0 + i]->readIntResult(); }
+
+ // used to shift args for indirect syscall
+ void setSyscallArg(int i, TheISA::IntReg val)
+ { thread->renameTable[TheISA::ArgumentReg0 + i]->setIntResult(i); }
+
+ void setSyscallReturn(SyscallReturn return_value)
+ { cpu->setSyscallReturn(return_value, thread->tid); }
+
+ Counter readFuncExeInst() { return thread->funcExeInst; }
+
+ void setFuncExeInst(Counter new_val)
+ { thread->funcExeInst = new_val; }
+#endif
+ };
+
+ // execution context proxy
+ OzoneXC ozoneXC;
+ ExecContext *xcProxy;
+ ExecContext *checkerXC;
+
+ typedef OzoneThreadState<Impl> ImplState;
+
+ private:
+ OzoneThreadState<Impl> thread;
+
public:
// main simulation loop (one cycle)
void tick();
+ std::set<InstSeqNum> snList;
+ std::set<Addr> lockAddrList;
private:
struct TickEvent : public Event
{
- OoOCPU *cpu;
+ OzoneCPU *cpu;
int width;
- TickEvent(OoOCPU *c, int w);
+ TickEvent(OzoneCPU *c, int w);
void process();
const char *description();
};
@@ -99,9 +268,9 @@ class OoOCPU : public BaseCPU
void scheduleTickEvent(int delay)
{
if (tickEvent.squashed())
- tickEvent.reschedule(curTick + delay);
+ tickEvent.reschedule(curTick + cycles(delay));
else if (!tickEvent.scheduled())
- tickEvent.schedule(curTick + delay);
+ tickEvent.schedule(curTick + cycles(delay));
}
/// Unschedule tick event, regardless of its current state.
@@ -118,20 +287,17 @@ class OoOCPU : public BaseCPU
void trace_data(T data);
public:
- //
enum Status {
Running,
Idle,
- IcacheMiss,
- IcacheMissComplete,
- DcacheMissStall,
SwitchedOut
};
- private:
Status _status;
public:
+ bool checkInterrupts;
+
void post_interrupt(int int_num, int index);
void zero_fill_64(Addr addr) {
@@ -142,41 +308,45 @@ class OoOCPU : public BaseCPU
}
};
- struct Params : public BaseCPU::Params
- {
- MemInterface *icache_interface;
- MemInterface *dcache_interface;
- int width;
-#if FULL_SYSTEM
- AlphaITB *itb;
- AlphaDTB *dtb;
- FunctionalMemory *mem;
-#else
- Process *process;
-#endif
- int issueWidth;
- };
+ typedef typename Impl::Params Params;
- OoOCPU(Params *params);
+ OzoneCPU(Params *params);
- virtual ~OoOCPU();
+ virtual ~OzoneCPU();
void init();
- private:
- void copyFromXC();
-
public:
- // execution context
- ExecContext *xc;
+ BaseCPU *getCpuPtr() { return this; }
+
+ void setCpuId(int id) { cpuId = id; }
+
+ int readCpuId() { return cpuId; }
+
+ int cpuId;
- void switchOut();
+ void switchOut(Sampler *sampler);
+ void signalSwitched();
void takeOverFrom(BaseCPU *oldCPU);
+ Sampler *sampler;
+
+ int switchCount;
+
#if FULL_SYSTEM
Addr dbg_vtophys(Addr addr);
bool interval_stats;
+
+ AlphaITB *itb;
+ AlphaDTB *dtb;
+ System *system;
+
+ // the following two fields are redundant, since we can always
+ // look them up through the system pointer, but we'll leave them
+ // here for now for convenience
+ MemoryController *memctrl;
+ PhysicalMemory *physmem;
#endif
// L1 instruction cache
@@ -185,54 +355,15 @@ class OoOCPU : public BaseCPU
// L1 data cache
MemInterface *dcacheInterface;
- FuncUnitPool *fuPool;
+ /** Pointer to memory. */
+ FunctionalMemory *mem;
- // Refcounted pointer to the one memory request.
- MemReqPtr cacheMemReq;
-
- class ICacheCompletionEvent : public Event
- {
- private:
- OoOCPU *cpu;
-
- public:
- ICacheCompletionEvent(OoOCPU *_cpu);
-
- virtual void process();
- virtual const char *description();
- };
-
- // Will need to create a cache completion event upon any memory miss.
- ICacheCompletionEvent iCacheCompletionEvent;
-
- class DCacheCompletionEvent;
-
- typedef typename
- std::list<DCacheCompletionEvent>::iterator DCacheCompEventIt;
-
- class DCacheCompletionEvent : public Event
- {
- private:
- OoOCPU *cpu;
- DynInstPtr inst;
- DCacheCompEventIt dcceIt;
-
- public:
- DCacheCompletionEvent(OoOCPU *_cpu, DynInstPtr &_inst,
- DCacheCompEventIt &_dcceIt);
-
- virtual void process();
- virtual const char *description();
- };
-
- friend class DCacheCompletionEvent;
-
- protected:
- std::list<DCacheCompletionEvent> dCacheCompList;
- DCacheCompEventIt dcceIt;
+ FrontEnd *frontEnd;
+ BackEnd *backEnd;
private:
Status status() const { return _status; }
+ void setStatus(Status new_status) { _status = new_status; }
virtual void activateContext(int thread_num, int delay);
virtual void suspendContext(int thread_num);
@@ -244,18 +375,16 @@ class OoOCPU : public BaseCPU
virtual void resetStats();
// number of simulated instructions
+ public:
Counter numInst;
Counter startNumInst;
- Stats::Scalar<> numInsts;
virtual Counter totalInstructions() const
{
return numInst - startNumInst;
}
- // number of simulated memory references
- Stats::Scalar<> numMemRefs;
-
+ private:
// number of simulated loads
Counter numLoad;
Counter startNumLoad;
@@ -263,27 +392,15 @@ class OoOCPU : public BaseCPU
// number of idle cycles
Stats::Average<> notIdleFraction;
Stats::Formula idleFraction;
-
- // number of cycles stalled for I-cache misses
- Stats::Scalar<> icacheStallCycles;
- Counter lastIcacheStall;
-
- // number of cycles stalled for D-cache misses
- Stats::Scalar<> dcacheStallCycles;
- Counter lastDcacheStall;
-
- void processICacheCompletion();
-
public:
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
+
#if FULL_SYSTEM
bool validInstAddr(Addr addr) { return true; }
bool validDataAddr(Addr addr) { return true; }
- int getInstAsid() { return xc->regs.instAsid(); }
- int getDataAsid() { return xc->regs.dataAsid(); }
Fault translateInstReq(MemReqPtr &req)
{
@@ -302,13 +419,13 @@ class OoOCPU : public BaseCPU
#else
bool validInstAddr(Addr addr)
- { return xc->validInstAddr(addr); }
+ { return true; }
bool validDataAddr(Addr addr)
- { return xc->validDataAddr(addr); }
+ { return true; }
- int getInstAsid() { return xc->asid; }
- int getDataAsid() { return xc->asid; }
+ int getInstAsid() { return thread.asid; }
+ int getDataAsid() { return thread.asid; }
Fault dummyTranslation(MemReqPtr &req)
{
@@ -321,318 +438,192 @@ class OoOCPU : public BaseCPU
req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16;
return NoFault;
}
+
+ /** Translates instruction requestion in syscall emulation mode. */
Fault translateInstReq(MemReqPtr &req)
{
return dummyTranslation(req);
}
+
+ /** Translates data read request in syscall emulation mode. */
Fault translateDataReadReq(MemReqPtr &req)
{
return dummyTranslation(req);
}
+
+ /** Translates data write request in syscall emulation mode. */
Fault translateDataWriteReq(MemReqPtr &req)
{
return dummyTranslation(req);
}
-
#endif
+ /** Old CPU read from memory function. No longer used. */
template <class T>
- Fault read(Addr addr, T &data, unsigned flags, DynInstPtr inst);
-
- template <class T>
- Fault write(T data, Addr addr, unsigned flags,
- uint64_t *res, DynInstPtr inst);
-
- void prefetch(Addr addr, unsigned flags)
+ Fault read(MemReqPtr &req, T &data)
{
- // need to do this...
- }
-
- void writeHint(Addr addr, int size, unsigned flags)
- {
- // need to do this...
- }
-
- Fault copySrcTranslate(Addr src);
-
- Fault copy(Addr dest);
-
- private:
- bool executeInst(DynInstPtr &inst);
-
- void renameInst(DynInstPtr &inst);
-
- void addInst(DynInstPtr &inst);
-
- void commitHeadInst();
-
- bool getOneInst();
-
- Fault fetchCacheLine();
-
- InstSeqNum getAndIncrementInstSeq();
-
- bool ambigMemAddr;
-
- private:
- InstSeqNum globalSeqNum;
-
- DynInstPtr renameTable[TheISA::TotalNumRegs];
- DynInstPtr commitTable[TheISA::TotalNumRegs];
-
- // Might need a table of the shadow registers as well.
-#if FULL_SYSTEM
- DynInstPtr palShadowTable[TheISA::NumIntRegs];
+#if 0
+#if FULL_SYSTEM && defined(TARGET_ALPHA)
+ if (req->flags & LOCKED) {
+ req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr);
+ req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true);
+ }
+#endif
#endif
+ Fault error;
+ if (req->flags & LOCKED) {
+ lockAddrList.insert(req->paddr);
+ lockFlag = true;
+ }
- public:
- // The register accessor methods provide the index of the
- // instruction's operand (e.g., 0 or 1), not the architectural
- // register index, to simplify the implementation of register
- // renaming. We find the architectural register index by indexing
- // into the instruction's own operand index table. Note that a
- // raw pointer to the StaticInst is provided instead of a
- // ref-counted StaticInstPtr to redice overhead. This is fine as
- // long as these methods don't copy the pointer into any long-term
- // storage (which is pretty hard to imagine they would have reason
- // to do).
-
- // In the OoO case these shouldn't read from the XC but rather from the
- // rename table of DynInsts. Also these likely shouldn't be called very
- // often, other than when adding things into the xc during say a syscall.
-
- uint64_t readIntReg(StaticInst *si, int idx)
- {
- return xc->readIntReg(si->srcRegIdx(idx));
+ error = this->mem->read(req, data);
+ data = gtoh(data);
+ return error;
}
- FloatReg readFloatReg(StaticInst *si, int idx, width)
- {
- int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
- return xc->readFloatReg(reg_idx, width);
- }
- FloatReg readFloatReg(StaticInst *si, int idx)
+ /** CPU read function, forwards read to LSQ. */
+ template <class T>
+ Fault read(MemReqPtr &req, T &data, int load_idx)
{
- int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
- return xc->readFloatReg(reg_idx);
+ return backEnd->read(req, data, load_idx);
}
- FloatRegBits readFloatRegBits(StaticInst *si, int idx, int width)
+ /** Old CPU write to memory function. No longer used. */
+ template <class T>
+ Fault write(MemReqPtr &req, T &data)
{
- int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
- return xc->readFloatRegBits(reg_idx, width);
- }
+#if 0
+#if FULL_SYSTEM && defined(TARGET_ALPHA)
+ 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);
+ }
+ }
- FloatRegBits readFloatRegBits(StaticInst *si, int idx)
- {
- int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
- return xc->readFloatRegBits(reg_idx);
- }
+ // 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 < this->system->execContexts.size(); i++){
+ xc = this->system->execContexts[i];
+ if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) ==
+ (req->paddr & ~0xf)) {
+ xc->setMiscReg(TheISA::Lock_Flag_DepTag, false);
+ }
+ }
- void setIntReg(StaticInst *si, int idx, uint64_t val)
- {
- xc->setIntReg(si->destRegIdx(idx), val);
- }
+#endif
+#endif
- void setFloatReg(StaticInst *si, int idx, FloatReg val, int width)
- {
- int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
- xc->setFloatReg(reg_idx, val, width);
- }
+ if (req->flags & LOCKED) {
+ if (req->flags & UNCACHEABLE) {
+ req->result = 2;
+ } else {
+ if (this->lockFlag) {
+ if (lockAddrList.find(req->paddr) !=
+ lockAddrList.end()) {
+ req->result = 1;
+ } else {
+ req->result = 0;
+ return NoFault;
+ }
+ } else {
+ req->result = 0;
+ return NoFault;
+ }
+ }
+ }
- void setFloatReg(StaticInst *si, int idx, FloatReg val)
- {
- int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
- xc->setFloatReg(reg_idx, val);
+ return this->mem->write(req, (T)htog(data));
}
- void setFloatRegBits(StaticInst *si, int idx, FloatRegBits val, int width)
+ /** CPU write function, forwards write to LSQ. */
+ template <class T>
+ Fault write(MemReqPtr &req, T &data, int store_idx)
{
- int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
- xc->setFloatRegBits(reg_idx, val, width);
+ return backEnd->write(req, data, store_idx);
}
- void setFloatRegBits(StaticInst *si, int idx, FloatRegBits val)
+ void prefetch(Addr addr, unsigned flags)
{
- int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
- xc->setFloatRegBits(reg_idx, val);
+ // need to do this...
}
- uint64_t readPC() { return PC; }
- void setNextPC(Addr val) { nextPC = val; }
-
- private:
- Addr PC;
- Addr nextPC;
-
- unsigned issueWidth;
-
- bool fetchRedirExcp;
- bool fetchRedirBranch;
-
- /** Mask to get a cache block's address. */
- Addr cacheBlkMask;
-
- unsigned cacheBlkSize;
-
- Addr cacheBlkPC;
-
- /** The cache line being fetched. */
- uint8_t *cacheData;
-
- protected:
- bool cacheBlkValid;
-
- private:
-
- // Align an address (typically a PC) to the start of an I-cache block.
- // We fold in the PISA 64- to 32-bit conversion here as well.
- Addr icacheBlockAlignPC(Addr addr)
+ void writeHint(Addr addr, int size, unsigned flags)
{
- addr = TheISA::realPCToFetchPC(addr);
- return (addr & ~(cacheBlkMask));
+ // need to do this...
}
- unsigned instSize;
+ Fault copySrcTranslate(Addr src);
- // ROB tracking stuff.
- DynInstPtr robHeadPtr;
- DynInstPtr robTailPtr;
- unsigned robSize;
- unsigned robInsts;
+ Fault copy(Addr dest);
- // List of outstanding EA instructions.
- protected:
- EAList eaList;
+ InstSeqNum globalSeqNum;
public:
- void branchToTarget(Addr val)
- {
- if (!fetchRedirExcp) {
- fetchRedirBranch = true;
- PC = val;
- }
- }
-
- // ISA stuff:
- uint64_t readUniq() { return xc->readUniq(); }
- void setUniq(uint64_t val) { xc->setUniq(val); }
+ void squashFromXC();
- uint64_t readFpcr() { return xc->readFpcr(); }
- void setFpcr(uint64_t val) { xc->setFpcr(val); }
+ // @todo: This can be a useful debug function. Implement it.
+ void dumpInsts() { frontEnd->dumpInsts(); }
#if FULL_SYSTEM
- uint64_t readIpr(int idx, Fault &fault) { return xc->readIpr(idx, fault); }
- Fault setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); }
- Fault hwrei() { return xc->hwrei(); }
- int readIntrFlag() { return xc->readIntrFlag(); }
- void setIntrFlag(int val) { xc->setIntrFlag(val); }
- bool inPalMode() { return xc->inPalMode(); }
- void trap(Fault fault) { fault->invoke(xc); }
- bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); }
+ Fault hwrei();
+ int readIntrFlag() { return thread.regs.intrflag; }
+ void setIntrFlag(int val) { thread.regs.intrflag = val; }
+ bool inPalMode() { return AlphaISA::PcPAL(thread.PC); }
+ bool inPalMode(Addr pc) { return AlphaISA::PcPAL(pc); }
+ bool simPalCheck(int palFunc);
+ void processInterrupts();
#else
- void syscall() { xc->syscall(); }
-#endif
-
- ExecContext *xcBase() { return xc; }
-};
-
-
-// precise architected memory state accessor macros
-template <class Impl>
-template <class T>
-Fault
-OoOCPU<Impl>::read(Addr addr, T &data, unsigned flags, DynInstPtr inst)
-{
- MemReqPtr readReq = new MemReq();
- readReq->xc = xc;
- readReq->asid = 0;
- readReq->data = new uint8_t[64];
-
- readReq->reset(addr, sizeof(T), flags);
-
- // translate to physical address - This might be an ISA impl call
- Fault fault = translateDataReadReq(readReq);
-
- // do functional access
- if (fault == NoFault)
- fault = xc->mem->read(readReq, data);
-#if 0
- if (traceData) {
- traceData->setAddr(addr);
- if (fault == NoFault)
- traceData->setData(data);
- }
+ void syscall();
+ void setSyscallReturn(SyscallReturn return_value, int tid);
#endif
- // if we have a cache, do cache access too
- if (fault == NoFault && dcacheInterface) {
- readReq->cmd = Read;
- readReq->completionEvent = NULL;
- readReq->time = curTick;
- /*MemAccessResult result = */dcacheInterface->access(readReq);
+ ExecContext *xcBase() { return xcProxy; }
- if (dcacheInterface->doEvents()) {
- readReq->completionEvent = new DCacheCompletionEvent(this, inst,
- dcceIt);
- }
- }
-
- if (!dcacheInterface && (readReq->flags & UNCACHEABLE))
- recordEvent("Uncached Read");
-
- return fault;
-}
-
-template <class Impl>
-template <class T>
-Fault
-OoOCPU<Impl>::write(T data, Addr addr, unsigned flags,
- uint64_t *res, DynInstPtr inst)
-{
- MemReqPtr writeReq = new MemReq();
- writeReq->xc = xc;
- writeReq->asid = 0;
- writeReq->data = new uint8_t[64];
+ bool decoupledFrontEnd;
+ struct CommStruct {
+ InstSeqNum doneSeqNum;
+ InstSeqNum nonSpecSeqNum;
+ bool uncached;
+ unsigned lqIdx;
-#if 0
- if (traceData) {
- traceData->setAddr(addr);
- traceData->setData(data);
- }
-#endif
-
- writeReq->reset(addr, sizeof(T), flags);
-
- // translate to physical address
- Fault fault = translateDataWriteReq(writeReq);
-
- // do functional access
- if (fault == NoFault)
- fault = xc->write(writeReq, data);
-
- if (fault == NoFault && dcacheInterface) {
- writeReq->cmd = Write;
- memcpy(writeReq->data,(uint8_t *)&data,writeReq->size);
- writeReq->completionEvent = NULL;
- writeReq->time = curTick;
- /*MemAccessResult result = */dcacheInterface->access(writeReq);
-
- if (dcacheInterface->doEvents()) {
- writeReq->completionEvent = new DCacheCompletionEvent(this, inst,
- dcceIt);
- }
- }
-
- if (res && (fault == NoFault))
- *res = writeReq->result;
+ bool stall;
+ };
+ TimeBuffer<CommStruct> comm;
- if (!dcacheInterface && (writeReq->flags & UNCACHEABLE))
- recordEvent("Uncached Write");
+ bool lockFlag;
- return fault;
-}
+ Stats::Scalar<> quiesceCycles;
+ Checker<DynInstPtr> *checker;
+};
-#endif // __CPU_OOO_CPU_OOO_CPU_HH__
+#endif // __CPU_OZONE_CPU_HH__