diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc index 991463d76..9050a1c30 100644 --- a/src/mem/cache/cache.cc +++ b/src/mem/cache/cache.cc @@ -185,7 +185,11 @@ Cache::satisfyCpuSideRequest(PacketPtr pkt, CacheBlk *blk, if (pkt->isLLSC()) { blk->trackLoadLocked(pkt); } + + // all read responses have a data payload + assert(pkt->hasRespData()); pkt->setDataFromBlock(blk->data, blkSize); + // determine if this read is from a (coherent) cache, or not // by looking at the command type; we could potentially add a // packet attribute such as 'FromCache' to make this check a @@ -796,10 +800,7 @@ Cache::recvTimingReq(PacketPtr pkt) } pkt->makeTimingResponse(); - // for debugging, set all the bits in the response data - // (also keeps valgrind from complaining when debugging settings - // print out instruction results) - std::memset(pkt->getPtr(), 0xFF, pkt->getSize()); + // request_time is used here, taking into account lat and the delay // charged if the packet comes from the xbar. cpuSidePort->schedTimingResp(pkt, request_time, true); @@ -2041,7 +2042,10 @@ Cache::handleSnoop(PacketPtr pkt, CacheBlk *blk, bool is_timing, doTimingSupplyResponse(pkt, blk->data, is_deferred, pending_inval); } else { pkt->makeAtomicResponse(); - pkt->setDataFromBlock(blk->data, blkSize); + // packets such as upgrades do not actually have any data + // payload + if (pkt->hasData()) + pkt->setDataFromBlock(blk->data, blkSize); } } diff --git a/src/mem/cache/mshr.cc b/src/mem/cache/mshr.cc index e2141a429..1d18a2861 100644 --- a/src/mem/cache/mshr.cc +++ b/src/mem/cache/mshr.cc @@ -115,6 +115,9 @@ MSHR::TargetList::add(PacketPtr pkt, Tick readyTime, static void replaceUpgrade(PacketPtr pkt) { + // remember if the current packet has data allocated + bool has_data = pkt->hasData() || pkt->hasRespData(); + if (pkt->cmd == MemCmd::UpgradeReq) { pkt->cmd = MemCmd::ReadExReq; DPRINTF(Cache, "Replacing UpgradeReq with ReadExReq\n"); @@ -125,6 +128,19 @@ replaceUpgrade(PacketPtr pkt) pkt->cmd = MemCmd::StoreCondFailReq; DPRINTF(Cache, "Replacing StoreCondReq with StoreCondFailReq\n"); } + + if (!has_data) { + // there is no sensible way of setting the data field if the + // new command actually would carry data + assert(!pkt->hasData()); + + if (pkt->hasRespData()) { + // we went from a packet that had no data (neither request, + // nor response), to one that does, and therefore we need to + // actually allocate space for the data payload + pkt->allocate(); + } + } } diff --git a/src/mem/packet.hh b/src/mem/packet.hh index 4614799bf..94508f697 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -508,6 +508,11 @@ class Packet : public Printable bool isEviction() const { return cmd.isEviction(); } bool isWriteback() const { return cmd.isWriteback(); } bool hasData() const { return cmd.hasData(); } + bool hasRespData() const + { + MemCmd resp_cmd = cmd.responseCommand(); + return resp_cmd.hasData(); + } bool isLLSC() const { return cmd.isLLSC(); } bool isError() const { return cmd.isError(); } bool isPrint() const { return cmd.isPrint(); } @@ -1058,9 +1063,13 @@ class Packet : public Printable void allocate() { - assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA)); - flags.set(DYNAMIC_DATA); - data = new uint8_t[getSize()]; + // if either this command or the response command has a data + // payload, actually allocate space + if (hasData() || hasRespData()) { + assert(flags.noneSet(STATIC_DATA|DYNAMIC_DATA)); + flags.set(DYNAMIC_DATA); + data = new uint8_t[getSize()]; + } } /** @} */