summaryrefslogtreecommitdiff
path: root/src/mem/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/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/bus.cc')
-rw-r--r--src/mem/bus.cc43
1 files changed, 24 insertions, 19 deletions
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index a2ddc0b69..16b581a7e 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -55,9 +55,8 @@
#include "mem/bus.hh"
BaseBus::BaseBus(const BaseBusParams *p)
- : MemObject(p), state(IDLE), clock(p->clock),
+ : MemObject(p), clock(p->clock),
headerCycles(p->header_cycles), width(p->width),
- drainEvent(NULL), busIdleEvent(this),
defaultPortID(InvalidPortID),
useDefaultRange(p->use_default_range),
defaultBlockSize(p->block_size),
@@ -138,7 +137,13 @@ BaseBus::calcPacketTiming(PacketPtr pkt)
return headerTime;
}
-void BaseBus::occupyBus(Tick until)
+BaseBus::Layer::Layer(BaseBus& _bus, const std::string& _name, Tick _clock) :
+ bus(_bus), _name(_name), state(IDLE), clock(_clock), drainEvent(NULL),
+ releaseEvent(this)
+{
+}
+
+void BaseBus::Layer::occupyLayer(Tick until)
{
// ensure the state is busy or in retry and never idle at this
// point, as the bus should transition from idle as soon as it has
@@ -153,14 +158,14 @@ void BaseBus::occupyBus(Tick until)
// until should never be 0 as express snoops never occupy the bus
assert(until != 0);
- schedule(busIdleEvent, until);
+ bus.schedule(releaseEvent, until);
DPRINTF(BaseBus, "The bus is now busy from tick %d to %d\n",
curTick(), until);
}
bool
-BaseBus::tryTiming(Port* port)
+BaseBus::Layer::tryTiming(Port* port)
{
// first we see if the bus is busy, next we check if we are in a
// retry with a port other than the current one
@@ -180,7 +185,7 @@ BaseBus::tryTiming(Port* port)
}
void
-BaseBus::succeededTiming(Tick busy_time)
+BaseBus::Layer::succeededTiming(Tick busy_time)
{
// if a retrying port succeeded, also take it off the retry list
if (state == RETRY) {
@@ -195,11 +200,11 @@ BaseBus::succeededTiming(Tick busy_time)
assert(state == BUSY);
// occupy the bus accordingly
- occupyBus(busy_time);
+ occupyLayer(busy_time);
}
void
-BaseBus::failedTiming(SlavePort* port, Tick busy_time)
+BaseBus::Layer::failedTiming(SlavePort* port, Tick busy_time)
{
// if we are not in a retry, i.e. busy (but never idle), or we are
// in a retry but not for the current port, then add the port at
@@ -213,15 +218,15 @@ BaseBus::failedTiming(SlavePort* port, Tick busy_time)
state = BUSY;
// occupy the bus accordingly
- occupyBus(busy_time);
+ occupyLayer(busy_time);
}
void
-BaseBus::releaseBus()
+BaseBus::Layer::releaseLayer()
{
// releasing the bus means we should now be idle
assert(state == BUSY);
- assert(!busIdleEvent.scheduled());
+ assert(!releaseEvent.scheduled());
// update the state
state = IDLE;
@@ -242,7 +247,7 @@ BaseBus::releaseBus()
}
void
-BaseBus::retryWaiting()
+BaseBus::Layer::retryWaiting()
{
// this should never be called with an empty retry list
assert(!retryList.empty());
@@ -277,23 +282,23 @@ BaseBus::retryWaiting()
// clock edge
Tick now = divCeil(curTick(), clock) * clock;
- occupyBus(now + clock);
+ occupyLayer(now + clock);
}
}
void
-BaseBus::recvRetry()
+BaseBus::Layer::recvRetry()
{
// we got a retry from a peer that we tried to send something to
// and failed, but we sent it on the account of someone else, and
// that source port should be on our retry list, however if the
- // bus is released before this happens and the retry (from the bus
- // point of view) is successful then this no longer holds and we
- // could in fact have an empty retry list
+ // bus layer is released before this happens and the retry (from
+ // the bus point of view) is successful then this no longer holds
+ // and we could in fact have an empty retry list
if (retryList.empty())
return;
- // if the bus is idle
+ // if the bus layer is idle
if (state == IDLE) {
// note that we do not care who told us to retry at the moment, we
// merely let the first one on the retry list go
@@ -481,7 +486,7 @@ BaseBus::findBlockSize()
unsigned int
-BaseBus::drain(Event * de)
+BaseBus::Layer::drain(Event * de)
{
//We should check that we're not "doing" anything, and that noone is
//waiting. We might be idle but have someone waiting if the device we