/*
- * Copyright (c) 2010-2018 ARM Limited
+ * Copyright (c) 2010-2019 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
tgt_pkt->setData(pkt->getConstPtr<uint8_t>());
}
+
+ // this response did not allocate here and therefore
+ // it was not consumed, make sure that any flags are
+ // carried over to cache above
+ tgt_pkt->copyResponderFlags(pkt);
}
tgt_pkt->makeTimingResponse();
// if this packet is an error copy that to the new packet
// first propagate snoop upward to see if anyone above us wants to
// handle it. save & restore packet src since it will get
// rewritten to be relative to cpu-side bus (if any)
- bool alreadyResponded = pkt->cacheResponding();
if (is_timing) {
// copy the packet so that we can clear any flags before
// forwarding it upwards, we also allocate data (passing
// cache
snoop_delay += snoopPkt.headerDelay;
- if (snoopPkt.cacheResponding()) {
- // cache-to-cache response from some upper cache
- assert(!alreadyResponded);
- pkt->setCacheResponding();
- }
- // upstream cache has the block, or has an outstanding
- // MSHR, pass the flag on
- if (snoopPkt.hasSharers()) {
- pkt->setHasSharers();
- }
// If this request is a prefetch or clean evict and an upper level
// signals block present, make sure to propagate the block
// presence to the requester.
if (snoopPkt.satisfied()) {
pkt->setSatisfied();
}
+
+ // Copy over flags from the snoop response to make sure we
+ // inform the final destination
+ pkt->copyResponderFlags(&snoopPkt);
} else {
+ bool already_responded = pkt->cacheResponding();
cpuSidePort.sendAtomicSnoop(pkt);
- if (!alreadyResponded && pkt->cacheResponding()) {
+ if (!already_responded && pkt->cacheResponding()) {
// cache-to-cache response from some upper cache:
// forward response to original requester
assert(pkt->isResponse());
/*
- * Copyright (c) 2011-2018 ARM Limited
+ * Copyright (c) 2011-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
return false;
}
+void
+Packet::copyResponderFlags(const PacketPtr pkt)
+{
+ assert(isRequest());
+ // If we have already found a responder, no other cache should
+ // commit to responding
+ assert(!pkt->cacheResponding() || !cacheResponding());
+ flags.set(pkt->flags & RESPONDER_FLAGS);
+}
+
void
Packet::pushSenderState(Packet::SenderState *sender_state)
{
/*
- * Copyright (c) 2012-2018 ARM Limited
+ * Copyright (c) 2012-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
// Flags to transfer across when copying a packet
COPY_FLAGS = 0x0000003F,
+ // Flags that are used to create reponse packets
+ RESPONDER_FLAGS = 0x00000009,
+
// Does this packet have sharers (which means it should not be
// considered writable) or not. See setHasSharers below.
HAS_SHARERS = 0x00000001,
bool responderHadWritable() const
{ return flags.isSet(RESPONDER_HAD_WRITABLE); }
+ /**
+ * Copy the reponse flags from an input packet to this packet. The
+ * reponse flags determine whether a responder has been found and
+ * the state at which the block will be at the destination.
+ *
+ * @pkt The packet that we will copy flags from
+ */
+ void copyResponderFlags(const PacketPtr pkt);
+
/**
* A writeback/writeclean cmd gets propagated further downstream
* by the receiver when the flag is set.