ns_gige.hh revision 1114
15449Sgblack@eecs.umich.edu/*
28610Snilay@cs.wisc.edu * Copyright (c) 2004 The Regents of The University of Michigan
34519Sgblack@eecs.umich.edu * All rights reserved.
44519Sgblack@eecs.umich.edu *
57087Snate@binkert.org * Redistribution and use in source and binary forms, with or without
67087Snate@binkert.org * modification, are permitted provided that the following conditions are
77087Snate@binkert.org * met: redistributions of source code must retain the above copyright
87087Snate@binkert.org * notice, this list of conditions and the following disclaimer;
97087Snate@binkert.org * redistributions in binary form must reproduce the above copyright
107087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
117087Snate@binkert.org * documentation and/or other materials provided with the distribution;
127087Snate@binkert.org * neither the name of the copyright holders nor the names of its
134519Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
147087Snate@binkert.org * this software without specific prior written permission.
157087Snate@binkert.org *
167087Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
177087Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
187087Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
197087Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
207087Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
217087Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
224519Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
237087Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
244519Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
254519Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
264519Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274519Sgblack@eecs.umich.edu */
284519Sgblack@eecs.umich.edu
294519Sgblack@eecs.umich.edu/* @file
304519Sgblack@eecs.umich.edu * Device module for modelling the National Semiconductor
314519Sgblack@eecs.umich.edu * DP83820 ethernet controller
324519Sgblack@eecs.umich.edu */
334519Sgblack@eecs.umich.edu
344519Sgblack@eecs.umich.edu#ifndef __DEV_NS_GIGE_HH__
354519Sgblack@eecs.umich.edu#define __DEV_NS_GIGE_HH__
364519Sgblack@eecs.umich.edu
374519Sgblack@eecs.umich.edu#include "base/inet.hh"
384519Sgblack@eecs.umich.edu#include "base/statistics.hh"
394519Sgblack@eecs.umich.edu#include "dev/etherint.hh"
404519Sgblack@eecs.umich.edu#include "dev/etherpkt.hh"
414519Sgblack@eecs.umich.edu#include "dev/io_device.hh"
424519Sgblack@eecs.umich.edu#include "dev/ns_gige_reg.h"
434519Sgblack@eecs.umich.edu#include "dev/pcidev.hh"
444519Sgblack@eecs.umich.edu#include "dev/tsunami.hh"
454590Sgblack@eecs.umich.edu#include "mem/bus/bus.hh"
465163Sgblack@eecs.umich.edu#include "sim/eventq.hh"
474590Sgblack@eecs.umich.edu
484590Sgblack@eecs.umich.edu/**
494590Sgblack@eecs.umich.edu * Ethernet device registers
505163Sgblack@eecs.umich.edu */
514590Sgblack@eecs.umich.edustruct dp_regs {
524590Sgblack@eecs.umich.edu    uint32_t	command;
535163Sgblack@eecs.umich.edu    uint32_t	config;
547620Sgblack@eecs.umich.edu    uint32_t	mear;
554590Sgblack@eecs.umich.edu    uint32_t	ptscr;
564696Sgblack@eecs.umich.edu    uint32_t    isr;
574696Sgblack@eecs.umich.edu    uint32_t    imr;
584590Sgblack@eecs.umich.edu    uint32_t    ier;
595172Sgblack@eecs.umich.edu    uint32_t    ihr;
605172Sgblack@eecs.umich.edu    uint32_t    txdp;
615172Sgblack@eecs.umich.edu    uint32_t    txdp_hi;
625172Sgblack@eecs.umich.edu    uint32_t    txcfg;
635172Sgblack@eecs.umich.edu    uint32_t    gpior;
647620Sgblack@eecs.umich.edu    uint32_t    rxdp;
657682Sgblack@eecs.umich.edu    uint32_t    rxdp_hi;
6610341Smitch.hayenga@arm.com    uint32_t    rxcfg;
6710341Smitch.hayenga@arm.com    uint32_t    pqcr;
687682Sgblack@eecs.umich.edu    uint32_t    wcsr;
695172Sgblack@eecs.umich.edu    uint32_t    pcr;
705172Sgblack@eecs.umich.edu    uint32_t    rfcr;
715172Sgblack@eecs.umich.edu    uint32_t    rfdr;
7212236Sgabeblack@google.com    uint32_t    srr;
735449Sgblack@eecs.umich.edu    uint32_t    mibc;
745449Sgblack@eecs.umich.edu    uint32_t    vrcr;
755449Sgblack@eecs.umich.edu    uint32_t    vtcr;
765172Sgblack@eecs.umich.edu    uint32_t    vdr;
774590Sgblack@eecs.umich.edu    uint32_t    ccsr;
784590Sgblack@eecs.umich.edu    uint32_t    tbicr;
795163Sgblack@eecs.umich.edu    uint32_t    tbisr;
805163Sgblack@eecs.umich.edu    uint32_t    tanar;
815163Sgblack@eecs.umich.edu    uint32_t    tanlpar;
825163Sgblack@eecs.umich.edu    uint32_t    taner;
835163Sgblack@eecs.umich.edu    uint32_t    tesr;
847620Sgblack@eecs.umich.edu};
855163Sgblack@eecs.umich.edu
8612236Sgabeblack@google.comstruct dp_rom {
875163Sgblack@eecs.umich.edu    /**
885163Sgblack@eecs.umich.edu     * for perfect match memory.
895163Sgblack@eecs.umich.edu     * the linux driver doesn't use any other ROM
905163Sgblack@eecs.umich.edu     */
9112234Sgabeblack@google.com    uint8_t perfectMatch[ETH_ADDR_LEN];
924519Sgblack@eecs.umich.edu};
934519Sgblack@eecs.umich.edu
945163Sgblack@eecs.umich.educlass IntrControl;
955163Sgblack@eecs.umich.educlass NSGigEInt;
965163Sgblack@eecs.umich.educlass PhysicalMemory;
975163Sgblack@eecs.umich.educlass BaseInterface;
985163Sgblack@eecs.umich.educlass HierParams;
995163Sgblack@eecs.umich.educlass Bus;
1005163Sgblack@eecs.umich.educlass PciConfigAll;
1015163Sgblack@eecs.umich.edu
1024519Sgblack@eecs.umich.edu/**
1034519Sgblack@eecs.umich.edu * NS DP82830 Ethernet device model
1044519Sgblack@eecs.umich.edu */
1055172Sgblack@eecs.umich.educlass NSGigE : public PciDev
1065172Sgblack@eecs.umich.edu{
10712234Sgabeblack@google.com  public:
1085172Sgblack@eecs.umich.edu    /** Transmit State Machine states */
1095173Sgblack@eecs.umich.edu    enum TxState
1105172Sgblack@eecs.umich.edu    {
1115172Sgblack@eecs.umich.edu        txIdle,
1125172Sgblack@eecs.umich.edu        txDescRefr,
1135172Sgblack@eecs.umich.edu        txDescRead,
1144590Sgblack@eecs.umich.edu        txFifoBlock,
11510184SCurtis.Dunham@arm.com        txFragRead,
1165163Sgblack@eecs.umich.edu        txDescWrite,
1177620Sgblack@eecs.umich.edu        txAdvance
1187620Sgblack@eecs.umich.edu    };
1195163Sgblack@eecs.umich.edu
1204519Sgblack@eecs.umich.edu    /** Receive State Machine States */
1214519Sgblack@eecs.umich.edu    enum RxState
1224519Sgblack@eecs.umich.edu    {
1234519Sgblack@eecs.umich.edu        rxIdle,
1245163Sgblack@eecs.umich.edu        rxDescRefr,
12510184SCurtis.Dunham@arm.com        rxDescRead,
1267620Sgblack@eecs.umich.edu        rxFifoBlock,
1275163Sgblack@eecs.umich.edu        rxFragWrite,
1287620Sgblack@eecs.umich.edu        rxDescWrite,
1295163Sgblack@eecs.umich.edu        rxAdvance
1307626Sgblack@eecs.umich.edu    };
1315163Sgblack@eecs.umich.edu
1325163Sgblack@eecs.umich.edu    enum DmaState
1335163Sgblack@eecs.umich.edu    {
1344696Sgblack@eecs.umich.edu        dmaIdle,
1355163Sgblack@eecs.umich.edu        dmaReading,
1364696Sgblack@eecs.umich.edu        dmaWriting,
1374696Sgblack@eecs.umich.edu        dmaReadWaiting,
1384696Sgblack@eecs.umich.edu        dmaWriteWaiting
1394696Sgblack@eecs.umich.edu    };
1404696Sgblack@eecs.umich.edu
1414696Sgblack@eecs.umich.edu  private:
1424696Sgblack@eecs.umich.edu    /** pointer to the chipset */
1434696Sgblack@eecs.umich.edu    Tsunami *tsunami;
1444696Sgblack@eecs.umich.edu
1454696Sgblack@eecs.umich.edu  private:
1464696Sgblack@eecs.umich.edu    Addr addr;
1474696Sgblack@eecs.umich.edu    static const Addr size = sizeof(dp_regs);
1485449Sgblack@eecs.umich.edu
1495449Sgblack@eecs.umich.edu  protected:
1505449Sgblack@eecs.umich.edu    typedef std::deque<PacketPtr> pktbuf_t;
1515449Sgblack@eecs.umich.edu    typedef pktbuf_t::iterator pktiter_t;
1525449Sgblack@eecs.umich.edu
1535449Sgblack@eecs.umich.edu    /** device register file */
1545449Sgblack@eecs.umich.edu    dp_regs regs;
1555449Sgblack@eecs.umich.edu    dp_rom rom;
1565449Sgblack@eecs.umich.edu
1575449Sgblack@eecs.umich.edu    /** pci settings */
1584696Sgblack@eecs.umich.edu    bool ioEnable;
1594696Sgblack@eecs.umich.edu#if 0
1604519Sgblack@eecs.umich.edu    bool memEnable;
1614590Sgblack@eecs.umich.edu    bool bmEnable;
1625163Sgblack@eecs.umich.edu#endif
1635163Sgblack@eecs.umich.edu
1644590Sgblack@eecs.umich.edu    /*** BASIC STRUCTURES FOR TX/RX ***/
1655163Sgblack@eecs.umich.edu    /* Data FIFOs */
1665163Sgblack@eecs.umich.edu    pktbuf_t txFifo;
1675163Sgblack@eecs.umich.edu    uint32_t maxTxFifoSize;
1685163Sgblack@eecs.umich.edu    pktbuf_t rxFifo;
1695163Sgblack@eecs.umich.edu    uint32_t maxRxFifoSize;
1705163Sgblack@eecs.umich.edu
1715163Sgblack@eecs.umich.edu    /** various helper vars */
1724590Sgblack@eecs.umich.edu    PacketPtr txPacket;
1737620Sgblack@eecs.umich.edu    PacketPtr rxPacket;
1747620Sgblack@eecs.umich.edu    uint8_t *txPacketBufPtr;
1755163Sgblack@eecs.umich.edu    uint8_t *rxPacketBufPtr;
1765163Sgblack@eecs.umich.edu    uint32_t txXferLen;
1774590Sgblack@eecs.umich.edu    uint32_t rxXferLen;
1785163Sgblack@eecs.umich.edu    bool rxDmaFree;
1795163Sgblack@eecs.umich.edu    bool txDmaFree;
1804590Sgblack@eecs.umich.edu
1815163Sgblack@eecs.umich.edu    /** DescCaches */
1825293Sgblack@eecs.umich.edu    ns_desc txDescCache;
1835163Sgblack@eecs.umich.edu    ns_desc rxDescCache;
1849211Snilay@cs.wisc.edu
1859010Snilay@cs.wisc.edu    /* tx State Machine */
1865163Sgblack@eecs.umich.edu    TxState txState;
1875163Sgblack@eecs.umich.edu    bool txEnable;
1885163Sgblack@eecs.umich.edu
1895293Sgblack@eecs.umich.edu    /** Current Transmit Descriptor Done */
1905163Sgblack@eecs.umich.edu    bool CTDD;
1915163Sgblack@eecs.umich.edu    /** current amt of free space in txDataFifo in bytes */
1925163Sgblack@eecs.umich.edu    uint32_t txFifoAvail;
1935163Sgblack@eecs.umich.edu    /** halt the tx state machine after next packet */
1945163Sgblack@eecs.umich.edu    bool txHalt;
1954590Sgblack@eecs.umich.edu    /** ptr to the next byte in the current fragment */
1965172Sgblack@eecs.umich.edu    Addr txFragPtr;
1975172Sgblack@eecs.umich.edu    /** count of bytes remaining in the current descriptor */
1986047Sgblack@eecs.umich.edu    uint32_t txDescCnt;
1995172Sgblack@eecs.umich.edu    DmaState txDmaState;
2005172Sgblack@eecs.umich.edu
2015172Sgblack@eecs.umich.edu    /** rx State Machine */
2027620Sgblack@eecs.umich.edu    RxState rxState;
2037620Sgblack@eecs.umich.edu    bool rxEnable;
2045172Sgblack@eecs.umich.edu
2055172Sgblack@eecs.umich.edu    /** Current Receive Descriptor Done */
2065172Sgblack@eecs.umich.edu    bool CRDD;
2074519Sgblack@eecs.umich.edu    /** num of bytes in the current packet being drained from rxDataFifo */
2088610Snilay@cs.wisc.edu    uint32_t rxPktBytes;
2098610Snilay@cs.wisc.edu    /** number of bytes in the rxFifo */
2108610Snilay@cs.wisc.edu    uint32_t rxFifoCnt;
2118610Snilay@cs.wisc.edu    /** halt the rx state machine after current packet */
2128610Snilay@cs.wisc.edu    bool rxHalt;
2138610Snilay@cs.wisc.edu    /** ptr to the next byte in current fragment */
2148610Snilay@cs.wisc.edu    Addr rxFragPtr;
2158610Snilay@cs.wisc.edu    /** count of bytes remaining in the current descriptor */
2168610Snilay@cs.wisc.edu    uint32_t rxDescCnt;
21712236Sgabeblack@google.com    DmaState rxDmaState;
2188610Snilay@cs.wisc.edu
2198610Snilay@cs.wisc.edu    bool extstsEnable;
2208610Snilay@cs.wisc.edu
2218610Snilay@cs.wisc.edu  protected:
22210184SCurtis.Dunham@arm.com    Tick dmaReadDelay;
2238610Snilay@cs.wisc.edu    Tick dmaWriteDelay;
2248610Snilay@cs.wisc.edu
2258610Snilay@cs.wisc.edu    Tick dmaReadFactor;
2268610Snilay@cs.wisc.edu    Tick dmaWriteFactor;
2278610Snilay@cs.wisc.edu
2288610Snilay@cs.wisc.edu    void *rxDmaData;
2298610Snilay@cs.wisc.edu    Addr  rxDmaAddr;
2308610Snilay@cs.wisc.edu    int   rxDmaLen;
2318610Snilay@cs.wisc.edu    bool  doRxDmaRead();
2328610Snilay@cs.wisc.edu    bool  doRxDmaWrite();
2338610Snilay@cs.wisc.edu    void  rxDmaReadCopy();
2348610Snilay@cs.wisc.edu    void  rxDmaWriteCopy();
2358610Snilay@cs.wisc.edu
2368610Snilay@cs.wisc.edu    void *txDmaData;
2378610Snilay@cs.wisc.edu    Addr  txDmaAddr;
2388610Snilay@cs.wisc.edu    int   txDmaLen;
2398610Snilay@cs.wisc.edu    bool  doTxDmaRead();
2408610Snilay@cs.wisc.edu    bool  doTxDmaWrite();
2418610Snilay@cs.wisc.edu    void  txDmaReadCopy();
2428610Snilay@cs.wisc.edu    void  txDmaWriteCopy();
2438610Snilay@cs.wisc.edu
2448610Snilay@cs.wisc.edu    void rxDmaReadDone();
2458610Snilay@cs.wisc.edu    friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>;
2468610Snilay@cs.wisc.edu    EventWrapper<NSGigE, &NSGigE::rxDmaReadDone> rxDmaReadEvent;
2478610Snilay@cs.wisc.edu
2488610Snilay@cs.wisc.edu    void rxDmaWriteDone();
2498610Snilay@cs.wisc.edu    friend class EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone>;
2508610Snilay@cs.wisc.edu    EventWrapper<NSGigE, &NSGigE::rxDmaWriteDone> rxDmaWriteEvent;
2518610Snilay@cs.wisc.edu
2528610Snilay@cs.wisc.edu    void txDmaReadDone();
2538610Snilay@cs.wisc.edu    friend class EventWrapper<NSGigE, &NSGigE::txDmaReadDone>;
2548610Snilay@cs.wisc.edu    EventWrapper<NSGigE, &NSGigE::txDmaReadDone> txDmaReadEvent;
2558610Snilay@cs.wisc.edu
2568610Snilay@cs.wisc.edu    void txDmaWriteDone();
2578610Snilay@cs.wisc.edu    friend class EventWrapper<NSGigE, &NSGigE::txDmaWriteDone>;
2588610Snilay@cs.wisc.edu    EventWrapper<NSGigE, &NSGigE::txDmaWriteDone> txDmaWriteEvent;
2598610Snilay@cs.wisc.edu
260    bool dmaDescFree;
261    bool dmaDataFree;
262
263
264  protected:
265    Tick txDelay;
266    Tick rxDelay;
267
268    void txReset();
269    void rxReset();
270    void regsReset();
271
272    void rxKick();
273    Tick rxKickTick;
274    typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
275    friend class RxKickEvent;
276
277    void txKick();
278    Tick txKickTick;
279    typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
280    friend class TxKickEvent;
281
282    /**
283     * Retransmit event
284     */
285    void transmit();
286    void txEventTransmit()
287    {
288        transmit();
289        if (txState == txFifoBlock)
290            txKick();
291    }
292    typedef EventWrapper<NSGigE, &NSGigE::txEventTransmit> TxEvent;
293    friend class TxEvent;
294    TxEvent txEvent;
295
296    void txDump() const;
297    void rxDump() const;
298
299    /**
300     * receive address filter
301     */
302    bool rxFilterEnable;
303    bool rxFilter(PacketPtr &packet);
304    bool acceptBroadcast;
305    bool acceptMulticast;
306    bool acceptUnicast;
307    bool acceptPerfect;
308    bool acceptArp;
309
310    PhysicalMemory *physmem;
311
312    /**
313     * Interrupt management
314     */
315    IntrControl *intctrl;
316    void devIntrPost(uint32_t interrupts);
317    void devIntrClear(uint32_t interrupts);
318    void devIntrChangeMask();
319
320    Tick intrDelay;
321    Tick intrTick;
322    bool cpuPendingIntr;
323    void cpuIntrPost(Tick when);
324    void cpuInterrupt();
325    void cpuIntrClear();
326
327    typedef EventWrapper<NSGigE, &NSGigE::cpuInterrupt> IntrEvent;
328    friend class IntrEvent;
329    IntrEvent *intrEvent;
330    NSGigEInt *interface;
331
332  public:
333    NSGigE(const std::string &name, IntrControl *i, Tick intr_delay,
334           PhysicalMemory *pmem, Tick tx_delay, Tick rx_delay,
335           MemoryController *mmu, HierParams *hier, Bus *header_bus,
336           Bus *payload_bus, Tick pio_latency, bool dma_desc_free,
337           bool dma_data_free, Tick dma_read_delay, Tick dma_write_delay,
338           Tick dma_read_factor, Tick dma_write_factor, PciConfigAll *cf,
339           PciConfigData *cd, Tsunami *t, uint32_t bus, uint32_t dev,
340           uint32_t func, bool rx_filter, Net::EthAddr eaddr,
341           uint32_t tx_fifo_size, uint32_t rx_fifo_size);
342    ~NSGigE();
343
344    virtual void WriteConfig(int offset, int size, uint32_t data);
345    virtual void ReadConfig(int offset, int size, uint8_t *data);
346
347    virtual Fault read(MemReqPtr &req, uint8_t *data);
348    virtual Fault write(MemReqPtr &req, const uint8_t *data);
349
350    bool cpuIntrPending() const;
351    void cpuIntrAck() { cpuIntrClear(); }
352
353    bool recvPacket(PacketPtr &packet);
354    void transferDone();
355
356    void setInterface(NSGigEInt *i) { assert(!interface); interface = i; }
357
358    virtual void serialize(std::ostream &os);
359    virtual void unserialize(Checkpoint *cp, const std::string &section);
360
361  public:
362    void regStats();
363
364  private:
365    Stats::Scalar<> txBytes;
366    Stats::Scalar<> rxBytes;
367    Stats::Scalar<> txPackets;
368    Stats::Scalar<> rxPackets;
369    Stats::Scalar<> txIpChecksums;
370    Stats::Scalar<> rxIpChecksums;
371    Stats::Scalar<> txTcpChecksums;
372    Stats::Scalar<> rxTcpChecksums;
373    Stats::Scalar<> txUdpChecksums;
374    Stats::Scalar<> rxUdpChecksums;
375    Stats::Scalar<> descDmaReads;
376    Stats::Scalar<> descDmaWrites;
377    Stats::Scalar<> descDmaRdBytes;
378    Stats::Scalar<> descDmaWrBytes;
379    Stats::Formula txBandwidth;
380    Stats::Formula rxBandwidth;
381    Stats::Formula txPacketRate;
382    Stats::Formula rxPacketRate;
383
384  public:
385    Tick cacheAccess(MemReqPtr &req);
386};
387
388/*
389 * Ethernet Interface for an Ethernet Device
390 */
391class NSGigEInt : public EtherInt
392{
393  private:
394    NSGigE *dev;
395
396  public:
397    NSGigEInt(const std::string &name, NSGigE *d)
398        : EtherInt(name), dev(d) { dev->setInterface(this); }
399
400    virtual bool recvPacket(PacketPtr &pkt) { return dev->recvPacket(pkt); }
401    virtual void sendDone() { dev->transferDone(); }
402};
403
404#endif // __DEV_NS_GIGE_HH__
405