summaryrefslogtreecommitdiff
path: root/src/mem/coherent_bus.cc
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2013-05-30 12:54:00 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2013-05-30 12:54:00 -0400
commite82996d9dad5ac38fe2c8709c05b26cf92d356e8 (patch)
tree0d71e4381030dce2e0bfdc15f2f379d572542825 /src/mem/coherent_bus.cc
parentcb62d39835f4764562e74b0e113437e76e8949ff (diff)
downloadgem5-e82996d9dad5ac38fe2c8709c05b26cf92d356e8.tar.xz
mem: Separate the two snoop response cases in the bus
This patch makes the flow control and state updates of the coherent bus more clear by separating the two cases, i.e. forward as a snoop response, or turn it into a normal response. With this change it is also more clear what resources are being occupied, and that we effectively bypass the busy check for the second case. As a result of the change in resource usage some stats change.
Diffstat (limited to 'src/mem/coherent_bus.cc')
-rw-r--r--src/mem/coherent_bus.cc49
1 files changed, 29 insertions, 20 deletions
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;