From 068379a9ed22bc00b9544e33b382da8d9aebc13a Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Fri, 9 Jun 2006 11:46:35 -0400 Subject: Fixes for some outstanding issues in the LSQ. It should now be able to retry. It should also be able to handle LL/SC (through hacks) for the UP case. src/cpu/o3/lsq_unit.hh: Handle being able to retry (untested but hopefully very close to working). Handle lock flag for LL/SC hack. Hopefully the memory system will add in LL/SC soon. Better output message. src/cpu/o3/lsq_unit_impl.hh: Handle being able to retry (untested but should be very close to working). Make SC's work (hopefully) while the memory system doesn't have a LL/SC implementation. --HG-- extra : convert_revision : bffa721b21405c88a9c6b3d9b9080957f8a2638f --- src/cpu/o3/lsq_unit_impl.hh | 151 +++++++++++++++++++++++++++----------------- 1 file changed, 94 insertions(+), 57 deletions(-) (limited to 'src/cpu/o3/lsq_unit_impl.hh') diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index 62bb96610..a768b021c 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -125,18 +125,7 @@ template void LSQUnit::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 @@ -615,55 +604,34 @@ LSQUnit::writebackStores() req->getPaddr(), *(inst->memData), storeQueue[storeWBIdx].inst->seqNum); - 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; - - // 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); + // @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 (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); - } + if (!dcachePort->sendTiming(data_pkt)) { + // Need to handle becoming blocked on a store. + isStoreBlocked = true; - incrStIdx(storeWBIdx); + assert(sendingPkt == NULL); + sendingPkt = data_pkt; + } else { + storePostSend(data_pkt); } } @@ -767,6 +735,53 @@ LSQUnit::squash(const InstSeqNum &squashed_num) } } +template +void +LSQUnit::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 void LSQUnit::writeback(DynInstPtr &inst, PacketPtr pkt) @@ -839,6 +854,28 @@ LSQUnit::completeStore(int store_idx) } } +template +void +LSQUnit::recvRetry() +{ + assert(sendingPkt != NULL); + + if (isStoreBlocked) { + if (dcachePort->sendTiming(sendingPkt)) { + storePostSend(sendingPkt); + sendingPkt = 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 inline void LSQUnit::incrStIdx(int &store_idx) -- cgit v1.2.3