summaryrefslogtreecommitdiff
path: root/src/mem/coherent_bus.cc
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2012-07-09 12:35:36 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2012-07-09 12:35:36 -0400
commit995e6e4670f52c52f798320055d74994e6539cda (patch)
treebd758d4a220f06412abe4a7484369b18ae1ea0be /src/mem/coherent_bus.cc
parent14f9c77dd36fef8ab509bc17ecbe422555daa9c6 (diff)
downloadgem5-995e6e4670f52c52f798320055d74994e6539cda.tar.xz
Bus: Add a notion of layers to the buses
This patch moves all flow control, arbitration and state information into a bus layer. The layer is thus responsible for all the state transitions, and for keeping hold of the retry list. Consequently the layer is also responsible for the draining. With this change, the non-coherent and coherent bus are given a single layer to avoid changing any temporal behaviour, but the patch opens up for adding more layers.
Diffstat (limited to 'src/mem/coherent_bus.cc')
-rw-r--r--src/mem/coherent_bus.cc30
1 files changed, 22 insertions, 8 deletions
diff --git a/src/mem/coherent_bus.cc b/src/mem/coherent_bus.cc
index f7d4b9d11..956654981 100644
--- a/src/mem/coherent_bus.cc
+++ b/src/mem/coherent_bus.cc
@@ -54,7 +54,7 @@
#include "mem/coherent_bus.hh"
CoherentBus::CoherentBus(const CoherentBusParams *p)
- : BaseBus(p)
+ : BaseBus(p), layer(*this, ".layer", p->clock)
{
// create the ports based on the size of the master and slave
// vector ports, and the presence of the default port, the ports
@@ -115,7 +115,7 @@ CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
// test if the bus should be considered occupied for the current
// port, and exclude express snoops from the check
- if (!is_express_snoop && !tryTiming(src_port)) {
+ if (!is_express_snoop && !layer.tryTiming(src_port)) {
DPRINTF(CoherentBus, "recvTimingReq: src %s %s 0x%x BUSY\n",
src_port->name(), pkt->cmdString(), pkt->getAddr());
return false;
@@ -176,10 +176,10 @@ CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
src_port->name(), pkt->cmdString(), pkt->getAddr());
// update the bus state and schedule an idle event
- failedTiming(src_port, headerFinishTime);
+ layer.failedTiming(src_port, headerFinishTime);
} else {
// update the bus state and schedule an idle event
- succeededTiming(packetFinishTime);
+ layer.succeededTiming(packetFinishTime);
}
}
@@ -194,7 +194,7 @@ CoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id)
// test if the bus should be considered occupied for the current
// port
- if (!tryTiming(src_port)) {
+ if (!layer.tryTiming(src_port)) {
DPRINTF(CoherentBus, "recvTimingResp: src %s %s 0x%x BUSY\n",
src_port->name(), pkt->cmdString(), pkt->getAddr());
return false;
@@ -221,7 +221,7 @@ CoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id)
// deadlock
assert(success);
- succeededTiming(packetFinishTime);
+ layer.succeededTiming(packetFinishTime);
return true;
}
@@ -258,7 +258,7 @@ CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id)
// test if the bus should be considered occupied for the current
// port
- if (!tryTiming(src_port)) {
+ if (!layer.tryTiming(src_port)) {
DPRINTF(CoherentBus, "recvTimingSnoopResp: src %s %s 0x%x BUSY\n",
src_port->name(), pkt->cmdString(), pkt->getAddr());
return false;
@@ -309,7 +309,7 @@ CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id)
assert(success);
}
- succeededTiming(packetFinishTime);
+ layer.succeededTiming(packetFinishTime);
return true;
}
@@ -332,6 +332,13 @@ CoherentBus::forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id)
}
}
+void
+CoherentBus::recvRetry()
+{
+ // only one layer that can deal with it
+ layer.recvRetry();
+}
+
Tick
CoherentBus::recvAtomic(PacketPtr pkt, PortID slave_port_id)
{
@@ -493,6 +500,13 @@ CoherentBus::forwardFunctional(PacketPtr pkt, PortID exclude_slave_port_id)
}
}
+unsigned int
+CoherentBus::drain(Event *de)
+{
+ // only one layer to worry about at the moment
+ return layer.drain(de);
+}
+
CoherentBus *
CoherentBusParams::create()
{