cache.cc (11601:382e0637fae0) | cache.cc (11602:7e0199f80816) |
---|---|
1/* 2 * Copyright (c) 2010-2016 ARM Limited 3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 186 unchanged lines hidden (view full) --- 195 if (pkt->fromCache()) { 196 assert(pkt->getSize() == blkSize); 197 // special handling for coherent block requests from 198 // upper-level caches 199 if (pkt->needsWritable()) { 200 // sanity check 201 assert(pkt->cmd == MemCmd::ReadExReq || 202 pkt->cmd == MemCmd::SCUpgradeFailReq); | 1/* 2 * Copyright (c) 2010-2016 ARM Limited 3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 186 unchanged lines hidden (view full) --- 195 if (pkt->fromCache()) { 196 assert(pkt->getSize() == blkSize); 197 // special handling for coherent block requests from 198 // upper-level caches 199 if (pkt->needsWritable()) { 200 // sanity check 201 assert(pkt->cmd == MemCmd::ReadExReq || 202 pkt->cmd == MemCmd::SCUpgradeFailReq); |
203 assert(!pkt->hasSharers()); |
|
203 204 // if we have a dirty copy, make sure the recipient 205 // keeps it marked dirty (in the modified state) 206 if (blk->isDirty()) { 207 pkt->setCacheResponding(); | 204 205 // if we have a dirty copy, make sure the recipient 206 // keeps it marked dirty (in the modified state) 207 if (blk->isDirty()) { 208 pkt->setCacheResponding(); |
209 blk->status &= ~BlkDirty; |
|
208 } | 210 } |
209 // on ReadExReq we give up our copy unconditionally, 210 // even if this cache is mostly inclusive, we may want 211 // to revisit this 212 invalidateBlock(blk); | |
213 } else if (blk->isWritable() && !pending_downgrade && 214 !pkt->hasSharers() && 215 pkt->cmd != MemCmd::ReadCleanReq) { 216 // we can give the requester a writable copy on a read 217 // request if: 218 // - we have a writable copy at this level (& below) 219 // - we don't have a pending snoop from below 220 // signaling another read request --- 34 unchanged lines hidden (view full) --- 255 pkt->setHasSharers(); 256 } 257 } 258 } else { 259 // otherwise only respond with a shared copy 260 pkt->setHasSharers(); 261 } 262 } | 211 } else if (blk->isWritable() && !pending_downgrade && 212 !pkt->hasSharers() && 213 pkt->cmd != MemCmd::ReadCleanReq) { 214 // we can give the requester a writable copy on a read 215 // request if: 216 // - we have a writable copy at this level (& below) 217 // - we don't have a pending snoop from below 218 // signaling another read request --- 34 unchanged lines hidden (view full) --- 253 pkt->setHasSharers(); 254 } 255 } 256 } else { 257 // otherwise only respond with a shared copy 258 pkt->setHasSharers(); 259 } 260 } |
263 } else { 264 // Upgrade or Invalidate 265 assert(pkt->isUpgrade() || pkt->isInvalidate()); | 261 } else if (pkt->isUpgrade()) { 262 // sanity check 263 assert(!pkt->hasSharers()); |
266 | 264 |
267 // for invalidations we could be looking at the temp block 268 // (for upgrades we always allocate) | 265 if (blk->isDirty()) { 266 // we were in the Owned state, and a cache above us that 267 // has the line in Shared state needs to be made aware 268 // that the data it already has is in fact dirty 269 pkt->setCacheResponding(); 270 blk->status &= ~BlkDirty; 271 } 272 } else { 273 assert(pkt->isInvalidate()); |
269 invalidateBlock(blk); 270 DPRINTF(CacheVerbose, "%s for %s addr %#llx size %d (invalidation)\n", 271 __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize()); 272 } 273} 274 275///////////////////////////////////////////////////// 276// --- 674 unchanged lines hidden (view full) --- 951 cmd = needsWritable ? MemCmd::ReadExReq : 952 (isReadOnly ? MemCmd::ReadCleanReq : MemCmd::ReadSharedReq); 953 } 954 PacketPtr pkt = new Packet(cpu_pkt->req, cmd, blkSize); 955 956 // if there are upstream caches that have already marked the 957 // packet as having sharers (not passing writable), pass that info 958 // downstream | 274 invalidateBlock(blk); 275 DPRINTF(CacheVerbose, "%s for %s addr %#llx size %d (invalidation)\n", 276 __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize()); 277 } 278} 279 280///////////////////////////////////////////////////// 281// --- 674 unchanged lines hidden (view full) --- 956 cmd = needsWritable ? MemCmd::ReadExReq : 957 (isReadOnly ? MemCmd::ReadCleanReq : MemCmd::ReadSharedReq); 958 } 959 PacketPtr pkt = new Packet(cpu_pkt->req, cmd, blkSize); 960 961 // if there are upstream caches that have already marked the 962 // packet as having sharers (not passing writable), pass that info 963 // downstream |
959 if (cpu_pkt->hasSharers()) { | 964 if (cpu_pkt->hasSharers() && !needsWritable) { |
960 // note that cpu_pkt may have spent a considerable time in the 961 // MSHR queue and that the information could possibly be out 962 // of date, however, there is no harm in conservatively 963 // assuming the block has sharers 964 pkt->setHasSharers(); 965 DPRINTF(Cache, "%s passing hasSharers from %s to %s addr %#llx " 966 "size %d\n", 967 __func__, cpu_pkt->cmdString(), pkt->cmdString(), --- 1086 unchanged lines hidden (view full) --- 2054 pkt->makeAtomicResponse(); 2055 // packets such as upgrades do not actually have any data 2056 // payload 2057 if (pkt->hasData()) 2058 pkt->setDataFromBlock(blk->data, blkSize); 2059 } 2060 } 2061 | 965 // note that cpu_pkt may have spent a considerable time in the 966 // MSHR queue and that the information could possibly be out 967 // of date, however, there is no harm in conservatively 968 // assuming the block has sharers 969 pkt->setHasSharers(); 970 DPRINTF(Cache, "%s passing hasSharers from %s to %s addr %#llx " 971 "size %d\n", 972 __func__, cpu_pkt->cmdString(), pkt->cmdString(), --- 1086 unchanged lines hidden (view full) --- 2059 pkt->makeAtomicResponse(); 2060 // packets such as upgrades do not actually have any data 2061 // payload 2062 if (pkt->hasData()) 2063 pkt->setDataFromBlock(blk->data, blkSize); 2064 } 2065 } 2066 |
2062 if (!respond && is_timing && is_deferred) { 2063 // if it's a deferred timing snoop to which we are not 2064 // responding, then we've made a copy of both the request and 2065 // the packet, delete them here | 2067 if (!respond && is_deferred) { |
2066 assert(pkt->needsResponse()); | 2068 assert(pkt->needsResponse()); |
2067 assert(!pkt->cacheResponding()); 2068 delete pkt->req; | 2069 2070 // if we copied the deferred packet with the intention to 2071 // respond, but are not responding, then a cache above us must 2072 // be, and we can use this as the indication of whether this 2073 // is a packet where we created a copy of the request or not 2074 if (!pkt->cacheResponding()) { 2075 delete pkt->req; 2076 } 2077 |
2069 delete pkt; 2070 } 2071 2072 // Do this last in case it deallocates block data or something 2073 // like that 2074 if (invalidate) { 2075 invalidateBlock(blk); 2076 } --- 606 unchanged lines hidden --- | 2078 delete pkt; 2079 } 2080 2081 // Do this last in case it deallocates block data or something 2082 // like that 2083 if (invalidate) { 2084 invalidateBlock(blk); 2085 } --- 606 unchanged lines hidden --- |