summaryrefslogtreecommitdiff
path: root/src/mem/noncoherent_bus.cc
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2013-03-26 14:46:47 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2013-03-26 14:46:47 -0400
commit93a8423dea8f8194d83df85a5b3043f9beaf0a1e (patch)
treeec1ea615c270a0e8524d4bc3ab442781a0c4f043 /src/mem/noncoherent_bus.cc
parent362f6f1a16a68a99c962628bcda00c7c576f935c (diff)
downloadgem5-93a8423dea8f8194d83df85a5b3043f9beaf0a1e.tar.xz
mem: Separate waiting for the bus and waiting for a peer
This patch splits the retryList into a list of ports that are waiting for the bus itself to become available, and a map that tracks the ports where forwarding failed due to a peer not accepting the packet. Thus, when a retry reaches the bus, it can be sent to the appropriate port that initiated that transaction. As a consequence of this patch, only ports that are really ready to go will get a retry, thus reducing the amount of redundant failed attempts. This patch also makes it easier to reason about the order of servicing requests as the ports waiting for the bus are now clearly FIFO and much easier to change if desired.
Diffstat (limited to 'src/mem/noncoherent_bus.cc')
-rw-r--r--src/mem/noncoherent_bus.cc25
1 files changed, 15 insertions, 10 deletions
diff --git a/src/mem/noncoherent_bus.cc b/src/mem/noncoherent_bus.cc
index f0955bb8f..f6c315297 100644
--- a/src/mem/noncoherent_bus.cc
+++ b/src/mem/noncoherent_bus.cc
@@ -55,8 +55,10 @@
#include "mem/noncoherent_bus.hh"
NoncoherentBus::NoncoherentBus(const NoncoherentBusParams *p)
- : BaseBus(p), reqLayer(*this, ".reqLayer"),
- respLayer(*this, ".respLayer")
+ : BaseBus(p),
+ reqLayer(*this, ".reqLayer", p->port_master_connection_count +
+ p->port_default_connection_count),
+ respLayer(*this, ".respLayer", p->port_slave_connection_count)
{
// create the ports based on the size of the master and slave
// vector ports, and the presence of the default port, the ports
@@ -96,9 +98,12 @@ NoncoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
// we should never see express snoops on a non-coherent bus
assert(!pkt->isExpressSnoop());
+ // determine the destination based on the address
+ PortID dest_port_id = findPort(pkt->getAddr());
+
// test if the bus should be considered occupied for the current
// port
- if (!reqLayer.tryTiming(src_port)) {
+ if (!reqLayer.tryTiming(src_port, dest_port_id)) {
DPRINTF(NoncoherentBus, "recvTimingReq: src %s %s 0x%x BUSY\n",
src_port->name(), pkt->cmdString(), pkt->getAddr());
return false;
@@ -113,9 +118,8 @@ NoncoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
calcPacketTiming(pkt);
Tick packetFinishTime = pkt->busLastWordDelay + curTick();
- // since it is a normal request, determine the destination
- // based on the address and attempt to send the packet
- bool success = masterPorts[findPort(pkt->getAddr())]->sendTimingReq(pkt);
+ // since it is a normal request, attempt to send the packet
+ bool success = masterPorts[dest_port_id]->sendTimingReq(pkt);
if (!success) {
// inhibited packets should never be forced to retry
@@ -128,7 +132,8 @@ NoncoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
pkt->busFirstWordDelay = pkt->busLastWordDelay = 0;
// occupy until the header is sent
- reqLayer.failedTiming(src_port, clockEdge(Cycles(headerCycles)));
+ reqLayer.failedTiming(src_port, dest_port_id,
+ clockEdge(Cycles(headerCycles)));
return false;
}
@@ -146,7 +151,7 @@ NoncoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id)
// test if the bus should be considered occupied for the current
// port
- if (!respLayer.tryTiming(src_port)) {
+ if (!respLayer.tryTiming(src_port, pkt->getDest())) {
DPRINTF(NoncoherentBus, "recvTimingResp: src %s %s 0x%x BUSY\n",
src_port->name(), pkt->cmdString(), pkt->getAddr());
return false;
@@ -172,12 +177,12 @@ NoncoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id)
}
void
-NoncoherentBus::recvRetry()
+NoncoherentBus::recvRetry(PortID master_port_id)
{
// responses never block on forwarding them, so the retry will
// always be coming from a port to which we tried to forward a
// request
- reqLayer.recvRetry();
+ reqLayer.recvRetry(master_port_id);
}
Tick