15794SN/A/*
28841SN/A * Copyright (c) 2012 ARM Limited
38841SN/A * All rights reserved
48841SN/A *
58841SN/A * The license below extends only to copyright in the software and shall
68841SN/A * not be construed as granting a license to any other intellectual
78841SN/A * property including but not limited to intellectual property relating
88841SN/A * to a hardware implementation of the functionality of the software
98841SN/A * licensed hereunder.  You may use the software subject to the license
108841SN/A * terms below provided that you ensure that this notice is replicated
118841SN/A * unmodified and in its entirety in all distributions of the software,
128841SN/A * modified or unmodified, in source code or in binary form.
138841SN/A *
145794SN/A * Copyright (c) 2008 The Regents of The University of Michigan
155794SN/A * All rights reserved.
165794SN/A *
175794SN/A * Redistribution and use in source and binary forms, with or without
185794SN/A * modification, are permitted provided that the following conditions are
195794SN/A * met: redistributions of source code must retain the above copyright
205794SN/A * notice, this list of conditions and the following disclaimer;
215794SN/A * redistributions in binary form must reproduce the above copyright
225794SN/A * notice, this list of conditions and the following disclaimer in the
235794SN/A * documentation and/or other materials provided with the distribution;
245794SN/A * neither the name of the copyright holders nor the names of its
255794SN/A * contributors may be used to endorse or promote products derived from
265794SN/A * this software without specific prior written permission.
275794SN/A *
285794SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
295794SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
305794SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
315794SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
325794SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
335794SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
345794SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
355794SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
365794SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
375794SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
385794SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
395794SN/A *
405794SN/A * Authors: Ali Saidi
415794SN/A */
425794SN/A
435794SN/A/* @file
445794SN/A * Device model for Intel's I/O Acceleration Technology (I/OAT).
455794SN/A * A DMA asyncronous copy engine
465794SN/A */
475794SN/A
4811261Sandreas.sandberg@arm.com#ifndef __DEV_PCI_COPY_ENGINE_HH__
4911261Sandreas.sandberg@arm.com#define __DEV_PCI_COPY_ENGINE_HH__
505794SN/A
515794SN/A#include <vector>
525794SN/A
539338SN/A#include "base/cp_annotate.hh"
545794SN/A#include "base/statistics.hh"
5511261Sandreas.sandberg@arm.com#include "dev/pci/copy_engine_defs.hh"
5611260SN/A#include "dev/pci/device.hh"
575794SN/A#include "params/CopyEngine.hh"
589342SN/A#include "sim/drain.hh"
595794SN/A#include "sim/eventq.hh"
605794SN/A
619807SN/Aclass CopyEngine : public PciDevice
625794SN/A{
6310905SN/A    class CopyEngineChannel : public Drainable, public Serializable
645794SN/A    {
655794SN/A      private:
668851SN/A        DmaPort cePort;
675794SN/A        CopyEngine *ce;
685794SN/A        CopyEngineReg::ChanRegs  cr;
695794SN/A        int channelId;
705794SN/A        CopyEngineReg::DmaDesc *curDmaDesc;
715794SN/A        uint8_t *copyBuffer;
725794SN/A
735794SN/A        bool busy;
745794SN/A        bool underReset;
755794SN/A        bool refreshNext;
765794SN/A        Addr lastDescriptorAddr;
775794SN/A        Addr fetchAddress;
785794SN/A
795794SN/A        Tick latBeforeBegin;
805794SN/A        Tick latAfterCompletion;
815794SN/A
825794SN/A        uint64_t completionDataReg;
835794SN/A
845794SN/A        enum ChannelState {
855794SN/A            Idle,
865794SN/A            AddressFetch,
875794SN/A            DescriptorFetch,
885794SN/A            DMARead,
895794SN/A            DMAWrite,
905794SN/A            CompletionWrite
915794SN/A        };
925794SN/A
935794SN/A        ChannelState nextState;
945794SN/A
955794SN/A      public:
965794SN/A        CopyEngineChannel(CopyEngine *_ce, int cid);
975809SN/A        virtual ~CopyEngineChannel();
9813784Sgabeblack@google.com        Port &getPort();
995794SN/A
1005794SN/A        std::string name() { assert(ce); return ce->name() + csprintf("-chan%d", channelId); }
1015794SN/A        virtual Tick read(PacketPtr pkt)
1025794SN/A                        { panic("CopyEngineChannel has no I/O access\n");}
1035794SN/A        virtual Tick write(PacketPtr pkt)
1045794SN/A                        { panic("CopyEngineChannel has no I/O access\n"); }
1055794SN/A
1065794SN/A        void channelRead(PacketPtr pkt, Addr daddr, int size);
1075794SN/A        void channelWrite(PacketPtr pkt, Addr daddr, int size);
1085794SN/A
10911168SN/A        DrainState drain() override;
11011168SN/A        void drainResume() override;
1119342SN/A
11211168SN/A        void serialize(CheckpointOut &cp) const override;
11311168SN/A        void unserialize(CheckpointIn &cp) override;
1145794SN/A
1155794SN/A      private:
1165794SN/A        void fetchDescriptor(Addr address);
1175794SN/A        void fetchDescComplete();
11812087Sspwilson2@wisc.edu        EventFunctionWrapper fetchCompleteEvent;
1195794SN/A
1205794SN/A        void fetchNextAddr(Addr address);
1215794SN/A        void fetchAddrComplete();
12212087Sspwilson2@wisc.edu        EventFunctionWrapper addrCompleteEvent;
1235794SN/A
1245794SN/A        void readCopyBytes();
1255794SN/A        void readCopyBytesComplete();
12612087Sspwilson2@wisc.edu        EventFunctionWrapper readCompleteEvent;
1275794SN/A
1285794SN/A        void writeCopyBytes();
1295794SN/A        void writeCopyBytesComplete();
13012087Sspwilson2@wisc.edu        EventFunctionWrapper writeCompleteEvent;
1315794SN/A
1325794SN/A        void writeCompletionStatus();
1335794SN/A        void writeStatusComplete();
13412087Sspwilson2@wisc.edu        EventFunctionWrapper statusCompleteEvent;
1355794SN/A
1365794SN/A
1375794SN/A        void continueProcessing();
1385794SN/A        void recvCommand();
1395794SN/A        bool inDrain();
1405794SN/A        void restartStateMachine();
1415954SN/A        inline void anBegin(const char *s)
1425954SN/A        {
1435954SN/A            CPA::cpa()->hwBegin(CPA::FL_NONE, ce->sys,
1445954SN/A                         channelId, "CopyEngine", s);
1455954SN/A        }
1465954SN/A
1475954SN/A        inline void anWait()
1485954SN/A        {
1495954SN/A            CPA::cpa()->hwWe(CPA::FL_NONE, ce->sys,
1505954SN/A                     channelId, "CopyEngine", "DMAUnusedDescQ", channelId);
1515954SN/A        }
1525954SN/A
1535954SN/A        inline void anDq()
1545954SN/A        {
1555954SN/A            CPA::cpa()->hwDq(CPA::FL_NONE, ce->sys,
1565954SN/A                      channelId, "CopyEngine", "DMAUnusedDescQ", channelId);
1575954SN/A        }
1585954SN/A
1595954SN/A        inline void anPq()
1605954SN/A        {
1615954SN/A            CPA::cpa()->hwDq(CPA::FL_NONE, ce->sys,
1625954SN/A                      channelId, "CopyEngine", "DMAUnusedDescQ", channelId);
1635954SN/A        }
1645954SN/A
1655954SN/A        inline void anQ(const char * s, uint64_t id, int size = 1)
1665954SN/A        {
1675954SN/A            CPA::cpa()->hwQ(CPA::FL_NONE, ce->sys, channelId,
1685954SN/A                    "CopyEngine", s, id, NULL, size);
1695954SN/A        }
1705954SN/A
1715794SN/A    };
1725794SN/A
1735794SN/A  private:
1745794SN/A
1755999SN/A    Stats::Vector bytesCopied;
1765999SN/A    Stats::Vector copiesProcessed;
1775794SN/A
1785794SN/A    // device registers
1795794SN/A    CopyEngineReg::Regs regs;
1805794SN/A
1815794SN/A    // Array of channels each one with regs/dma port/etc
1825794SN/A    std::vector<CopyEngineChannel*> chan;
1835794SN/A
1845794SN/A  public:
1855794SN/A    typedef CopyEngineParams Params;
1865794SN/A    const Params *
1875794SN/A    params() const
1885794SN/A    {
1895794SN/A        return dynamic_cast<const Params *>(_params);
1905794SN/A    }
1915794SN/A    CopyEngine(const Params *params);
1925794SN/A    ~CopyEngine();
1935794SN/A
19411169SN/A    void regStats() override;
1958841SN/A
19613784Sgabeblack@google.com    Port &getPort(const std::string &if_name,
19713784Sgabeblack@google.com            PortID idx = InvalidPortID) override;
1985794SN/A
19911169SN/A    Tick read(PacketPtr pkt) override;
20011169SN/A    Tick write(PacketPtr pkt) override;
2015794SN/A
20211168SN/A    void serialize(CheckpointOut &cp) const override;
20311168SN/A    void unserialize(CheckpointIn &cp) override;
2045794SN/A};
2055794SN/A
20611261Sandreas.sandberg@arm.com#endif //__DEV_PCI_COPY_ENGINE_HH__
2075794SN/A
208