diff options
Diffstat (limited to 'src/dev/dma_device.hh')
-rw-r--r-- | src/dev/dma_device.hh | 60 |
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__ |