164c164,165
< Cache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat)
---
> Cache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
> PacketList &writebacks)
176,178d176
< // lookupLatency is the latency in case the request is uncacheable.
< lat = lookupLatency;
<
182c180
< BaseCache::evictBlock(old_blk, clockEdge(lat + forwardLatency));
---
> BaseCache::evictBlock(old_blk, writebacks);
185a184,185
> // lookupLatency is the latency in case the request is uncacheable.
> lat = lookupLatency;
189c189
< return BaseCache::access(pkt, blk, lat);
---
> return BaseCache::access(pkt, blk, lat, writebacks);
193c193
< Cache::doWritebacks(PacketPtr pkt, Tick forward_time)
---
> Cache::doWritebacks(PacketList& writebacks, Tick forward_time)
195,196c195,198
< // We use forwardLatency here because we are copying writebacks to
< // write buffer.
---
> while (!writebacks.empty()) {
> PacketPtr wbPkt = writebacks.front();
> // We use forwardLatency here because we are copying writebacks to
> // write buffer.
198,211c200,222
< // Call isCachedAbove for Writebacks, CleanEvicts and
< // WriteCleans to discover if the block is cached above.
< if (isCachedAbove(pkt)) {
< if (pkt->cmd == MemCmd::CleanEvict) {
< // Delete CleanEvict because cached copies exist above. The
< // packet destructor will delete the request object because
< // this is a non-snoop request packet which does not require a
< // response.
< delete pkt;
< } else if (pkt->cmd == MemCmd::WritebackClean) {
< // clean writeback, do not send since the block is
< // still cached above
< assert(writebackClean);
< delete pkt;
---
> // Call isCachedAbove for Writebacks, CleanEvicts and
> // WriteCleans to discover if the block is cached above.
> if (isCachedAbove(wbPkt)) {
> if (wbPkt->cmd == MemCmd::CleanEvict) {
> // Delete CleanEvict because cached copies exist above. The
> // packet destructor will delete the request object because
> // this is a non-snoop request packet which does not require a
> // response.
> delete wbPkt;
> } else if (wbPkt->cmd == MemCmd::WritebackClean) {
> // clean writeback, do not send since the block is
> // still cached above
> assert(writebackClean);
> delete wbPkt;
> } else {
> assert(wbPkt->cmd == MemCmd::WritebackDirty ||
> wbPkt->cmd == MemCmd::WriteClean);
> // Set BLOCK_CACHED flag in Writeback and send below, so that
> // the Writeback does not reset the bit corresponding to this
> // address in the snoop filter below.
> wbPkt->setBlockCached();
> allocateWriteBuffer(wbPkt, forward_time);
> }
213,219c224,228
< assert(pkt->cmd == MemCmd::WritebackDirty ||
< pkt->cmd == MemCmd::WriteClean);
< // Set BLOCK_CACHED flag in Writeback and send below, so that
< // the Writeback does not reset the bit corresponding to this
< // address in the snoop filter below.
< pkt->setBlockCached();
< allocateWriteBuffer(pkt, forward_time);
---
> // If the block is not cached above, send packet below. Both
> // CleanEvict and Writeback with BLOCK_CACHED flag cleared will
> // reset the bit corresponding to this address in the snoop filter
> // below.
> allocateWriteBuffer(wbPkt, forward_time);
221,226c230
< } else {
< // If the block is not cached above, send packet below. Both
< // CleanEvict and Writeback with BLOCK_CACHED flag cleared will
< // reset the bit corresponding to this address in the snoop filter
< // below.
< allocateWriteBuffer(pkt, forward_time);
---
> writebacks.pop_front();
231c235
< Cache::doWritebacksAtomic(PacketPtr pkt)
---
> Cache::doWritebacksAtomic(PacketList& writebacks)
233,245c237,258
< // Call isCachedAbove for both Writebacks and CleanEvicts. If
< // isCachedAbove returns true we set BLOCK_CACHED flag in Writebacks
< // and discard CleanEvicts.
< if (isCachedAbove(pkt, false)) {
< if (pkt->cmd == MemCmd::WritebackDirty ||
< pkt->cmd == MemCmd::WriteClean) {
< // Set BLOCK_CACHED flag in Writeback and send below,
< // so that the Writeback does not reset the bit
< // corresponding to this address in the snoop filter
< // below. We can discard CleanEvicts because cached
< // copies exist above. Atomic mode isCachedAbove
< // modifies packet to set BLOCK_CACHED flag
< memSidePort.sendAtomic(pkt);
---
> while (!writebacks.empty()) {
> PacketPtr wbPkt = writebacks.front();
> // Call isCachedAbove for both Writebacks and CleanEvicts. If
> // isCachedAbove returns true we set BLOCK_CACHED flag in Writebacks
> // and discard CleanEvicts.
> if (isCachedAbove(wbPkt, false)) {
> if (wbPkt->cmd == MemCmd::WritebackDirty ||
> wbPkt->cmd == MemCmd::WriteClean) {
> // Set BLOCK_CACHED flag in Writeback and send below,
> // so that the Writeback does not reset the bit
> // corresponding to this address in the snoop filter
> // below. We can discard CleanEvicts because cached
> // copies exist above. Atomic mode isCachedAbove
> // modifies packet to set BLOCK_CACHED flag
> memSidePort.sendAtomic(wbPkt);
> }
> } else {
> // If the block is not cached above, send packet below. Both
> // CleanEvict and Writeback with BLOCK_CACHED flag cleared will
> // reset the bit corresponding to this address in the snoop filter
> // below.
> memSidePort.sendAtomic(wbPkt);
247,252c260,264
< } else {
< // If the block is not cached above, send packet below. Both
< // CleanEvict and Writeback with BLOCK_CACHED flag cleared will
< // reset the bit corresponding to this address in the snoop filter
< // below.
< memSidePort.sendAtomic(pkt);
---
> writebacks.pop_front();
> // In case of CleanEvicts, the packet destructor will delete the
> // request object because this is a non-snoop request packet which
> // does not require a response.
> delete wbPkt;
254,258d265
<
< // In case of CleanEvicts, the packet destructor will delete the
< // request object because this is a non-snoop request packet which
< // does not require a response.
< delete pkt;
260a268
>
558c566,567
< Cache::handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk)
---
> Cache::handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk,
> PacketList &writebacks)
620c629
< blk = handleFill(bus_pkt, blk, allocate);
---
> blk = handleFill(bus_pkt, blk, writebacks, allocate);
628c637,638
< blk = handleFill(bus_pkt, blk, allocOnFill(pkt->cmd));
---
> blk = handleFill(bus_pkt, blk, writebacks,
> allocOnFill(pkt->cmd));
1013a1024,1025
> PacketList writebacks;
> writebacks.push_back(wb_pkt);
1020c1032
< doWritebacks(wb_pkt, forward_time);
---
> doWritebacks(writebacks, forward_time);
1022c1034
< doWritebacksAtomic(wb_pkt);
---
> doWritebacksAtomic(writebacks);