diff options
Diffstat (limited to 'src/mem/cache/cache_impl.hh')
-rw-r--r-- | src/mem/cache/cache_impl.hh | 159 |
1 files changed, 49 insertions, 110 deletions
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; } |