sinic.hh revision 2008
11156SN/A/*
21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
31156SN/A * All rights reserved.
41156SN/A *
51156SN/A * Redistribution and use in source and binary forms, with or without
61156SN/A * modification, are permitted provided that the following conditions are
71156SN/A * met: redistributions of source code must retain the above copyright
81156SN/A * notice, this list of conditions and the following disclaimer;
91156SN/A * redistributions in binary form must reproduce the above copyright
101156SN/A * notice, this list of conditions and the following disclaimer in the
111156SN/A * documentation and/or other materials provided with the distribution;
121156SN/A * neither the name of the copyright holders nor the names of its
131156SN/A * contributors may be used to endorse or promote products derived from
141156SN/A * this software without specific prior written permission.
151156SN/A *
161156SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171156SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181156SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191156SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201156SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211156SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221156SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231156SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241156SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251156SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261156SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665SN/A */
282665SN/A
291156SN/A#ifndef __DEV_SINIC_HH__
301156SN/A#define __DEV_SINIC_HH__
3111263Sandreas.sandberg@arm.com
3211263Sandreas.sandberg@arm.com#include "base/inet.hh"
331156SN/A#include "base/statistics.hh"
341156SN/A#include "dev/etherint.hh"
351156SN/A#include "dev/etherpkt.hh"
361156SN/A#include "dev/io_device.hh"
3711263Sandreas.sandberg@arm.com#include "dev/pcidev.hh"
3811263Sandreas.sandberg@arm.com#include "dev/pktfifo.hh"
3911263Sandreas.sandberg@arm.com#include "dev/sinicreg.hh"
4011263Sandreas.sandberg@arm.com#include "mem/bus/bus.hh"
4111263Sandreas.sandberg@arm.com#include "sim/eventq.hh"
4211260SN/A
434762SN/Anamespace Sinic {
441156SN/A
451156SN/Aclass Interface;
461156SN/Aclass Base : public PciDev
471156SN/A{
481156SN/A  protected:
499339SN/A    bool rxEnable;
501156SN/A    bool txEnable;
511156SN/A    Tick clock;
521156SN/A    inline Tick cycles(int numCycles) const { return numCycles * clock; }
531156SN/A
541156SN/A  protected:
551156SN/A    Tick intrDelay;
561156SN/A    Tick intrTick;
571156SN/A    bool cpuIntrEnable;
581156SN/A    bool cpuPendingIntr;
591156SN/A    void cpuIntrPost(Tick when);
601156SN/A    void cpuInterrupt();
611156SN/A    void cpuIntrClear();
621156SN/A
631156SN/A    typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent;
6412087Sspwilson2@wisc.edu    friend void IntrEvent::process();
651156SN/A    IntrEvent *intrEvent;
661156SN/A    Interface *interface;
671156SN/A
681156SN/A    bool cpuIntrPending() const;
691156SN/A    void cpuIntrAck() { cpuIntrClear(); }
701156SN/A
711156SN/A/**
721156SN/A * Serialization stuff
731156SN/A */
7411168SN/A  public:
7511168SN/A    virtual void serialize(std::ostream &os);
761156SN/A    virtual void unserialize(Checkpoint *cp, const std::string &section);
771156SN/A
781156SN/A/**
791156SN/A * Construction/Destruction/Parameters
801156SN/A */
814762SN/A  public:
824762SN/A    struct Params : public PciDev::Params
834981SN/A    {
841156SN/A        Tick clock;
851156SN/A        Tick intr_delay;
861156SN/A    };
871156SN/A
881156SN/A    Base(Params *p);
891156SN/A};
901156SN/A
911156SN/Aclass Device : public Base
921156SN/A{
931156SN/A  protected:
941156SN/A    Platform *plat;
951156SN/A    PhysicalMemory *physmem;
961156SN/A
971156SN/A  protected:
981156SN/A    /** Receive State Machine States */
991156SN/A    enum RxState {
1001156SN/A        rxIdle,
1011156SN/A        rxFifoBlock,
1021156SN/A        rxBeginCopy,
1031156SN/A        rxCopy,
1041156SN/A        rxCopyDone
1051156SN/A    };
1061156SN/A
1071156SN/A    /** Transmit State Machine states */
1081156SN/A    enum TxState {
1091939SN/A        txIdle,
1101939SN/A        txFifoBlock,
1111939SN/A        txBeginCopy,
1121939SN/A        txCopy,
1131939SN/A        txCopyDone
1141939SN/A    };
1155603SN/A
1165603SN/A    /** device register file */
1175603SN/A    struct {
1185603SN/A        uint32_t Config;       // 0x00
1195603SN/A        uint32_t Command;      // 0x04
1205603SN/A        uint32_t IntrStatus;   // 0x08
1215603SN/A        uint32_t IntrMask;     // 0x0c
1225603SN/A        uint32_t RxMaxCopy;    // 0x10
1235603SN/A        uint32_t TxMaxCopy;    // 0x14
1245603SN/A        uint32_t RxMaxIntr;    // 0x18
1255603SN/A        uint32_t Reserved0;    // 0x1c
1265603SN/A        uint32_t RxFifoSize;   // 0x20
1275603SN/A        uint32_t TxFifoSize;   // 0x24
1285603SN/A        uint32_t RxFifoMark;   // 0x28
1295603SN/A        uint32_t TxFifoMark;   // 0x2c
1305603SN/A        uint64_t RxData;       // 0x30
1315603SN/A        uint64_t RxDone;       // 0x38
1325603SN/A        uint64_t RxWait;       // 0x40
1331156SN/A        uint64_t TxData;       // 0x48
1341156SN/A        uint64_t TxDone;       // 0x50
1352008SN/A        uint64_t TxWait;       // 0x58
1362008SN/A        uint64_t HwAddr;       // 0x60
1372008SN/A    } regs;
1382008SN/A
1392008SN/A    struct VirtualReg {
1402008SN/A        uint64_t RxData;
1415603SN/A        uint64_t RxDone;
1426227SN/A        uint64_t TxData;
1436227SN/A        uint64_t TxDone;
1442008SN/A
1452008SN/A        PacketFifo::iterator rxPacket;
1462282SN/A        int rxPacketOffset;
1472282SN/A        int rxPacketBytes;
1482282SN/A        uint64_t rxDoneData;
1492008SN/A
1502008SN/A        VirtualReg()
1512008SN/A            : RxData(0), RxDone(0), TxData(0), TxDone(0),
1522008SN/A              rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0)
1532008SN/A        { }
1542008SN/A    };
1556227SN/A    typedef std::vector<VirtualReg> VirtualRegs;
1562282SN/A    typedef std::list<int> VirtualList;
1572282SN/A    VirtualRegs virtualRegs;
1582008SN/A    VirtualList rxList;
1592008SN/A    VirtualList txList;
1602282SN/A
1612282SN/A    uint8_t  &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
1622008SN/A    uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
1632008SN/A    uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }
1645603SN/A
1655603SN/A  private:
1665603SN/A    Addr addr;
1675603SN/A    static const Addr size = Regs::Size;
1681939SN/A
1691939SN/A  protected:
1701939SN/A    RxState rxState;
1711939SN/A    PacketFifo rxFifo;
1721156SN/A    PacketFifo::iterator rxFifoPtr;
1731156SN/A    bool rxEmpty;
1741156SN/A    Addr rxDmaAddr;
1752008SN/A    uint8_t *rxDmaData;
1761939SN/A    int rxDmaLen;
1772282SN/A
1781156SN/A    TxState txState;
1791156SN/A    PacketFifo txFifo;
1806227SN/A    bool txFull;
1811156SN/A    PacketPtr txPacket;
1821156SN/A    int txPacketOffset;
1831156SN/A    int txPacketBytes;
1841939SN/A    Addr txDmaAddr;
1852566SN/A    uint8_t *txDmaData;
1862008SN/A    int txDmaLen;
1872008SN/A
1881156SN/A  protected:
1891156SN/A    void reset();
1901156SN/A
1911156SN/A    void rxKick();
1921156SN/A    Tick rxKickTick;
1931156SN/A    typedef EventWrapper<Device, &Device::rxKick> RxKickEvent;
1941156SN/A    friend void RxKickEvent::process();
1951156SN/A
1961156SN/A    void txKick();
1971156SN/A    Tick txKickTick;
1981156SN/A    typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
1991156SN/A    friend void TxKickEvent::process();
2001156SN/A
2011156SN/A    /**
2021156SN/A     * Retransmit event
2031156SN/A     */
2041156SN/A    void transmit();
2051156SN/A    void txEventTransmit()
2061156SN/A    {
2071156SN/A        transmit();
2081156SN/A        if (txState == txFifoBlock)
2091156SN/A            txKick();
2101156SN/A    }
21112087Sspwilson2@wisc.edu    typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent;
2121156SN/A    friend void TxEvent::process();
2131156SN/A    TxEvent txEvent;
2141156SN/A
2151156SN/A    void txDump() const;
2161156SN/A    void rxDump() const;
2171156SN/A
2181156SN/A    /**
2192566SN/A     * receive address filter
2201156SN/A     */
2211156SN/A    bool rxFilter(const PacketPtr &packet);
2221156SN/A
2231156SN/A/**
2241156SN/A * device configuration
2251939SN/A */
2261156SN/A    void changeConfig(uint32_t newconfig);
2271156SN/A    void command(uint32_t command);
2281156SN/A
2291156SN/A/**
2301156SN/A * device ethernet interface
2312566SN/A */
2321156SN/A  public:
23313784Sgabeblack@google.com    bool recvPacket(PacketPtr packet);
23413784Sgabeblack@google.com    void transferDone();
2351156SN/A    void setInterface(Interface *i) { assert(!interface); interface = i; }
2361156SN/A
2371156SN/A/**
2381156SN/A * DMA parameters
2391156SN/A */
2401156SN/A  protected:
24112087Sspwilson2@wisc.edu    void rxDmaCopy();
2421156SN/A    void rxDmaDone();
2431156SN/A    friend class EventWrapper<Device, &Device::rxDmaDone>;
24412087Sspwilson2@wisc.edu    EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
2451156SN/A
2461156SN/A    void txDmaCopy();
2471156SN/A    void txDmaDone();
2481156SN/A    friend class EventWrapper<Device, &Device::txDmaDone>;
2491156SN/A    EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
2501156SN/A
2511156SN/A    Tick dmaReadDelay;
2521156SN/A    Tick dmaReadFactor;
2531156SN/A    Tick dmaWriteDelay;
2541156SN/A    Tick dmaWriteFactor;
2551156SN/A
2561156SN/A/**
2571156SN/A * Interrupt management
2581156SN/A */
2591156SN/A  protected:
2601156SN/A    void devIntrPost(uint32_t interrupts);
2611156SN/A    void devIntrClear(uint32_t interrupts = Regs::Intr_All);
2621156SN/A    void devIntrChangeMask(uint32_t newmask);
26311169SN/A
26411169SN/A/**
26511168SN/A * PCI Configuration interface
2661993SN/A */
26711005SN/A  public:
26811005SN/A    virtual void writeConfig(int offset, int size, const uint8_t *data);
26911005SN/A
27011005SN/A/**
2711156SN/A * Memory Interface
2721156SN/A */
2731156SN/A  public:
2741156SN/A    virtual Fault read(MemReqPtr &req, uint8_t *data);
2751156SN/A    virtual Fault write(MemReqPtr &req, const uint8_t *data);
2765999SN/A
2775999SN/A    void prepareIO(int cpu, int index);
2785999SN/A    void prepareRead(int cpu, int index);
2795603SN/A    void prepareWrite(int cpu, int index);
2805603SN/A    Fault iprRead(Addr daddr, int cpu, uint64_t &result);
2815603SN/A    Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data);
2825603SN/A    Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data);
2831156SN/A    void regWrite(Addr daddr, int cpu, const uint8_t *data);
28411169SN/A    Tick cacheAccess(MemReqPtr &req);
28511169SN/A
2861156SN/A  protected:
2871156SN/A    struct RegWriteData {
2881156SN/A        Addr daddr;
2891156SN/A        uint64_t value;
2901156SN/A        RegWriteData(Addr da, uint64_t val) : daddr(da), value(val) {}
29111168SN/A    };
29211168SN/A
2931156SN/A    std::vector<std::list<RegWriteData> > writeQueue;
2941156SN/A
2954981SN/A    bool pioDelayWrite;
2961156SN/A
2971156SN/A/**
2981156SN/A * Statistics
2991156SN/A */
3001156SN/A  private:
3011156SN/A    Stats::Scalar<> rxBytes;
3021156SN/A    Stats::Formula  rxBandwidth;
3031156SN/A    Stats::Scalar<> rxPackets;
3041156SN/A    Stats::Formula  rxPacketRate;
3051156SN/A    Stats::Scalar<> rxIpPackets;
3061156SN/A    Stats::Scalar<> rxTcpPackets;
3071156SN/A    Stats::Scalar<> rxUdpPackets;
3081156SN/A    Stats::Scalar<> rxIpChecksums;
3094981SN/A    Stats::Scalar<> rxTcpChecksums;
3104981SN/A    Stats::Scalar<> rxUdpChecksums;
3111156SN/A
3122566SN/A    Stats::Scalar<> txBytes;
3131156SN/A    Stats::Formula  txBandwidth;
3141156SN/A    Stats::Formula totBandwidth;
3151156SN/A    Stats::Formula totPackets;
3167811SN/A    Stats::Formula totBytes;
3171156SN/A    Stats::Formula totPacketRate;
31811263Sandreas.sandberg@arm.com    Stats::Scalar<> txPackets;
319    Stats::Formula  txPacketRate;
320    Stats::Scalar<> txIpPackets;
321    Stats::Scalar<> txTcpPackets;
322    Stats::Scalar<> txUdpPackets;
323    Stats::Scalar<> txIpChecksums;
324    Stats::Scalar<> txTcpChecksums;
325    Stats::Scalar<> txUdpChecksums;
326
327  public:
328    virtual void regStats();
329
330/**
331 * Serialization stuff
332 */
333  public:
334    virtual void serialize(std::ostream &os);
335    virtual void unserialize(Checkpoint *cp, const std::string &section);
336
337/**
338 * Construction/Destruction/Parameters
339 */
340  public:
341    struct Params : public Base::Params
342    {
343        IntrControl *i;
344        PhysicalMemory *pmem;
345        Tick tx_delay;
346        Tick rx_delay;
347        HierParams *hier;
348        Bus *pio_bus;
349        Bus *header_bus;
350        Bus *payload_bus;
351        Tick pio_latency;
352        bool pio_delay_write;
353        PhysicalMemory *physmem;
354        IntrControl *intctrl;
355        bool rx_filter;
356        Net::EthAddr eaddr;
357        uint32_t rx_max_copy;
358        uint32_t tx_max_copy;
359        uint32_t rx_max_intr;
360        uint32_t rx_fifo_size;
361        uint32_t tx_fifo_size;
362        uint32_t rx_fifo_threshold;
363        uint32_t tx_fifo_threshold;
364        Tick dma_read_delay;
365        Tick dma_read_factor;
366        Tick dma_write_delay;
367        Tick dma_write_factor;
368        bool dma_no_allocate;
369        bool rx_thread;
370        bool tx_thread;
371    };
372
373  protected:
374    const Params *params() const { return (const Params *)_params; }
375
376  public:
377    Device(Params *params);
378    ~Device();
379};
380
381/*
382 * Ethernet Interface for an Ethernet Device
383 */
384class Interface : public EtherInt
385{
386  private:
387    Device *dev;
388
389  public:
390    Interface(const std::string &name, Device *d)
391        : EtherInt(name), dev(d) { dev->setInterface(this); }
392
393    virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); }
394    virtual void sendDone() { dev->transferDone(); }
395};
396
397/* namespace Sinic */ }
398
399#endif // __DEV_SINIC_HH__
400