-bool
-Bus::recvTimingSnoop(PacketPtr pkt)
-{
- // get the source id
- Packet::NodeID src_id = pkt->getSrc();
-
- if (pkt->isRequest()) {
- DPRINTF(Bus, "recvTimingSnoop: src %d %s 0x%x\n",
- src_id, pkt->cmdString(), pkt->getAddr());
-
- // the packet is an express snoop request and should be
- // broadcasted to our snoopers
- assert(pkt->isExpressSnoop());
-
- // forward to all snoopers
- forwardTiming(pkt, Port::INVALID_PORT_ID);
-
- // a snoop request came from a connected slave device (one of
- // our master ports), and if it is not coming from the slave
- // device responsible for the address range something is
- // wrong, hence there is nothing further to do as the packet
- // would be going back to where it came from
- assert(src_id == findPort(pkt->getAddr()));
-
- // this is an express snoop and is never forced to retry
- assert(!inRetry);
-
- return true;
- } else {
- // determine the source port based on the id
- SlavePort* src_port = slavePorts[src_id];
-
- if (isOccupied(pkt, src_port)) {
- DPRINTF(Bus, "recvTimingSnoop: src %s %s 0x%x BUSY\n",
- src_port->name(), pkt->cmdString(), pkt->getAddr());
- return false;
- }
-
- DPRINTF(Bus, "recvTimingSnoop: src %s %s 0x%x\n",
- src_port->name(), pkt->cmdString(), pkt->getAddr());
-
- // get the destination from the packet
- Packet::NodeID dest = pkt->getDest();
-
- // responses are never express snoops
- assert(!pkt->isExpressSnoop());
-
- calcPacketTiming(pkt);
- Tick packetFinishTime = pkt->finishTime;
-
- // determine if the response is from a snoop request we
- // created as the result of a normal request (in which case it
- // should be in the outstandingReq), or if we merely forwarded
- // someone else's snoop request
- if (outstandingReq.find(pkt->req) == outstandingReq.end()) {
- // this is a snoop response to a snoop request we
- // forwarded, e.g. coming from the L1 and going to the L2
- // this should be forwarded as a snoop response
- bool success M5_VAR_USED = masterPorts[dest]->sendTimingSnoop(pkt);
- assert(success);
- } else {
- // we got a snoop response on one of our slave ports,
- // i.e. from a coherent master connected to the bus, and
- // since we created the snoop request as part of
- // recvTiming, this should now be a normal response again
- outstandingReq.erase(pkt->req);
-
- // this is a snoop response from a coherent master, with a
- // destination field set on its way through the bus as
- // request, hence it should never go back to where the
- // snoop response came from, but instead to where the
- // original request came from
- assert(src_id != dest);
-
- // as a normal response, it should go back to a master
- // through one of our slave ports
- bool success M5_VAR_USED = slavePorts[dest]->sendTiming(pkt);
-
- // currently it is illegal to block responses... can lead
- // to deadlock
- assert(success);
- }
-
- succeededTiming(packetFinishTime);
-
- return true;
- }
-}
-