cache.cc (11483:d4c2e56d18b2) cache.cc (11484:08b33c52a16d)
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

--- 308 unchanged lines hidden (view full) ---

317 if (old_blk->isDirty() || writebackClean)
318 writebacks.push_back(writebackBlk(old_blk));
319 else
320 writebacks.push_back(cleanEvictBlk(old_blk));
321 tags->invalidate(old_blk);
322 old_blk->invalidate();
323 }
324
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

--- 308 unchanged lines hidden (view full) ---

317 if (old_blk->isDirty() || writebackClean)
318 writebacks.push_back(writebackBlk(old_blk));
319 else
320 writebacks.push_back(cleanEvictBlk(old_blk));
321 tags->invalidate(old_blk);
322 old_blk->invalidate();
323 }
324
325 blk = NULL;
325 blk = nullptr;
326 // lookupLatency is the latency in case the request is uncacheable.
327 lat = lookupLatency;
328 return false;
329 }
330
331 ContextID id = pkt->req->hasContextId() ?
332 pkt->req->contextId() : InvalidContextID;
333 // Here lat is the value passed as parameter to accessBlock() function

--- 55 unchanged lines hidden (view full) ---

389 // any ordering/decisions about ownership already taken
390 if (pkt->cmd == MemCmd::WritebackClean &&
391 mshrQueue.findMatch(pkt->getAddr(), pkt->isSecure())) {
392 DPRINTF(Cache, "Clean writeback %#llx to block with MSHR, "
393 "dropping\n", pkt->getAddr());
394 return true;
395 }
396
326 // lookupLatency is the latency in case the request is uncacheable.
327 lat = lookupLatency;
328 return false;
329 }
330
331 ContextID id = pkt->req->hasContextId() ?
332 pkt->req->contextId() : InvalidContextID;
333 // Here lat is the value passed as parameter to accessBlock() function

--- 55 unchanged lines hidden (view full) ---

389 // any ordering/decisions about ownership already taken
390 if (pkt->cmd == MemCmd::WritebackClean &&
391 mshrQueue.findMatch(pkt->getAddr(), pkt->isSecure())) {
392 DPRINTF(Cache, "Clean writeback %#llx to block with MSHR, "
393 "dropping\n", pkt->getAddr());
394 return true;
395 }
396
397 if (blk == NULL) {
397 if (blk == nullptr) {
398 // need to do a replacement
399 blk = allocateBlock(pkt->getAddr(), pkt->isSecure(), writebacks);
398 // need to do a replacement
399 blk = allocateBlock(pkt->getAddr(), pkt->isSecure(), writebacks);
400 if (blk == NULL) {
400 if (blk == nullptr) {
401 // no replaceable block available: give up, fwd to next level.
402 incMissCount(pkt);
403 return false;
404 }
405 tags->insertBlock(pkt, blk);
406
407 blk->status = (BlkValid | BlkReadable);
408 if (pkt->isSecure()) {

--- 13 unchanged lines hidden (view full) ---

422 }
423 // nothing else to do; writeback doesn't expect response
424 assert(!pkt->needsResponse());
425 std::memcpy(blk->data, pkt->getConstPtr<uint8_t>(), blkSize);
426 DPRINTF(Cache, "%s new state is %s\n", __func__, blk->print());
427 incHitCount(pkt);
428 return true;
429 } else if (pkt->cmd == MemCmd::CleanEvict) {
401 // no replaceable block available: give up, fwd to next level.
402 incMissCount(pkt);
403 return false;
404 }
405 tags->insertBlock(pkt, blk);
406
407 blk->status = (BlkValid | BlkReadable);
408 if (pkt->isSecure()) {

--- 13 unchanged lines hidden (view full) ---

422 }
423 // nothing else to do; writeback doesn't expect response
424 assert(!pkt->needsResponse());
425 std::memcpy(blk->data, pkt->getConstPtr<uint8_t>(), blkSize);
426 DPRINTF(Cache, "%s new state is %s\n", __func__, blk->print());
427 incHitCount(pkt);
428 return true;
429 } else if (pkt->cmd == MemCmd::CleanEvict) {
430 if (blk != NULL) {
430 if (blk != nullptr) {
431 // Found the block in the tags, need to stop CleanEvict from
432 // propagating further down the hierarchy. Returning true will
433 // treat the CleanEvict like a satisfied write request and delete
434 // it.
435 return true;
436 }
437 // We didn't find the block here, propagate the CleanEvict further
438 // down the memory hierarchy. Returning false will treat the CleanEvict
439 // like a Writeback which could not find a replaceable block so has to
440 // go to next level.
441 return false;
431 // Found the block in the tags, need to stop CleanEvict from
432 // propagating further down the hierarchy. Returning true will
433 // treat the CleanEvict like a satisfied write request and delete
434 // it.
435 return true;
436 }
437 // We didn't find the block here, propagate the CleanEvict further
438 // down the memory hierarchy. Returning false will treat the CleanEvict
439 // like a Writeback which could not find a replaceable block so has to
440 // go to next level.
441 return false;
442 } else if ((blk != NULL) &&
442 } else if ((blk != nullptr) &&
443 (pkt->needsWritable() ? blk->isWritable() :
444 blk->isReadable())) {
445 // OK to satisfy access
446 incHitCount(pkt);
447 satisfyCpuSideRequest(pkt, blk);
448 return true;
449 }
450
443 (pkt->needsWritable() ? blk->isWritable() :
444 blk->isReadable())) {
445 // OK to satisfy access
446 incHitCount(pkt);
447 satisfyCpuSideRequest(pkt, blk);
448 return true;
449 }
450
451 // Can't satisfy access normally... either no block (blk == NULL)
451 // Can't satisfy access normally... either no block (blk == nullptr)
452 // or have block but need writable
453
454 incMissCount(pkt);
455
452 // or have block but need writable
453
454 incMissCount(pkt);
455
456 if (blk == NULL && pkt->isLLSC() && pkt->isWrite()) {
456 if (blk == nullptr && pkt->isLLSC() && pkt->isWrite()) {
457 // complete miss on store conditional... just give up now
458 pkt->req->setExtraData(0);
459 return true;
460 }
461
462 return false;
463}
464

