From 69e82539fd81299751e1000c0dac49f2eddbbdb6 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Tue, 23 Oct 2012 04:49:33 -0400 Subject: 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. --- src/dev/dma_device.hh | 60 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 19 deletions(-) (limited to 'src/dev/dma_device.hh') 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 transmitList; + /** Event used to schedule a future sending from the transmit list. */ + EventWrapper 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__ -- cgit v1.2.3