summaryrefslogtreecommitdiff
path: root/src/dev/dma_device.hh
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2012-10-23 04:49:33 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2012-10-23 04:49:33 -0400
commit69e82539fd81299751e1000c0dac49f2eddbbdb6 (patch)
tree90a4d9e4bb2cbf51fbb1340d5faf35cad34b4ebc /src/dev/dma_device.hh
parent37ded2c2cc2523d43cb2a4ae6a421ddba5f22919 (diff)
downloadgem5-69e82539fd81299751e1000c0dac49f2eddbbdb6.tar.xz
dev: Remove zero-time loop in DMA timing send
This patch removes the zero-time loop used to send items from the DMA port transmit list. Instead of having a loop, the DMA port now uses an event to schedule sending of a single packet. Ultimately this patch serves to ease the transition to a blocking 4-phase handshake. A follow-on patch will update the regression statistics.
Diffstat (limited to 'src/dev/dma_device.hh')
-rw-r--r--src/dev/dma_device.hh60
1 files changed, 41 insertions, 19 deletions
diff --git a/src/dev/dma_device.hh b/src/dev/dma_device.hh
index c46fbfd76..cd328f3d6 100644
--- a/src/dev/dma_device.hh
+++ b/src/dev/dma_device.hh
@@ -51,7 +51,37 @@
class DmaPort : public MasterPort
{
- protected:
+ private:
+
+ /**
+ * Take the first packet of the transmit list and attempt to send
+ * it as a timing request. If it is successful, schedule the
+ * sending of the next packet, otherwise remember that we are
+ * waiting for a retry.
+ */
+ void trySendTimingReq();
+
+ /**
+ * For timing, attempt to send the first item on the transmit
+ * list, and if it is successful and there are more packets
+ * waiting, then schedule the sending of the next packet. For
+ * atomic, simply send and process everything on the transmit
+ * list.
+ */
+ void sendDma();
+
+ /**
+ * Handle a response packet by updating the corresponding DMA
+ * request state to reflect the bytes received, and also update
+ * the pending request counter. If the DMA request that this
+ * packet is part of is complete, then signal the completion event
+ * if present, potentially with a delay added to it.
+ *
+ * @param pkt Response packet to handler
+ * @param delay Additional delay for scheduling the completion event
+ */
+ void handleResp(PacketPtr pkt, Tick delay = 0);
+
struct DmaReqState : public Packet::SenderState
{
/** Event to call on the device when this transaction (all packets)
@@ -59,30 +89,34 @@ class DmaPort : public MasterPort
Event *completionEvent;
/** Total number of bytes that this transaction involves. */
- Addr totBytes;
+ const Addr totBytes;
/** Number of bytes that have been acked for this transaction. */
Addr numBytes;
/** Amount to delay completion of dma by */
- Tick delay;
+ const Tick delay;
DmaReqState(Event *ce, Addr tb, Tick _delay)
: completionEvent(ce), totBytes(tb), numBytes(0), delay(_delay)
{}
};
+ /** The device that owns this port. */
MemObject *device;
- /** Use a deque as we never to any insertion or removal in the middle */
+ /** Use a deque as we never do any insertion or removal in the middle */
std::deque<PacketPtr> transmitList;
+ /** Event used to schedule a future sending from the transmit list. */
+ EventWrapper<DmaPort, &DmaPort::sendDma> sendEvent;
+
/** The system that device/port are in. This is used to select which mode
* we are currently operating in. */
System *sys;
/** Id for all requests */
- MasterID masterId;
+ const MasterID masterId;
/** Number of outstanding packets the dma port has. */
uint32_t pendingCount;
@@ -95,23 +129,12 @@ class DmaPort : public MasterPort
* send whatever it is that it's sending. */
bool inRetry;
- /**
- * Handle a response packet by updating the corresponding DMA
- * request state to reflect the bytes received, and also update
- * the pending request counter. If the DMA request that this
- * packet is part of is complete, then signal the completion event
- * if present, potentially with a delay added to it.
- *
- * @param pkt Response packet to handler
- * @param delay Additional delay for scheduling the completion event
- */
- void handleResp(PacketPtr pkt, Tick delay = 0);
+ protected:
bool recvTimingResp(PacketPtr pkt);
void recvRetry() ;
void queueDma(PacketPtr pkt);
- void sendDma();
public:
@@ -148,7 +171,7 @@ class DmaDevice : public PioDevice
dmaPort.dmaAction(MemCmd::ReadReq, addr, size, event, data, delay);
}
- bool dmaPending() { return dmaPort.dmaPending(); }
+ bool dmaPending() const { return dmaPort.dmaPending(); }
virtual void init();
@@ -159,7 +182,6 @@ class DmaDevice : public PioDevice
virtual BaseMasterPort &getMasterPort(const std::string &if_name,
PortID idx = InvalidPortID);
- friend class DmaPort;
};
#endif // __DEV_DMA_DEVICE_HH__