misc: Delete the now unnecessary create methods.
[gem5.git] / src / mem / tport.hh
index d720f227c5df621ae21597cc17e4f05e7d2a0c94..fe32872d17c9f2087b0b5d3643c4bf81f4fbae06 100644 (file)
@@ -36,9 +36,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Authors: Ali Saidi
- *          Andreas Hansson
  */
 
 #ifndef __MEM_TPORT_HH__
  * Declaration of SimpleTimingPort.
  */
 
-#include <list>
-#include <string>
+#include "mem/qport.hh"
 
-#include "mem/port.hh"
-#include "sim/eventq.hh"
+class SimObject;
 
 /**
- * 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 recvTimingReq through recvAtomic. It is always a
+ * response port.
  */
-class SimpleTimingPort : public Port
+class SimpleTimingPort : public QueuedResponsePort
 {
-  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; }
+  private:
 
     /**
-     * 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
+     * The packet queue used to store outgoing responses. Note that
+     * the queue is made private and that we avoid overloading the
+     * name used in the QueuedResponsePort. Access is provided through
+     * the queue reference in the base class.
      */
-    void schedSendEvent(Tick when);
+    RespPacketQueue queueImpl;
 
-    /** 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);
+  protected:
 
-    /** 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();
+    /** Implemented using recvAtomic(). */
+    void recvFunctional(PacketPtr pkt);
 
-    /**
-     * 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();
+    /** Implemented using recvAtomic(). */
+    bool recvTimingReq(PacketPtr pkt);
+
+    virtual Tick recvAtomic(PacketPtr pkt) = 0;
 
     /**
-     * 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
+     * Upstream caches need this packet until true is returned, so
+     * hold it for deletion until a subsequent call
      */
-    void scheduleSend(Tick time = MaxTick);
-
-    /** This function is notification that the device should attempt to send a
-     * packet again. */
-    virtual void recvRetry();
+    std::unique_ptr<Packet> pendingDelete;
 
-    /** Implemented using recvAtomic(). */
-    void recvFunctional(PacketPtr pkt);
-
-    /** Implemented using recvAtomic(). */
-    bool recvTiming(PacketPtr pkt);
+  public:
 
     /**
-     * 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.
+     * Create a new SimpleTimingPort that relies on a packet queue to
+     * hold responses, and implements recvTimingReq 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
      */
-    virtual void recvRangeChange() { }
+    SimpleTimingPort(const std::string& name, SimObject* owner);
 
+    virtual ~SimpleTimingPort() { }
 
-  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);
-
-    /** 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__