summaryrefslogtreecommitdiff
path: root/src/mem/tport.hh
diff options
context:
space:
mode:
authorSteve Reinhardt <stever@eecs.umich.edu>2006-08-30 16:24:26 -0700
committerSteve Reinhardt <stever@eecs.umich.edu>2006-08-30 16:24:26 -0700
commitf9ae0dcf1065454ca3d08512cd36a2dad9f08b2d (patch)
tree37e20bde0e0098eca99969f975c055d50cb65914 /src/mem/tport.hh
parenta8a7ce2b886ca2571f9470a48a4f12302f9cc830 (diff)
downloadgem5-f9ae0dcf1065454ca3d08512cd36a2dad9f08b2d.tar.xz
Move more common functionality into SimpleTimingPort,
allowing derived classes to be simplified. --HG-- extra : convert_revision : c980d3aec5e6c044d8f41e96252726fe9a256605
Diffstat (limited to 'src/mem/tport.hh')
-rw-r--r--src/mem/tport.hh89
1 files changed, 50 insertions, 39 deletions
diff --git a/src/mem/tport.hh b/src/mem/tport.hh
index 4d5c4599d..df6d48196 100644
--- a/src/mem/tport.hh
+++ b/src/mem/tport.hh
@@ -28,57 +28,40 @@
* Authors: Ali Saidi
*/
+#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.
-
-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)
-{
- unsigned int count;
- count = SimpleTimingPort->drain(de);
- if (count)
- changeState(Draining);
- else
- changeState(Drained);
- return count;
-}
-*/
-
-#ifndef __MEM_TPORT_HH__
-#define __MEM_TPORT_HH__
-
#include "mem/port.hh"
#include "sim/eventq.hh"
#include <list>
#include <string>
+/**
+ * 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.
+ */
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
@@ -112,20 +95,48 @@ class SimpleTimingPort : public Port
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); }
+ void sendTimingLater(Packet *pkt, Tick time)
+ { outTiming++; new SendEvent(this, pkt, time); }
/** This function is notification that the device should attempt to send a
* packet again. */
virtual void recvRetry();
- void resendNacked(Packet *pkt);
+ /** Implemented using recvAtomic(). */
+ void recvFunctional(Packet *pkt);
+
+ /** Implemented using recvAtomic(). */
+ bool recvTiming(Packet *pkt);
+
+ /**
+ * Simple ports generally don't care about any status
+ * changes... can always override this in cases where that's not
+ * true. */
+ virtual void recvStatusChange(Status status) { }
+
+
public:
SimpleTimingPort(std::string pname)
: Port(pname), outTiming(0), drainEvent(NULL)
{}
+ /** 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);
};