ruby: add functions for computing next stride/page address
[gem5.git] / src / mem / tport.hh
index 5473e945e9c656cde96ea02dde63fe13038503ae..5e80f4fab081d5dd6ecee7a44f1abb25bf22193e 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2012 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2006 The Regents of The University of Michigan
  * All rights reserved.
  *
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Authors: Ali Saidi
+ *          Andreas Hansson
  */
 
+#ifndef __MEM_TPORT_HH__
+#define __MEM_TPORT_HH__
+
 /**
  * @file
- * Implement a port which adds simple support of a sendTiming() function that
- * takes a delay. In this way the * device can immediatly call
- * sendTiming(pkt, time) after processing a request and the request will be
- * handled by the port even if the port bus the device connects to is blocked.
+ *
+ * Declaration of SimpleTimingPort.
  */
 
-/** recvTiming and drain should be implemented something like this when this
- * class is used.
+#include "mem/qport.hh"
 
-bool
-PioPort::recvTiming(Packet *pkt)
-{
-    if (pkt->result == Packet::Nacked) {
-        resendNacked(pkt);
-    } else {
-        Tick latency = device->recvAtomic(pkt);
-        // turn packet around to go back to requester
-        pkt->makeTimingResponse();
-        sendTiming(pkt, latency);
-    }
-    return true;
-}
-
-PioDevice::drain(Event *de)
+/**
+ * The simple timing port uses a queued port to implement
+ * recvFunctional and recvTimingReq through recvAtomic. It is always a
+ * slave port.
+ */
+class SimpleTimingPort : public QueuedSlavePort
 {
-    unsigned int count;
-    count = SimpleTimingPort->drain(de);
-    if (count)
-        changeState(Draining);
-    else
-        changeState(Drained);
-    return count;
-}
-*/
 
-#ifndef __MEM_TPORT_HH__
-#define __MEM_TPORT_HH__
+  private:
 
-#include "mem/port.hh"
-#include "sim/eventq.hh"
-#include <list>
-#include <string>
-
-class SimpleTimingPort : public Port
-{
-  protected:
-    /** A list of outgoing timing response packets that haven't been serviced
-     * yet. */
-    std::list<Packet*> transmitList;
     /**
-     * This class is used to implemented sendTiming() with a delay. When a delay
-     * is requested a new event is created. When the event time expires it
-     * attempts to send the packet. If it cannot, the packet is pushed onto the
-     * transmit list to be sent when recvRetry() is called. */
-    class SendEvent : public Event
-    {
-        SimpleTimingPort *port;
-        Packet *packet;
-
-        SendEvent(SimpleTimingPort *p, Packet *pkt, Tick t)
-            : Event(&mainEventQueue), port(p), packet(pkt)
-        { setFlags(AutoDelete); schedule(curTick + t); }
+     * 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 QueuedSlavePort. Access is provided through
+     * the queue reference in the base class.
+     */
+    SlavePacketQueue queueImpl;
 
-        virtual void process();
+  protected:
 
-        virtual const char *description()
-        { return "Future scheduled sendTiming event"; }
+    /** Implemented using recvAtomic(). */
+    void recvFunctional(PacketPtr pkt);
 
-        friend class SimpleTimingPort;
-    };
+    /** Implemented using recvAtomic(). */
+    bool recvTimingReq(PacketPtr pkt);
 
+    virtual Tick recvAtomic(PacketPtr pkt) = 0;
 
-    /** Number of timing requests that are emulating the device timing before
-     * attempting to end up on the bus.
+    /**
+     * @todo this is a temporary workaround until the 4-phase code is committed.
+     * upstream caches need this packet until true is returned, so hold it for
+     * deletion until a subsequent call
      */
-    int outTiming;
-
-    /** If we need to drain, keep the drain event around until we're done
-     * here.*/
-    Event *drainEvent;
-
-    /** Schedule a sendTiming() event to be called in the future. */
-    void sendTiming(Packet *pkt, Tick time)
-    { outTiming++; new SimpleTimingPort::SendEvent(this, pkt, time); }
+    std::vector<PacketPtr> pendingDelete;
 
-    /** This function is notification that the device should attempt to send a
-     * packet again. */
-    virtual void recvRetry();
 
-    void resendNacked(Packet *pkt);
   public:
 
-    SimpleTimingPort(std::string pname)
-        : Port(pname), outTiming(0), drainEvent(NULL)
-    {}
+    /**
+     * 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
+     */
+    SimpleTimingPort(const std::string& name, MemObject* owner);
 
-    unsigned int drain(Event *de);
+    virtual ~SimpleTimingPort() { }
 
-    friend class SimpleTimingPort::SendEvent;
 };
 
 #endif // __MEM_TPORT_HH__