ns_gige.hh revision 1762
12SN/A/*
21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
282665Ssaidi@eecs.umich.edu
292SN/A/** @file
302SN/A * Device module for modelling the National Semiconductor
312439SN/A * DP83820 ethernet controller
322984Sgblack@eecs.umich.edu */
33146SN/A
34146SN/A#ifndef __DEV_NS_GIGE_HH__
35146SN/A#define __DEV_NS_GIGE_HH__
36146SN/A
37146SN/A#include "base/inet.hh"
38146SN/A#include "base/statistics.hh"
391717SN/A#include "dev/etherint.hh"
40146SN/A#include "dev/etherpkt.hh"
411717SN/A#include "dev/io_device.hh"
42146SN/A#include "dev/ns_gige_reg.h"
431977SN/A#include "dev/pcidev.hh"
442623SN/A#include "dev/pktfifo.hh"
452683Sktlim@umich.edu#include "mem/bus/bus.hh"
461717SN/A#include "sim/eventq.hh"
47146SN/A
482683Sktlim@umich.edu/**
493348Sbinkertn@umich.edu * Ethernet device registers
502683Sktlim@umich.edu */
512036SN/Astruct dp_regs {
52146SN/A    uint32_t	command;
5356SN/A    uint32_t	config;
5456SN/A    uint32_t	mear;
5556SN/A    uint32_t	ptscr;
56695SN/A    uint32_t    isr;
572901Ssaidi@eecs.umich.edu    uint32_t    imr;
582SN/A    uint32_t    ier;
591858SN/A    uint32_t    ihr;
603565Sgblack@eecs.umich.edu    uint32_t    txdp;
613565Sgblack@eecs.umich.edu    uint32_t    txdp_hi;
622171SN/A    uint32_t    txcfg;
632170SN/A    uint32_t    gpior;
643562Sgblack@eecs.umich.edu    uint32_t    rxdp;
65146SN/A    uint32_t    rxdp_hi;
662462SN/A    uint32_t    rxcfg;
67146SN/A    uint32_t    pqcr;
682SN/A    uint32_t    wcsr;
692SN/A    uint32_t    pcr;
702449SN/A    uint32_t    rfcr;
711355SN/A    uint32_t    rfdr;
722623SN/A    uint32_t    srr;
734495Sacolyte@umich.edu    uint32_t    mibc;
74224SN/A    uint32_t    vrcr;
751858SN/A    uint32_t    vtcr;
762683Sktlim@umich.edu    uint32_t    vdr;
772420SN/A    uint32_t    ccsr;
782683Sktlim@umich.edu    uint32_t    tbicr;
793402Sktlim@umich.edu    uint32_t    tbisr;
802420SN/A    uint32_t    tanar;
812SN/A    uint32_t    tanlpar;
824400Srdreslin@umich.edu    uint32_t    taner;
832672Sktlim@umich.edu    uint32_t    tesr;
842683Sktlim@umich.edu};
852SN/A
862SN/Astruct dp_rom {
87334SN/A    /**
88140SN/A     * for perfect match memory.
89334SN/A     * the linux driver doesn't use any other ROM
902SN/A     */
912SN/A    uint8_t perfectMatch[ETH_ADDR_LEN];
922SN/A};
932680Sktlim@umich.edu
944377Sgblack@eecs.umich.educlass NSGigEInt;
954377Sgblack@eecs.umich.educlass PhysicalMemory;
964377Sgblack@eecs.umich.educlass BaseInterface;
972SN/Aclass HierParams;
982SN/Aclass Bus;
992623SN/Aclass PciConfigAll;
1002SN/A
1012SN/A/**
1022SN/A * NS DP82830 Ethernet device model
103180SN/A */
1042623SN/Aclass NSGigE : public PciDev
105393SN/A{
106393SN/A  public:
107393SN/A    /** Transmit State Machine states */
108393SN/A    enum TxState
109384SN/A    {
110384SN/A        txIdle,
111393SN/A        txDescRefr,
1122623SN/A        txDescRead,
113393SN/A        txFifoBlock,
114393SN/A        txFragRead,
115393SN/A        txDescWrite,
116393SN/A        txAdvance
117384SN/A    };
118189SN/A
119189SN/A    /** Receive State Machine States */
1202623SN/A    enum RxState
1212SN/A    {
122729SN/A        rxIdle,
123334SN/A        rxDescRefr,
1242SN/A        rxDescRead,
1252SN/A        rxFifoBlock,
1262SN/A        rxFragWrite,
1272SN/A        rxDescWrite,
1282SN/A        rxAdvance
1292SN/A    };
1302SN/A
1312SN/A    enum DmaState
1322SN/A    {
1332SN/A        dmaIdle,
1342SN/A        dmaReading,
1352SN/A        dmaWriting,
1361001SN/A        dmaReadWaiting,
1371001SN/A        dmaWriteWaiting
1381001SN/A    };
1391001SN/A
1401001SN/A  private:
1412SN/A    Addr addr;
1422SN/A    static const Addr size = sizeof(dp_regs);
1432SN/A
1442SN/A  protected:
1452SN/A    typedef std::deque<PacketPtr> pktbuf_t;
1462SN/A    typedef pktbuf_t::iterator pktiter_t;
1472SN/A
1482SN/A    /** device register file */
1492SN/A    dp_regs regs;
1502SN/A    dp_rom rom;
1512SN/A
1522SN/A    /** pci settings */
1532SN/A    bool ioEnable;
1542SN/A#if 0
1552SN/A    bool memEnable;
1562SN/A    bool bmEnable;
1572SN/A#endif
1582390SN/A
1592390SN/A    /*** BASIC STRUCTURES FOR TX/RX ***/
1602390SN/A    /* Data FIFOs */
1612390SN/A    PacketFifo txFifo;
1622390SN/A    PacketFifo rxFifo;
1632390SN/A
1642390SN/A    /** various helper vars */
1652390SN/A    PacketPtr txPacket;
1662390SN/A    PacketPtr rxPacket;
1672390SN/A    uint8_t *txPacketBufPtr;
1682390SN/A    uint8_t *rxPacketBufPtr;
1692390SN/A    uint32_t txXferLen;
170385SN/A    uint32_t rxXferLen;
1712SN/A    bool rxDmaFree;
1722SN/A    bool txDmaFree;
1732SN/A
1742623SN/A    /** DescCaches */
175334SN/A    ns_desc txDescCache;
1762361SN/A    ns_desc rxDescCache;
1772623SN/A
178334SN/A    /* state machine cycle time */
179334SN/A    Tick clock;
180334SN/A    inline Tick cycles(int numCycles) const { return numCycles * clock; }
1812623SN/A
1822SN/A    /* tx State Machine */
183921SN/A    TxState txState;
1842915Sktlim@umich.edu    bool txEnable;
1852915Sktlim@umich.edu
1862683Sktlim@umich.edu    /** Current Transmit Descriptor Done */
1872SN/A    bool CTDD;
1882SN/A    /** halt the tx state machine after next packet */
1892SN/A    bool txHalt;
1902623SN/A    /** ptr to the next byte in the current fragment */
1912SN/A    Addr txFragPtr;
192921SN/A    /** count of bytes remaining in the current descriptor */
1932915Sktlim@umich.edu    uint32_t txDescCnt;
1942915Sktlim@umich.edu    DmaState txDmaState;
1952SN/A
1962SN/A    /** rx State Machine */
1972SN/A    RxState rxState;
1982SN/A    bool rxEnable;
1992SN/A
2002SN/A    /** Current Receive Descriptor Done */
2012SN/A    bool CRDD;
202595SN/A    /** num of bytes in the current packet being drained from rxDataFifo */
2032623SN/A    uint32_t rxPktBytes;
204595SN/A    /** halt the rx state machine after current packet */
2052390SN/A    bool rxHalt;
2061080SN/A    /** ptr to the next byte in current fragment */
2071080SN/A    Addr rxFragPtr;
2081080SN/A    /** count of bytes remaining in the current descriptor */
2091080SN/A    uint32_t rxDescCnt;
2101080SN/A    DmaState rxDmaState;
2111080SN/A
2121080SN/A    bool extstsEnable;
2131121SN/A
2142107SN/A  protected:
2151089SN/A    Tick dmaReadDelay;
2161089SN/A    Tick dmaWriteDelay;
2171080SN/A
2181080SN/A    Tick dmaReadFactor;
2191080SN/A    Tick dmaWriteFactor;
2201080SN/A
221595SN/A    void *rxDmaData;
2222623SN/A    Addr  rxDmaAddr;
2232683Sktlim@umich.edu    int   rxDmaLen;
224595SN/A    bool  doRxDmaRead();
2252090SN/A    bool  doRxDmaWrite();
2262683Sktlim@umich.edu    void  rxDmaReadCopy();
2272683Sktlim@umich.edu    void  rxDmaWriteCopy();
228595SN/A
2292205SN/A    void *txDmaData;
2302205SN/A    Addr  txDmaAddr;
2312683Sktlim@umich.edu    int   txDmaLen;
2322683Sktlim@umich.edu    bool  doTxDmaRead();
233595SN/A    bool  doTxDmaWrite();
234595SN/A    void  txDmaReadCopy();
2352390SN/A    void  txDmaWriteCopy();
2362423SN/A
2372390SN/A    void rxDmaReadDone();
238595SN/A    friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
239595SN/A    EventWrapper<NSGigE, &NSGigE::rxDmaReadDone> rxDmaReadEvent;
240595SN/A
2412623SN/A    void rxDmaWriteDone();
242595SN/A    friend class EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone>;
2432390SN/A    EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone> rxDmaWriteEvent;
2441080SN/A
245595SN/A    void txDmaReadDone();
2461080SN/A    friend class EventWrapper<NSGigE, &NSGigE::txDmaReadDone>;
2471080SN/A    EventWrapper<NSGigE, &NSGigE::txDmaReadDone> txDmaReadEvent;
248595SN/A
2492683Sktlim@umich.edu    void txDmaWriteDone();
2501080SN/A    friend class EventWrapper<NSGigE, &NSGigE::txDmaWriteDone>;
2511080SN/A    EventWrapper<NSGigE, &NSGigE::txDmaWriteDone> txDmaWriteEvent;
2521080SN/A
2531121SN/A    bool dmaDescFree;
2542107SN/A    bool dmaDataFree;
2551089SN/A
2561080SN/A
2571089SN/A  protected:
2581080SN/A    Tick txDelay;
2591080SN/A    Tick rxDelay;
2601080SN/A
261595SN/A    void txReset();
2622683Sktlim@umich.edu    void rxReset();
2631080SN/A    void regsReset();
2642090SN/A
2651080SN/A    void rxKick();
266595SN/A    Tick rxKickTick;
2672683Sktlim@umich.edu    typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
2682683Sktlim@umich.edu    friend void RxKickEvent::process();
269595SN/A
2702683Sktlim@umich.edu    void txKick();
2711098SN/A    Tick txKickTick;
2721098SN/A    typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
2731098SN/A    friend void TxKickEvent::process();
2742683Sktlim@umich.edu
2751098SN/A    /**
2761098SN/A     * Retransmit event
2771098SN/A     */
2782012SN/A    void transmit();
2791098SN/A    void txEventTransmit()
2801098SN/A    {
281595SN/A        transmit();
2822205SN/A        if (txState == txFifoBlock)
2832205SN/A            txKick();
2842205SN/A    }
285595SN/A    typedef EventWrapper<NSGigE, &NSGigE::txEventTransmit> TxEvent;
2862390SN/A    friend void TxEvent::process();
2872420SN/A    TxEvent txEvent;
2882423SN/A
2892390SN/A    void txDump() const;
290595SN/A    void rxDump() const;
291595SN/A
2921858SN/A    /**
2932SN/A     * receive address filter
2942623SN/A     */
2952SN/A    bool rxFilterEnable;
2962680Sktlim@umich.edu    bool rxFilter(const PacketPtr &packet);
2972SN/A    bool acceptBroadcast;
2982SN/A    bool acceptMulticast;
2992SN/A    bool acceptUnicast;
3001858SN/A    bool acceptPerfect;
3012SN/A    bool acceptArp;
3022623SN/A
3032SN/A    PhysicalMemory *physmem;
3042SN/A
3052SN/A    /**
3062683Sktlim@umich.edu     * Interrupt management
3074216Ssaidi@eecs.umich.edu     */
3082683Sktlim@umich.edu    void devIntrPost(uint32_t interrupts);
3092SN/A    void devIntrClear(uint32_t interrupts);
3102SN/A    void devIntrChangeMask();
3112SN/A
3122SN/A    Tick intrDelay;
3132SN/A    Tick intrTick;
3142623SN/A    bool cpuPendingIntr;
3152SN/A    void cpuIntrPost(Tick when);
3161858SN/A    void cpuInterrupt();
3173923Shsul@eecs.umich.edu    void cpuIntrClear();
3183520Sgblack@eecs.umich.edu
3192SN/A    typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent;
3203520Sgblack@eecs.umich.edu    friend void IntrEvent::process();
3213633Sktlim@umich.edu    IntrEvent *intrEvent;
3223520Sgblack@eecs.umich.edu    NSGigEInt *interface;
3232SN/A
3242SN/A  public:
3252SN/A    struct Params : public PciDev::Params
3262623SN/A    {
3272SN/A        PhysicalMemory *pmem;
3282623SN/A        HierParams *hier;
3292623SN/A        Bus *header_bus;
3302662Sstever@eecs.umich.edu        Bus *payload_bus;
3312623SN/A        Tick clock;
3324514Ssaidi@eecs.umich.edu        Tick intr_delay;
3334495Sacolyte@umich.edu        Tick tx_delay;
3342623SN/A        Tick rx_delay;
3353093Sksewell@umich.edu        Tick pio_latency;
3364495Sacolyte@umich.edu        bool dma_desc_free;
3373093Sksewell@umich.edu        bool dma_data_free;
3383093Sksewell@umich.edu        Tick dma_read_delay;
3394495Sacolyte@umich.edu        Tick dma_write_delay;
3402741Sksewell@umich.edu        Tick dma_read_factor;
3412741Sksewell@umich.edu        Tick dma_write_factor;
3422623SN/A        bool rx_filter;
3434514Ssaidi@eecs.umich.edu        Net::EthAddr eaddr;
3444514Ssaidi@eecs.umich.edu        uint32_t tx_fifo_size;
3454514Ssaidi@eecs.umich.edu        uint32_t rx_fifo_size;
3462623SN/A        uint32_t m5reg;
3472683Sktlim@umich.edu        bool dma_no_allocate;
3482623SN/A    };
3492623SN/A
3502623SN/A    NSGigE(Params *params);
3512623SN/A    ~NSGigE();
3522623SN/A    const Params *params() const { return (const Params *)_params; }
3532623SN/A
3542623SN/A    virtual void WriteConfig(int offset, int size, uint32_t data);
3552623SN/A    virtual void ReadConfig(int offset, int size, uint8_t *data);
3562SN/A
3572683Sktlim@umich.edu    virtual Fault read(MemReqPtr &req, uint8_t *data);
3582427SN/A    virtual Fault write(MemReqPtr &req, const uint8_t *data);
3592683Sktlim@umich.edu
3602427SN/A    bool cpuIntrPending() const;
3612SN/A    void cpuIntrAck() { cpuIntrClear(); }
3622623SN/A
3632623SN/A    bool recvPacket(PacketPtr packet);
3642623SN/A    void transferDone();
3652SN/A
3662683Sktlim@umich.edu    void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
3672SN/A
3682623SN/A    virtual void serialize(std::ostream &os);
3692623SN/A    virtual void unserialize(Checkpoint *cp, const std::string &section);
3702SN/A
3712623SN/A  public:
3722623SN/A    void regStats();
3734377Sgblack@eecs.umich.edu
3743276Sgblack@eecs.umich.edu  private:
3753276Sgblack@eecs.umich.edu    Stats::Scalar<> txBytes;
3764377Sgblack@eecs.umich.edu    Stats::Scalar<> rxBytes;
3774181Sgblack@eecs.umich.edu    Stats::Scalar<> txPackets;
3784181Sgblack@eecs.umich.edu    Stats::Scalar<> rxPackets;
3794181Sgblack@eecs.umich.edu    Stats::Scalar<> txIpChecksums;
3804182Sgblack@eecs.umich.edu    Stats::Scalar<> rxIpChecksums;
3814182Sgblack@eecs.umich.edu    Stats::Scalar<> txTcpChecksums;
3824182Sgblack@eecs.umich.edu    Stats::Scalar<> rxTcpChecksums;
3834182Sgblack@eecs.umich.edu    Stats::Scalar<> txUdpChecksums;
3844518Sgblack@eecs.umich.edu    Stats::Scalar<> rxUdpChecksums;
3854182Sgblack@eecs.umich.edu    Stats::Scalar<> descDmaReads;
3864182Sgblack@eecs.umich.edu    Stats::Scalar<> descDmaWrites;
3874377Sgblack@eecs.umich.edu    Stats::Scalar<> descDmaRdBytes;
3884377Sgblack@eecs.umich.edu    Stats::Scalar<> descDmaWrBytes;
3894377Sgblack@eecs.umich.edu    Stats::Formula totBandwidth;
3904377Sgblack@eecs.umich.edu    Stats::Formula totPackets;
3914377Sgblack@eecs.umich.edu    Stats::Formula totBytes;
3924377Sgblack@eecs.umich.edu    Stats::Formula totPacketRate;
3934377Sgblack@eecs.umich.edu    Stats::Formula txBandwidth;
3944377Sgblack@eecs.umich.edu    Stats::Formula rxBandwidth;
3954182Sgblack@eecs.umich.edu    Stats::Formula txPacketRate;
3964377Sgblack@eecs.umich.edu    Stats::Formula rxPacketRate;
3974377Sgblack@eecs.umich.edu    Stats::Scalar<> postedSwi;
3984377Sgblack@eecs.umich.edu    Stats::Formula coalescedSwi;
3994377Sgblack@eecs.umich.edu    Stats::Scalar<> totalSwi;
4004181Sgblack@eecs.umich.edu    Stats::Scalar<> postedRxIdle;
4014181Sgblack@eecs.umich.edu    Stats::Formula coalescedRxIdle;
4024181Sgblack@eecs.umich.edu    Stats::Scalar<> totalRxIdle;
4034181Sgblack@eecs.umich.edu    Stats::Scalar<> postedRxOk;
4043276Sgblack@eecs.umich.edu    Stats::Formula coalescedRxOk;
4053442Sgblack@eecs.umich.edu    Stats::Scalar<> totalRxOk;
4063442Sgblack@eecs.umich.edu    Stats::Scalar<> postedRxDesc;
4073280Sgblack@eecs.umich.edu    Stats::Formula coalescedRxDesc;
4083280Sgblack@eecs.umich.edu    Stats::Scalar<> totalRxDesc;
4093276Sgblack@eecs.umich.edu    Stats::Scalar<> postedTxOk;
4103276Sgblack@eecs.umich.edu    Stats::Formula coalescedTxOk;
4113276Sgblack@eecs.umich.edu    Stats::Scalar<> totalTxOk;
4123442Sgblack@eecs.umich.edu    Stats::Scalar<> postedTxIdle;
4133442Sgblack@eecs.umich.edu    Stats::Formula coalescedTxIdle;
4143276Sgblack@eecs.umich.edu    Stats::Scalar<> totalTxIdle;
4153276Sgblack@eecs.umich.edu    Stats::Scalar<> postedTxDesc;
4164495Sacolyte@umich.edu    Stats::Formula coalescedTxDesc;
4174181Sgblack@eecs.umich.edu    Stats::Scalar<> totalTxDesc;
4184181Sgblack@eecs.umich.edu    Stats::Scalar<> postedRxOrn;
4194181Sgblack@eecs.umich.edu    Stats::Formula coalescedRxOrn;
4204181Sgblack@eecs.umich.edu    Stats::Scalar<> totalRxOrn;
4214181Sgblack@eecs.umich.edu    Stats::Formula coalescedTotal;
4222470SN/A    Stats::Scalar<> postedInterrupts;
4234181Sgblack@eecs.umich.edu    Stats::Scalar<> droppedPackets;
4244181Sgblack@eecs.umich.edu
4252623SN/A  public:
4262623SN/A    Tick cacheAccess(MemReqPtr &req);
4274181Sgblack@eecs.umich.edu};
4282623SN/A
4294181Sgblack@eecs.umich.edu/*
4304495Sacolyte@umich.edu * Ethernet Interface for an Ethernet Device
4312623SN/A */
4322623SN/Aclass NSGigEInt : public EtherInt
4332623SN/A{
4342623SN/A  private:
4352623SN/A    NSGigE *dev;
4362623SN/A
4372683Sktlim@umich.edu  public:
4383577Sgblack@eecs.umich.edu    NSGigEInt(const std::string &name, NSGigE *d)
4392683Sktlim@umich.edu        : EtherInt(name), dev(d) { dev->setInterface(this); }
4404254Sgblack@eecs.umich.edu
4414254Sgblack@eecs.umich.edu    virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); }
4422623SN/A    virtual void sendDone() { dev->transferDone(); }
4432683Sktlim@umich.edu};
4442623SN/A
4452420SN/A#endif // __DEV_NS_GIGE_HH__
4462SN/A