dma_device.hh revision 10621
1545SN/A/*
29814Sandreas.hansson@arm.com * Copyright (c) 2012-2013 ARM Limited
38948SN/A * All rights reserved.
48948SN/A *
58948SN/A * The license below extends only to copyright in the software and shall
68948SN/A * not be construed as granting a license to any other intellectual
78948SN/A * property including but not limited to intellectual property relating
88948SN/A * to a hardware implementation of the functionality of the software
98948SN/A * licensed hereunder.  You may use the software subject to the license
108948SN/A * terms below provided that you ensure that this notice is replicated
118948SN/A * unmodified and in its entirety in all distributions of the software,
128948SN/A * modified or unmodified, in source code or in binary form.
138948SN/A *
141762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
15545SN/A * All rights reserved.
16545SN/A *
17545SN/A * Redistribution and use in source and binary forms, with or without
18545SN/A * modification, are permitted provided that the following conditions are
19545SN/A * met: redistributions of source code must retain the above copyright
20545SN/A * notice, this list of conditions and the following disclaimer;
21545SN/A * redistributions in binary form must reproduce the above copyright
22545SN/A * notice, this list of conditions and the following disclaimer in the
23545SN/A * documentation and/or other materials provided with the distribution;
24545SN/A * neither the name of the copyright holders nor the names of its
25545SN/A * contributors may be used to endorse or promote products derived from
26545SN/A * this software without specific prior written permission.
27545SN/A *
28545SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29545SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30545SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31545SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32545SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33545SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34545SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35545SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36545SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37545SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38545SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392665SN/A *
402665SN/A * Authors: Ali Saidi
412665SN/A *          Nathan Binkert
42545SN/A */
43545SN/A
449016Sandreas.hansson@arm.com#ifndef __DEV_DMA_DEVICE_HH__
459016Sandreas.hansson@arm.com#define __DEV_DMA_DEVICE_HH__
46545SN/A
479166Sandreas.hansson@arm.com#include <deque>
489166Sandreas.hansson@arm.com
499016Sandreas.hansson@arm.com#include "dev/io_device.hh"
504762SN/A#include "params/DmaDevice.hh"
519342SAndreas.Sandberg@arm.com#include "sim/drain.hh"
529814Sandreas.hansson@arm.com#include "sim/system.hh"
532565SN/A
548922SN/Aclass DmaPort : public MasterPort
552384SN/A{
569307Sandreas.hansson@arm.com  private:
572784SN/A
589307Sandreas.hansson@arm.com    /**
599307Sandreas.hansson@arm.com     * Take the first packet of the transmit list and attempt to send
609307Sandreas.hansson@arm.com     * it as a timing request. If it is successful, schedule the
619307Sandreas.hansson@arm.com     * sending of the next packet, otherwise remember that we are
629307Sandreas.hansson@arm.com     * waiting for a retry.
639307Sandreas.hansson@arm.com     */
649307Sandreas.hansson@arm.com    void trySendTimingReq();
652784SN/A
669307Sandreas.hansson@arm.com    /**
679307Sandreas.hansson@arm.com     * For timing, attempt to send the first item on the transmit
689307Sandreas.hansson@arm.com     * list, and if it is successful and there are more packets
699307Sandreas.hansson@arm.com     * waiting, then schedule the sending of the next packet. For
709307Sandreas.hansson@arm.com     * atomic, simply send and process everything on the transmit
719307Sandreas.hansson@arm.com     * list.
729307Sandreas.hansson@arm.com     */
739307Sandreas.hansson@arm.com    void sendDma();
744435SN/A
759166Sandreas.hansson@arm.com    /**
769166Sandreas.hansson@arm.com     * Handle a response packet by updating the corresponding DMA
779166Sandreas.hansson@arm.com     * request state to reflect the bytes received, and also update
789166Sandreas.hansson@arm.com     * the pending request counter. If the DMA request that this
799166Sandreas.hansson@arm.com     * packet is part of is complete, then signal the completion event
809166Sandreas.hansson@arm.com     * if present, potentially with a delay added to it.
819166Sandreas.hansson@arm.com     *
829166Sandreas.hansson@arm.com     * @param pkt Response packet to handler
839166Sandreas.hansson@arm.com     * @param delay Additional delay for scheduling the completion event
849166Sandreas.hansson@arm.com     */
859166Sandreas.hansson@arm.com    void handleResp(PacketPtr pkt, Tick delay = 0);
868948SN/A
879307Sandreas.hansson@arm.com    struct DmaReqState : public Packet::SenderState
889307Sandreas.hansson@arm.com    {
899307Sandreas.hansson@arm.com        /** Event to call on the device when this transaction (all packets)
909307Sandreas.hansson@arm.com         * complete. */
919307Sandreas.hansson@arm.com        Event *completionEvent;
929307Sandreas.hansson@arm.com
939307Sandreas.hansson@arm.com        /** Total number of bytes that this transaction involves. */
949307Sandreas.hansson@arm.com        const Addr totBytes;
959307Sandreas.hansson@arm.com
969307Sandreas.hansson@arm.com        /** Number of bytes that have been acked for this transaction. */
979307Sandreas.hansson@arm.com        Addr numBytes;
989307Sandreas.hansson@arm.com
999307Sandreas.hansson@arm.com        /** Amount to delay completion of dma by */
1009307Sandreas.hansson@arm.com        const Tick delay;
1019307Sandreas.hansson@arm.com
1029307Sandreas.hansson@arm.com        DmaReqState(Event *ce, Addr tb, Tick _delay)
1039307Sandreas.hansson@arm.com            : completionEvent(ce), totBytes(tb), numBytes(0), delay(_delay)
1049307Sandreas.hansson@arm.com        {}
1059307Sandreas.hansson@arm.com    };
1069307Sandreas.hansson@arm.com
1079307Sandreas.hansson@arm.com    /** The device that owns this port. */
1089307Sandreas.hansson@arm.com    MemObject *device;
1099307Sandreas.hansson@arm.com
1109307Sandreas.hansson@arm.com    /** Use a deque as we never do any insertion or removal in the middle */
1119307Sandreas.hansson@arm.com    std::deque<PacketPtr> transmitList;
1129307Sandreas.hansson@arm.com
1139307Sandreas.hansson@arm.com    /** Event used to schedule a future sending from the transmit list. */
1149307Sandreas.hansson@arm.com    EventWrapper<DmaPort, &DmaPort::sendDma> sendEvent;
1159307Sandreas.hansson@arm.com
1169307Sandreas.hansson@arm.com    /** The system that device/port are in. This is used to select which mode
1179307Sandreas.hansson@arm.com     * we are currently operating in. */
1189307Sandreas.hansson@arm.com    System *sys;
1199307Sandreas.hansson@arm.com
1209307Sandreas.hansson@arm.com    /** Id for all requests */
1219307Sandreas.hansson@arm.com    const MasterID masterId;
1229307Sandreas.hansson@arm.com
1239307Sandreas.hansson@arm.com    /** Number of outstanding packets the dma port has. */
1249307Sandreas.hansson@arm.com    uint32_t pendingCount;
1259307Sandreas.hansson@arm.com
1269307Sandreas.hansson@arm.com    /** If we need to drain, keep the drain event around until we're done
1279307Sandreas.hansson@arm.com     * here.*/
1289342SAndreas.Sandberg@arm.com    DrainManager *drainManager;
1299307Sandreas.hansson@arm.com
1309307Sandreas.hansson@arm.com    /** If the port is currently waiting for a retry before it can
1319307Sandreas.hansson@arm.com     * send whatever it is that it's sending. */
1329307Sandreas.hansson@arm.com    bool inRetry;
1339307Sandreas.hansson@arm.com
1349307Sandreas.hansson@arm.com  protected:
1359307Sandreas.hansson@arm.com
1369166Sandreas.hansson@arm.com    bool recvTimingResp(PacketPtr pkt);
1379166Sandreas.hansson@arm.com    void recvRetry() ;
1382384SN/A
1399166Sandreas.hansson@arm.com    void queueDma(PacketPtr pkt);
1404435SN/A
1419165Sandreas.hansson@arm.com  public:
1422489SN/A
1439165Sandreas.hansson@arm.com    DmaPort(MemObject *dev, System *s);
1442565SN/A
14510621SCurtis.Dunham@arm.com    RequestPtr dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
14610621SCurtis.Dunham@arm.com                         uint8_t *data, Tick delay, Request::Flags flag = 0);
1472565SN/A
1489166Sandreas.hansson@arm.com    bool dmaPending() const { return pendingCount > 0; }
1492384SN/A
1509342SAndreas.Sandberg@arm.com    unsigned int drain(DrainManager *drainManger);
1512384SN/A};
1522384SN/A
153545SN/Aclass DmaDevice : public PioDevice
154545SN/A{
1554435SN/A   protected:
1568851SN/A    DmaPort dmaPort;
157545SN/A
158545SN/A  public:
1594762SN/A    typedef DmaDeviceParams Params;
1604762SN/A    DmaDevice(const Params *p);
1619166Sandreas.hansson@arm.com    virtual ~DmaDevice() { }
1624762SN/A
1638851SN/A    void dmaWrite(Addr addr, int size, Event *event, uint8_t *data,
1648851SN/A                  Tick delay = 0)
1654022SN/A    {
1668851SN/A        dmaPort.dmaAction(MemCmd::WriteReq, addr, size, event, data, delay);
1674022SN/A    }
1682565SN/A
1698851SN/A    void dmaRead(Addr addr, int size, Event *event, uint8_t *data,
1708851SN/A                 Tick delay = 0)
1714263SN/A    {
1728851SN/A        dmaPort.dmaAction(MemCmd::ReadReq, addr, size, event, data, delay);
1734263SN/A    }
1742565SN/A
1759307Sandreas.hansson@arm.com    bool dmaPending() const { return dmaPort.dmaPending(); }
1768851SN/A
1778851SN/A    virtual void init();
1782565SN/A
1799342SAndreas.Sandberg@arm.com    unsigned int drain(DrainManager *drainManger);
1802901SN/A
1819814Sandreas.hansson@arm.com    unsigned int cacheBlockSize() const { return sys->cacheLineSize(); }
1824263SN/A
1839294Sandreas.hansson@arm.com    virtual BaseMasterPort &getMasterPort(const std::string &if_name,
1849294Sandreas.hansson@arm.com                                          PortID idx = InvalidPortID);
1852489SN/A
186545SN/A};
187545SN/A
1889016Sandreas.hansson@arm.com#endif // __DEV_DMA_DEVICE_HH__
189