--- 204 unchanged lines hidden (view full) ---

669
670 // anything that is merely forwarded pays for the forward latency and
671 // the delay provided by the crossbar
672 Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay;
673
674 // We use lookupLatency here because it is used to specify the latency
675 // to access.
676 Cycles lat = lookupLatency;
457 // complete miss on store conditional... just give up now
458 pkt->req->setExtraData(0);
459 return true;
460 }
461
462 return false;
463}
464

--- 204 unchanged lines hidden (view full) ---

669
670 // anything that is merely forwarded pays for the forward latency and
671 // the delay provided by the crossbar
672 Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay;
673
674 // We use lookupLatency here because it is used to specify the latency
675 // to access.
676 Cycles lat = lookupLatency;
677 CacheBlk *blk = NULL;
677 CacheBlk *blk = nullptr;
678 bool satisfied = false;
679 {
680 PacketList writebacks;
681 // Note that lat is passed by reference here. The function
682 // access() calls accessBlock() which can modify lat value.
683 satisfied = access(pkt, blk, lat, writebacks);
684
685 // copy writebacks to write buffer here to ensure they logically

--- 322 unchanged lines hidden (view full) ---

1008
1009 return lat * clockPeriod();
1010 }
1011
1012 // should assert here that there are no outstanding MSHRs or
1013 // writebacks... that would mean that someone used an atomic
1014 // access in timing mode
1015
678 bool satisfied = false;
679 {
680 PacketList writebacks;
681 // Note that lat is passed by reference here. The function
682 // access() calls accessBlock() which can modify lat value.
683 satisfied = access(pkt, blk, lat, writebacks);
684
685 // copy writebacks to write buffer here to ensure they logically

--- 322 unchanged lines hidden (view full) ---

1008
1009 return lat * clockPeriod();
1010 }
1011
1012 // should assert here that there are no outstanding MSHRs or
1013 // writebacks... that would mean that someone used an atomic
1014 // access in timing mode
1015
1016 CacheBlk *blk = NULL;
1016 CacheBlk *blk = nullptr;
1017 PacketList writebacks;
1018 bool satisfied = access(pkt, blk, lat, writebacks);
1019
1020 // handle writebacks resulting from the access here to ensure they
1021 // logically proceed anything happening below
1022 doWritebacksAtomic(writebacks);
1023
1024 if (!satisfied) {

--- 5 unchanged lines hidden (view full) ---

1030 (pkt->req->isUncacheable() && pkt->isWrite())) {
1031 lat += ticksToCycles(memSidePort->sendAtomic(pkt));
1032 return lat * clockPeriod();
1033 }
1034 // only misses left
1035
1036 PacketPtr bus_pkt = createMissPacket(pkt, blk, pkt->needsWritable());
1037
1017 PacketList writebacks;
1018 bool satisfied = access(pkt, blk, lat, writebacks);
1019
1020 // handle writebacks resulting from the access here to ensure they
1021 // logically proceed anything happening below
1022 doWritebacksAtomic(writebacks);
1023
1024 if (!satisfied) {

--- 5 unchanged lines hidden (view full) ---

1030 (pkt->req->isUncacheable() && pkt->isWrite())) {
1031 lat += ticksToCycles(memSidePort->sendAtomic(pkt));
1032 return lat * clockPeriod();
1033 }
1034 // only misses left
1035
1036 PacketPtr bus_pkt = createMissPacket(pkt, blk, pkt->needsWritable());
1037
1038 bool is_forward = (bus_pkt == NULL);
1038 bool is_forward = (bus_pkt == nullptr);
1039
1040 if (is_forward) {
1041 // just forwarding the same request to the next level
1042 // no local cache operation involved
1043 bus_pkt = pkt;
1044 }
1045
1046 DPRINTF(Cache, "Sending an atomic %s for %#llx (%s)\n",

--- 223 unchanged lines hidden (view full) ---

1270 // we have dealt with any (uncacheable) writes above, from here on
1271 // we know we are dealing with an MSHR due to a miss or a prefetch
1272 MSHR *mshr = dynamic_cast<MSHR*>(pkt->popSenderState());
1273 assert(mshr);
1274
1275 if (mshr == noTargetMSHR) {
1276 // we always clear at least one target
1277 clearBlocked(Blocked_NoTargets);
1039
1040 if (is_forward) {
1041 // just forwarding the same request to the next level
1042 // no local cache operation involved
1043 bus_pkt = pkt;
1044 }
1045
1046 DPRINTF(Cache, "Sending an atomic %s for %#llx (%s)\n",

--- 223 unchanged lines hidden (view full) ---

1270 // we have dealt with any (uncacheable) writes above, from here on
1271 // we know we are dealing with an MSHR due to a miss or a prefetch
1272 MSHR *mshr = dynamic_cast<MSHR*>(pkt->popSenderState());
1273 assert(mshr);
1274
1275 if (mshr == noTargetMSHR) {
1276 // we always clear at least one target
1277 clearBlocked(Blocked_NoTargets);
1278 noTargetMSHR = NULL;
1278 noTargetMSHR = nullptr;
1279 }
1280
1281 // Initial target is used just for stats
1282 MSHR::Target *initial_tgt = mshr->getTarget();
1283 int stats_cmd_idx = initial_tgt->pkt->cmdToIndex();
1284 Tick miss_latency = curTick() - initial_tgt->recvTime;
1285
1286 if (pkt->req->isUncacheable()) {

--- 23 unchanged lines hidden (view full) ---

1310
1311 CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure());
1312
1313 if (is_fill && !is_error) {
1314 DPRINTF(Cache, "Block for addr %#llx being updated in Cache\n",
1315 pkt->getAddr());
1316
1317 blk = handleFill(pkt, blk, writebacks, mshr->allocOnFill);
1279 }
1280
1281 // Initial target is used just for stats
1282 MSHR::Target *initial_tgt = mshr->getTarget();
1283 int stats_cmd_idx = initial_tgt->pkt->cmdToIndex();
1284 Tick miss_latency = curTick() - initial_tgt->recvTime;
1285
1286 if (pkt->req->isUncacheable()) {

--- 23 unchanged lines hidden (view full) ---

1310
1311 CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure());
1312
1313 if (is_fill && !is_error) {
1314 DPRINTF(Cache, "Block for addr %#llx being updated in Cache\n",
1315 pkt->getAddr());
1316
1317 blk = handleFill(pkt, blk, writebacks, mshr->allocOnFill);
1318 assert(blk != NULL);
1318 assert(blk != nullptr);
1319 }
1320
1321 // allow invalidation responses originating from write-line
1322 // requests to be discarded
1323 bool is_invalidate = pkt->isInvalidate();
1324
1325 // First offset for critical word first calculations
1326 int initial_offset = initial_tgt->pkt->getOffset(blkSize);

--- 28 unchanged lines hidden (view full) ---

1355 // from above.
1356 if (tgt_pkt->cmd == MemCmd::WriteLineReq) {
1357 assert(!is_error);
1358 // we got the block in a writable state, so promote
1359 // any deferred targets if possible
1360 mshr->promoteWritable();
1361 // NB: we use the original packet here and not the response!
1362 blk = handleFill(tgt_pkt, blk, writebacks, mshr->allocOnFill);
1319 }
1320
1321 // allow invalidation responses originating from write-line
1322 // requests to be discarded
1323 bool is_invalidate = pkt->isInvalidate();
1324
1325 // First offset for critical word first calculations
1326 int initial_offset = initial_tgt->pkt->getOffset(blkSize);

--- 28 unchanged lines hidden (view full) ---

1355 // from above.
1356 if (tgt_pkt->cmd == MemCmd::WriteLineReq) {
1357 assert(!is_error);
1358 // we got the block in a writable state, so promote
1359 // any deferred targets if possible
1360 mshr->promoteWritable();
1361 // NB: we use the original packet here and not the response!
1362 blk = handleFill(tgt_pkt, blk, writebacks, mshr->allocOnFill);
1363 assert(blk != NULL);
1363 assert(blk != nullptr);
1364
1365 // treat as a fill, and discard the invalidation
1366 // response
1367 is_fill = true;
1368 is_invalidate = false;
1369 }
1370
1371 if (is_fill) {

--- 283 unchanged lines hidden (view full) ---

1655 return true;
1656}
1657
1658CacheBlk*
1659Cache::allocateBlock(Addr addr, bool is_secure, PacketList &writebacks)
1660{
1661 CacheBlk *blk = tags->findVictim(addr);
1662
1364
1365 // treat as a fill, and discard the invalidation
1366 // response
1367 is_fill = true;
1368 is_invalidate = false;
1369 }
1370
1371 if (is_fill) {

--- 283 unchanged lines hidden (view full) ---

1655 return true;
1656}
1657
1658CacheBlk*
1659Cache::allocateBlock(Addr addr, bool is_secure, PacketList &writebacks)
1660{
1661 CacheBlk *blk = tags->findVictim(addr);
1662
1663 // It is valid to return NULL if there is no victim
1663 // It is valid to return nullptr if there is no victim
1664 if (!blk)
1665 return nullptr;
1666
1667 if (blk->isValid()) {
1668 Addr repl_addr = tags->regenerateBlkAddr(blk->tag, blk->set);
1669 MSHR *repl_mshr = mshrQueue.findMatch(repl_addr, blk->isSecure());
1670 if (repl_mshr) {
1671 // must be an outstanding upgrade request
1672 // on a block we're about to replace...
1673 assert(!blk->isWritable() || blk->isDirty());
1674 assert(repl_mshr->needsWritable());
1675 // too hard to replace block with transient state
1676 // allocation failed, block not inserted
1664 if (!blk)
1665 return nullptr;
1666
1667 if (blk->isValid()) {
1668 Addr repl_addr = tags->regenerateBlkAddr(blk->tag, blk->set);
1669 MSHR *repl_mshr = mshrQueue.findMatch(repl_addr, blk->isSecure());
1670 if (repl_mshr) {
1671 // must be an outstanding upgrade request
1672 // on a block we're about to replace...
1673 assert(!blk->isWritable() || blk->isDirty());
1674 assert(repl_mshr->needsWritable());
1675 // too hard to replace block with transient state
1676 // allocation failed, block not inserted
1677 return NULL;
1677 return nullptr;
1678 } else {
1679 DPRINTF(Cache, "replacement: replacing %#llx (%s) with %#llx "
1680 "(%s): %s\n", repl_addr, blk->isSecure() ? "s" : "ns",
1681 addr, is_secure ? "s" : "ns",
1682 blk->isDirty() ? "writeback" : "clean");
1683
1684 if (blk->wasPrefetched()) {
1685 unusedPrefetches++;

--- 35 unchanged lines hidden (view full) ---

1721#if TRACING_ON
1722 CacheBlk::State old_state = blk ? blk->status : 0;
1723#endif
1724
1725 // When handling a fill, we should have no writes to this line.
1726 assert(addr == blockAlign(addr));
1727 assert(!writeBuffer.findMatch(addr, is_secure));
1728
1678 } else {
1679 DPRINTF(Cache, "replacement: replacing %#llx (%s) with %#llx "
1680 "(%s): %s\n", repl_addr, blk->isSecure() ? "s" : "ns",
1681 addr, is_secure ? "s" : "ns",
1682 blk->isDirty() ? "writeback" : "clean");
1683
1684 if (blk->wasPrefetched()) {
1685 unusedPrefetches++;

--- 35 unchanged lines hidden (view full) ---

1721#if TRACING_ON
1722 CacheBlk::State old_state = blk ? blk->status : 0;
1723#endif
1724
1725 // When handling a fill, we should have no writes to this line.
1726 assert(addr == blockAlign(addr));
1727 assert(!writeBuffer.findMatch(addr, is_secure));
1728
1729 if (blk == NULL) {
1729 if (blk == nullptr) {
1730 // better have read new data...
1731 assert(pkt->hasData());
1732
1733 // only read responses and write-line requests have data;
1734 // note that we don't write the data here for write-line - that
1735 // happens in the subsequent satisfyCpuSideRequest.
1736 assert(pkt->isRead() || pkt->cmd == MemCmd::WriteLineReq);
1737
1738 // need to do a replacement if allocating, otherwise we stick
1739 // with the temporary storage
1730 // better have read new data...
1731 assert(pkt->hasData());
1732
1733 // only read responses and write-line requests have data;
1734 // note that we don't write the data here for write-line - that
1735 // happens in the subsequent satisfyCpuSideRequest.
1736 assert(pkt->isRead() || pkt->cmd == MemCmd::WriteLineReq);
1737
1738 // need to do a replacement if allocating, otherwise we stick
1739 // with the temporary storage
1740 blk = allocate ? allocateBlock(addr, is_secure, writebacks) : NULL;
1740 blk = allocate ? allocateBlock(addr, is_secure, writebacks) : nullptr;
1741
1741
1742 if (blk == NULL) {
1742 if (blk == nullptr) {
1743 // No replaceable block or a mostly exclusive
1744 // cache... just use temporary storage to complete the
1745 // current request and then get rid of it
1746 assert(!tempBlock->isValid());
1747 blk = tempBlock;
1748 tempBlock->set = tags->extractSet(addr);
1749 tempBlock->tag = tags->extractTag(addr);
1750 // @todo: set security state as well...

--- 553 unchanged lines hidden (view full) ---

2304 // of the block.
2305 if (is_timing) {
2306 Packet snoop_pkt(pkt, true, false);
2307 snoop_pkt.setExpressSnoop();
2308 // Assert that packet is either Writeback or CleanEvict and not a
2309 // prefetch request because prefetch requests need an MSHR and may
2310 // generate a snoop response.
2311 assert(pkt->isEviction());
1743 // No replaceable block or a mostly exclusive
1744 // cache... just use temporary storage to complete the
1745 // current request and then get rid of it
1746 assert(!tempBlock->isValid());
1747 blk = tempBlock;
1748 tempBlock->set = tags->extractSet(addr);
1749 tempBlock->tag = tags->extractTag(addr);
1750 // @todo: set security state as well...

--- 553 unchanged lines hidden (view full) ---

2304 // of the block.
2305 if (is_timing) {
2306 Packet snoop_pkt(pkt, true, false);
2307 snoop_pkt.setExpressSnoop();
2308 // Assert that packet is either Writeback or CleanEvict and not a
2309 // prefetch request because prefetch requests need an MSHR and may
2310 // generate a snoop response.
2311 assert(pkt->isEviction());
2312 snoop_pkt.senderState = NULL;
2312 snoop_pkt.senderState = nullptr;
2313 cpuSidePort->sendTimingSnoopReq(&snoop_pkt);
2314 // Writeback/CleanEvict snoops do not generate a snoop response.
2315 assert(!(snoop_pkt.cacheResponding()));
2316 return snoop_pkt.isBlockCached();
2317 } else {
2318 cpuSidePort->sendAtomicSnoop(pkt);
2319 return pkt->isBlockCached();
2320 }

--- 27 unchanged lines hidden (view full) ---

2348 tgt_pkt->cmdString(), tgt_pkt->getAddr(),
2349 tgt_pkt->getSize());
2350
2351 CacheBlk *blk = tags->findBlock(mshr->blkAddr, mshr->isSecure);
2352
2353 if (tgt_pkt->cmd == MemCmd::HardPFReq && forwardSnoops) {
2354 // we should never have hardware prefetches to allocated
2355 // blocks
2313 cpuSidePort->sendTimingSnoopReq(&snoop_pkt);
2314 // Writeback/CleanEvict snoops do not generate a snoop response.
2315 assert(!(snoop_pkt.cacheResponding()));
2316 return snoop_pkt.isBlockCached();
2317 } else {
2318 cpuSidePort->sendAtomicSnoop(pkt);
2319 return pkt->isBlockCached();
2320 }

--- 27 unchanged lines hidden (view full) ---

2348 tgt_pkt->cmdString(), tgt_pkt->getAddr(),
2349 tgt_pkt->getSize());
2350
2351 CacheBlk *blk = tags->findBlock(mshr->blkAddr, mshr->isSecure);
2352
2353 if (tgt_pkt->cmd == MemCmd::HardPFReq && forwardSnoops) {
2354 // we should never have hardware prefetches to allocated
2355 // blocks
2356 assert(blk == NULL);
2356 assert(blk == nullptr);
2357
2358 // We need to check the caches above us to verify that
2359 // they don't have a copy of this block in the dirty state
2360 // at the moment. Without this check we could get a stale
2361 // copy from memory that might get used in place of the
2362 // dirty one.
2363 Packet snoop_pkt(tgt_pkt, true, false);
2364 snoop_pkt.setExpressSnoop();

--- 45 unchanged lines hidden (view full) ---

2410 return false;
2411 }
2412 }
2413
2414 // either a prefetch that is not present upstream, or a normal
2415 // MSHR request, proceed to get the packet to send downstream
2416 PacketPtr pkt = createMissPacket(tgt_pkt, blk, mshr->needsWritable());
2417
2357
2358 // We need to check the caches above us to verify that
2359 // they don't have a copy of this block in the dirty state
2360 // at the moment. Without this check we could get a stale
2361 // copy from memory that might get used in place of the
2362 // dirty one.
2363 Packet snoop_pkt(tgt_pkt, true, false);
2364 snoop_pkt.setExpressSnoop();

--- 45 unchanged lines hidden (view full) ---

2410 return false;
2411 }
2412 }
2413
2414 // either a prefetch that is not present upstream, or a normal
2415 // MSHR request, proceed to get the packet to send downstream
2416 PacketPtr pkt = createMissPacket(tgt_pkt, blk, mshr->needsWritable());
2417
2418 mshr->isForward = (pkt == NULL);
2418 mshr->isForward = (pkt == nullptr);
2419
2420 if (mshr->isForward) {
2421 // not a cache block request, but a response is expected
2422 // make copy of current packet to forward, keep current
2423 // copy for response handling
2424 pkt = new Packet(tgt_pkt, false, true);
2425 assert(!pkt->isWrite());
2426 }

--- 236 unchanged lines hidden ---
2419
2420 if (mshr->isForward) {
2421 // not a cache block request, but a response is expected
2422 // make copy of current packet to forward, keep current
2423 // copy for response handling
2424 pkt = new Packet(tgt_pkt, false, true);
2425 assert(!pkt->isWrite());
2426 }

--- 236 unchanged lines hidden ---