Updates to Ozone model for quiesce, store conditionals.

--HG--
extra : convert_revision : 72ddd75ad0b5783aca9484e7d178c2915ee8e355
This commit is contained in:
Kevin Lim 2006-04-24 17:10:06 -04:00
parent 676afbe2c7
commit e704960c80
9 changed files with 272 additions and 116 deletions

View file

@ -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 <class T>
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 <class T>
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 <class T>
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 <class T>
Fault write(MemReqPtr &req, T &data, int store_idx)
@ -507,6 +611,8 @@ class OzoneCPU : public BaseCPU
bool stall;
};
TimeBuffer<CommStruct> comm;
bool lockFlag;
};
#endif // __CPU_OZONE_CPU_HH__

View file

@ -149,12 +149,14 @@ OzoneCPU<Impl>::DCacheCompletionEvent::description()
template <class Impl>
OzoneCPU<Impl>::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<Impl>::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<Impl>::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<Impl>::activateContext(int thread_num, int delay)
scheduleTickEvent(delay);
_status = Running;
thread._status = ExecContext::Active;
frontEnd->wakeFromQuiesce();
}
template <class Impl>
@ -401,8 +362,8 @@ OzoneCPU<Impl>::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<Impl>::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<Impl>::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<Impl>::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();

View file

@ -237,6 +237,7 @@ OzoneDynInst<Impl>::hwrei()
this->cpu->kernelStats->hwrei();
this->cpu->checkInterrupts = true;
this->cpu->lockFlag = false;
// FIXME: XXX check for interrupts? XXX
return NoFault;

View file

@ -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:

View file

@ -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 <class Impl>
FrontEnd<Impl>::FrontEnd(Params *params)
: branchPred(params),
cacheCompletionEvent(this),
icacheInterface(params->icacheInterface),
instBufferSize(0),
maxInstBufferSize(params->maxInstBufferSize),
@ -26,10 +26,12 @@ FrontEnd<Impl>::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<Impl>::FrontEnd(Params *params)
cacheBlkValid = false;
#if !FULL_SYSTEM
pTable = params->pTable;
// pTable = params->pTable;
#endif
fetchFault = NoFault;
}
@ -72,7 +74,7 @@ void
FrontEnd<Impl>::setXC(ExecContext *xc_ptr)
{
xc = xc_ptr;
memReq->xc = xc;
// memReq->xc = xc;
}
template <class Impl>
@ -269,6 +271,9 @@ FrontEnd<Impl>::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<Impl>::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<Impl>::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<Impl>::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<Impl>::fetchCacheLine()
cacheBlkValid = true;
memcpy(cacheData, memReq->data, memReq->size);
// memcpy(cacheData, memReq->data, memReq->size);
}
}
@ -541,7 +570,8 @@ FrontEnd<Impl>::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<Impl>::getInst()
template <class Impl>
void
FrontEnd<Impl>::processCacheCompletion()
FrontEnd<Impl>::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<Impl>::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 <class Impl>
@ -766,6 +798,15 @@ FrontEnd<Impl>::renameInst(DynInstPtr &inst)
}
}
template <class Impl>
void
FrontEnd<Impl>::wakeFromQuiesce()
{
DPRINTF(FE, "Waking up from quiesce\n");
// Hopefully this is safe
status = Running;
}
template <class Impl>
void
FrontEnd<Impl>::dumpInsts()
@ -786,8 +827,8 @@ FrontEnd<Impl>::dumpInsts()
}
template <class Impl>
FrontEnd<Impl>::ICacheCompletionEvent::ICacheCompletionEvent(FrontEnd *fe)
: Event(&mainEventQueue, Delayed_Writeback_Pri), frontEnd(fe)
FrontEnd<Impl>::ICacheCompletionEvent::ICacheCompletionEvent(MemReqPtr &_req, FrontEnd *fe)
: Event(&mainEventQueue, Delayed_Writeback_Pri), req(_req), frontEnd(fe)
{
this->setFlags(Event::AutoDelete);
}
@ -796,7 +837,7 @@ template <class Impl>
void
FrontEnd<Impl>::ICacheCompletionEvent::process()
{
frontEnd->processCacheCompletion();
frontEnd->processCacheCompletion(req);
}
template <class Impl>

View file

@ -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;

View file

@ -480,6 +480,18 @@ LWBackEnd<Impl>::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<Impl>::regStats()
// IQ.regStats();
}
template <class Impl>
void
LWBackEnd<Impl>::setCPU(FullCPU *cpu_ptr)
{
cpu = cpu_ptr;
LSQ.setCPU(cpu_ptr);
}
template <class Impl>
void
LWBackEnd<Impl>::setCommBuffer(TimeBuffer<CommStruct> *_comm)
@ -1044,35 +1064,24 @@ LWBackEnd<Impl>::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<TheISA::MachInst>(inst->staticInst->machInst));
DPRINTF(BE, "Inst [sn:%lli] PC %#x has a fault\n",
inst->seqNum, inst->readPC());
thread->setInst(
static_cast<TheISA::MachInst>(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<Impl>::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 <class Impl>
void
LWBackEnd<Impl>::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<Impl>::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<Impl>::squash(const InstSeqNum &sn)
(*insts_it)->clearDependents();
squashedInsts[(*insts_it)->threadNumber]++;
instList.erase(insts_it++);
--numInsts;
}
@ -1350,6 +1360,7 @@ LWBackEnd<Impl>::updateComInstStats(DynInstPtr &inst)
{
unsigned thread = inst->threadNumber;
cpu->numInst++;
//
// Pick off the software prefetches
//

View file

@ -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<Impl>::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<Impl>::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 =

View file

@ -131,7 +131,7 @@ OzoneLWLSQ<Impl>::clearSQ()
{
storeQueue.clear();
}
/*
template<class Impl>
void
OzoneLWLSQ<Impl>::setPageTable(PageTable *pt_ptr)
@ -139,7 +139,7 @@ OzoneLWLSQ<Impl>::setPageTable(PageTable *pt_ptr)
DPRINTF(OzoneLSQ, "Setting the page table pointer.\n");
pTable = pt_ptr;
}
*/
template<class Impl>
void
OzoneLWLSQ<Impl>::resizeLQ(unsigned size)
@ -519,6 +519,23 @@ OzoneLWLSQ<Impl>::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<Impl>::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<Impl>::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<Impl>::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,