From e704960c80033dd008907caa7c24742a1020d302 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Mon, 24 Apr 2006 17:10:06 -0400 Subject: Updates to Ozone model for quiesce, store conditionals. --HG-- extra : convert_revision : 72ddd75ad0b5783aca9484e7d178c2915ee8e355 --- cpu/ozone/cpu.hh | 122 +++++++++++++++++++++++++++++++++++++++--- cpu/ozone/cpu_impl.hh | 62 +++++---------------- cpu/ozone/dyn_inst_impl.hh | 1 + cpu/ozone/front_end.hh | 10 ++-- cpu/ozone/front_end_impl.hh | 69 +++++++++++++++++++----- cpu/ozone/lw_back_end.hh | 6 ++- cpu/ozone/lw_back_end_impl.hh | 61 ++++++++++++--------- cpu/ozone/lw_lsq.hh | 25 +++++---- cpu/ozone/lw_lsq_impl.hh | 32 +++++++++-- 9 files changed, 272 insertions(+), 116 deletions(-) (limited to 'cpu/ozone') diff --git a/cpu/ozone/cpu.hh b/cpu/ozone/cpu.hh index 17e0f5c42..d37d3360c 100644 --- a/cpu/ozone/cpu.hh +++ b/cpu/ozone/cpu.hh @@ -42,7 +42,6 @@ #include "cpu/pc_event.hh" #include "cpu/static_inst.hh" #include "mem/mem_interface.hh" -#include "mem/page_table.hh" #include "sim/eventq.hh" // forward declarations @@ -59,7 +58,6 @@ class GDBListener; #else -class PageTable; class Process; #endif // FULL_SYSTEM @@ -349,9 +347,8 @@ class OzoneCPU : public BaseCPU // L1 data cache MemInterface *dcacheInterface; -#if !FULL_SYSTEM - PageTable *pTable; -#endif + /** Pointer to memory. */ + FunctionalMemory *mem; FrontEnd *frontEnd; @@ -428,24 +425,62 @@ class OzoneCPU : public BaseCPU int getInstAsid() { return thread.asid; } int getDataAsid() { return thread.asid; } + Fault dummyTranslation(MemReqPtr &req) + { +#if 0 + assert((req->vaddr >> 48 & 0xffff) == 0); +#endif + + // put the asid in the upper 16 bits of the paddr + req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16); + 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 this->pTable->translate(req); + return dummyTranslation(req); } /** Translates data read request in syscall emulation mode. */ Fault translateDataReadReq(MemReqPtr &req) { - return this->pTable->translate(req); + return dummyTranslation(req); } /** Translates data write request in syscall emulation mode. */ Fault translateDataWriteReq(MemReqPtr &req) { - return this->pTable->translate(req); + return dummyTranslation(req); } #endif + + /** Old CPU read from memory function. No longer used. */ + template + Fault read(MemReqPtr &req, T &data) + { +// panic("CPU READ NOT IMPLEMENTED W/NEW MEMORY\n"); +#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) { +// lockAddr = req->paddr; + lockFlag = true; + } + + error = this->mem->read(req, data); + data = gtoh(data); + return error; + } + + /** CPU read function, forwards read to LSQ. */ template Fault read(MemReqPtr &req, T &data, int load_idx) @@ -453,6 +488,75 @@ class OzoneCPU : public BaseCPU return backEnd->read(req, data, load_idx); } + /** Old CPU write to memory function. No longer used. */ + template + Fault write(MemReqPtr &req, T &data) + { +#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); + } + } + + // 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); + } + } + +#endif +#endif + + if (req->flags & LOCKED) { + if (req->flags & UNCACHEABLE) { + req->result = 2; + } else { + if (this->lockFlag/* && this->lockAddr == req->paddr*/) { + req->result = 1; + } else { + req->result = 0; + return NoFault; + } + } + } + + return this->mem->write(req, (T)htog(data)); + } + /** CPU write function, forwards write to LSQ. */ template Fault write(MemReqPtr &req, T &data, int store_idx) @@ -507,6 +611,8 @@ class OzoneCPU : public BaseCPU bool stall; }; TimeBuffer comm; + + bool lockFlag; }; #endif // __CPU_OZONE_CPU_HH__ diff --git a/cpu/ozone/cpu_impl.hh b/cpu/ozone/cpu_impl.hh index c205ad319..a7bc61603 100644 --- a/cpu/ozone/cpu_impl.hh +++ b/cpu/ozone/cpu_impl.hh @@ -149,12 +149,14 @@ OzoneCPU::DCacheCompletionEvent::description() template OzoneCPU::OzoneCPU(Params *p) #if FULL_SYSTEM - : BaseCPU(p), thread(this, 0, p->mem), tickEvent(this, p->width), + : BaseCPU(p), thread(this, 0, p->mem), tickEvent(this, p->width), mem(p->mem), #else : BaseCPU(p), thread(this, 0, p->workload[0], 0), tickEvent(this, p->width), + mem(p->workload[0]->getMemory()), #endif comm(5, 5) { + frontEnd = new FrontEnd(p); backEnd = new BackEnd(p); @@ -245,51 +247,7 @@ OzoneCPU::OzoneCPU(Params *p) globalSeqNum = 1; checkInterrupts = false; -/* - fetchRedirBranch = true; - fetchRedirExcp = true; - - // Need to initialize the rename maps, and the head and tail pointers. - robHeadPtr = new DynInst(this); - robTailPtr = new DynInst(this); - - robHeadPtr->setNextInst(robTailPtr); -// robHeadPtr->setPrevInst(NULL); -// robTailPtr->setNextInst(NULL); - robTailPtr->setPrevInst(robHeadPtr); - - robHeadPtr->setCompleted(); - robTailPtr->setCompleted(); - - for (int i = 0; i < ISA::TotalNumRegs; ++i) { - renameTable[i] = new DynInst(this); - commitTable[i] = new DynInst(this); - renameTable[i]->setCompleted(); - commitTable[i]->setCompleted(); - } - -#if FULL_SYSTEM - for (int i = 0; i < ISA::NumIntRegs; ++i) { - palShadowTable[i] = new DynInst(this); - palShadowTable[i]->setCompleted(); - } -#endif - - // Size of cache block. - cacheBlkSize = icacheInterface ? icacheInterface->getBlockSize() : 64; - - // Create mask to get rid of offset bits. - cacheBlkMask = (cacheBlkSize - 1); - - // Get the size of an instruction. - instSize = sizeof(MachInst); - - // Create space to store a cache line. - cacheData = new uint8_t[cacheBlkSize]; - - cacheBlkValid = false; -*/ for (int i = 0; i < TheISA::TotalNumRegs; ++i) { thread.renameTable[i] = new DynInst(this); thread.renameTable[i]->setCompleted(); @@ -299,9 +257,11 @@ OzoneCPU::OzoneCPU(Params *p) backEnd->renameTable.copyFrom(thread.renameTable); #if !FULL_SYSTEM - pTable = p->pTable; +// pTable = p->pTable; #endif + lockFlag = 0; + DPRINTF(OzoneCPU, "OzoneCPU: Created Ozone cpu object.\n"); } @@ -392,6 +352,7 @@ OzoneCPU::activateContext(int thread_num, int delay) scheduleTickEvent(delay); _status = Running; thread._status = ExecContext::Active; + frontEnd->wakeFromQuiesce(); } template @@ -401,8 +362,8 @@ OzoneCPU::suspendContext(int thread_num) // Eventually change this in SMT. assert(thread_num == 0); // assert(xcProxy); - - assert(_status == Running); + // @todo: Figure out how to initially set the status properly so this is running. +// assert(_status == Running); notIdleFraction--; unscheduleTickEvent(); _status = Idle; @@ -665,6 +626,7 @@ OzoneCPU::tick() { DPRINTF(OzoneCPU, "\n\nOzoneCPU: Ticking cpu.\n"); + _status = Running; thread.renameTable[ZeroReg]->setIntResult(0); thread.renameTable[ZeroReg+TheISA::FP_Base_DepTag]-> setDoubleResult(0.0); @@ -756,7 +718,7 @@ OzoneCPU::tick() // check for instruction-count-based events comInstEventQueue[0]->serviceEvents(numInst); - if (!tickEvent.scheduled()) + if (!tickEvent.scheduled() && _status == Running) tickEvent.schedule(curTick + 1); } @@ -821,6 +783,8 @@ OzoneCPU::hwrei() thread.setNextPC(thread.readMiscReg(AlphaISA::IPR_EXC_ADDR)); + lockFlag = false; + // Not sure how to make a similar check in the Ozone model // if (!misspeculating()) { kernelStats->hwrei(); diff --git a/cpu/ozone/dyn_inst_impl.hh b/cpu/ozone/dyn_inst_impl.hh index 2d86ced62..c83481c9a 100644 --- a/cpu/ozone/dyn_inst_impl.hh +++ b/cpu/ozone/dyn_inst_impl.hh @@ -237,6 +237,7 @@ OzoneDynInst::hwrei() this->cpu->kernelStats->hwrei(); this->cpu->checkInterrupts = true; + this->cpu->lockFlag = false; // FIXME: XXX check for interrupts? XXX return NoFault; diff --git a/cpu/ozone/front_end.hh b/cpu/ozone/front_end.hh index 251f4200c..2bff2544d 100644 --- a/cpu/ozone/front_end.hh +++ b/cpu/ozone/front_end.hh @@ -60,7 +60,7 @@ class FrontEnd const bool is_branch = false, const bool branch_taken = false); DynInstPtr getInst(); - void processCacheCompletion(); + void processCacheCompletion(MemReqPtr &req); void addFreeRegs(int num_freed); @@ -109,6 +109,7 @@ class FrontEnd SerializeBlocked, SerializeComplete, RenameBlocked, + QuiescePending, BEBlocked }; @@ -130,17 +131,16 @@ class FrontEnd class ICacheCompletionEvent : public Event { private: + MemReqPtr req; FrontEnd *frontEnd; public: - ICacheCompletionEvent(FrontEnd *_fe); + ICacheCompletionEvent(MemReqPtr &_req, FrontEnd *_fe); virtual void process(); virtual const char *description(); }; - ICacheCompletionEvent cacheCompletionEvent; - MemInterface *icacheInterface; #if !FULL_SYSTEM @@ -174,6 +174,8 @@ class FrontEnd void setPC(Addr val) { PC = val; } void setNextPC(Addr val) { nextPC = val; } + void wakeFromQuiesce(); + void dumpInsts(); private: diff --git a/cpu/ozone/front_end_impl.hh b/cpu/ozone/front_end_impl.hh index af452fe95..7c18386cf 100644 --- a/cpu/ozone/front_end_impl.hh +++ b/cpu/ozone/front_end_impl.hh @@ -1,4 +1,5 @@ +#include "arch/faults.hh" #include "arch/isa_traits.hh" #include "base/statistics.hh" #include "cpu/exec_context.hh" @@ -12,7 +13,6 @@ using namespace TheISA; template FrontEnd::FrontEnd(Params *params) : branchPred(params), - cacheCompletionEvent(this), icacheInterface(params->icacheInterface), instBufferSize(0), maxInstBufferSize(params->maxInstBufferSize), @@ -26,10 +26,12 @@ FrontEnd::FrontEnd(Params *params) // Setup branch predictor. // Setup Memory Request +/* memReq = new MemReq(); memReq->asid = 0; memReq->data = new uint8_t[64]; - +*/ + memReq = NULL; // Size of cache block. cacheBlkSize = icacheInterface ? icacheInterface->getBlockSize() : 64; @@ -46,7 +48,7 @@ FrontEnd::FrontEnd(Params *params) cacheBlkValid = false; #if !FULL_SYSTEM - pTable = params->pTable; +// pTable = params->pTable; #endif fetchFault = NoFault; } @@ -72,7 +74,7 @@ void FrontEnd::setXC(ExecContext *xc_ptr) { xc = xc_ptr; - memReq->xc = xc; +// memReq->xc = xc; } template @@ -269,6 +271,9 @@ FrontEnd::tick() } updateStatus(); return; + } else if (status == QuiescePending) { + DPRINTF(FE, "Waiting for quiesce to execute or get squashed.\n"); + return; } else if (status != IcacheMissComplete) { if (fetchCacheLineNextCycle) { Fault fault = fetchCacheLine(); @@ -325,6 +330,14 @@ FrontEnd::tick() // rename(num_inst); // } +#if FULL_SYSTEM + if (inst->isQuiesce()) { + warn("%lli: Quiesce instruction encountered, halting fetch!", curTick); + status = QuiescePending; + break; + } +#endif + if (inst->predTaken()) { // Start over with tick? break; @@ -364,6 +377,12 @@ FrontEnd::fetchCacheLine() // Setup the memReq to do a read of the first isntruction's address. // Set the appropriate read size and flags as well. + memReq = new MemReq(); + + memReq->asid = 0; + memReq->thread_num = 0; + memReq->data = new uint8_t[64]; + memReq->xc = xc; memReq->cmd = Read; memReq->reset(fetch_PC, cacheBlkSize, flags); @@ -377,16 +396,26 @@ FrontEnd::fetchCacheLine() // Now do the timing access to see whether or not the instruction // exists within the cache. if (icacheInterface && fault == NoFault) { +#if FULL_SYSTEM + if (cpu->system->memctrl->badaddr(memReq->paddr)) { + DPRINTF(FE, "Fetch: Bad address %#x (hopefully on a " + "misspeculating path!", + memReq->paddr); + return TheISA::genMachineCheckFault(); + } +#endif + memReq->completionEvent = NULL; memReq->time = curTick; + fault = cpu->mem->read(memReq, cacheData); MemAccessResult res = icacheInterface->access(memReq); // If the cache missed then schedule an event to wake // up this stage once the cache miss completes. if (icacheInterface->doEvents() && res != MA_HIT) { - memReq->completionEvent = new ICacheCompletionEvent(this); + memReq->completionEvent = new ICacheCompletionEvent(memReq, this); status = IcacheMissStall; @@ -398,7 +427,7 @@ FrontEnd::fetchCacheLine() cacheBlkValid = true; - memcpy(cacheData, memReq->data, memReq->size); +// memcpy(cacheData, memReq->data, memReq->size); } } @@ -541,7 +570,8 @@ FrontEnd::squash(const InstSeqNum &squash_num, const Addr &next_PC, // Clear the icache miss if it's outstanding. if (status == IcacheMissStall && icacheInterface) { DPRINTF(FE, "Squashing outstanding Icache miss.\n"); - icacheInterface->squash(0); +// icacheInterface->squash(0); + memReq = NULL; } if (status == SerializeBlocked) { @@ -577,12 +607,13 @@ FrontEnd::getInst() template void -FrontEnd::processCacheCompletion() +FrontEnd::processCacheCompletion(MemReqPtr &req) { DPRINTF(FE, "Processing cache completion\n"); // Do something here. - if (status != IcacheMissStall) { + if (status != IcacheMissStall || + req != memReq) { DPRINTF(FE, "Previous fetch was squashed.\n"); return; } @@ -595,10 +626,11 @@ FrontEnd::processCacheCompletion() fetchStatus[tid] = IcacheMissComplete; } */ - memcpy(cacheData, memReq->data, memReq->size); +// memcpy(cacheData, memReq->data, memReq->size); // Reset the completion event to NULL. - memReq->completionEvent = NULL; +// memReq->completionEvent = NULL; + memReq = NULL; } template @@ -766,6 +798,15 @@ FrontEnd::renameInst(DynInstPtr &inst) } } +template +void +FrontEnd::wakeFromQuiesce() +{ + DPRINTF(FE, "Waking up from quiesce\n"); + // Hopefully this is safe + status = Running; +} + template void FrontEnd::dumpInsts() @@ -786,8 +827,8 @@ FrontEnd::dumpInsts() } template -FrontEnd::ICacheCompletionEvent::ICacheCompletionEvent(FrontEnd *fe) - : Event(&mainEventQueue, Delayed_Writeback_Pri), frontEnd(fe) +FrontEnd::ICacheCompletionEvent::ICacheCompletionEvent(MemReqPtr &_req, FrontEnd *fe) + : Event(&mainEventQueue, Delayed_Writeback_Pri), req(_req), frontEnd(fe) { this->setFlags(Event::AutoDelete); } @@ -796,7 +837,7 @@ template void FrontEnd::ICacheCompletionEvent::process() { - frontEnd->processCacheCompletion(); + frontEnd->processCacheCompletion(req); } template diff --git a/cpu/ozone/lw_back_end.hh b/cpu/ozone/lw_back_end.hh index b89957aad..f17c93ff4 100644 --- a/cpu/ozone/lw_back_end.hh +++ b/cpu/ozone/lw_back_end.hh @@ -94,8 +94,7 @@ class LWBackEnd void regStats(); - void setCPU(FullCPU *cpu_ptr) - { cpu = cpu_ptr; } + void setCPU(FullCPU *cpu_ptr); void setFrontEnd(FrontEnd *front_end_ptr) { frontEnd = front_end_ptr; } @@ -404,6 +403,9 @@ class LWBackEnd Stats::Scalar<> commit_eligible_samples; Stats::Vector<> commit_eligible; + Stats::Vector<> squashedInsts; + Stats::Vector<> ROBSquashedInsts; + Stats::Scalar<> ROB_fcount; Stats::Formula ROB_full_rate; diff --git a/cpu/ozone/lw_back_end_impl.hh b/cpu/ozone/lw_back_end_impl.hh index 115821787..d1290239c 100644 --- a/cpu/ozone/lw_back_end_impl.hh +++ b/cpu/ozone/lw_back_end_impl.hh @@ -480,6 +480,18 @@ LWBackEnd::regStats() .desc("number cycles where commit BW limit reached") ; + squashedInsts + .init(cpu->number_of_threads) + .name(name() + ".COM:squashed_insts") + .desc("Number of instructions removed from inst list") + ; + + ROBSquashedInsts + .init(cpu->number_of_threads) + .name(name() + ".COM:rob_squashed_insts") + .desc("Number of instructions removed from inst list when they reached the head of the ROB") + ; + ROB_fcount .name(name() + ".ROB:full_count") .desc("number of cycles where ROB was full") @@ -515,6 +527,14 @@ LWBackEnd::regStats() // IQ.regStats(); } +template +void +LWBackEnd::setCPU(FullCPU *cpu_ptr) +{ + cpu = cpu_ptr; + LSQ.setCPU(cpu_ptr); +} + template void LWBackEnd::setCommBuffer(TimeBuffer *_comm) @@ -1044,35 +1064,24 @@ LWBackEnd::commitInst(int inst_num) } } - // Now check if it's one of the special trap or barrier or - // serializing instructions. - if (inst->isThreadSync()) - { - // Not handled for now. - panic("Thread sync instructions are not handled yet.\n"); - } + // Not handled for now. + assert(!inst->isThreadSync()); // Check if the instruction caused a fault. If so, trap. Fault inst_fault = inst->getFault(); if (inst_fault != NoFault) { - if (!inst->isNop()) { - DPRINTF(BE, "Inst [sn:%lli] PC %#x has a fault\n", - inst->seqNum, inst->readPC()); - thread->setInst( - static_cast(inst->staticInst->machInst)); + DPRINTF(BE, "Inst [sn:%lli] PC %#x has a fault\n", + inst->seqNum, inst->readPC()); + thread->setInst( + static_cast(inst->staticInst->machInst)); #if FULL_SYSTEM - handleFault(inst_fault); - return false; + handleFault(inst_fault); + return false; #else // !FULL_SYSTEM - panic("fault (%d) detected @ PC %08p", inst_fault, - inst->PC); + panic("fault (%d) detected @ PC %08p", inst_fault, + inst->PC); #endif // FULL_SYSTEM - } - } - - if (inst->isControl()) { -// ++commitCommittedBranches; } int freed_regs = 0; @@ -1096,7 +1105,6 @@ LWBackEnd::commitInst(int inst_num) instList.pop_back(); --numInsts; - cpu->numInst++; thread->numInsts++; ++thread->funcExeInst; // Maybe move this to where teh fault is handled; if the fault is handled, @@ -1134,15 +1142,14 @@ template void LWBackEnd::commitInsts() { - int commit_width = commitWidth ? commitWidth : width; - // Not sure this should be a loop or not. int inst_num = 0; - while (!instList.empty() && inst_num < commit_width) { + while (!instList.empty() && inst_num < commitWidth) { if (instList.back()->isSquashed()) { instList.back()->clearDependents(); instList.pop_back(); --numInsts; + ROBSquashedInsts[instList.back()->threadNumber]++; continue; } @@ -1150,6 +1157,7 @@ LWBackEnd::commitInsts() DPRINTF(BE, "Can't commit, Instruction [sn:%lli] PC " "%#x is head of ROB and not ready\n", instList.back()->seqNum, instList.back()->readPC()); + --inst_num; break; } } @@ -1217,6 +1225,8 @@ LWBackEnd::squash(const InstSeqNum &sn) (*insts_it)->clearDependents(); + squashedInsts[(*insts_it)->threadNumber]++; + instList.erase(insts_it++); --numInsts; } @@ -1350,6 +1360,7 @@ LWBackEnd::updateComInstStats(DynInstPtr &inst) { unsigned thread = inst->threadNumber; + cpu->numInst++; // // Pick off the software prefetches // diff --git a/cpu/ozone/lw_lsq.hh b/cpu/ozone/lw_lsq.hh index 2b2c25b58..eb9886244 100644 --- a/cpu/ozone/lw_lsq.hh +++ b/cpu/ozone/lw_lsq.hh @@ -43,7 +43,7 @@ //#include "mem/page_table.hh" #include "sim/sim_object.hh" -class PageTable; +//class PageTable; /** * Class that implements the actual LQ and SQ for each specific thread. @@ -115,7 +115,7 @@ class OzoneLWLSQ { { be = be_ptr; } /** Sets the page table pointer. */ - void setPageTable(PageTable *pt_ptr); +// void setPageTable(PageTable *pt_ptr); /** Ticks the LSQ unit, which in this case only resets the number of * used cache ports. @@ -243,7 +243,7 @@ class OzoneLWLSQ { MemInterface *dcacheInterface; /** Pointer to the page table. */ - PageTable *pTable; +// PageTable *pTable; public: struct SQEntry { @@ -562,6 +562,19 @@ OzoneLWLSQ::read(MemReqPtr &req, T &data, int load_idx) // If there's no forwarding case, then go access memory + DPRINTF(OzoneLSQ, "Doing functional access for inst PC %#x\n", + inst->readPC()); + + + // Setup MemReq pointer + req->cmd = Read; + req->completionEvent = NULL; + req->time = curTick; + assert(!req->data); + req->data = new uint8_t[64]; + Fault fault = cpu->read(req, data); + memcpy(req->data, &data, sizeof(T)); + ++usedPorts; // if we have a cache, do cache access too @@ -582,12 +595,6 @@ OzoneLWLSQ::read(MemReqPtr &req, T &data, int load_idx) "vaddr:%#x flags:%i\n", inst->readPC(), req->paddr, req->vaddr, req->flags); - // Setup MemReq pointer - req->cmd = Read; - req->completionEvent = NULL; - req->time = curTick; - assert(!req->data); - req->data = new uint8_t[64]; assert(!req->completionEvent); req->completionEvent = diff --git a/cpu/ozone/lw_lsq_impl.hh b/cpu/ozone/lw_lsq_impl.hh index 54d7ead6c..7b22d2564 100644 --- a/cpu/ozone/lw_lsq_impl.hh +++ b/cpu/ozone/lw_lsq_impl.hh @@ -131,7 +131,7 @@ OzoneLWLSQ::clearSQ() { storeQueue.clear(); } - +/* template void OzoneLWLSQ::setPageTable(PageTable *pt_ptr) @@ -139,7 +139,7 @@ OzoneLWLSQ::setPageTable(PageTable *pt_ptr) DPRINTF(OzoneLSQ, "Setting the page table pointer.\n"); pTable = pt_ptr; } - +*/ template void OzoneLWLSQ::resizeLQ(unsigned size) @@ -519,6 +519,23 @@ OzoneLWLSQ::writebackStores() req->paddr, *(req->data), inst->seqNum); + switch((*sq_it).size) { + case 1: + cpu->write(req, (uint8_t &)(*sq_it).data); + break; + case 2: + cpu->write(req, (uint16_t &)(*sq_it).data); + break; + case 4: + cpu->write(req, (uint32_t &)(*sq_it).data); + break; + case 8: + cpu->write(req, (uint64_t &)(*sq_it).data); + break; + default: + panic("Unexpected store size!\n"); + } + if (dcacheInterface) { MemAccessResult result = dcacheInterface->access(req); @@ -538,7 +555,7 @@ OzoneLWLSQ::writebackStores() typename BackEnd::LdWritebackEvent *wb = NULL; if (req->flags & LOCKED) { // Stx_C does not generate a system port transaction. - req->result=1; +// req->result=1; wb = new typename BackEnd::LdWritebackEvent(inst, be); } @@ -571,12 +588,12 @@ OzoneLWLSQ::writebackStores() if (req->flags & LOCKED) { // Stx_C does not generate a system port transaction. - if (req->flags & UNCACHEABLE) { +/* if (req->flags & UNCACHEABLE) { req->result = 2; } else { req->result = 1; } - +*/ typename BackEnd::LdWritebackEvent *wb = new typename BackEnd::LdWritebackEvent(inst, be); @@ -642,6 +659,11 @@ OzoneLWLSQ::squash(const InstSeqNum &squashed_num) while (stores != 0 && (*sq_it).inst->seqNum > squashed_num) { assert(!storeQueue.empty()); + + if ((*sq_it).canWB) { + break; + } + // Clear the smart pointer to make sure it is decremented. DPRINTF(OzoneLSQ,"Store Instruction PC %#x idx:%i squashed [sn:%lli]\n", (*sq_it).inst->readPC(), (*sq_it).inst->sqIdx, -- cgit v1.2.3