diff options
Diffstat (limited to 'src/cpu/o3/lsq_unit_impl.hh')
-rw-r--r-- | src/cpu/o3/lsq_unit_impl.hh | 158 |
1 files changed, 98 insertions, 60 deletions
diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index 2679eb52b..6f32ec304 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -24,6 +24,9 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Kevin Lim + * Korey Sewell */ #include "cpu/checker/cpu.hh" @@ -63,7 +66,7 @@ LSQUnit<Impl>::completeDataAccess(PacketPtr pkt) LSQSenderState *state = dynamic_cast<LSQSenderState *>(pkt->senderState); DynInstPtr inst = state->inst; DPRINTF(IEW, "Writeback event [sn:%lli]\n", inst->seqNum); -// DPRINTF(Activity, "Activity: Ld Writeback event [sn:%lli]\n", inst->seqNum); + DPRINTF(Activity, "Activity: Writeback event [sn:%lli]\n", inst->seqNum); //iewStage->ldstQueue.removeMSHR(inst->threadNumber,inst->seqNum); @@ -122,18 +125,7 @@ template <class Impl> void LSQUnit<Impl>::DcachePort::recvRetry() { - panic("Retry unsupported for now!"); - // we shouldn't get a retry unless we have a packet that we're - // waiting to transmit -/* - assert(cpu->dcache_pkt != NULL); - assert(cpu->_status == DcacheRetry); - PacketPtr tmp = cpu->dcache_pkt; - if (sendTiming(tmp)) { - cpu->_status = DcacheWaitResponse; - cpu->dcache_pkt = NULL; - } -*/ + lsq->recvRetry(); } template <class Impl> @@ -217,16 +209,6 @@ LSQUnit<Impl>::clearSQ() storeQueue.clear(); } -#if 0 -template<class Impl> -void -LSQUnit<Impl>::setPageTable(PageTable *pt_ptr) -{ - DPRINTF(LSQUnit, "Setting the page table pointer.\n"); - pTable = pt_ptr; -} -#endif - template<class Impl> void LSQUnit<Impl>::switchOut() @@ -612,47 +594,34 @@ LSQUnit<Impl>::writebackStores() req->getPaddr(), *(inst->memData), storeQueue[storeWBIdx].inst->seqNum); + // @todo: Remove this SC hack once the memory system handles it. + if (req->getFlags() & LOCKED) { + if (req->getFlags() & UNCACHEABLE) { + req->setScResult(2); + } else { + if (cpu->lockFlag) { + req->setScResult(1); + } else { + req->setScResult(0); + // Hack: Instantly complete this store. + completeDataAccess(data_pkt); + incrStIdx(storeWBIdx); + continue; + } + } + } else { + // Non-store conditionals do not need a writeback. + state->noWB = true; + } + if (!dcachePort->sendTiming(data_pkt)) { // Need to handle becoming blocked on a store. isStoreBlocked = true; - } else { - if (isStalled() && - storeQueue[storeWBIdx].inst->seqNum == stallingStoreIsn) { - DPRINTF(LSQUnit, "Unstalling, stalling store [sn:%lli] " - "load idx:%i\n", - stallingStoreIsn, stallingLoadIdx); - stalled = false; - stallingStoreIsn = 0; - iewStage->replayMemInst(loadQueue[stallingLoadIdx]); - } - - if (!(req->getFlags() & LOCKED)) { - assert(!storeQueue[storeWBIdx].inst->isStoreConditional()); - // Non-store conditionals do not need a writeback. - state->noWB = true; - } - - if (data_pkt->result != Packet::Success) { - DPRINTF(LSQUnit,"D-Cache Write Miss on idx:%i!\n", - storeWBIdx); - - DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n", - storeQueue[storeWBIdx].inst->seqNum); - - //mshrSeqNums.push_back(storeQueue[storeWBIdx].inst->seqNum); - - //DPRINTF(LSQUnit, "Added MSHR. count = %i\n",mshrSeqNums.size()); - - // @todo: Increment stat here. - } else { - DPRINTF(LSQUnit,"D-Cache: Write Hit on idx:%i !\n", - storeWBIdx); - - DPRINTF(Activity, "Active st accessing mem hit [sn:%lli]\n", - storeQueue[storeWBIdx].inst->seqNum); - } - incrStIdx(storeWBIdx); + assert(retryPkt == NULL); + retryPkt = data_pkt; + } else { + storePostSend(data_pkt); } } @@ -758,6 +727,53 @@ LSQUnit<Impl>::squash(const InstSeqNum &squashed_num) template <class Impl> void +LSQUnit<Impl>::storePostSend(Packet *pkt) +{ + if (isStalled() && + storeQueue[storeWBIdx].inst->seqNum == stallingStoreIsn) { + DPRINTF(LSQUnit, "Unstalling, stalling store [sn:%lli] " + "load idx:%i\n", + stallingStoreIsn, stallingLoadIdx); + stalled = false; + stallingStoreIsn = 0; + iewStage->replayMemInst(loadQueue[stallingLoadIdx]); + } + + if (!storeQueue[storeWBIdx].inst->isStoreConditional()) { + // The store is basically completed at this time. This + // only works so long as the checker doesn't try to + // verify the value in memory for stores. + storeQueue[storeWBIdx].inst->setCompleted(); + if (cpu->checker) { + cpu->checker->tick(storeQueue[storeWBIdx].inst); + } + } + + if (pkt->result != Packet::Success) { + DPRINTF(LSQUnit,"D-Cache Write Miss on idx:%i!\n", + storeWBIdx); + + DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n", + storeQueue[storeWBIdx].inst->seqNum); + + //mshrSeqNums.push_back(storeQueue[storeWBIdx].inst->seqNum); + + //DPRINTF(LSQUnit, "Added MSHR. count = %i\n",mshrSeqNums.size()); + + // @todo: Increment stat here. + } else { + DPRINTF(LSQUnit,"D-Cache: Write Hit on idx:%i !\n", + storeWBIdx); + + DPRINTF(Activity, "Active st accessing mem hit [sn:%lli]\n", + storeQueue[storeWBIdx].inst->seqNum); + } + + incrStIdx(storeWBIdx); +} + +template <class Impl> +void LSQUnit<Impl>::writeback(DynInstPtr &inst, PacketPtr pkt) { iewStage->wakeCPU(); @@ -829,6 +845,28 @@ LSQUnit<Impl>::completeStore(int store_idx) } template <class Impl> +void +LSQUnit<Impl>::recvRetry() +{ + if (isStoreBlocked) { + assert(retryPkt != NULL); + + if (dcachePort->sendTiming(retryPkt)) { + storePostSend(retryPkt); + retryPkt = NULL; + isStoreBlocked = false; + } else { + // Still blocked! + } + } else if (isLoadBlocked) { + DPRINTF(LSQUnit, "Loads squash themselves and all younger insts, " + "no need to resend packet.\n"); + } else { + DPRINTF(LSQUnit, "Retry received but LSQ is no longer blocked.\n"); + } +} + +template <class Impl> inline void LSQUnit<Impl>::incrStIdx(int &store_idx) { |