sinic.hh revision 4762
17927SN/A/*
27927SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
38673SN/A * All rights reserved.
48673SN/A *
58721SN/A * Redistribution and use in source and binary forms, with or without
67927SN/A * modification, are permitted provided that the following conditions are
78983Snate@binkert.org * met: redistributions of source code must retain the above copyright
88983Snate@binkert.org * notice, this list of conditions and the following disclaimer;
98983Snate@binkert.org * redistributions in binary form must reproduce the above copyright
108983Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
118983Snate@binkert.org * documentation and/or other materials provided with the distribution;
128835SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its
138835SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from
148721SN/A * this software without specific prior written permission.
158721SN/A *
168721SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
178721SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
188721SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
198721SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
208721SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
218721SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
228721SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
238721SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
248673SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258673SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
268673SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278673SN/A *
288673SN/A * Authors: Nathan Binkert
298613SN/A */
308835SAli.Saidi@ARM.com
318835SAli.Saidi@ARM.com#ifndef __DEV_SINIC_HH__
328835SAli.Saidi@ARM.com#define __DEV_SINIC_HH__
338835SAli.Saidi@ARM.com
348835SAli.Saidi@ARM.com#include "base/inet.hh"
358835SAli.Saidi@ARM.com#include "base/statistics.hh"
368835SAli.Saidi@ARM.com#include "dev/etherint.hh"
378835SAli.Saidi@ARM.com#include "dev/etherpkt.hh"
388835SAli.Saidi@ARM.com#include "dev/io_device.hh"
398835SAli.Saidi@ARM.com#include "dev/pcidev.hh"
408835SAli.Saidi@ARM.com#include "dev/pktfifo.hh"
418835SAli.Saidi@ARM.com#include "dev/sinicreg.hh"
428835SAli.Saidi@ARM.com#include "params/Sinic.hh"
438835SAli.Saidi@ARM.com#include "params/SinicInt.hh"
448835SAli.Saidi@ARM.com#include "sim/eventq.hh"
458673SN/A
468835SAli.Saidi@ARM.comnamespace Sinic {
478673SN/A
488835SAli.Saidi@ARM.comclass Interface;
498673SN/Aclass Base : public PciDev
508835SAli.Saidi@ARM.com{
518673SN/A  protected:
528835SAli.Saidi@ARM.com    bool rxEnable;
538835SAli.Saidi@ARM.com    bool txEnable;
548835SAli.Saidi@ARM.com    Tick clock;
558835SAli.Saidi@ARM.com    inline Tick cycles(int numCycles) const { return numCycles * clock; }
568673SN/A
578835SAli.Saidi@ARM.com  protected:
588835SAli.Saidi@ARM.com    Tick intrDelay;
598835SAli.Saidi@ARM.com    Tick intrTick;
608835SAli.Saidi@ARM.com    bool cpuIntrEnable;
618673SN/A    bool cpuPendingIntr;
628835SAli.Saidi@ARM.com    void cpuIntrPost(Tick when);
638835SAli.Saidi@ARM.com    void cpuInterrupt();
648835SAli.Saidi@ARM.com    void cpuIntrClear();
658835SAli.Saidi@ARM.com
668673SN/A    typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent;
678835SAli.Saidi@ARM.com    friend void IntrEvent::process();
688673SN/A    IntrEvent *intrEvent;
698835SAli.Saidi@ARM.com    Interface *interface;
708673SN/A
718835SAli.Saidi@ARM.com    bool cpuIntrPending() const;
728835SAli.Saidi@ARM.com    void cpuIntrAck() { cpuIntrClear(); }
738835SAli.Saidi@ARM.com
748835SAli.Saidi@ARM.com/**
758673SN/A * Serialization stuff
768835SAli.Saidi@ARM.com */
778835SAli.Saidi@ARM.com  public:
788835SAli.Saidi@ARM.com    virtual void serialize(std::ostream &os);
798835SAli.Saidi@ARM.com    virtual void unserialize(Checkpoint *cp, const std::string &section);
808673SN/A
818835SAli.Saidi@ARM.com/**
828835SAli.Saidi@ARM.com * Construction/Destruction/Parameters
838835SAli.Saidi@ARM.com */
848835SAli.Saidi@ARM.com  public:
858673SN/A    typedef SinicParams Params;
868835SAli.Saidi@ARM.com    const Params *params() const { return (const Params *)_params; }
878673SN/A    Base(Params *p);
888835SAli.Saidi@ARM.com};
898673SN/A
908835SAli.Saidi@ARM.comclass Device : public Base
918673SN/A{
928835SAli.Saidi@ARM.com  protected:
938835SAli.Saidi@ARM.com    /** Receive State Machine States */
948835SAli.Saidi@ARM.com    enum RxState {
958835SAli.Saidi@ARM.com        rxIdle,
968673SN/A        rxFifoBlock,
978835SAli.Saidi@ARM.com        rxBeginCopy,
988835SAli.Saidi@ARM.com        rxCopy,
998835SAli.Saidi@ARM.com        rxCopyDone
1008835SAli.Saidi@ARM.com    };
1018673SN/A
1028835SAli.Saidi@ARM.com    /** Transmit State Machine states */
1038835SAli.Saidi@ARM.com    enum TxState {
1048835SAli.Saidi@ARM.com        txIdle,
1058835SAli.Saidi@ARM.com        txFifoBlock,
1068835SAli.Saidi@ARM.com        txBeginCopy,
1078835SAli.Saidi@ARM.com        txCopy,
1088835SAli.Saidi@ARM.com        txCopyDone
1098835SAli.Saidi@ARM.com    };
1108835SAli.Saidi@ARM.com
1118835SAli.Saidi@ARM.com    /** device register file */
1128835SAli.Saidi@ARM.com    struct {
1138835SAli.Saidi@ARM.com        uint32_t Config;       // 0x00
1148835SAli.Saidi@ARM.com        uint32_t Command;      // 0x04
1158835SAli.Saidi@ARM.com        uint32_t IntrStatus;   // 0x08
1168613SN/A        uint32_t IntrMask;     // 0x0c
1178613SN/A        uint32_t RxMaxCopy;    // 0x10
1188613SN/A        uint32_t TxMaxCopy;    // 0x14
1198613SN/A        uint32_t RxMaxIntr;    // 0x18
1208983Snate@binkert.org        uint32_t VirtualCount; // 0x1c
1218983Snate@binkert.org        uint32_t RxFifoSize;   // 0x20
1228613SN/A        uint32_t TxFifoSize;   // 0x24
1238613SN/A        uint32_t RxFifoMark;   // 0x28
1248835SAli.Saidi@ARM.com        uint32_t TxFifoMark;   // 0x2c
1258835SAli.Saidi@ARM.com        uint64_t RxData;       // 0x30
1268613SN/A        uint64_t RxDone;       // 0x38
1278673SN/A        uint64_t RxWait;       // 0x40
1288673SN/A        uint64_t TxData;       // 0x48
1298613SN/A        uint64_t TxDone;       // 0x50
1308673SN/A        uint64_t TxWait;       // 0x58
1318613SN/A        uint64_t HwAddr;       // 0x60
1328673SN/A    } regs;
1338835SAli.Saidi@ARM.com
1348835SAli.Saidi@ARM.com    struct VirtualReg {
1358835SAli.Saidi@ARM.com        uint64_t RxData;
1368835SAli.Saidi@ARM.com        uint64_t RxDone;
1378673SN/A        uint64_t TxData;
1388835SAli.Saidi@ARM.com        uint64_t TxDone;
1398613SN/A
1408835SAli.Saidi@ARM.com        PacketFifo::iterator rxPacket;
1418673SN/A        int rxPacketOffset;
1428835SAli.Saidi@ARM.com        int rxPacketBytes;
1438673SN/A        uint64_t rxDoneData;
1448835SAli.Saidi@ARM.com
1458673SN/A        Counter rxUnique;
1468835SAli.Saidi@ARM.com        Counter txUnique;
1478613SN/A
1488835SAli.Saidi@ARM.com        VirtualReg()
1498673SN/A            : RxData(0), RxDone(0), TxData(0), TxDone(0),
1508835SAli.Saidi@ARM.com              rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0)
1518673SN/A        { }
1528835SAli.Saidi@ARM.com    };
1538835SAli.Saidi@ARM.com    typedef std::vector<VirtualReg> VirtualRegs;
1548835SAli.Saidi@ARM.com    typedef std::list<int> VirtualList;
1558835SAli.Saidi@ARM.com    Counter rxUnique;
1568613SN/A    Counter txUnique;
1578613SN/A    VirtualRegs virtualRegs;
1588613SN/A    VirtualList rxList;
1598613SN/A    VirtualList rxBusy;
1608983Snate@binkert.org    int rxActive;
1618983Snate@binkert.org    VirtualList txList;
1628613SN/A
1638613SN/A    uint8_t  &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
1648835SAli.Saidi@ARM.com    uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
1658835SAli.Saidi@ARM.com    uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }
1668613SN/A
1678613SN/A  protected:
1688613SN/A    RxState rxState;
1698613SN/A    PacketFifo rxFifo;
1708613SN/A    PacketFifo::iterator rxFifoPtr;
1718613SN/A    bool rxEmpty;
1728613SN/A    bool rxLow;
1738613SN/A    Addr rxDmaAddr;
1748613SN/A    uint8_t *rxDmaData;
1758613SN/A    int rxDmaLen;
1768613SN/A
1778613SN/A    TxState txState;
1788613SN/A    PacketFifo txFifo;
1798673SN/A    bool txFull;
1808613SN/A    EthPacketPtr txPacket;
1818613SN/A    int txPacketOffset;
1828835SAli.Saidi@ARM.com    int txPacketBytes;
1838835SAli.Saidi@ARM.com    Addr txDmaAddr;
1848673SN/A    uint8_t *txDmaData;
1858613SN/A    int txDmaLen;
1868613SN/A
1878673SN/A  protected:
1888673SN/A    void reset();
1898613SN/A
1908673SN/A    void rxKick();
1918673SN/A    Tick rxKickTick;
1928613SN/A    typedef EventWrapper<Device, &Device::rxKick> RxKickEvent;
1938613SN/A    friend void RxKickEvent::process();
1948673SN/A
1958673SN/A    void txKick();
1968673SN/A    Tick txKickTick;
1978673SN/A    typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
1988673SN/A    friend void TxKickEvent::process();
1998673SN/A
2008673SN/A    /**
2018613SN/A     * Retransmit event
2028613SN/A     */
2038673SN/A    void transmit();
2048673SN/A    void txEventTransmit()
2058673SN/A    {
2068673SN/A        transmit();
2078673SN/A        if (txState == txFifoBlock)
2088673SN/A            txKick();
2098835SAli.Saidi@ARM.com    }
2108835SAli.Saidi@ARM.com    typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent;
2118835SAli.Saidi@ARM.com    friend void TxEvent::process();
2128835SAli.Saidi@ARM.com    TxEvent txEvent;
2138673SN/A
2148835SAli.Saidi@ARM.com    void txDump() const;
2158673SN/A    void rxDump() const;
2168835SAli.Saidi@ARM.com
2178673SN/A    /**
2188835SAli.Saidi@ARM.com     * receive address filter
2198673SN/A     */
2208835SAli.Saidi@ARM.com    bool rxFilter(const EthPacketPtr &packet);
2218673SN/A
2228835SAli.Saidi@ARM.com/**
2238673SN/A * device configuration
2248835SAli.Saidi@ARM.com */
2258673SN/A    void changeConfig(uint32_t newconfig);
2268835SAli.Saidi@ARM.com    void command(uint32_t command);
2278673SN/A
2288835SAli.Saidi@ARM.com/**
2298673SN/A * device ethernet interface
2308835SAli.Saidi@ARM.com */
2318835SAli.Saidi@ARM.com  public:
2328835SAli.Saidi@ARM.com    bool recvPacket(EthPacketPtr packet);
2338613SN/A    void transferDone();
2348613SN/A    void setInterface(Interface *i) { assert(!interface); interface = i; }
2358613SN/A
2368613SN/A/**
2378983Snate@binkert.org * DMA parameters
2388983Snate@binkert.org */
2398613SN/A  protected:
2408613SN/A    void rxDmaDone();
2418835SAli.Saidi@ARM.com    friend class EventWrapper<Device, &Device::rxDmaDone>;
2428835SAli.Saidi@ARM.com    EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
2438613SN/A
2448673SN/A    void txDmaDone();
2458673SN/A    friend class EventWrapper<Device, &Device::txDmaDone>;
2468673SN/A    EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
2478673SN/A
2488673SN/A    Tick dmaReadDelay;
2498673SN/A    Tick dmaReadFactor;
2508835SAli.Saidi@ARM.com    Tick dmaWriteDelay;
2518835SAli.Saidi@ARM.com    Tick dmaWriteFactor;
2528835SAli.Saidi@ARM.com
2538835SAli.Saidi@ARM.com/**
2548673SN/A * Interrupt management
2558835SAli.Saidi@ARM.com */
2568613SN/A  protected:
2578835SAli.Saidi@ARM.com    void devIntrPost(uint32_t interrupts);
2588673SN/A    void devIntrClear(uint32_t interrupts = Regs::Intr_All);
2598835SAli.Saidi@ARM.com    void devIntrChangeMask(uint32_t newmask);
2608673SN/A
2618835SAli.Saidi@ARM.com/**
2628673SN/A * Memory Interface
2638835SAli.Saidi@ARM.com */
2648673SN/A  public:
2658835SAli.Saidi@ARM.com    virtual Tick read(PacketPtr pkt);
2668673SN/A    virtual Tick write(PacketPtr pkt);
2678835SAli.Saidi@ARM.com    virtual void resume();
2688673SN/A
2698835SAli.Saidi@ARM.com    void prepareIO(int cpu, int index);
2708613SN/A    void prepareRead(int cpu, int index);
2718835SAli.Saidi@ARM.com    void prepareWrite(int cpu, int index);
2728673SN/A //   Fault iprRead(Addr daddr, int cpu, uint64_t &result);
2738835SAli.Saidi@ARM.com
2748673SN/A/**
2758835SAli.Saidi@ARM.com * Statistics
2768835SAli.Saidi@ARM.com */
2778835SAli.Saidi@ARM.com  private:
2788613SN/A    Stats::Scalar<> rxBytes;
2798613SN/A    Stats::Formula  rxBandwidth;
2808613SN/A    Stats::Scalar<> rxPackets;
2818613SN/A    Stats::Formula  rxPacketRate;
2828983Snate@binkert.org    Stats::Scalar<> rxIpPackets;
2838983Snate@binkert.org    Stats::Scalar<> rxTcpPackets;
2848613SN/A    Stats::Scalar<> rxUdpPackets;
2858613SN/A    Stats::Scalar<> rxIpChecksums;
2868835SAli.Saidi@ARM.com    Stats::Scalar<> rxTcpChecksums;
2878835SAli.Saidi@ARM.com    Stats::Scalar<> rxUdpChecksums;
2888613SN/A
2898673SN/A    Stats::Scalar<> txBytes;
2908673SN/A    Stats::Formula  txBandwidth;
2918673SN/A    Stats::Formula totBandwidth;
2928673SN/A    Stats::Formula totPackets;
2938673SN/A    Stats::Formula totBytes;
2948673SN/A    Stats::Formula totPacketRate;
2958835SAli.Saidi@ARM.com    Stats::Scalar<> txPackets;
2968835SAli.Saidi@ARM.com    Stats::Formula  txPacketRate;
2978835SAli.Saidi@ARM.com    Stats::Scalar<> txIpPackets;
2988835SAli.Saidi@ARM.com    Stats::Scalar<> txTcpPackets;
2998673SN/A    Stats::Scalar<> txUdpPackets;
3008835SAli.Saidi@ARM.com    Stats::Scalar<> txIpChecksums;
3018673SN/A    Stats::Scalar<> txTcpChecksums;
3028835SAli.Saidi@ARM.com    Stats::Scalar<> txUdpChecksums;
3038673SN/A
3048835SAli.Saidi@ARM.com  public:
3058673SN/A    virtual void regStats();
3068835SAli.Saidi@ARM.com
3078673SN/A/**
3088835SAli.Saidi@ARM.com * Serialization stuff
3098673SN/A */
3108835SAli.Saidi@ARM.com  public:
3118673SN/A    virtual void serialize(std::ostream &os);
3128835SAli.Saidi@ARM.com    virtual void unserialize(Checkpoint *cp, const std::string &section);
3138673SN/A
3148835SAli.Saidi@ARM.com  public:
3158673SN/A    Device(Params *p);
3168835SAli.Saidi@ARM.com    ~Device();
3178835SAli.Saidi@ARM.com};
3188835SAli.Saidi@ARM.com
3198613SN/A/*
3208613SN/A * Ethernet Interface for an Ethernet Device
3218613SN/A */
3228613SN/Aclass Interface : public EtherInt
3238983Snate@binkert.org{
3248983Snate@binkert.org  private:
3258613SN/A    Device *dev;
3268613SN/A
3278835SAli.Saidi@ARM.com  public:
3288835SAli.Saidi@ARM.com    Interface(const std::string &name, Device *d)
3298613SN/A        : EtherInt(name), dev(d) { dev->setInterface(this); }
3308673SN/A
3318613SN/A    virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
3328673SN/A    virtual void sendDone() { dev->transferDone(); }
3338673SN/A};
3348673SN/A
3358613SN/A/* namespace Sinic */ }
3368835SAli.Saidi@ARM.com
3378835SAli.Saidi@ARM.com#endif // __DEV_SINIC_HH__
3388835SAli.Saidi@ARM.com