diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mem/bus.cc | 3 | ||||
-rw-r--r-- | src/mem/bus.hh | 3 | ||||
-rw-r--r-- | src/mem/coherent_bus.cc | 49 |
3 files changed, 31 insertions, 24 deletions
diff --git a/src/mem/bus.cc b/src/mem/bus.cc index 8e74212e0..3fa7c7231 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -195,8 +195,7 @@ BaseBus::Layer<PortClass>::tryTiming(PortClass* port, PortID dest_port_id) // if the destination port is already engaged in a transaction // waiting for a retry from the peer if (state == BUSY || (state == RETRY && port != retryingPort) || - (dest_port_id != InvalidPortID && - waitingForPeer[dest_port_id] != NULL)) { + waitingForPeer[dest_port_id] != NULL) { // put the port at the end of the retry list waiting for the // layer to be freed up (and in the case of a busy peer, for // that transaction to go through, and then the bus to free diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 5e9023c89..079d6a08d 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -130,8 +130,7 @@ class BaseBus : public MemObject * Determine if the bus layer accepts a packet from a specific * port. If not, the port in question is also added to the * retry list. In either case the state of the layer is - * updated accordingly. To ignore checking the destination - * port (used by snoops), pass InvalidPortID. + * updated accordingly. * * @param port Source port presenting the packet * @param dest_port_id Destination port id diff --git a/src/mem/coherent_bus.cc b/src/mem/coherent_bus.cc index aa0f2797d..923fa08d6 100644 --- a/src/mem/coherent_bus.cc +++ b/src/mem/coherent_bus.cc @@ -304,17 +304,27 @@ CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id) // determine the source port based on the id SlavePort* src_port = slavePorts[slave_port_id]; + // get the destination from the packet + PortID dest_port_id = pkt->getDest(); + + // 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 + bool forwardAsSnoop = outstandingReq.find(pkt->req) == + outstandingReq.end(); + // test if the bus should be considered occupied for the current - // port, do not use the destination port in the check as we do not - // know yet if it is to be passed on as a snoop response or normal - // response and we never block on either - if (!snoopRespLayer.tryTiming(src_port, InvalidPortID)) { + // port, note that the check is bypassed if the response is being + // passed on as a normal response since this is occupying the + // response layer rather than the snoop response layer + if (forwardAsSnoop && !snoopRespLayer.tryTiming(src_port, dest_port_id)) { DPRINTF(CoherentBus, "recvTimingSnoopResp: src %s %s 0x%x BUSY\n", src_port->name(), pkt->cmdString(), pkt->getAddr()); return false; } - DPRINTF(CoherentBus, "recvTimingSnoop: src %s %s 0x%x\n", + DPRINTF(CoherentBus, "recvTimingSnoopResp: src %s %s 0x%x\n", src_port->name(), pkt->cmdString(), pkt->getAddr()); // store size and command as they might be modified when @@ -322,28 +332,24 @@ CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id) unsigned int pkt_size = pkt->hasData() ? pkt->getSize() : 0; unsigned int pkt_cmd = pkt->cmdToIndex(); - // get the destination from the packet - PortID dest_port_id = pkt->getDest(); - // responses are never express snoops assert(!pkt->isExpressSnoop()); calcPacketTiming(pkt); Tick packetFinishTime = pkt->busLastWordDelay + curTick(); - // 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 + // forward it either as a snoop response or a normal response + if (forwardAsSnoop) { + // this is a snoop response to a snoop request we forwarded, + // e.g. coming from the L1 and going to the L2, and it should + // be forwarded as a snoop response bool success M5_VAR_USED = masterPorts[dest_port_id]->sendTimingSnoopResp(pkt); pktCount[slave_port_id][dest_port_id]++; totPktSize[slave_port_id][dest_port_id] += pkt_size; assert(success); + + snoopRespLayer.succeededTiming(packetFinishTime); } else { // we got a snoop response on one of our slave ports, // i.e. from a coherent master connected to the bus, and @@ -358,18 +364,21 @@ CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id) // original request came from assert(slave_port_id != dest_port_id); - // as a normal response, it should go back to a master - // through one of our slave ports + // as a normal response, it should go back to a master through + // one of our slave ports, at this point we are ignoring the + // fact that the response layer could be busy and do not touch + // its state bool success M5_VAR_USED = slavePorts[dest_port_id]->sendTimingResp(pkt); + // @todo Put the response in an internal FIFO and pass it on + // to the response layer from there + // currently it is illegal to block responses... can lead // to deadlock assert(success); } - snoopRespLayer.succeededTiming(packetFinishTime); - // stats updates transDist[pkt_cmd]++; snoopDataThroughBus += pkt_size; |