sinic.hh revision 2566
16657Snate@binkert.org/*
26657Snate@binkert.org * Copyright (c) 2004-2005 The Regents of The University of Michigan
36657Snate@binkert.org * All rights reserved.
46657Snate@binkert.org *
56657Snate@binkert.org * Redistribution and use in source and binary forms, with or without
66657Snate@binkert.org * modification, are permitted provided that the following conditions are
76657Snate@binkert.org * met: redistributions of source code must retain the above copyright
86657Snate@binkert.org * notice, this list of conditions and the following disclaimer;
96657Snate@binkert.org * redistributions in binary form must reproduce the above copyright
106657Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
116657Snate@binkert.org * documentation and/or other materials provided with the distribution;
126657Snate@binkert.org * neither the name of the copyright holders nor the names of its
136657Snate@binkert.org * contributors may be used to endorse or promote products derived from
146657Snate@binkert.org * this software without specific prior written permission.
156657Snate@binkert.org *
166657Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176657Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186657Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196657Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206657Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216657Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226657Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236657Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246657Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256657Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266657Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276657Snate@binkert.org */
286999Snate@binkert.org
296657Snate@binkert.org#ifndef __DEV_SINIC_HH__
306657Snate@binkert.org#define __DEV_SINIC_HH__
316657Snate@binkert.org
326657Snate@binkert.org#include "base/inet.hh"
338189SLisa.Hsu@amd.com#include "base/statistics.hh"
346657Snate@binkert.org#include "dev/etherint.hh"
356882SBrad.Beckmann@amd.com#include "dev/etherpkt.hh"
367055Snate@binkert.org#include "dev/io_device.hh"
376882SBrad.Beckmann@amd.com#include "dev/pcidev.hh"
386882SBrad.Beckmann@amd.com#include "dev/pktfifo.hh"
398191SLisa.Hsu@amd.com#include "dev/sinicreg.hh"
406882SBrad.Beckmann@amd.com#include "sim/eventq.hh"
416882SBrad.Beckmann@amd.com
429102SNuwan.Jayasena@amd.comnamespace Sinic {
436888SBrad.Beckmann@amd.com
446882SBrad.Beckmann@amd.comclass Interface;
456882SBrad.Beckmann@amd.comclass Base : public PciDev
466657Snate@binkert.org{
476657Snate@binkert.org  protected:
486657Snate@binkert.org    bool rxEnable;
496657Snate@binkert.org    bool txEnable;
506657Snate@binkert.org    Tick clock;
517839Snilay@cs.wisc.edu    inline Tick cycles(int numCycles) const { return numCycles * clock; }
526657Snate@binkert.org
536882SBrad.Beckmann@amd.com  protected:
546882SBrad.Beckmann@amd.com    Tick intrDelay;
556882SBrad.Beckmann@amd.com    Tick intrTick;
566882SBrad.Beckmann@amd.com    bool cpuIntrEnable;
576882SBrad.Beckmann@amd.com    bool cpuPendingIntr;
586882SBrad.Beckmann@amd.com    void cpuIntrPost(Tick when);
596657Snate@binkert.org    void cpuInterrupt();
606657Snate@binkert.org    void cpuIntrClear();
616657Snate@binkert.org
626657Snate@binkert.org    typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent;
636657Snate@binkert.org    friend void IntrEvent::process();
646657Snate@binkert.org    IntrEvent *intrEvent;
656657Snate@binkert.org    Interface *interface;
666657Snate@binkert.org
676657Snate@binkert.org    bool cpuIntrPending() const;
687839Snilay@cs.wisc.edu    void cpuIntrAck() { cpuIntrClear(); }
697839Snilay@cs.wisc.edu
706657Snate@binkert.org/**
716657Snate@binkert.org * Serialization stuff
726657Snate@binkert.org */
736657Snate@binkert.org  public:
746657Snate@binkert.org    virtual void serialize(std::ostream &os);
756657Snate@binkert.org    virtual void unserialize(Checkpoint *cp, const std::string &section);
766657Snate@binkert.org
776657Snate@binkert.org/**
786657Snate@binkert.org * Construction/Destruction/Parameters
796657Snate@binkert.org */
806657Snate@binkert.org  public:
816657Snate@binkert.org    struct Params : public PciDev::Params
826657Snate@binkert.org    {
836657Snate@binkert.org        Tick clock;
846657Snate@binkert.org        Tick intr_delay;
856657Snate@binkert.org    };
866657Snate@binkert.org
876657Snate@binkert.org    Base(Params *p);
886657Snate@binkert.org};
896657Snate@binkert.org
906779SBrad.Beckmann@amd.comclass Device : public Base
916657Snate@binkert.org{
926657Snate@binkert.org  protected:
936657Snate@binkert.org    /** Receive State Machine States */
946657Snate@binkert.org    enum RxState {
956657Snate@binkert.org        rxIdle,
966657Snate@binkert.org        rxFifoBlock,
976657Snate@binkert.org        rxBeginCopy,
986657Snate@binkert.org        rxCopy,
996657Snate@binkert.org        rxCopyDone
1006657Snate@binkert.org    };
1016657Snate@binkert.org
1026657Snate@binkert.org    /** Transmit State Machine states */
1036657Snate@binkert.org    enum TxState {
1046657Snate@binkert.org        txIdle,
1056657Snate@binkert.org        txFifoBlock,
1066657Snate@binkert.org        txBeginCopy,
1076657Snate@binkert.org        txCopy,
1086657Snate@binkert.org        txCopyDone
1096657Snate@binkert.org    };
1106657Snate@binkert.org
1116657Snate@binkert.org    /** device register file */
1126657Snate@binkert.org    struct {
1136657Snate@binkert.org        uint32_t Config;       // 0x00
1146657Snate@binkert.org        uint32_t Command;      // 0x04
1157839Snilay@cs.wisc.edu        uint32_t IntrStatus;   // 0x08
1167839Snilay@cs.wisc.edu        uint32_t IntrMask;     // 0x0c
1177839Snilay@cs.wisc.edu        uint32_t RxMaxCopy;    // 0x10
1187839Snilay@cs.wisc.edu        uint32_t TxMaxCopy;    // 0x14
1197839Snilay@cs.wisc.edu        uint32_t RxMaxIntr;    // 0x18
1207839Snilay@cs.wisc.edu        uint32_t Reserved0;    // 0x1c
1217839Snilay@cs.wisc.edu        uint32_t RxFifoSize;   // 0x20
1227839Snilay@cs.wisc.edu        uint32_t TxFifoSize;   // 0x24
1237839Snilay@cs.wisc.edu        uint32_t RxFifoMark;   // 0x28
1247839Snilay@cs.wisc.edu        uint32_t TxFifoMark;   // 0x2c
1257839Snilay@cs.wisc.edu        uint64_t RxData;       // 0x30
1267839Snilay@cs.wisc.edu        uint64_t RxDone;       // 0x38
1277839Snilay@cs.wisc.edu        uint64_t RxWait;       // 0x40
1287839Snilay@cs.wisc.edu        uint64_t TxData;       // 0x48
1297839Snilay@cs.wisc.edu        uint64_t TxDone;       // 0x50
1306657Snate@binkert.org        uint64_t TxWait;       // 0x58
1316657Snate@binkert.org        uint64_t HwAddr;       // 0x60
1326657Snate@binkert.org    } regs;
1336657Snate@binkert.org
1346657Snate@binkert.org    struct VirtualReg {
1356657Snate@binkert.org        uint64_t RxData;
1366657Snate@binkert.org        uint64_t RxDone;
1376657Snate@binkert.org        uint64_t TxData;
1386657Snate@binkert.org        uint64_t TxDone;
1396657Snate@binkert.org
1406657Snate@binkert.org        PacketFifo::iterator rxPacket;
1416657Snate@binkert.org        int rxPacketOffset;
1426657Snate@binkert.org        int rxPacketBytes;
1436657Snate@binkert.org        uint64_t rxDoneData;
1446657Snate@binkert.org
1456657Snate@binkert.org        VirtualReg()
1466657Snate@binkert.org            : RxData(0), RxDone(0), TxData(0), TxDone(0),
1476657Snate@binkert.org              rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0)
1486657Snate@binkert.org        { }
1496657Snate@binkert.org    };
1506657Snate@binkert.org    typedef std::vector<VirtualReg> VirtualRegs;
1516657Snate@binkert.org    typedef std::list<int> VirtualList;
1526657Snate@binkert.org    VirtualRegs virtualRegs;
1536657Snate@binkert.org    VirtualList rxList;
1546657Snate@binkert.org    VirtualList txList;
1556657Snate@binkert.org
1566657Snate@binkert.org    uint8_t  &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
1576657Snate@binkert.org    uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
1586657Snate@binkert.org    uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }
1596657Snate@binkert.org
1606657Snate@binkert.org  protected:
1616877Ssteve.reinhardt@amd.com    RxState rxState;
1626657Snate@binkert.org    PacketFifo rxFifo;
1636657Snate@binkert.org    PacketFifo::iterator rxFifoPtr;
1646657Snate@binkert.org    bool rxEmpty;
1656657Snate@binkert.org    Addr rxDmaAddr;
1666657Snate@binkert.org    uint8_t *rxDmaData;
1676657Snate@binkert.org    int rxDmaLen;
1687542SBrad.Beckmann@amd.com
1697542SBrad.Beckmann@amd.com    TxState txState;
1706657Snate@binkert.org    PacketFifo txFifo;
1716877Ssteve.reinhardt@amd.com    bool txFull;
1726999Snate@binkert.org    EthPacketPtr txPacket;
1736877Ssteve.reinhardt@amd.com    int txPacketOffset;
1746877Ssteve.reinhardt@amd.com    int txPacketBytes;
1756877Ssteve.reinhardt@amd.com    Addr txDmaAddr;
1766877Ssteve.reinhardt@amd.com    uint8_t *txDmaData;
1776877Ssteve.reinhardt@amd.com    int txDmaLen;
1786877Ssteve.reinhardt@amd.com
1796877Ssteve.reinhardt@amd.com  protected:
1806877Ssteve.reinhardt@amd.com    void reset();
1816877Ssteve.reinhardt@amd.com
1826877Ssteve.reinhardt@amd.com    void rxKick();
1836877Ssteve.reinhardt@amd.com    Tick rxKickTick;
1846877Ssteve.reinhardt@amd.com    typedef EventWrapper<Device, &Device::rxKick> RxKickEvent;
1856877Ssteve.reinhardt@amd.com    friend void RxKickEvent::process();
1866877Ssteve.reinhardt@amd.com
1876877Ssteve.reinhardt@amd.com    void txKick();
1886877Ssteve.reinhardt@amd.com    Tick txKickTick;
1896882SBrad.Beckmann@amd.com    typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
1906882SBrad.Beckmann@amd.com    friend void TxKickEvent::process();
1916882SBrad.Beckmann@amd.com
1926882SBrad.Beckmann@amd.com    /**
1936882SBrad.Beckmann@amd.com     * Retransmit event
1946882SBrad.Beckmann@amd.com     */
1956882SBrad.Beckmann@amd.com    void transmit();
1966877Ssteve.reinhardt@amd.com    void txEventTransmit()
1976877Ssteve.reinhardt@amd.com    {
1986877Ssteve.reinhardt@amd.com        transmit();
1996877Ssteve.reinhardt@amd.com        if (txState == txFifoBlock)
2006657Snate@binkert.org            txKick();
2016657Snate@binkert.org    }
2026999Snate@binkert.org    typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent;
2036657Snate@binkert.org    friend void TxEvent::process();
2046657Snate@binkert.org    TxEvent txEvent;
2056657Snate@binkert.org
2066657Snate@binkert.org    void txDump() const;
2076657Snate@binkert.org    void rxDump() const;
2086657Snate@binkert.org
2097007Snate@binkert.org    /**
2106657Snate@binkert.org     * receive address filter
2116657Snate@binkert.org     */
2126657Snate@binkert.org    bool rxFilter(const EthPacketPtr &packet);
2136657Snate@binkert.org
2146657Snate@binkert.org/**
2157007Snate@binkert.org * device configuration
2167007Snate@binkert.org */
2176657Snate@binkert.org    void changeConfig(uint32_t newconfig);
2187002Snate@binkert.org    void command(uint32_t command);
2197002Snate@binkert.org
2207002Snate@binkert.org/**
2217002Snate@binkert.org * device ethernet interface
2228229Snate@binkert.org */
2238229Snate@binkert.org  public:
2246657Snate@binkert.org    bool recvPacket(EthPacketPtr packet);
2256657Snate@binkert.org    void transferDone();
2268229Snate@binkert.org    void setInterface(Interface *i) { assert(!interface); interface = i; }
2278229Snate@binkert.org
2288229Snate@binkert.org/**
2298229Snate@binkert.org * DMA parameters
2306657Snate@binkert.org */
2316657Snate@binkert.org  protected:
2326657Snate@binkert.org    void rxDmaDone();
2336657Snate@binkert.org    friend class EventWrapper<Device, &Device::rxDmaDone>;
2346793SBrad.Beckmann@amd.com    EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
2356657Snate@binkert.org
2366657Snate@binkert.org    void txDmaDone();
2376657Snate@binkert.org    friend class EventWrapper<Device, &Device::txDmaDone>;
2386657Snate@binkert.org    EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
2396657Snate@binkert.org
2407002Snate@binkert.org    Tick dmaReadDelay;
2416657Snate@binkert.org    Tick dmaReadFactor;
2427007Snate@binkert.org    Tick dmaWriteDelay;
2437007Snate@binkert.org    Tick dmaWriteFactor;
2447007Snate@binkert.org
2457007Snate@binkert.org/**
2467007Snate@binkert.org * Interrupt management
2476657Snate@binkert.org */
2486877Ssteve.reinhardt@amd.com  protected:
2496877Ssteve.reinhardt@amd.com    void devIntrPost(uint32_t interrupts);
2506657Snate@binkert.org    void devIntrClear(uint32_t interrupts = Regs::Intr_All);
2516877Ssteve.reinhardt@amd.com    void devIntrChangeMask(uint32_t newmask);
2526657Snate@binkert.org
2536657Snate@binkert.org/**
2547002Snate@binkert.org * Memory Interface
2557002Snate@binkert.org */
2567567SBrad.Beckmann@amd.com  public:
2577567SBrad.Beckmann@amd.com    virtual Tick read(Packet &pkt);
2587922SBrad.Beckmann@amd.com    virtual Tick write(Packet &pkt);
2596881SBrad.Beckmann@amd.com
2607002Snate@binkert.org    void prepareIO(int cpu, int index);
2617002Snate@binkert.org    void prepareRead(int cpu, int index);
2626657Snate@binkert.org    void prepareWrite(int cpu, int index);
2637002Snate@binkert.org //   Fault iprRead(Addr daddr, int cpu, uint64_t &result);
2646902SBrad.Beckmann@amd.com
2656863Sdrh5@cs.wisc.edu/**
2666863Sdrh5@cs.wisc.edu * Statistics
2678683Snilay@cs.wisc.edu */
2688683Snilay@cs.wisc.edu  private:
2697007Snate@binkert.org    Stats::Scalar<> rxBytes;
2706657Snate@binkert.org    Stats::Formula  rxBandwidth;
2716657Snate@binkert.org    Stats::Scalar<> rxPackets;
2726657Snate@binkert.org    Stats::Formula  rxPacketRate;
2736657Snate@binkert.org    Stats::Scalar<> rxIpPackets;
2746657Snate@binkert.org    Stats::Scalar<> rxTcpPackets;
2756657Snate@binkert.org    Stats::Scalar<> rxUdpPackets;
2766882SBrad.Beckmann@amd.com    Stats::Scalar<> rxIpChecksums;
2776882SBrad.Beckmann@amd.com    Stats::Scalar<> rxTcpChecksums;
2786882SBrad.Beckmann@amd.com    Stats::Scalar<> rxUdpChecksums;
2796882SBrad.Beckmann@amd.com
2806657Snate@binkert.org    Stats::Scalar<> txBytes;
2816657Snate@binkert.org    Stats::Formula  txBandwidth;
2826657Snate@binkert.org    Stats::Formula totBandwidth;
2836657Snate@binkert.org    Stats::Formula totPackets;
2847007Snate@binkert.org    Stats::Formula totBytes;
2857839Snilay@cs.wisc.edu    Stats::Formula totPacketRate;
2867839Snilay@cs.wisc.edu    Stats::Scalar<> txPackets;
2877839Snilay@cs.wisc.edu    Stats::Formula  txPacketRate;
2887839Snilay@cs.wisc.edu    Stats::Scalar<> txIpPackets;
2897839Snilay@cs.wisc.edu    Stats::Scalar<> txTcpPackets;
2907839Snilay@cs.wisc.edu    Stats::Scalar<> txUdpPackets;
2917839Snilay@cs.wisc.edu    Stats::Scalar<> txIpChecksums;
2927839Snilay@cs.wisc.edu    Stats::Scalar<> txTcpChecksums;
2937839Snilay@cs.wisc.edu    Stats::Scalar<> txUdpChecksums;
2947839Snilay@cs.wisc.edu
2957839Snilay@cs.wisc.edu  public:
2967839Snilay@cs.wisc.edu    virtual void regStats();
2977007Snate@binkert.org
2987007Snate@binkert.org/**
2997007Snate@binkert.org * Serialization stuff
3007007Snate@binkert.org */
3017007Snate@binkert.org  public:
3027839Snilay@cs.wisc.edu    virtual void serialize(std::ostream &os);
3037839Snilay@cs.wisc.edu    virtual void unserialize(Checkpoint *cp, const std::string &section);
3047839Snilay@cs.wisc.edu
3057839Snilay@cs.wisc.edu/**
3067839Snilay@cs.wisc.edu * Construction/Destruction/Parameters
3077839Snilay@cs.wisc.edu */
3087839Snilay@cs.wisc.edu  public:
3097839Snilay@cs.wisc.edu    struct Params : public Base::Params
3107839Snilay@cs.wisc.edu    {
3117839Snilay@cs.wisc.edu        Tick tx_delay;
3127839Snilay@cs.wisc.edu        Tick rx_delay;
3137839Snilay@cs.wisc.edu        bool rx_filter;
3147007Snate@binkert.org        Net::EthAddr eaddr;
3157007Snate@binkert.org        uint32_t rx_max_copy;
3167002Snate@binkert.org        uint32_t tx_max_copy;
3176657Snate@binkert.org        uint32_t rx_max_intr;
3186657Snate@binkert.org        uint32_t rx_fifo_size;
3196657Snate@binkert.org        uint32_t tx_fifo_size;
3207055Snate@binkert.org        uint32_t rx_fifo_threshold;
3216657Snate@binkert.org        uint32_t tx_fifo_threshold;
3226657Snate@binkert.org        Tick dma_read_delay;
3236657Snate@binkert.org        Tick dma_read_factor;
3246863Sdrh5@cs.wisc.edu        Tick dma_write_delay;
3257055Snate@binkert.org        Tick dma_write_factor;
3267567SBrad.Beckmann@amd.com        bool rx_thread;
3278943Sandreas.hansson@arm.com        bool tx_thread;
3287567SBrad.Beckmann@amd.com        bool rss;
3297567SBrad.Beckmann@amd.com    };
3307567SBrad.Beckmann@amd.com
3317542SBrad.Beckmann@amd.com  protected:
3327542SBrad.Beckmann@amd.com    const Params *params() const { return (const Params *)_params; }
3336657Snate@binkert.org
3347007Snate@binkert.org  public:
3356657Snate@binkert.org    Device(Params *params);
3366657Snate@binkert.org    ~Device();
3376657Snate@binkert.org};
3386657Snate@binkert.org
3396657Snate@binkert.org/*
3406657Snate@binkert.org * Ethernet Interface for an Ethernet Device
3416657Snate@binkert.org */
3426657Snate@binkert.orgclass Interface : public EtherInt
3437839Snilay@cs.wisc.edu{
3447839Snilay@cs.wisc.edu  private:
3457839Snilay@cs.wisc.edu    Device *dev;
3467839Snilay@cs.wisc.edu
3477839Snilay@cs.wisc.edu  public:
3487839Snilay@cs.wisc.edu    Interface(const std::string &name, Device *d)
3497839Snilay@cs.wisc.edu        : EtherInt(name), dev(d) { dev->setInterface(this); }
3507839Snilay@cs.wisc.edu
3517839Snilay@cs.wisc.edu    virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
3527839Snilay@cs.wisc.edu    virtual void sendDone() { dev->transferDone(); }
3537839Snilay@cs.wisc.edu};
3547839Snilay@cs.wisc.edu
3557839Snilay@cs.wisc.edu/* namespace Sinic */ }
3567839Snilay@cs.wisc.edu
3577839Snilay@cs.wisc.edu#endif // __DEV_SINIC_HH__
3587839Snilay@cs.wisc.edu