summaryrefslogtreecommitdiff
path: root/src/mem/tport.hh
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2012-03-22 06:36:27 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2012-03-22 06:36:27 -0400
commitc2d2ea99e3efe13bc50d410e2eeae9dd6757e57f (patch)
tree5836cc125091b436dee3fbc32ef26e1eeed49a6c /src/mem/tport.hh
parentfb395b56dd2432b862c550bad7b4bbe1f205ec59 (diff)
downloadgem5-c2d2ea99e3efe13bc50d410e2eeae9dd6757e57f.tar.xz
MEM: Split SimpleTimingPort into PacketQueue and ports
This patch decouples the queueing and the port interactions to simplify the introduction of the master and slave ports. By separating the queueing functionality from the port itself, it becomes much easier to distinguish between master and slave ports, and still retain the queueing ability for both (without code duplication). As part of the split into a PacketQueue and a port, there is now also a hierarchy of two port classes, QueuedPort and SimpleTimingPort. The QueuedPort is useful for ports that want to leave the packet transmission of outgoing packets to the queue and is used by both master and slave ports. The SimpleTimingPort inherits from the QueuedPort and adds the implemention of recvTiming and recvFunctional through recvAtomic. The PioPort and MessagePort are cleaned up as part of the changes. --HG-- rename : src/mem/tport.cc => src/mem/packet_queue.cc rename : src/mem/tport.hh => src/mem/packet_queue.hh
Diffstat (limited to 'src/mem/tport.hh')
-rw-r--r--src/mem/tport.hh160
1 files changed, 23 insertions, 137 deletions
diff --git a/src/mem/tport.hh b/src/mem/tport.hh
index d720f227c..c77166386 100644
--- a/src/mem/tport.hh
+++ b/src/mem/tport.hh
@@ -50,117 +50,20 @@
* Declaration of SimpleTimingPort.
*/
-#include <list>
-#include <string>
-
-#include "mem/port.hh"
-#include "sim/eventq.hh"
+#include "mem/qport.hh"
/**
- * A simple port for interfacing objects that basically have only
- * functional memory behavior (e.g. I/O devices) to the memory system.
- * Both timing and functional accesses are implemented in terms of
- * atomic accesses. A derived port class thus only needs to provide
- * recvAtomic() to support all memory access modes.
- *
- * The tricky part is handling recvTiming(), where the response must
- * be scheduled separately via a later call to sendTiming(). This
- * feature is handled by scheduling an internal event that calls
- * sendTiming() after a delay, and optionally rescheduling the
- * response if it is nacked.
+ * The simple timing port uses a queued port to implement
+ * recvFunctional and recvTiming through recvAtomic. It is always a
+ * slave port.
*/
-class SimpleTimingPort : public Port
+class SimpleTimingPort : public QueuedPort
{
- protected:
- /** A deferred packet, buffered to transmit later. */
- class DeferredPacket {
- public:
- Tick tick; ///< The tick when the packet is ready to transmit
- PacketPtr pkt; ///< Pointer to the packet to transmit
- DeferredPacket(Tick t, PacketPtr p)
- : tick(t), pkt(p)
- {}
- };
-
- typedef std::list<DeferredPacket> DeferredPacketList;
- typedef std::list<DeferredPacket>::iterator DeferredPacketIterator;
-
- /** A list of outgoing timing response packets that haven't been
- * serviced yet. */
- DeferredPacketList transmitList;
-
- /** Label to use for print request packets label stack. */
- const std::string label;
-
- /** This function attempts to send deferred packets. Scheduled to
- * be called in the future via SendEvent. */
- void processSendEvent();
-
- /**
- * This class is used to implemented sendTiming() with a delay. When
- * a delay is requested a the event is scheduled if it isn't already.
- * When the event time expires it attempts to send the packet.
- * If it cannot, the packet sent when recvRetry() is called.
- **/
- EventWrapper<SimpleTimingPort,
- &SimpleTimingPort::processSendEvent> sendEvent;
- /** If we need to drain, keep the drain event around until we're done
- * here.*/
- Event *drainEvent;
-
- /** Remember whether we're awaiting a retry from the bus. */
- bool waitingOnRetry;
-
- /** Check whether we have a packet ready to go on the transmit list. */
- bool deferredPacketReady()
- { return !transmitList.empty() && transmitList.front().tick <= curTick(); }
-
- Tick deferredPacketReadyTime()
- { return transmitList.empty() ? MaxTick : transmitList.front().tick; }
-
- /**
- * Schedule a send even if not already waiting for a retry. If the
- * requested time is before an already scheduled send event it
- * will be rescheduled.
- *
- * @param when
- */
- void schedSendEvent(Tick when);
-
- /** Schedule a sendTiming() event to be called in the future.
- * @param pkt packet to send
- * @param absolute time (in ticks) to send packet
- */
- void schedSendTiming(PacketPtr pkt, Tick when);
-
- /** Attempt to send the packet at the head of the deferred packet
- * list. Caller must guarantee that the deferred packet list is
- * non-empty and that the head packet is scheduled for curTick() (or
- * earlier).
- */
- virtual void sendDeferredPacket();
-
- /**
- * Attempt to send the packet at the front of the transmit list,
- * and set waitingOnRetry accordingly. The packet is temporarily
- * taken off the list, but put back at the front if not
- * successfully sent.
- */
- void trySendTiming();
-
- /**
- * Based on the transmit list, or the provided time, schedule a
- * send event if there are packets to send. If we are idle and
- * asked to drain then do so.
- *
- * @param time an alternative time for the next send event
- */
- void scheduleSend(Tick time = MaxTick);
+ protected:
- /** This function is notification that the device should attempt to send a
- * packet again. */
- virtual void recvRetry();
+ /** The packet queue used to store outgoing responses. */
+ PacketQueue queue;
/** Implemented using recvAtomic(). */
void recvFunctional(PacketPtr pkt);
@@ -168,42 +71,25 @@ class SimpleTimingPort : public Port
/** Implemented using recvAtomic(). */
bool recvTiming(PacketPtr pkt);
- /**
- * Simple ports are generally used as slave ports (i.e. the
- * respond to requests) and thus do not expect to receive any
- * range changes (as the neighbouring port has a master role and
- * do not have any address ranges. A subclass can override the
- * default behaviuor if needed.
- */
- virtual void recvRangeChange() { }
-
+ virtual Tick recvAtomic(PacketPtr pkt) = 0;
public:
- SimpleTimingPort(const std::string &_name, MemObject *_owner,
- const std::string _label = "SimpleTimingPort");
- ~SimpleTimingPort();
- /** Check the list of buffered packets against the supplied
- * functional request. */
- bool checkFunctional(PacketPtr pkt);
+ /**
+ * Create a new SimpleTimingPort that relies on a packet queue to
+ * hold responses, and implements recvTiming and recvFunctional
+ * through calls to recvAtomic. Once a request arrives, it is
+ * passed to recvAtomic, and in the case of a timing access any
+ * response is scheduled to be sent after the delay of the atomic
+ * operation.
+ *
+ * @param name port name
+ * @param owner structural owner
+ */
+ SimpleTimingPort(const std::string& name, MemObject* owner);
+
+ virtual ~SimpleTimingPort() { }
- /** Hook for draining timing accesses from the system. The
- * associated SimObject's drain() functions should be implemented
- * something like this when this class is used:
- \code
- PioDevice::drain(Event *de)
- {
- unsigned int count;
- count = SimpleTimingPort->drain(de);
- if (count)
- changeState(Draining);
- else
- changeState(Drained);
- return count;
- }
- \endcode
- */
- unsigned int drain(Event *de);
};
#endif // __MEM_TPORT_HH__