dma_device.hh revision 9342:6fec8f26e56d
17202Sgblack@eecs.umich.edu/*
27202Sgblack@eecs.umich.edu * Copyright (c) 2012 ARM Limited
37202Sgblack@eecs.umich.edu * All rights reserved.
47202Sgblack@eecs.umich.edu *
57202Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
67202Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
77202Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
87202Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
97202Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
107202Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
117202Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
127202Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
137202Sgblack@eecs.umich.edu *
147202Sgblack@eecs.umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan
157202Sgblack@eecs.umich.edu * All rights reserved.
167202Sgblack@eecs.umich.edu *
177202Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
187202Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
197202Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
207202Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
217202Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
227202Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
237202Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
247202Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
257202Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
267202Sgblack@eecs.umich.edu * this software without specific prior written permission.
277202Sgblack@eecs.umich.edu *
287202Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
297202Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
307202Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
317202Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
327202Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
337202Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
347202Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
357202Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
367202Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
377202Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
387202Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
397202Sgblack@eecs.umich.edu *
407202Sgblack@eecs.umich.edu * Authors: Ali Saidi
417202Sgblack@eecs.umich.edu *          Nathan Binkert
427202Sgblack@eecs.umich.edu */
437202Sgblack@eecs.umich.edu
447202Sgblack@eecs.umich.edu#ifndef __DEV_DMA_DEVICE_HH__
457202Sgblack@eecs.umich.edu#define __DEV_DMA_DEVICE_HH__
467202Sgblack@eecs.umich.edu
477202Sgblack@eecs.umich.edu#include <deque>
487202Sgblack@eecs.umich.edu
497202Sgblack@eecs.umich.edu#include "dev/io_device.hh"
507202Sgblack@eecs.umich.edu#include "params/DmaDevice.hh"
517202Sgblack@eecs.umich.edu#include "sim/drain.hh"
527202Sgblack@eecs.umich.edu
537202Sgblack@eecs.umich.educlass DmaPort : public MasterPort
547202Sgblack@eecs.umich.edu{
557202Sgblack@eecs.umich.edu  private:
567202Sgblack@eecs.umich.edu
577202Sgblack@eecs.umich.edu    /**
587202Sgblack@eecs.umich.edu     * Take the first packet of the transmit list and attempt to send
597202Sgblack@eecs.umich.edu     * it as a timing request. If it is successful, schedule the
607202Sgblack@eecs.umich.edu     * sending of the next packet, otherwise remember that we are
617202Sgblack@eecs.umich.edu     * waiting for a retry.
627202Sgblack@eecs.umich.edu     */
637202Sgblack@eecs.umich.edu    void trySendTimingReq();
647202Sgblack@eecs.umich.edu
657202Sgblack@eecs.umich.edu    /**
667202Sgblack@eecs.umich.edu     * For timing, attempt to send the first item on the transmit
677202Sgblack@eecs.umich.edu     * list, and if it is successful and there are more packets
687202Sgblack@eecs.umich.edu     * waiting, then schedule the sending of the next packet. For
697202Sgblack@eecs.umich.edu     * atomic, simply send and process everything on the transmit
707202Sgblack@eecs.umich.edu     * list.
717202Sgblack@eecs.umich.edu     */
727202Sgblack@eecs.umich.edu    void sendDma();
737202Sgblack@eecs.umich.edu
747202Sgblack@eecs.umich.edu    /**
757202Sgblack@eecs.umich.edu     * Handle a response packet by updating the corresponding DMA
767202Sgblack@eecs.umich.edu     * request state to reflect the bytes received, and also update
777202Sgblack@eecs.umich.edu     * the pending request counter. If the DMA request that this
787202Sgblack@eecs.umich.edu     * packet is part of is complete, then signal the completion event
797202Sgblack@eecs.umich.edu     * if present, potentially with a delay added to it.
807202Sgblack@eecs.umich.edu     *
817202Sgblack@eecs.umich.edu     * @param pkt Response packet to handler
827202Sgblack@eecs.umich.edu     * @param delay Additional delay for scheduling the completion event
837202Sgblack@eecs.umich.edu     */
847202Sgblack@eecs.umich.edu    void handleResp(PacketPtr pkt, Tick delay = 0);
857202Sgblack@eecs.umich.edu
867202Sgblack@eecs.umich.edu    struct DmaReqState : public Packet::SenderState
877202Sgblack@eecs.umich.edu    {
887202Sgblack@eecs.umich.edu        /** Event to call on the device when this transaction (all packets)
897202Sgblack@eecs.umich.edu         * complete. */
907202Sgblack@eecs.umich.edu        Event *completionEvent;
917202Sgblack@eecs.umich.edu
927202Sgblack@eecs.umich.edu        /** Total number of bytes that this transaction involves. */
937202Sgblack@eecs.umich.edu        const Addr totBytes;
947202Sgblack@eecs.umich.edu
957202Sgblack@eecs.umich.edu        /** Number of bytes that have been acked for this transaction. */
967202Sgblack@eecs.umich.edu        Addr numBytes;
977202Sgblack@eecs.umich.edu
987202Sgblack@eecs.umich.edu        /** Amount to delay completion of dma by */
997202Sgblack@eecs.umich.edu        const Tick delay;
1007202Sgblack@eecs.umich.edu
1017208Sgblack@eecs.umich.edu        DmaReqState(Event *ce, Addr tb, Tick _delay)
1027208Sgblack@eecs.umich.edu            : completionEvent(ce), totBytes(tb), numBytes(0), delay(_delay)
1037208Sgblack@eecs.umich.edu        {}
1047208Sgblack@eecs.umich.edu    };
1057208Sgblack@eecs.umich.edu
1067208Sgblack@eecs.umich.edu    /** The device that owns this port. */
1077208Sgblack@eecs.umich.edu    MemObject *device;
1087208Sgblack@eecs.umich.edu
1097208Sgblack@eecs.umich.edu    /** Use a deque as we never do any insertion or removal in the middle */
1107208Sgblack@eecs.umich.edu    std::deque<PacketPtr> transmitList;
1117208Sgblack@eecs.umich.edu
1127208Sgblack@eecs.umich.edu    /** Event used to schedule a future sending from the transmit list. */
1137208Sgblack@eecs.umich.edu    EventWrapper<DmaPort, &DmaPort::sendDma> sendEvent;
1147208Sgblack@eecs.umich.edu
1157208Sgblack@eecs.umich.edu    /** The system that device/port are in. This is used to select which mode
1167208Sgblack@eecs.umich.edu     * we are currently operating in. */
1177208Sgblack@eecs.umich.edu    System *sys;
1187208Sgblack@eecs.umich.edu
1197208Sgblack@eecs.umich.edu    /** Id for all requests */
1207208Sgblack@eecs.umich.edu    const MasterID masterId;
1217208Sgblack@eecs.umich.edu
1227225Sgblack@eecs.umich.edu    /** Number of outstanding packets the dma port has. */
1237233Sgblack@eecs.umich.edu    uint32_t pendingCount;
1247233Sgblack@eecs.umich.edu
1257233Sgblack@eecs.umich.edu    /** If we need to drain, keep the drain event around until we're done
1267233Sgblack@eecs.umich.edu     * here.*/
1277233Sgblack@eecs.umich.edu    DrainManager *drainManager;
1287233Sgblack@eecs.umich.edu
1297233Sgblack@eecs.umich.edu    /** If the port is currently waiting for a retry before it can
1307233Sgblack@eecs.umich.edu     * send whatever it is that it's sending. */
1317233Sgblack@eecs.umich.edu    bool inRetry;
1327233Sgblack@eecs.umich.edu
1337233Sgblack@eecs.umich.edu  protected:
1347233Sgblack@eecs.umich.edu
1357233Sgblack@eecs.umich.edu    bool recvTimingResp(PacketPtr pkt);
1367233Sgblack@eecs.umich.edu    void recvRetry() ;
1377233Sgblack@eecs.umich.edu
1387233Sgblack@eecs.umich.edu    void queueDma(PacketPtr pkt);
1397233Sgblack@eecs.umich.edu
1407233Sgblack@eecs.umich.edu  public:
1417233Sgblack@eecs.umich.edu
1427233Sgblack@eecs.umich.edu    DmaPort(MemObject *dev, System *s);
1437233Sgblack@eecs.umich.edu
1447233Sgblack@eecs.umich.edu    void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
1457233Sgblack@eecs.umich.edu                   uint8_t *data, Tick delay, Request::Flags flag = 0);
1467233Sgblack@eecs.umich.edu
1477233Sgblack@eecs.umich.edu    bool dmaPending() const { return pendingCount > 0; }
1487233Sgblack@eecs.umich.edu
1497232Sgblack@eecs.umich.edu    unsigned cacheBlockSize() const { return peerBlockSize(); }
1507225Sgblack@eecs.umich.edu    unsigned int drain(DrainManager *drainManger);
1517225Sgblack@eecs.umich.edu};
1527225Sgblack@eecs.umich.edu
1537225Sgblack@eecs.umich.educlass DmaDevice : public PioDevice
1547225Sgblack@eecs.umich.edu{
1557225Sgblack@eecs.umich.edu   protected:
1567232Sgblack@eecs.umich.edu    DmaPort dmaPort;
1577225Sgblack@eecs.umich.edu
1587225Sgblack@eecs.umich.edu  public:
1597225Sgblack@eecs.umich.edu    typedef DmaDeviceParams Params;
1607225Sgblack@eecs.umich.edu    DmaDevice(const Params *p);
1617232Sgblack@eecs.umich.edu    virtual ~DmaDevice() { }
1627225Sgblack@eecs.umich.edu
1637225Sgblack@eecs.umich.edu    void dmaWrite(Addr addr, int size, Event *event, uint8_t *data,
1647232Sgblack@eecs.umich.edu                  Tick delay = 0)
1657225Sgblack@eecs.umich.edu    {
1667225Sgblack@eecs.umich.edu        dmaPort.dmaAction(MemCmd::WriteReq, addr, size, event, data, delay);
1677232Sgblack@eecs.umich.edu    }
1687225Sgblack@eecs.umich.edu
1697225Sgblack@eecs.umich.edu    void dmaRead(Addr addr, int size, Event *event, uint8_t *data,
1707225Sgblack@eecs.umich.edu                 Tick delay = 0)
1717225Sgblack@eecs.umich.edu    {
1727225Sgblack@eecs.umich.edu        dmaPort.dmaAction(MemCmd::ReadReq, addr, size, event, data, delay);
1737232Sgblack@eecs.umich.edu    }
1747225Sgblack@eecs.umich.edu
1757225Sgblack@eecs.umich.edu    bool dmaPending() const { return dmaPort.dmaPending(); }
1767225Sgblack@eecs.umich.edu
1777225Sgblack@eecs.umich.edu    virtual void init();
1787225Sgblack@eecs.umich.edu
1797225Sgblack@eecs.umich.edu    unsigned int drain(DrainManager *drainManger);
1807232Sgblack@eecs.umich.edu
1817225Sgblack@eecs.umich.edu    unsigned cacheBlockSize() const { return dmaPort.cacheBlockSize(); }
1827225Sgblack@eecs.umich.edu
1837225Sgblack@eecs.umich.edu    virtual BaseMasterPort &getMasterPort(const std::string &if_name,
1847225Sgblack@eecs.umich.edu                                          PortID idx = InvalidPortID);
1857225Sgblack@eecs.umich.edu
1867232Sgblack@eecs.umich.edu};
1877225Sgblack@eecs.umich.edu
1887225Sgblack@eecs.umich.edu#endif // __DEV_DMA_DEVICE_HH__
1897232Sgblack@eecs.umich.edu