sinic.hh revision 1993
12207SN/A/*
25254Sksewell@umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan
35254Sksewell@umich.edu * All rights reserved.
42207SN/A *
55254Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without
65254Sksewell@umich.edu * modification, are permitted provided that the following conditions are
75254Sksewell@umich.edu * met: redistributions of source code must retain the above copyright
85254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer;
95254Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright
105254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the
115254Sksewell@umich.edu * documentation and/or other materials provided with the distribution;
125254Sksewell@umich.edu * neither the name of the copyright holders nor the names of its
135254Sksewell@umich.edu * contributors may be used to endorse or promote products derived from
145254Sksewell@umich.edu * this software without specific prior written permission.
152207SN/A *
165254Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175254Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185254Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195254Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205254Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215254Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225254Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235254Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245254Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255254Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265254Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
285254Sksewell@umich.edu
295254Sksewell@umich.edu#ifndef __DEV_SINIC_HH__
305254Sksewell@umich.edu#define __DEV_SINIC_HH__
312207SN/A
322207SN/A#include "base/inet.hh"
3311793Sbrandon.potter@amd.com#include "base/statistics.hh"
3411793Sbrandon.potter@amd.com#include "dev/etherint.hh"
352474SN/A#include "dev/etherpkt.hh"
368229Snate@binkert.org#include "dev/io_device.hh"
372454SN/A#include "dev/pcidev.hh"
382454SN/A#include "dev/pktfifo.hh"
392680Sktlim@umich.edu#include "dev/sinicreg.hh"
408232Snate@binkert.org#include "mem/bus/bus.hh"
416650Sksewell@umich.edu#include "sim/eventq.hh"
4211854Sbrandon.potter@amd.com
436650Sksewell@umich.edunamespace Sinic {
446650Sksewell@umich.edu
4511800Sbrandon.potter@amd.comclass Interface;
462474SN/Aclass Base : public PciDev
472207SN/A{
482447SN/A  protected:
492474SN/A    bool rxEnable;
502447SN/A    bool txEnable;
5111851Sbrandon.potter@amd.com    Tick clock;
5211851Sbrandon.potter@amd.com    inline Tick cycles(int numCycles) const { return numCycles * clock; }
532474SN/A
542686Sksewell@umich.edu  protected:
552686Sksewell@umich.edu    Tick intrDelay;
5611905SBrandon.Potter@amd.com    Tick intrTick;
5711905SBrandon.Potter@amd.com    bool cpuIntrEnable;
5811905SBrandon.Potter@amd.com    bool cpuPendingIntr;
592474SN/A    void cpuIntrPost(Tick when);
602474SN/A    void cpuInterrupt();
6111905SBrandon.Potter@amd.com    void cpuIntrClear();
622474SN/A
632686Sksewell@umich.edu    typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent;
6411905SBrandon.Potter@amd.com    friend void IntrEvent::process();
6511905SBrandon.Potter@amd.com    IntrEvent *intrEvent;
6611905SBrandon.Potter@amd.com    Interface *interface;
672686Sksewell@umich.edu
686811SMatt DeVuyst    bool cpuIntrPending() const;
6911905SBrandon.Potter@amd.com    void cpuIntrAck() { cpuIntrClear(); }
7011905SBrandon.Potter@amd.com
7111905SBrandon.Potter@amd.com/**
7211905SBrandon.Potter@amd.com * Serialization stuff
732474SN/A */
742474SN/A  public:
752474SN/A    virtual void serialize(std::ostream &os);
7611851Sbrandon.potter@amd.com    virtual void unserialize(Checkpoint *cp, const std::string &section);
772474SN/A
7811851Sbrandon.potter@amd.com/**
796650Sksewell@umich.edu * Construction/Destruction/Parameters
8010318Sandreas.hansson@arm.com */
812474SN/A  public:
825958Sgblack@eecs.umich.edu    struct Params : public PciDev::Params
836811SMatt DeVuyst    {
846650Sksewell@umich.edu        Tick clock;
8511851Sbrandon.potter@amd.com        Tick intr_delay;
866650Sksewell@umich.edu    };
876811SMatt DeVuyst
886811SMatt DeVuyst    Base(Params *p);
8911389Sbrandon.potter@amd.com};
9011389Sbrandon.potter@amd.com
9111389Sbrandon.potter@amd.comclass Device : public Base
926650Sksewell@umich.edu{
936650Sksewell@umich.edu  protected:
946650Sksewell@umich.edu    Platform *plat;
956811SMatt DeVuyst    PhysicalMemory *physmem;
966811SMatt DeVuyst
976811SMatt DeVuyst  protected:
986811SMatt DeVuyst    /** Receive State Machine States */
996811SMatt DeVuyst    enum RxState {
1006811SMatt DeVuyst        rxIdle,
1016811SMatt DeVuyst        rxFifoBlock,
10210318Sandreas.hansson@arm.com        rxBeginCopy,
1036811SMatt DeVuyst        rxCopy,
1046811SMatt DeVuyst        rxCopyDone
1056811SMatt DeVuyst    };
1066811SMatt DeVuyst
1076811SMatt DeVuyst    /** Transmit State Machine states */
1086811SMatt DeVuyst    enum TxState {
1096811SMatt DeVuyst        txIdle,
1106811SMatt DeVuyst        txFifoBlock,
1116811SMatt DeVuyst        txBeginCopy,
1126811SMatt DeVuyst        txCopy,
1136811SMatt DeVuyst        txCopyDone
11411389Sbrandon.potter@amd.com    };
11511389Sbrandon.potter@amd.com
11611389Sbrandon.potter@amd.com    /** device register file */
11711389Sbrandon.potter@amd.com    struct {
1186811SMatt DeVuyst        uint32_t Config;       // 0x00
1196811SMatt DeVuyst        uint32_t Command;      // 0x04
1206811SMatt DeVuyst        uint32_t IntrStatus;   // 0x08
1216811SMatt DeVuyst        uint32_t IntrMask;     // 0x0c
1226811SMatt DeVuyst        uint32_t RxMaxCopy;    // 0x10
1236811SMatt DeVuyst        uint32_t TxMaxCopy;    // 0x14
1246811SMatt DeVuyst        uint32_t RxMaxIntr;    // 0x18
1256811SMatt DeVuyst        uint32_t Reserved0;    // 0x1c
1266811SMatt DeVuyst        uint32_t RxFifoSize;   // 0x20
1276811SMatt DeVuyst        uint32_t TxFifoSize;   // 0x24
1286650Sksewell@umich.edu        uint32_t RxFifoMark;   // 0x28
1296650Sksewell@umich.edu        uint32_t TxFifoMark;   // 0x2c
1306811SMatt DeVuyst        uint64_t RxData;       // 0x30
1316811SMatt DeVuyst        uint64_t RxDone;       // 0x38
1326650Sksewell@umich.edu        uint64_t RxWait;       // 0x40
1336650Sksewell@umich.edu        uint64_t TxData;       // 0x48
1346650Sksewell@umich.edu        uint64_t TxDone;       // 0x50
1356650Sksewell@umich.edu        uint64_t TxWait;       // 0x58
1366650Sksewell@umich.edu        uint64_t HwAddr;       // 0x60
1376650Sksewell@umich.edu    } regs;
1386650Sksewell@umich.edu
1396650Sksewell@umich.edu    uint8_t  &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
1406650Sksewell@umich.edu    uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
1416650Sksewell@umich.edu    uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }
1426811SMatt DeVuyst
1436811SMatt DeVuyst  private:
1446811SMatt DeVuyst    Addr addr;
1456811SMatt DeVuyst    static const Addr size = Regs::Size;
1466811SMatt DeVuyst
1476650Sksewell@umich.edu  protected:
1486650Sksewell@umich.edu    RxState rxState;
14911905SBrandon.Potter@amd.com    PacketFifo rxFifo;
1506650Sksewell@umich.edu    bool rxEmpty;
15111905SBrandon.Potter@amd.com    PacketPtr rxPacket;
15211905SBrandon.Potter@amd.com    uint8_t *rxPacketBufPtr;
1536650Sksewell@umich.edu    int rxPktBytes;
15411905SBrandon.Potter@amd.com    uint64_t rxDoneData;
15511905SBrandon.Potter@amd.com    Addr rxDmaAddr;
1566650Sksewell@umich.edu    uint8_t *rxDmaData;
15711905SBrandon.Potter@amd.com    int rxDmaLen;
15811905SBrandon.Potter@amd.com
1596811SMatt DeVuyst    TxState txState;
1606811SMatt DeVuyst    PacketFifo txFifo;
1616811SMatt DeVuyst    bool txFull;
1626811SMatt DeVuyst    PacketPtr txPacket;
1636650Sksewell@umich.edu    uint8_t *txPacketBufPtr;
1646650Sksewell@umich.edu    int txPktBytes;
1656811SMatt DeVuyst    Addr txDmaAddr;
1666650Sksewell@umich.edu    uint8_t *txDmaData;
1676811SMatt DeVuyst    int txDmaLen;
1686650Sksewell@umich.edu
16911905SBrandon.Potter@amd.com  protected:
1706650Sksewell@umich.edu    void reset();
1716650Sksewell@umich.edu
1726650Sksewell@umich.edu    void rxKick();
1736650Sksewell@umich.edu    Tick rxKickTick;
1746650Sksewell@umich.edu    typedef EventWrapper<Device, &Device::rxKick> RxKickEvent;
1756811SMatt DeVuyst    friend void RxKickEvent::process();
1766811SMatt DeVuyst
1778852Sandreas.hansson@arm.com    void txKick();
1786811SMatt DeVuyst    Tick txKickTick;
1798852Sandreas.hansson@arm.com    typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
1806811SMatt DeVuyst    friend void TxKickEvent::process();
1816811SMatt DeVuyst
1826811SMatt DeVuyst    /**
1836811SMatt DeVuyst     * Retransmit event
1846811SMatt DeVuyst     */
1856811SMatt DeVuyst    void transmit();
1866811SMatt DeVuyst    void txEventTransmit()
1878852Sandreas.hansson@arm.com    {
1886811SMatt DeVuyst        transmit();
1896811SMatt DeVuyst        if (txState == txFifoBlock)
1906650Sksewell@umich.edu            txKick();
1916650Sksewell@umich.edu    }
1926650Sksewell@umich.edu    typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent;
1936650Sksewell@umich.edu    friend void TxEvent::process();
19411905SBrandon.Potter@amd.com    TxEvent txEvent;
1956650Sksewell@umich.edu
19611389Sbrandon.potter@amd.com    void txDump() const;
1976650Sksewell@umich.edu    void rxDump() const;
1986650Sksewell@umich.edu
1996650Sksewell@umich.edu    /**
2005958Sgblack@eecs.umich.edu     * receive address filter
20111851Sbrandon.potter@amd.com     */
2025958Sgblack@eecs.umich.edu    bool rxFilter(const PacketPtr &packet);
2035958Sgblack@eecs.umich.edu
2046701Sgblack@eecs.umich.edu/**
2055958Sgblack@eecs.umich.edu * device configuration
2065958Sgblack@eecs.umich.edu */
2075958Sgblack@eecs.umich.edu    void changeConfig(uint32_t newconfig);
20811851Sbrandon.potter@amd.com    void command(uint32_t command);
2095958Sgblack@eecs.umich.edu
2105958Sgblack@eecs.umich.edu/**
2115958Sgblack@eecs.umich.edu * device ethernet interface
2125958Sgblack@eecs.umich.edu */
2135958Sgblack@eecs.umich.edu  public:
2145958Sgblack@eecs.umich.edu    bool recvPacket(PacketPtr packet);
21511851Sbrandon.potter@amd.com    void transferDone();
2165958Sgblack@eecs.umich.edu    void setInterface(Interface *i) { assert(!interface); interface = i; }
21710223Ssteve.reinhardt@amd.com
2185958Sgblack@eecs.umich.edu/**
2195958Sgblack@eecs.umich.edu * DMA parameters
22010223Ssteve.reinhardt@amd.com */
2215958Sgblack@eecs.umich.edu  protected:
2225958Sgblack@eecs.umich.edu    void rxDmaCopy();
2235958Sgblack@eecs.umich.edu    void rxDmaDone();
22410223Ssteve.reinhardt@amd.com    friend class EventWrapper<Device, &Device::rxDmaDone>;
2255958Sgblack@eecs.umich.edu    EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
2265958Sgblack@eecs.umich.edu
227    void txDmaCopy();
228    void txDmaDone();
229    friend class EventWrapper<Device, &Device::txDmaDone>;
230    EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
231
232    Tick dmaReadDelay;
233    Tick dmaReadFactor;
234    Tick dmaWriteDelay;
235    Tick dmaWriteFactor;
236
237/**
238 * PIO parameters
239 */
240  protected:
241    MemReqPtr rxPioRequest;
242    MemReqPtr txPioRequest;
243
244/**
245 * Interrupt management
246 */
247  protected:
248    void devIntrPost(uint32_t interrupts);
249    void devIntrClear(uint32_t interrupts = Regs::Intr_All);
250    void devIntrChangeMask(uint32_t newmask);
251
252/**
253 * PCI Configuration interface
254 */
255  public:
256    virtual void writeConfig(int offset, int size, const uint8_t *data);
257
258/**
259 * Memory Interface
260 */
261  public:
262    virtual Fault read(MemReqPtr &req, uint8_t *data);
263    virtual Fault write(MemReqPtr &req, const uint8_t *data);
264
265    void prepareRead();
266    Fault iprRead(Addr daddr, uint64_t &result);
267    Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data);
268    Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data);
269    Tick cacheAccess(MemReqPtr &req);
270
271/**
272 * Statistics
273 */
274  private:
275    Stats::Scalar<> rxBytes;
276    Stats::Formula  rxBandwidth;
277    Stats::Scalar<> rxPackets;
278    Stats::Formula  rxPacketRate;
279    Stats::Scalar<> rxIpPackets;
280    Stats::Scalar<> rxTcpPackets;
281    Stats::Scalar<> rxUdpPackets;
282    Stats::Scalar<> rxIpChecksums;
283    Stats::Scalar<> rxTcpChecksums;
284    Stats::Scalar<> rxUdpChecksums;
285
286    Stats::Scalar<> txBytes;
287    Stats::Formula  txBandwidth;
288    Stats::Formula totBandwidth;
289    Stats::Formula totPackets;
290    Stats::Formula totBytes;
291    Stats::Formula totPacketRate;
292    Stats::Scalar<> txPackets;
293    Stats::Formula  txPacketRate;
294    Stats::Scalar<> txIpPackets;
295    Stats::Scalar<> txTcpPackets;
296    Stats::Scalar<> txUdpPackets;
297    Stats::Scalar<> txIpChecksums;
298    Stats::Scalar<> txTcpChecksums;
299    Stats::Scalar<> txUdpChecksums;
300
301  public:
302    virtual void regStats();
303
304/**
305 * Serialization stuff
306 */
307  public:
308    virtual void serialize(std::ostream &os);
309    virtual void unserialize(Checkpoint *cp, const std::string &section);
310
311/**
312 * Construction/Destruction/Parameters
313 */
314  public:
315    struct Params : public Base::Params
316    {
317        IntrControl *i;
318        PhysicalMemory *pmem;
319        Tick tx_delay;
320        Tick rx_delay;
321        HierParams *hier;
322        Bus *pio_bus;
323        Bus *header_bus;
324        Bus *payload_bus;
325        Tick pio_latency;
326        PhysicalMemory *physmem;
327        IntrControl *intctrl;
328        bool rx_filter;
329        Net::EthAddr eaddr;
330        uint32_t rx_max_copy;
331        uint32_t tx_max_copy;
332        uint32_t rx_max_intr;
333        uint32_t rx_fifo_size;
334        uint32_t tx_fifo_size;
335        uint32_t rx_fifo_threshold;
336        uint32_t tx_fifo_threshold;
337        Tick dma_read_delay;
338        Tick dma_read_factor;
339        Tick dma_write_delay;
340        Tick dma_write_factor;
341        bool dma_no_allocate;
342        bool dedicated;
343    };
344
345  protected:
346    const Params *params() const { return (const Params *)_params; }
347
348  public:
349    Device(Params *params);
350    ~Device();
351};
352
353/*
354 * Ethernet Interface for an Ethernet Device
355 */
356class Interface : public EtherInt
357{
358  private:
359    Device *dev;
360
361  public:
362    Interface(const std::string &name, Device *d)
363        : EtherInt(name), dev(d) { dev->setInterface(this); }
364
365    virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); }
366    virtual void sendDone() { dev->transferDone(); }
367};
368
369/* namespace Sinic */ }
370
371#endif // __DEV_SINIC_HH__
372