Updates to Ozone CPU.
cpu/ozone/cpu_impl.hh: Be sure to update rename tables. cpu/ozone/front_end_impl.hh: Handle serialize instructions slightly differently. This allows front end to continue even if back end hasn't processed it yet. cpu/ozone/lw_back_end_impl.hh: Handle stores with faults properly. cpu/ozone/lw_lsq.hh: Handle committed stores properly. cpu/ozone/lw_lsq_impl.hh: Handle uncacheable loads properly. --HG-- extra : convert_revision : 093edc2eee890139a9962c97c938575e6d313f09
This commit is contained in:
parent
51f19f2e28
commit
30b719fd76
5 changed files with 40 additions and 16 deletions
|
@ -267,6 +267,8 @@ OzoneCPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
|
|||
|
||||
backEnd->takeOverFrom();
|
||||
frontEnd->takeOverFrom();
|
||||
frontEnd->renameTable.copyFrom(thread.renameTable);
|
||||
backEnd->renameTable.copyFrom(thread.renameTable);
|
||||
assert(!tickEvent.scheduled());
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
|
|
@ -288,8 +288,8 @@ FrontEnd<Impl>::tick()
|
|||
cacheBlkValid = true;
|
||||
|
||||
status = Running;
|
||||
if (barrierInst)
|
||||
status = SerializeBlocked;
|
||||
// if (barrierInst)
|
||||
// status = SerializeBlocked;
|
||||
if (freeRegs <= 0)
|
||||
status = RenameBlocked;
|
||||
checkBE();
|
||||
|
@ -537,10 +537,10 @@ FrontEnd<Impl>::processBarriers(DynInstPtr &inst)
|
|||
|
||||
// Change status over to SerializeBlocked so that other stages know
|
||||
// what this is blocked on.
|
||||
status = SerializeBlocked;
|
||||
// status = SerializeBlocked;
|
||||
|
||||
barrierInst = inst;
|
||||
return true;
|
||||
// barrierInst = inst;
|
||||
// return true;
|
||||
} else if ((inst->isStoreConditional() || inst->isSerializeAfter())
|
||||
&& !inst->isSerializeHandled()) {
|
||||
DPRINTF(FE, "Serialize after instruction encountered.\n");
|
||||
|
@ -647,12 +647,12 @@ FrontEnd<Impl>::squash(const InstSeqNum &squash_num, const Addr &next_PC,
|
|||
DPRINTF(FE, "Squashing outstanding Icache miss.\n");
|
||||
memReq = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
if (status == SerializeBlocked) {
|
||||
assert(barrierInst->seqNum > squash_num);
|
||||
barrierInst = NULL;
|
||||
}
|
||||
|
||||
*/
|
||||
// Unless this squash originated from the front end, we're probably
|
||||
// in running mode now.
|
||||
// Actually might want to make this latency dependent.
|
||||
|
@ -670,6 +670,15 @@ FrontEnd<Impl>::getInst()
|
|||
|
||||
DynInstPtr inst = feBuffer.front();
|
||||
|
||||
if (inst->isSerializeBefore() || inst->isIprAccess()) {
|
||||
DPRINTF(FE, "Back end is getting a serialize before inst\n");
|
||||
if (!backEnd->robEmpty()) {
|
||||
DPRINTF(FE, "Rob is not empty yet, not returning inst\n");
|
||||
return NULL;
|
||||
}
|
||||
inst->clearSerializeBefore();
|
||||
}
|
||||
|
||||
feBuffer.pop_front();
|
||||
|
||||
--instBufferSize;
|
||||
|
@ -740,11 +749,11 @@ FrontEnd<Impl>::updateStatus()
|
|||
}
|
||||
|
||||
if (status == BEBlocked && !be_block) {
|
||||
if (barrierInst) {
|
||||
status = SerializeBlocked;
|
||||
} else {
|
||||
// if (barrierInst) {
|
||||
// status = SerializeBlocked;
|
||||
// } else {
|
||||
status = Running;
|
||||
}
|
||||
// }
|
||||
ret_val = true;
|
||||
}
|
||||
return ret_val;
|
||||
|
@ -766,6 +775,7 @@ template <class Impl>
|
|||
typename Impl::DynInstPtr
|
||||
FrontEnd<Impl>::getInstFromCacheline()
|
||||
{
|
||||
/*
|
||||
if (status == SerializeComplete) {
|
||||
DynInstPtr inst = barrierInst;
|
||||
status = Running;
|
||||
|
@ -773,7 +783,7 @@ FrontEnd<Impl>::getInstFromCacheline()
|
|||
inst->clearSerializeBefore();
|
||||
return inst;
|
||||
}
|
||||
|
||||
*/
|
||||
InstSeqNum inst_seq;
|
||||
MachInst inst;
|
||||
// @todo: Fix this magic number used here to handle word offset (and
|
||||
|
|
|
@ -952,8 +952,17 @@ LWBackEnd<Impl>::executeInsts()
|
|||
if (inst->isLoad()) {
|
||||
LSQ.executeLoad(inst);
|
||||
} else if (inst->isStore()) {
|
||||
LSQ.executeStore(inst);
|
||||
if (inst->req && !(inst->req->flags & LOCKED)) {
|
||||
Fault fault = LSQ.executeStore(inst);
|
||||
|
||||
if (!inst->isStoreConditional() && fault == NoFault) {
|
||||
inst->setExecuted();
|
||||
|
||||
instToCommit(inst);
|
||||
} else if (fault != NoFault) {
|
||||
// If the instruction faulted, then we need to send it along to commit
|
||||
// without the instruction completing.
|
||||
// Send this instruction to commit, also make sure iew stage
|
||||
// realizes there is activity.
|
||||
inst->setExecuted();
|
||||
|
||||
instToCommit(inst);
|
||||
|
@ -1114,7 +1123,7 @@ LWBackEnd<Impl>::commitInst(int inst_num)
|
|||
// or store inst. Signal backwards that it should be executed.
|
||||
if (!inst->isExecuted()) {
|
||||
if (inst->isNonSpeculative() ||
|
||||
inst->isStoreConditional() ||
|
||||
(inst->isStoreConditional() && inst->getFault() == NoFault) ||
|
||||
inst->isMemBarrier() ||
|
||||
inst->isWriteBarrier()) {
|
||||
#if !FULL_SYSTEM
|
||||
|
|
|
@ -486,7 +486,7 @@ OzoneLWLSQ<Impl>::read(MemReqPtr &req, T &data, int load_idx)
|
|||
|
||||
store_size = (*sq_it).size;
|
||||
|
||||
if (store_size == 0) {
|
||||
if (store_size == 0 || (*sq_it).committed) {
|
||||
sq_it++;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -335,6 +335,9 @@ OzoneLWLSQ<Impl>::executeLoad(DynInstPtr &inst)
|
|||
// Actually probably want the oldest faulting load
|
||||
if (load_fault != NoFault) {
|
||||
DPRINTF(OzoneLSQ, "Load [sn:%lli] has a fault\n", inst->seqNum);
|
||||
if (!(inst->req->flags & UNCACHEABLE && !inst->isAtCommit())) {
|
||||
inst->setExecuted();
|
||||
}
|
||||
// Maybe just set it as can commit here, although that might cause
|
||||
// some other problems with sending traps to the ROB too quickly.
|
||||
be->instToCommit(inst);
|
||||
|
|
Loading…
Reference in a new issue