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 ---