summaryrefslogtreecommitdiff
path: root/src/mem/bus.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/bus.cc')
-rw-r--r--src/mem/bus.cc81
1 files changed, 39 insertions, 42 deletions
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index 3fa7c7231..855f82db4 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -156,18 +156,17 @@ BaseBus::calcPacketTiming(PacketPtr pkt)
offset;
}
-template <typename PortClass>
-BaseBus::Layer<PortClass>::Layer(BaseBus& _bus, const std::string& _name,
- uint16_t num_dest_ports) :
- Drainable(),
- bus(_bus), _name(_name), state(IDLE), drainManager(NULL),
- retryingPort(NULL), waitingForPeer(num_dest_ports, NULL),
+template <typename SrcType, typename DstType>
+BaseBus::Layer<SrcType,DstType>::Layer(DstType& _port, BaseBus& _bus,
+ const std::string& _name) :
+ port(_port), bus(_bus), _name(_name), state(IDLE), drainManager(NULL),
+ retryingPort(NULL), waitingForPeer(NULL),
releaseEvent(this)
{
}
-template <typename PortClass>
-void BaseBus::Layer<PortClass>::occupyLayer(Tick until)
+template <typename SrcType, typename DstType>
+void BaseBus::Layer<SrcType,DstType>::occupyLayer(Tick until)
{
// ensure the state is busy at this point, as the bus should
// transition from idle as soon as it has decided to forward the
@@ -186,21 +185,21 @@ void BaseBus::Layer<PortClass>::occupyLayer(Tick until)
curTick(), until);
}
-template <typename PortClass>
+template <typename SrcType, typename DstType>
bool
-BaseBus::Layer<PortClass>::tryTiming(PortClass* port, PortID dest_port_id)
+BaseBus::Layer<SrcType,DstType>::tryTiming(SrcType* src_port)
{
- // first we see if the bus is busy, next we check if we are in a
+ // first we see if the layer is busy, next we check if we are in a
// retry with a port other than the current one, lastly we check
// if the destination port is already engaged in a transaction
// waiting for a retry from the peer
- if (state == BUSY || (state == RETRY && port != retryingPort) ||
- waitingForPeer[dest_port_id] != NULL) {
+ if (state == BUSY || (state == RETRY && src_port != retryingPort) ||
+ waitingForPeer != 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
// up)
- waitingForLayer.push_back(port);
+ waitingForLayer.push_back(src_port);
return false;
}
@@ -213,9 +212,9 @@ BaseBus::Layer<PortClass>::tryTiming(PortClass* port, PortID dest_port_id)
return true;
}
-template <typename PortClass>
+template <typename SrcType, typename DstType>
void
-BaseBus::Layer<PortClass>::succeededTiming(Tick busy_time)
+BaseBus::Layer<SrcType,DstType>::succeededTiming(Tick busy_time)
{
// we should have gone from idle or retry to busy in the tryTiming
// test
@@ -225,19 +224,19 @@ BaseBus::Layer<PortClass>::succeededTiming(Tick busy_time)
occupyLayer(busy_time);
}
-template <typename PortClass>
+template <typename SrcType, typename DstType>
void
-BaseBus::Layer<PortClass>::failedTiming(PortClass* src_port,
- PortID dest_port_id, Tick busy_time)
+BaseBus::Layer<SrcType,DstType>::failedTiming(SrcType* src_port,
+ Tick busy_time)
{
// ensure no one got in between and tried to send something to
// this port
- assert(waitingForPeer[dest_port_id] == NULL);
+ assert(waitingForPeer == NULL);
// if the source port is the current retrying one or not, we have
// failed in forwarding and should track that we are now waiting
// for the peer to send a retry
- waitingForPeer[dest_port_id] = src_port;
+ waitingForPeer = src_port;
// we should have gone from idle or retry to busy in the tryTiming
// test
@@ -247,9 +246,9 @@ BaseBus::Layer<PortClass>::failedTiming(PortClass* src_port,
occupyLayer(busy_time);
}
-template <typename PortClass>
+template <typename SrcType, typename DstType>
void
-BaseBus::Layer<PortClass>::releaseLayer()
+BaseBus::Layer<SrcType,DstType>::releaseLayer()
{
// releasing the bus means we should now be idle
assert(state == BUSY);
@@ -270,9 +269,9 @@ BaseBus::Layer<PortClass>::releaseLayer()
}
}
-template <typename PortClass>
+template <typename SrcType, typename DstType>
void
-BaseBus::Layer<PortClass>::retryWaiting()
+BaseBus::Layer<SrcType,DstType>::retryWaiting()
{
// this should never be called with no one waiting
assert(!waitingForLayer.empty());
@@ -306,23 +305,21 @@ BaseBus::Layer<PortClass>::retryWaiting()
}
}
-template <typename PortClass>
+template <typename SrcType, typename DstType>
void
-BaseBus::Layer<PortClass>::recvRetry(PortID port_id)
+BaseBus::Layer<SrcType,DstType>::recvRetry()
{
// we should never get a retry without having failed to forward
// something to this port
- assert(waitingForPeer[port_id] != NULL);
+ assert(waitingForPeer != NULL);
- // find the port where the failed packet originated and remove the
- // item from the waiting list
- PortClass* retry_port = waitingForPeer[port_id];
- waitingForPeer[port_id] = NULL;
+ // add the port where the failed packet originated to the front of
+ // the waiting ports for the layer, this allows us to call retry
+ // on the port immediately if the bus layer is idle
+ waitingForLayer.push_front(waitingForPeer);
- // add this port at the front of the waiting ports for the layer,
- // this allows us to call retry on the port immediately if the bus
- // layer is idle
- waitingForLayer.push_front(retry_port);
+ // we are no longer waiting for the peer
+ waitingForPeer = NULL;
// if the bus layer is idle, retry this port straight away, if we
// are busy, then simply let the port wait for its turn
@@ -606,9 +603,9 @@ BaseBus::regStats()
}
}
-template <typename PortClass>
+template <typename SrcType, typename DstType>
unsigned int
-BaseBus::Layer<PortClass>::drain(DrainManager *dm)
+BaseBus::Layer<SrcType,DstType>::drain(DrainManager *dm)
{
//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
@@ -621,9 +618,9 @@ BaseBus::Layer<PortClass>::drain(DrainManager *dm)
return 0;
}
-template <typename PortClass>
+template <typename SrcType, typename DstType>
void
-BaseBus::Layer<PortClass>::regStats()
+BaseBus::Layer<SrcType,DstType>::regStats()
{
using namespace Stats;
@@ -646,5 +643,5 @@ BaseBus::Layer<PortClass>::regStats()
* file, but since there are only two given options (MasterPort and
* SlavePort) it seems a bit excessive at this point.
*/
-template class BaseBus::Layer<SlavePort>;
-template class BaseBus::Layer<MasterPort>;
+template class BaseBus::Layer<SlavePort,MasterPort>;
+template class BaseBus::Layer<MasterPort,SlavePort>;