dma_device.hh revision 9307
15361Srstrong@cs.ucsd.edu/*
23671Sbinkertn@umich.edu * Copyright (c) 2012 ARM Limited
33671Sbinkertn@umich.edu * All rights reserved.
43671Sbinkertn@umich.edu *
53671Sbinkertn@umich.edu * The license below extends only to copyright in the software and shall
63671Sbinkertn@umich.edu * not be construed as granting a license to any other intellectual
73671Sbinkertn@umich.edu * property including but not limited to intellectual property relating
83671Sbinkertn@umich.edu * to a hardware implementation of the functionality of the software
93671Sbinkertn@umich.edu * licensed hereunder.  You may use the software subject to the license
103671Sbinkertn@umich.edu * terms below provided that you ensure that this notice is replicated
113671Sbinkertn@umich.edu * unmodified and in its entirety in all distributions of the software,
123671Sbinkertn@umich.edu * modified or unmodified, in source code or in binary form.
133671Sbinkertn@umich.edu *
143671Sbinkertn@umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan
153671Sbinkertn@umich.edu * All rights reserved.
163671Sbinkertn@umich.edu *
173671Sbinkertn@umich.edu * Redistribution and use in source and binary forms, with or without
183671Sbinkertn@umich.edu * modification, are permitted provided that the following conditions are
193671Sbinkertn@umich.edu * met: redistributions of source code must retain the above copyright
203671Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer;
213671Sbinkertn@umich.edu * redistributions in binary form must reproduce the above copyright
223671Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer in the
233671Sbinkertn@umich.edu * documentation and/or other materials provided with the distribution;
243671Sbinkertn@umich.edu * neither the name of the copyright holders nor the names of its
253671Sbinkertn@umich.edu * contributors may be used to endorse or promote products derived from
263671Sbinkertn@umich.edu * this software without specific prior written permission.
273671Sbinkertn@umich.edu *
283671Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
293671Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
303671Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
313671Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
323671Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
333671Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
346028Ssteve.reinhardt@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
353671Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
363671Sbinkertn@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
373671Sbinkertn@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
383671Sbinkertn@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
393671Sbinkertn@umich.edu *
403671Sbinkertn@umich.edu * Authors: Ali Saidi
413671Sbinkertn@umich.edu *          Nathan Binkert
423671Sbinkertn@umich.edu */
433671Sbinkertn@umich.edu
443671Sbinkertn@umich.edu#ifndef __DEV_DMA_DEVICE_HH__
453671Sbinkertn@umich.edu#define __DEV_DMA_DEVICE_HH__
463671Sbinkertn@umich.edu
473671Sbinkertn@umich.edu#include <deque>
483671Sbinkertn@umich.edu
493671Sbinkertn@umich.edu#include "dev/io_device.hh"
503671Sbinkertn@umich.edu#include "params/DmaDevice.hh"
513671Sbinkertn@umich.edu
523671Sbinkertn@umich.educlass DmaPort : public MasterPort
533671Sbinkertn@umich.edu{
543671Sbinkertn@umich.edu  private:
553671Sbinkertn@umich.edu
563671Sbinkertn@umich.edu    /**
573671Sbinkertn@umich.edu     * Take the first packet of the transmit list and attempt to send
583671Sbinkertn@umich.edu     * it as a timing request. If it is successful, schedule the
593671Sbinkertn@umich.edu     * sending of the next packet, otherwise remember that we are
603671Sbinkertn@umich.edu     * waiting for a retry.
613671Sbinkertn@umich.edu     */
623671Sbinkertn@umich.edu    void trySendTimingReq();
633671Sbinkertn@umich.edu
643671Sbinkertn@umich.edu    /**
653671Sbinkertn@umich.edu     * For timing, attempt to send the first item on the transmit
663671Sbinkertn@umich.edu     * list, and if it is successful and there are more packets
673671Sbinkertn@umich.edu     * waiting, then schedule the sending of the next packet. For
683671Sbinkertn@umich.edu     * atomic, simply send and process everything on the transmit
693671Sbinkertn@umich.edu     * list.
703671Sbinkertn@umich.edu     */
713671Sbinkertn@umich.edu    void sendDma();
723671Sbinkertn@umich.edu
733671Sbinkertn@umich.edu    /**
743671Sbinkertn@umich.edu     * Handle a response packet by updating the corresponding DMA
753671Sbinkertn@umich.edu     * request state to reflect the bytes received, and also update
763671Sbinkertn@umich.edu     * the pending request counter. If the DMA request that this
773671Sbinkertn@umich.edu     * packet is part of is complete, then signal the completion event
783671Sbinkertn@umich.edu     * if present, potentially with a delay added to it.
793671Sbinkertn@umich.edu     *
803671Sbinkertn@umich.edu     * @param pkt Response packet to handler
813671Sbinkertn@umich.edu     * @param delay Additional delay for scheduling the completion event
823671Sbinkertn@umich.edu     */
833671Sbinkertn@umich.edu    void handleResp(PacketPtr pkt, Tick delay = 0);
843671Sbinkertn@umich.edu
853671Sbinkertn@umich.edu    struct DmaReqState : public Packet::SenderState
863671Sbinkertn@umich.edu    {
873671Sbinkertn@umich.edu        /** Event to call on the device when this transaction (all packets)
885361Srstrong@cs.ucsd.edu         * complete. */
895361Srstrong@cs.ucsd.edu        Event *completionEvent;
905361Srstrong@cs.ucsd.edu
913671Sbinkertn@umich.edu        /** Total number of bytes that this transaction involves. */
923671Sbinkertn@umich.edu        const Addr totBytes;
933671Sbinkertn@umich.edu
943671Sbinkertn@umich.edu        /** Number of bytes that have been acked for this transaction. */
953671Sbinkertn@umich.edu        Addr numBytes;
963671Sbinkertn@umich.edu
973671Sbinkertn@umich.edu        /** Amount to delay completion of dma by */
983671Sbinkertn@umich.edu        const Tick delay;
993671Sbinkertn@umich.edu
1003671Sbinkertn@umich.edu        DmaReqState(Event *ce, Addr tb, Tick _delay)
1013671Sbinkertn@umich.edu            : completionEvent(ce), totBytes(tb), numBytes(0), delay(_delay)
1023671Sbinkertn@umich.edu        {}
1033671Sbinkertn@umich.edu    };
1043671Sbinkertn@umich.edu
1053671Sbinkertn@umich.edu    /** The device that owns this port. */
1063671Sbinkertn@umich.edu    MemObject *device;
1073671Sbinkertn@umich.edu
1083671Sbinkertn@umich.edu    /** Use a deque as we never do any insertion or removal in the middle */
1093671Sbinkertn@umich.edu    std::deque<PacketPtr> transmitList;
1104116Sgblack@eecs.umich.edu
1114116Sgblack@eecs.umich.edu    /** Event used to schedule a future sending from the transmit list. */
1123671Sbinkertn@umich.edu    EventWrapper<DmaPort, &DmaPort::sendDma> sendEvent;
1133671Sbinkertn@umich.edu
1143671Sbinkertn@umich.edu    /** The system that device/port are in. This is used to select which mode
1153671Sbinkertn@umich.edu     * we are currently operating in. */
1163671Sbinkertn@umich.edu    System *sys;
1173671Sbinkertn@umich.edu
1183671Sbinkertn@umich.edu    /** Id for all requests */
1193671Sbinkertn@umich.edu    const MasterID masterId;
1203671Sbinkertn@umich.edu
1213671Sbinkertn@umich.edu    /** Number of outstanding packets the dma port has. */
1223671Sbinkertn@umich.edu    uint32_t pendingCount;
1233671Sbinkertn@umich.edu
1243671Sbinkertn@umich.edu    /** If we need to drain, keep the drain event around until we're done
1253671Sbinkertn@umich.edu     * here.*/
1263671Sbinkertn@umich.edu    Event *drainEvent;
1273671Sbinkertn@umich.edu
1283671Sbinkertn@umich.edu    /** If the port is currently waiting for a retry before it can
1293671Sbinkertn@umich.edu     * send whatever it is that it's sending. */
1303671Sbinkertn@umich.edu    bool inRetry;
1313671Sbinkertn@umich.edu
1323671Sbinkertn@umich.edu  protected:
1333671Sbinkertn@umich.edu
1343671Sbinkertn@umich.edu    bool recvTimingResp(PacketPtr pkt);
1353671Sbinkertn@umich.edu    void recvRetry() ;
1363671Sbinkertn@umich.edu
1374555Sbinkertn@umich.edu    void queueDma(PacketPtr pkt);
1383671Sbinkertn@umich.edu
1393671Sbinkertn@umich.edu  public:
1403671Sbinkertn@umich.edu
1413671Sbinkertn@umich.edu    DmaPort(MemObject *dev, System *s);
1423671Sbinkertn@umich.edu
1435378Ssaidi@eecs.umich.edu    void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
1445378Ssaidi@eecs.umich.edu                   uint8_t *data, Tick delay, Request::Flags flag = 0);
1453671Sbinkertn@umich.edu
1463671Sbinkertn@umich.edu    bool dmaPending() const { return pendingCount > 0; }
1473671Sbinkertn@umich.edu
1483671Sbinkertn@umich.edu    unsigned cacheBlockSize() const { return peerBlockSize(); }
1493671Sbinkertn@umich.edu    unsigned int drain(Event *de);
1503671Sbinkertn@umich.edu};
1513671Sbinkertn@umich.edu
1523671Sbinkertn@umich.educlass DmaDevice : public PioDevice
1533671Sbinkertn@umich.edu{
1543671Sbinkertn@umich.edu   protected:
1553671Sbinkertn@umich.edu    DmaPort dmaPort;
1565361Srstrong@cs.ucsd.edu
1573671Sbinkertn@umich.edu  public:
1588246Snate@binkert.org    typedef DmaDeviceParams Params;
1593671Sbinkertn@umich.edu    DmaDevice(const Params *p);
1603671Sbinkertn@umich.edu    virtual ~DmaDevice() { }
1613671Sbinkertn@umich.edu
1623671Sbinkertn@umich.edu    void dmaWrite(Addr addr, int size, Event *event, uint8_t *data,
1633671Sbinkertn@umich.edu                  Tick delay = 0)
1643671Sbinkertn@umich.edu    {
1653671Sbinkertn@umich.edu        dmaPort.dmaAction(MemCmd::WriteReq, addr, size, event, data, delay);
1663671Sbinkertn@umich.edu    }
1673671Sbinkertn@umich.edu
1683671Sbinkertn@umich.edu    void dmaRead(Addr addr, int size, Event *event, uint8_t *data,
1693671Sbinkertn@umich.edu                 Tick delay = 0)
1703671Sbinkertn@umich.edu    {
1713671Sbinkertn@umich.edu        dmaPort.dmaAction(MemCmd::ReadReq, addr, size, event, data, delay);
1723671Sbinkertn@umich.edu    }
1733671Sbinkertn@umich.edu
1743671Sbinkertn@umich.edu    bool dmaPending() const { return dmaPort.dmaPending(); }
1753671Sbinkertn@umich.edu
1763671Sbinkertn@umich.edu    virtual void init();
1773671Sbinkertn@umich.edu
1783671Sbinkertn@umich.edu    virtual unsigned int drain(Event *de);
1793671Sbinkertn@umich.edu
1803671Sbinkertn@umich.edu    unsigned cacheBlockSize() const { return dmaPort.cacheBlockSize(); }
1813671Sbinkertn@umich.edu
1823671Sbinkertn@umich.edu    virtual BaseMasterPort &getMasterPort(const std::string &if_name,
1833671Sbinkertn@umich.edu                                          PortID idx = InvalidPortID);
1843671Sbinkertn@umich.edu
1853671Sbinkertn@umich.edu};
1863671Sbinkertn@umich.edu
1875361Srstrong@cs.ucsd.edu#endif // __DEV_DMA_DEVICE_HH__
1883671Sbinkertn@umich.edu