diff options
author | Kevin Lim <ktlim@umich.edu> | 2006-05-31 11:34:42 -0400 |
---|---|---|
committer | Kevin Lim <ktlim@umich.edu> | 2006-05-31 11:34:42 -0400 |
commit | d4b73086b6b0856c28433b55c8dd5c7b56a1b6df (patch) | |
tree | b54cb10579c6c5788fc09e7abd5d3a0ab1dd533c /src/cpu/ozone/cpu.hh | |
parent | d77d39daee5c3ba8483d58911a1d5b12c4707040 (diff) | |
parent | 4a5b51b516853c9fcaabc44caacdd7e8e93dc0ef (diff) | |
download | gem5-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.hh | 713 |
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 §ion); + +#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 §ion); + #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__ |