diff options
Diffstat (limited to 'src/mem/cache')
-rw-r--r-- | src/mem/cache/base_cache.cc | 31 | ||||
-rw-r--r-- | src/mem/cache/cache_impl.hh | 159 | ||||
-rw-r--r-- | src/mem/cache/coherence/coherence_protocol.cc | 257 | ||||
-rw-r--r-- | src/mem/cache/coherence/coherence_protocol.hh | 20 | ||||
-rw-r--r-- | src/mem/cache/miss/blocking_buffer.hh | 18 | ||||
-rw-r--r-- | src/mem/cache/miss/miss_queue.hh | 22 | ||||
-rw-r--r-- | src/mem/cache/miss/mshr.hh | 20 | ||||
-rw-r--r-- | src/mem/cache/miss/mshr_queue.hh | 26 | ||||
-rw-r--r-- | src/mem/cache/tags/split.hh | 8 | ||||
-rw-r--r-- | src/mem/cache/tags/split_blk.hh | 2 |
10 files changed, 196 insertions, 367 deletions
diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index 6cbeef5a4..599958222 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -79,9 +79,7 @@ BaseCache::CachePort::recvTiming(PacketPtr pkt) && !pkt->isRead() && !pkt->isWrite()) { //Upgrade or Invalidate //Look into what happens if two slave caches on bus - DPRINTF(Cache, "%s %x ? blk_addr: %x\n", pkt->cmdString(), - pkt->getAddr() & (((ULL(1))<<48)-1), - pkt->getAddr() & ~((Addr)cache->blkSize - 1)); + DPRINTF(Cache, "%s %x ?\n", pkt->cmdString(), pkt->getAddr()); assert(!(pkt->flags & SATISFIED)); pkt->flags |= SATISFIED; @@ -115,32 +113,7 @@ BaseCache::CachePort::recvFunctional(PacketPtr pkt) // If the target contains data, and it overlaps the // probed request, need to update data if (target->intersect(pkt)) { - uint8_t* pkt_data; - uint8_t* write_data; - int data_size; - if (target->getAddr() < pkt->getAddr()) { - int offset = pkt->getAddr() - target->getAddr(); - pkt_data = pkt->getPtr<uint8_t>(); - write_data = target->getPtr<uint8_t>() + offset; - data_size = target->getSize() - offset; - assert(data_size > 0); - if (data_size > pkt->getSize()) - data_size = pkt->getSize(); - } else { - int offset = target->getAddr() - pkt->getAddr(); - pkt_data = pkt->getPtr<uint8_t>() + offset; - write_data = target->getPtr<uint8_t>(); - data_size = pkt->getSize() - offset; - assert(data_size >= pkt->getSize()); - if (data_size > target->getSize()) - data_size = target->getSize(); - } - - if (pkt->isWrite()) { - memcpy(pkt_data, write_data, data_size); - } else { - memcpy(write_data, pkt_data, data_size); - } + fixPacket(pkt, target); } } cache->doFunctionalAccess(pkt, isCpuSide); diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index dcb0e7b78..9bb72e85c 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -205,9 +205,10 @@ Cache<TagStore,Buffering,Coherence>::access(PacketPtr &pkt) missQueue->doWriteback(writebacks.front()); writebacks.pop_front(); } - DPRINTF(Cache, "%s %x %s blk_addr: %x\n", pkt->cmdString(), - pkt->getAddr() & (((ULL(1))<<48)-1), (blk) ? "hit" : "miss", - pkt->getAddr() & ~((Addr)blkSize - 1)); + + DPRINTF(Cache, "%s %x %s\n", pkt->cmdString(), pkt->getAddr(), + (blk) ? "hit" : "miss"); + if (blk) { // Hit hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++; @@ -231,8 +232,16 @@ Cache<TagStore,Buffering,Coherence>::access(PacketPtr &pkt) exitSimLoop("A cache reached the maximum miss count"); } } - missQueue->handleMiss(pkt, size, curTick + hitLatency); -// return MA_CACHE_MISS; + + if (pkt->flags & SATISFIED) { + // happens when a store conditional fails because it missed + // the cache completely + if (pkt->needsResponse()) + respond(pkt, curTick+lat); + } else { + missQueue->handleMiss(pkt, size, curTick + hitLatency); + } + return true; } @@ -280,10 +289,8 @@ Cache<TagStore,Buffering,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr, CacheBlk::State old_state = (blk) ? blk->status : 0; CacheBlk::State new_state = coherence->getNewState(pkt,old_state); if (old_state != new_state) - DPRINTF(Cache, "Block for blk addr %x moving from " - "state %i to %i\n", - pkt->getAddr() & (((ULL(1))<<48)-1), - old_state, new_state); + DPRINTF(Cache, "Block for blk addr %x moving from state " + "%i to %i\n", pkt->getAddr(), old_state, new_state); //Set the state on the upgrade memcpy(pkt->getPtr<uint8_t>(), blk->data, blkSize); PacketList writebacks; @@ -323,8 +330,7 @@ Cache<TagStore,Buffering,Coherence>::handleResponse(PacketPtr &pkt) //Make the response a Bad address and send it } // MemDebug::cacheResponse(pkt); - DPRINTF(Cache, "Handling reponse to %x, blk addr: %x\n",pkt->getAddr(), - pkt->getAddr() & (((ULL(1))<<48)-1)); + DPRINTF(Cache, "Handling reponse to %x\n", pkt->getAddr()); if (pkt->isCacheFill() && !pkt->isNoAllocate()) { blk = tags->findBlock(pkt); @@ -334,7 +340,7 @@ Cache<TagStore,Buffering,Coherence>::handleResponse(PacketPtr &pkt) if (old_state != new_state) DPRINTF(Cache, "Block for blk addr %x moving from " "state %i to %i\n", - pkt->getAddr() & (((ULL(1))<<48)-1), + pkt->getAddr(), old_state, new_state); blk = tags->handleFill(blk, (MSHR*)pkt->senderState, new_state, writebacks, pkt); @@ -419,8 +425,8 @@ Cache<TagStore,Buffering,Coherence>::snoop(PacketPtr &pkt) //Append the invalidate on missQueue->addTarget(mshr,invalidatePkt); - DPRINTF(Cache, "Appending Invalidate to blk_addr: %x\n", - pkt->getAddr() & (((ULL(1))<<48)-1)); + DPRINTF(Cache, "Appending Invalidate to addr: %x\n", + pkt->getAddr()); return; } } @@ -428,8 +434,8 @@ Cache<TagStore,Buffering,Coherence>::snoop(PacketPtr &pkt) //We also need to check the writeback buffers and handle those std::vector<MSHR *> writebacks; if (missQueue->findWrites(blk_addr, writebacks)) { - DPRINTF(Cache, "Snoop hit in writeback to blk_addr: %x\n", - pkt->getAddr() & (((ULL(1))<<48)-1)); + DPRINTF(Cache, "Snoop hit in writeback to addr: %x\n", + pkt->getAddr()); //Look through writebacks for any non-uncachable writes, use that for (int i=0; i<writebacks.size(); i++) { @@ -520,12 +526,9 @@ Cache<TagStore,Buffering,Coherence>::probe(PacketPtr &pkt, bool update, { // MemDebug::cacheProbe(pkt); if (!pkt->req->isUncacheable()) { - if (pkt->isInvalidate() && !pkt->isRead() - && !pkt->isWrite()) { + if (pkt->isInvalidate() && !pkt->isRead() && !pkt->isWrite()) { //Upgrade or Invalidate, satisfy it, don't forward - DPRINTF(Cache, "%s %x ? blk_addr: %x\n", pkt->cmdString(), - pkt->getAddr() & (((ULL(1))<<48)-1), - pkt->getAddr() & ~((Addr)blkSize - 1)); + DPRINTF(Cache, "%s %x ?\n", pkt->cmdString(), pkt->getAddr()); pkt->flags |= SATISFIED; return 0; } @@ -542,9 +545,8 @@ Cache<TagStore,Buffering,Coherence>::probe(PacketPtr &pkt, bool update, int lat; BlkType *blk = tags->handleAccess(pkt, lat, writebacks, update); - DPRINTF(Cache, "%s %x %s blk_addr: %x\n", pkt->cmdString(), - pkt->getAddr() & (((ULL(1))<<48)-1), (blk) ? "hit" : "miss", - pkt->getAddr() & ~((Addr)blkSize - 1)); + DPRINTF(Cache, "%s %x %s\n", pkt->cmdString(), + pkt->getAddr(), (blk) ? "hit" : "miss"); // Need to check for outstanding misses and writes @@ -560,7 +562,6 @@ Cache<TagStore,Buffering,Coherence>::probe(PacketPtr &pkt, bool update, if (!update) { // Check for data in MSHR and writebuffer. if (mshr) { - warn("Found outstanding miss on an non-update probe"); MSHR::TargetList *targets = mshr->getTargetList(); MSHR::TargetList::iterator i = targets->begin(); MSHR::TargetList::iterator end = targets->end(); @@ -568,71 +569,15 @@ Cache<TagStore,Buffering,Coherence>::probe(PacketPtr &pkt, bool update, PacketPtr target = *i; // If the target contains data, and it overlaps the // probed request, need to update data - if (target->isWrite() && target->intersect(pkt)) { - uint8_t* pkt_data; - uint8_t* write_data; - int data_size; - if (target->getAddr() < pkt->getAddr()) { - int offset = pkt->getAddr() - target->getAddr(); - pkt_data = pkt->getPtr<uint8_t>(); - write_data = target->getPtr<uint8_t>() + offset; - data_size = target->getSize() - offset; - assert(data_size > 0); - if (data_size > pkt->getSize()) - data_size = pkt->getSize(); - } else { - int offset = target->getAddr() - pkt->getAddr(); - pkt_data = pkt->getPtr<uint8_t>() + offset; - write_data = target->getPtr<uint8_t>(); - data_size = pkt->getSize() - offset; - assert(data_size >= pkt->getSize()); - if (data_size > target->getSize()) - data_size = target->getSize(); - } - - if (pkt->isWrite()) { - memcpy(pkt_data, write_data, data_size); - } else { - pkt->flags |= SATISFIED; - pkt->result = Packet::Success; - memcpy(write_data, pkt_data, data_size); - } + if (target->intersect(pkt)) { + fixPacket(pkt, target); } } } for (int i = 0; i < writes.size(); ++i) { PacketPtr write = writes[i]->pkt; if (write->intersect(pkt)) { - warn("Found outstanding write on an non-update probe"); - uint8_t* pkt_data; - uint8_t* write_data; - int data_size; - if (write->getAddr() < pkt->getAddr()) { - int offset = pkt->getAddr() - write->getAddr(); - pkt_data = pkt->getPtr<uint8_t>(); - write_data = write->getPtr<uint8_t>() + offset; - data_size = write->getSize() - offset; - assert(data_size > 0); - if (data_size > pkt->getSize()) - data_size = pkt->getSize(); - } else { - int offset = write->getAddr() - pkt->getAddr(); - pkt_data = pkt->getPtr<uint8_t>() + offset; - write_data = write->getPtr<uint8_t>(); - data_size = pkt->getSize() - offset; - assert(data_size >= pkt->getSize()); - if (data_size > write->getSize()) - data_size = write->getSize(); - } - - if (pkt->isWrite()) { - memcpy(pkt_data, write_data, data_size); - } else { - pkt->flags |= SATISFIED; - pkt->result = Packet::Success; - memcpy(write_data, pkt_data, data_size); - } - + fixPacket(pkt, write); } } if (pkt->isRead() @@ -642,10 +587,10 @@ Cache<TagStore,Buffering,Coherence>::probe(PacketPtr &pkt, bool update, assert(pkt->result == Packet::Success); } return 0; - } else if (!blk) { + } else if (!blk && !(pkt->flags & SATISFIED)) { // update the cache state and statistics if (mshr || !writes.empty()){ - // Can't handle it, return pktuest unsatisfied. + // Can't handle it, return request unsatisfied. panic("Atomic access ran into outstanding MSHR's or WB's!"); } if (!pkt->req->isUncacheable()) { @@ -660,10 +605,8 @@ Cache<TagStore,Buffering,Coherence>::probe(PacketPtr &pkt, bool update, busPkt->time = curTick; - DPRINTF(Cache, "Sending a atomic %s for %x blk_addr: %x\n", - busPkt->cmdString(), - busPkt->getAddr() & (((ULL(1))<<48)-1), - busPkt->getAddr() & ~((Addr)blkSize - 1)); + DPRINTF(Cache, "Sending a atomic %s for %x\n", + busPkt->cmdString(), busPkt->getAddr()); lat = memSidePort->sendAtomic(busPkt); @@ -682,19 +625,13 @@ return 0; CacheBlk::State old_state = (blk) ? blk->status : 0; CacheBlk::State new_state = coherence->getNewState(busPkt, old_state); - DPRINTF(Cache, - "Receive response:%s for blk addr %x in state %i\n", - busPkt->cmdString(), - busPkt->getAddr() & (((ULL(1))<<48)-1), old_state); + DPRINTF(Cache, "Receive response: %s for addr %x in state %i\n", + busPkt->cmdString(), busPkt->getAddr(), old_state); if (old_state != new_state) - DPRINTF(Cache, "Block for blk addr %x moving from " - "state %i to %i\n", - busPkt->getAddr() & (((ULL(1))<<48)-1), - old_state, new_state); - - tags->handleFill(blk, busPkt, - new_state, - writebacks, pkt); + DPRINTF(Cache, "Block for blk addr %x moving from state " + "%i to %i\n", busPkt->getAddr(), old_state, new_state); + + tags->handleFill(blk, busPkt, new_state, writebacks, pkt); //Free the packet delete busPkt; @@ -710,18 +647,20 @@ return 0; return memSidePort->sendAtomic(pkt); } } else { - // There was a cache hit. - // Handle writebacks if needed - while (!writebacks.empty()){ - memSidePort->sendAtomic(writebacks.front()); - writebacks.pop_front(); - } + if (blk) { + // There was a cache hit. + // Handle writebacks if needed + while (!writebacks.empty()){ + memSidePort->sendAtomic(writebacks.front()); + writebacks.pop_front(); + } - hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++; + hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++; + } return hitLatency; } - fatal("Probe not handled.\n"); + return 0; } diff --git a/src/mem/cache/coherence/coherence_protocol.cc b/src/mem/cache/coherence/coherence_protocol.cc index 52beb0880..3d7721805 100644 --- a/src/mem/cache/coherence/coherence_protocol.cc +++ b/src/mem/cache/coherence/coherence_protocol.cc @@ -206,8 +206,7 @@ bool CoherenceProtocol::supplyTrans(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, - CacheBlk::State & new_state - ) + CacheBlk::State & new_state) { return true; } @@ -263,182 +262,106 @@ CoherenceProtocol::CoherenceProtocol(const string &name, const bool doUpgrades) : SimObject(name) { - if ((protocol == "mosi" || protocol == "moesi") && !doUpgrades) { - cerr << "CoherenceProtocol: ownership protocols require upgrade transactions" - << "(write miss on owned block generates ReadExcl, which will clobber dirty block)" - << endl; - fatal(""); + // Python should catch this, but in case it doesn't... + if (!(protocol == "msi" || protocol == "mesi" || + protocol == "mosi" || protocol == "moesi")) { + fatal("CoherenceProtocol: unrecognized protocol %s\n", protocol); } - Packet::Command writeToSharedCmd = doUpgrades ? Packet::UpgradeReq : Packet::ReadExReq; - Packet::Command writeToSharedResp = doUpgrades ? Packet::UpgradeReq : Packet::ReadExResp; - -//@todo add in hardware prefetch to this list - if (protocol == "msi") { - // incoming requests: specify outgoing bus request - transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq); - transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq); - transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd); - //Prefetching causes a read - transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq); - transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq); - - // on response to given request: specify new state - transitionTable[Invalid][Packet::ReadResp].onResponse(Shared); - transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified); - transitionTable[Shared][writeToSharedResp].onResponse(Modified); - - // bus snoop transition functions - transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition); - transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition); - transitionTable[Shared][Packet::ReadReq].onSnoop(nullTransition); - transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans); - transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoSharedTrans); - //Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv) - transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - - if (doUpgrades) { - transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition); - transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans); - } + bool hasOwned = (protocol == "mosi" || protocol == "moesi"); + bool hasExclusive = (protocol == "mesi" || protocol == "moesi"); + + if (hasOwned && !doUpgrades) { + fatal("CoherenceProtocol: ownership protocols require upgrade " + "transactions\n(write miss on owned block generates ReadExcl, " + "which will clobber dirty block)\n"); } - else if(protocol == "mesi") { - // incoming requests: specify outgoing bus request - transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq); - transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq); - transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd); - //Prefetching causes a read - transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq); - transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq); - - // on response to given request: specify new state - transitionTable[Invalid][Packet::ReadResp].onResponse(Exclusive); - //It will move into shared if the shared line is asserted in the - //getNewState function - transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified); - transitionTable[Shared][writeToSharedResp].onResponse(Modified); - - // bus snoop transition functions - transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition); - transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition); - transitionTable[Shared][Packet::ReadReq].onSnoop(assertShared); - transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans); - transitionTable[Exclusive][Packet::ReadReq].onSnoop(assertShared); - transitionTable[Exclusive][Packet::ReadExReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans); - transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoSharedTrans); - //Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv) - transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Exclusive][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Exclusive][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - - if (doUpgrades) { - transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition); - transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans); - } + // set up a few shortcuts to save typing & visual clutter + typedef Packet P; + StateTransition (&tt)[stateMax+1][NUM_MEM_CMDS] = transitionTable; + + P::Command writeToSharedCmd = doUpgrades ? P::UpgradeReq : P::ReadExReq; + P::Command writeToSharedResp = doUpgrades ? P::UpgradeReq : P::ReadExResp; + + // Note that all transitions by default cause a panic. + // Override the valid transitions with the appropriate actions here. + + // + // ----- incoming requests: specify outgoing bus request ----- + // + tt[Invalid][P::ReadReq].onRequest(P::ReadReq); + // we only support write allocate right now + tt[Invalid][P::WriteReq].onRequest(P::ReadExReq); + tt[Shared][P::WriteReq].onRequest(writeToSharedCmd); + if (hasOwned) { + tt[Owned][P::WriteReq].onRequest(writeToSharedCmd); } - else if(protocol == "mosi") { - // incoming requests: specify outgoing bus request - transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq); - transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq); - transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd); - transitionTable[Owned][Packet::WriteReq].onRequest(writeToSharedCmd); - //Prefetching causes a read - transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq); - transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq); - - // on response to given request: specify new state - transitionTable[Invalid][Packet::ReadResp].onResponse(Shared); - transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified); - transitionTable[Shared][writeToSharedResp].onResponse(Modified); - transitionTable[Owned][writeToSharedResp].onResponse(Modified); - - // bus snoop transition functions - transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition); - transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition); - transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition); - transitionTable[Shared][Packet::ReadReq].onSnoop(assertShared); - transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans); - transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans); - transitionTable[Owned][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans); - transitionTable[Owned][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans); - transitionTable[Owned][Packet::UpgradeReq].onSnoop(invalidateTrans); - //Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv) - transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Owned][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Owned][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); + // Prefetching causes a read + tt[Invalid][P::SoftPFReq].onRequest(P::ReadReq); + tt[Invalid][P::HardPFReq].onRequest(P::ReadReq); + + // + // ----- on response to given request: specify new state ----- + // + tt[Invalid][P::ReadExResp].onResponse(Modified); + tt[Shared][writeToSharedResp].onResponse(Modified); + // Go to Exclusive state on read response if we have one (will + // move into shared if the shared line is asserted in the + // getNewState function) + // + // originally had this as: + // tt[Invalid][P::ReadResp].onResponse(hasExclusive ? Exclusive: Shared); + // ...but for some reason that caused a link error... + if (hasExclusive) { + tt[Invalid][P::ReadResp].onResponse(Exclusive); + } else { + tt[Invalid][P::ReadResp].onResponse(Shared); + } + if (hasOwned) { + tt[Owned][writeToSharedResp].onResponse(Modified); } - else if(protocol == "moesi") { - // incoming requests: specify outgoing bus request - transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq); - transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq); - transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd); - transitionTable[Owned][Packet::WriteReq].onRequest(writeToSharedCmd); - //Prefetching causes a read - transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq); - transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq); - - // on response to given request: specify new state - transitionTable[Invalid][Packet::ReadResp].onResponse(Exclusive); - //It will move into shared if the shared line is asserted in the - //getNewState function - transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified); - transitionTable[Shared][writeToSharedResp].onResponse(Modified); - transitionTable[Owned][writeToSharedResp].onResponse(Modified); - - // bus snoop transition functions - transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition); - transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition); - transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition); - transitionTable[Shared][Packet::ReadReq].onSnoop(assertShared); - transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans); - transitionTable[Exclusive][Packet::ReadReq].onSnoop(assertShared); - transitionTable[Exclusive][Packet::ReadExReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans); - transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans); - transitionTable[Owned][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans); - transitionTable[Owned][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans); - transitionTable[Owned][Packet::UpgradeReq].onSnoop(invalidateTrans); - //Transitions on seeing a DMA (writeInv(samelevel) or DMAInv) - transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Exclusive][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Owned][Packet::InvalidateReq].onSnoop(invalidateTrans); - transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Exclusive][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); - transitionTable[Owned][Packet::WriteInvalidateReq].onSnoop(invalidateTrans); + // + // ----- bus snoop transition functions ----- + // + tt[Invalid][P::ReadReq].onSnoop(nullTransition); + tt[Invalid][P::ReadExReq].onSnoop(nullTransition); + tt[Invalid][P::InvalidateReq].onSnoop(invalidateTrans); + tt[Invalid][P::WriteInvalidateReq].onSnoop(invalidateTrans); + tt[Shared][P::ReadReq].onSnoop(hasExclusive + ? assertShared : nullTransition); + tt[Shared][P::ReadExReq].onSnoop(invalidateTrans); + tt[Shared][P::InvalidateReq].onSnoop(invalidateTrans); + tt[Shared][P::WriteInvalidateReq].onSnoop(invalidateTrans); + if (doUpgrades) { + tt[Invalid][P::UpgradeReq].onSnoop(nullTransition); + tt[Shared][P::UpgradeReq].onSnoop(invalidateTrans); + } + tt[Modified][P::ReadExReq].onSnoop(supplyAndInvalidateTrans); + tt[Modified][P::ReadReq].onSnoop(hasOwned + ? supplyAndGotoOwnedTrans + : supplyAndGotoSharedTrans); + tt[Modified][P::InvalidateReq].onSnoop(invalidateTrans); + tt[Modified][P::WriteInvalidateReq].onSnoop(invalidateTrans); + + if (hasExclusive) { + tt[Exclusive][P::ReadReq].onSnoop(assertShared); + tt[Exclusive][P::ReadExReq].onSnoop(invalidateTrans); + tt[Exclusive][P::InvalidateReq].onSnoop(invalidateTrans); + tt[Exclusive][P::WriteInvalidateReq].onSnoop(invalidateTrans); } - else { - cerr << "CoherenceProtocol: unrecognized protocol " << protocol - << endl; - fatal(""); + if (hasOwned) { + tt[Owned][P::ReadReq].onSnoop(supplyAndGotoOwnedTrans); + tt[Owned][P::ReadExReq].onSnoop(supplyAndInvalidateTrans); + tt[Owned][P::UpgradeReq].onSnoop(invalidateTrans); + tt[Owned][P::InvalidateReq].onSnoop(invalidateTrans); + tt[Owned][P::WriteInvalidateReq].onSnoop(invalidateTrans); } + + // @todo add in hardware prefetch to this list } diff --git a/src/mem/cache/coherence/coherence_protocol.hh b/src/mem/cache/coherence/coherence_protocol.hh index b30fb053b..481277523 100644 --- a/src/mem/cache/coherence/coherence_protocol.hh +++ b/src/mem/cache/coherence/coherence_protocol.hh @@ -211,31 +211,25 @@ class CoherenceProtocol : public SimObject friend class CoherenceProtocol::StateTransition; /** Mask to select status bits relevant to coherence protocol. */ - const static CacheBlk::State - stateMask = BlkValid | BlkWritable | BlkDirty; + static const int stateMask = BlkValid | BlkWritable | BlkDirty; /** The Modified (M) state. */ - const static CacheBlk::State - Modified = BlkValid | BlkWritable | BlkDirty; + static const int Modified = BlkValid | BlkWritable | BlkDirty; /** The Owned (O) state. */ - const static CacheBlk::State - Owned = BlkValid | BlkDirty; + static const int Owned = BlkValid | BlkDirty; /** The Exclusive (E) state. */ - const static CacheBlk::State - Exclusive = BlkValid | BlkWritable; + static const int Exclusive = BlkValid | BlkWritable; /** The Shared (S) state. */ - const static CacheBlk::State - Shared = BlkValid; + static const int Shared = BlkValid; /** The Invalid (I) state. */ - const static CacheBlk::State - Invalid = 0; + static const int Invalid = 0; /** * Maximum state encoding value (used to size transition lookup * table). Could be more than number of states, depends on * encoding of status bits. */ - const static int stateMax = stateMask; + static const int stateMax = stateMask; /** * The table of all possible transitions, organized by starting state and diff --git a/src/mem/cache/miss/blocking_buffer.hh b/src/mem/cache/miss/blocking_buffer.hh index 4408cfc4f..934a843a6 100644 --- a/src/mem/cache/miss/blocking_buffer.hh +++ b/src/mem/cache/miss/blocking_buffer.hh @@ -128,8 +128,8 @@ public: } /** - * Selects a outstanding pktuest to service. - * @return The pktuest to service, NULL if none found. + * Selects a outstanding request to service. + * @return The request to service, NULL if none found. */ PacketPtr getPacket(); @@ -147,7 +147,7 @@ public: void restoreOrigCmd(PacketPtr &pkt); /** - * Marks a pktuest as in service (sent on the bus). This can have side + * Marks a request as in service (sent on the bus). This can have side * effect since storage for no response commands is deallocated once they * are successfully sent. * @param pkt The request that was sent on the bus. @@ -155,14 +155,14 @@ public: void markInService(PacketPtr &pkt, MSHR* mshr); /** - * Frees the resources of the pktuest and unblock the cache. + * Frees the resources of the request and unblock the cache. * @param pkt The request that has been satisfied. - * @param time The time when the pktuest is satisfied. + * @param time The time when the request is satisfied. */ void handleResponse(PacketPtr &pkt, Tick time); /** - * Removes all outstanding pktuests for a given thread number. If a request + * Removes all outstanding requests for a given thread number. If a request * has been sent to the bus, this function removes all of its targets. * @param threadNum The thread number of the requests to squash. */ @@ -220,14 +220,14 @@ public: int size, uint8_t *data, bool compressed); /** - * Perform a writeback pktuest. + * Perform a writeback request. * @param pkt The writeback request. */ void doWriteback(PacketPtr &pkt); /** - * Returns true if there are outstanding pktuests. - * @return True if there are outstanding pktuests. + * Returns true if there are outstanding requests. + * @return True if there are outstanding requests. */ bool havePending() { diff --git a/src/mem/cache/miss/miss_queue.hh b/src/mem/cache/miss/miss_queue.hh index 2e04802fb..b67a896f4 100644 --- a/src/mem/cache/miss/miss_queue.hh +++ b/src/mem/cache/miss/miss_queue.hh @@ -77,7 +77,7 @@ class MissQueue /** The block size of the parent cache. */ int blkSize; - /** Increasing order number assigned to each incoming pktuest. */ + /** Increasing order number assigned to each incoming request. */ uint64_t order; bool prefetchMiss; @@ -212,7 +212,7 @@ class MissQueue void setPrefetcher(BasePrefetcher *_prefetcher); /** - * Handle a cache miss properly. Either allocate an MSHR for the pktuest, + * Handle a cache miss properly. Either allocate an MSHR for the request, * or forward it through the write buffer. * @param pkt The request that missed in the cache. * @param blk_size The block size of the cache. @@ -232,8 +232,8 @@ class MissQueue PacketPtr &target); /** - * Selects a outstanding pktuest to service. - * @return The pktuest to service, NULL if none found. + * Selects a outstanding request to service. + * @return The request to service, NULL if none found. */ PacketPtr getPacket(); @@ -251,7 +251,7 @@ class MissQueue void restoreOrigCmd(PacketPtr &pkt); /** - * Marks a pktuest as in service (sent on the bus). This can have side + * Marks a request as in service (sent on the bus). This can have side * effect since storage for no response commands is deallocated once they * are successfully sent. * @param pkt The request that was sent on the bus. @@ -259,14 +259,14 @@ class MissQueue void markInService(PacketPtr &pkt, MSHR* mshr); /** - * Collect statistics and free resources of a satisfied pktuest. + * Collect statistics and free resources of a satisfied request. * @param pkt The request that has been satisfied. - * @param time The time when the pktuest is satisfied. + * @param time The time when the request is satisfied. */ void handleResponse(PacketPtr &pkt, Tick time); /** - * Removes all outstanding pktuests for a given thread number. If a request + * Removes all outstanding requests for a given thread number. If a request * has been sent to the bus, this function removes all of its targets. * @param threadNum The thread number of the requests to squash. */ @@ -313,14 +313,14 @@ class MissQueue int size, uint8_t *data, bool compressed); /** - * Perform the given writeback pktuest. + * Perform the given writeback request. * @param pkt The writeback request. */ void doWriteback(PacketPtr &pkt); /** - * Returns true if there are outstanding pktuests. - * @return True if there are outstanding pktuests. + * Returns true if there are outstanding requests. + * @return True if there are outstanding requests. */ bool havePending(); diff --git a/src/mem/cache/miss/mshr.hh b/src/mem/cache/miss/mshr.hh index d92aa8a85..281ea9d49 100644 --- a/src/mem/cache/miss/mshr.hh +++ b/src/mem/cache/miss/mshr.hh @@ -44,7 +44,7 @@ class MSHR; /** * Miss Status and handling Register. This class keeps all the information - * needed to handle a cache miss including a list of target pktuests. + * needed to handle a cache miss including a list of target requests. */ class MSHR { public: @@ -63,15 +63,15 @@ class MSHR { Addr addr; /** Adress space id of the miss. */ short asid; - /** True if the pktuest has been sent to the bus. */ + /** True if the request has been sent to the bus. */ bool inService; /** Thread number of the miss. */ int threadNum; - /** The pktuest that is forwarded to the next level of the hierarchy. */ + /** The request that is forwarded to the next level of the hierarchy. */ PacketPtr pkt; /** The number of currently allocated targets. */ short ntargets; - /** The original pktuesting command. */ + /** The original requesting command. */ Packet::Command originalCmd; /** Order number of assigned by the miss queue. */ uint64_t order; @@ -88,24 +88,24 @@ class MSHR { Iterator allocIter; private: - /** List of all pktuests that match the address */ + /** List of all requests that match the address */ TargetList targets; public: /** * Allocate a miss to this MSHR. - * @param cmd The pktuesting command. + * @param cmd The requesting command. * @param addr The address of the miss. * @param asid The address space id of the miss. - * @param size The number of bytes to pktuest. + * @param size The number of bytes to request. * @param pkt The original miss. */ void allocate(Packet::Command cmd, Addr addr, int size, PacketPtr &pkt); /** - * Allocate this MSHR as a buffer for the given pktuest. - * @param target The memory pktuest to buffer. + * Allocate this MSHR as a buffer for the given request. + * @param target The memory request to buffer. */ void allocateAsBuffer(PacketPtr &target); @@ -115,7 +115,7 @@ public: void deallocate(); /** - * Add a pktuest to the list of targets. + * Add a request to the list of targets. * @param target The target. */ void allocateTarget(PacketPtr &target); diff --git a/src/mem/cache/miss/mshr_queue.hh b/src/mem/cache/miss/mshr_queue.hh index 30397d9a0..ec2ddae8a 100644 --- a/src/mem/cache/miss/mshr_queue.hh +++ b/src/mem/cache/miss/mshr_queue.hh @@ -39,7 +39,7 @@ #include "mem/cache/miss/mshr.hh" /** - * A Class for maintaining a list of pending and allocated memory pktuests. + * A Class for maintaining a list of pending and allocated memory requests. */ class MSHRQueue { private: @@ -55,7 +55,7 @@ class MSHRQueue { // Parameters /** * The total number of MSHRs in this queue. This number is set as the - * number of MSHRs pktuested plus (numReserve - 1). This allows for + * number of MSHRs requested plus (numReserve - 1). This allows for * the same number of effective MSHRs while still maintaining the reserve. */ const int numMSHRs; @@ -103,14 +103,14 @@ class MSHRQueue { bool findMatches(Addr addr, std::vector<MSHR*>& matches) const; /** - * Find any pending pktuests that overlap the given request. + * Find any pending requests that overlap the given request. * @param pkt The request to find. * @return A pointer to the earliest matching MSHR. */ MSHR* findPending(PacketPtr &pkt) const; /** - * Allocates a new MSHR for the pktuest and size. This places the request + * Allocates a new MSHR for the request and size. This places the request * as the first target in the MSHR. * @param pkt The request to handle. * @param size The number in bytes to fetch from memory. @@ -121,12 +121,12 @@ class MSHRQueue { MSHR* allocate(PacketPtr &pkt, int size = 0); /** - * Allocate a read pktuest for the given address, and places the given + * Allocate a read request for the given address, and places the given * target on the target list. * @param addr The address to fetch. * @param asid The address space for the fetch. - * @param size The number of bytes to pktuest. - * @param target The first target for the pktuest. + * @param size The number of bytes to request. + * @param target The first target for the request. * @return Pointer to the new MSHR. */ MSHR* allocateFetch(Addr addr, int size, PacketPtr &target); @@ -135,7 +135,7 @@ class MSHRQueue { * Allocate a target list for the given address. * @param addr The address to fetch. * @param asid The address space for the fetch. - * @param size The number of bytes to pktuest. + * @param size The number of bytes to request. * @return Pointer to the new MSHR. */ MSHR* allocateTargetList(Addr addr, int size); @@ -181,14 +181,14 @@ class MSHRQueue { void markInService(MSHR* mshr); /** - * Mark an in service mshr as pending, used to resend a pktuest. + * Mark an in service mshr as pending, used to resend a request. * @param mshr The MSHR to resend. * @param cmd The command to resend. */ void markPending(MSHR* mshr, Packet::Command cmd); /** - * Squash outstanding pktuests with the given thread number. If a request + * Squash outstanding requests with the given thread number. If a request * is in service, just squashes the targets. * @param threadNum The thread to squash. */ @@ -196,7 +196,7 @@ class MSHRQueue { /** * Returns true if the pending list is not empty. - * @return True if there are outstanding pktuests. + * @return True if there are outstanding requests. */ bool havePending() const { @@ -213,8 +213,8 @@ class MSHRQueue { } /** - * Returns the pktuest at the head of the pendingList. - * @return The next pktuest to service. + * Returns the request at the head of the pendingList. + * @return The next request to service. */ PacketPtr getReq() const { diff --git a/src/mem/cache/tags/split.hh b/src/mem/cache/tags/split.hh index 748f6fb25..898d3c7a0 100644 --- a/src/mem/cache/tags/split.hh +++ b/src/mem/cache/tags/split.hh @@ -71,13 +71,13 @@ class Split : public BaseTags Addr blkMask; - /** Number of NIC pktuests that hit in the NIC partition */ + /** Number of NIC requests that hit in the NIC partition */ Stats::Scalar<> NR_NP_hits; - /** Number of NIC pktuests that hit in the CPU partition */ + /** Number of NIC requests that hit in the CPU partition */ Stats::Scalar<> NR_CP_hits; - /** Number of CPU pktuests that hit in the NIC partition */ + /** Number of CPU requests that hit in the NIC partition */ Stats::Scalar<> CR_NP_hits; - /** Number of CPU pktuests that hit in the CPU partition */ + /** Number of CPU requests that hit in the CPU partition */ Stats::Scalar<> CR_CP_hits; /** The number of nic replacements (i.e. misses) */ Stats::Scalar<> nic_repl; diff --git a/src/mem/cache/tags/split_blk.hh b/src/mem/cache/tags/split_blk.hh index 64d903579..f38516180 100644 --- a/src/mem/cache/tags/split_blk.hh +++ b/src/mem/cache/tags/split_blk.hh @@ -47,7 +47,7 @@ class SplitBlk : public CacheBlk { bool isTouched; /** Has this block been used after being brought in? (for LIFO partition) */ bool isUsed; - /** is this blk a NIC block? (i.e. pktuested by the NIC) */ + /** is this blk a NIC block? (i.e. requested by the NIC) */ bool isNIC; /** timestamp of the arrival of this block into the cache */ Tick ts; |