sinic.hh revision 4762
114184Sgabeblack@google.com/*
214184Sgabeblack@google.com * Copyright (c) 2004-2005 The Regents of The University of Michigan
314184Sgabeblack@google.com * All rights reserved.
414184Sgabeblack@google.com *
514184Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
614184Sgabeblack@google.com * modification, are permitted provided that the following conditions are
714184Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
814184Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
914184Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1014184Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1114184Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1214184Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1314184Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1414184Sgabeblack@google.com * this software without specific prior written permission.
1514184Sgabeblack@google.com *
1614184Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1714184Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1814184Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1914184Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2014184Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2114184Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2214184Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2314184Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2414184Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2514184Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2614184Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2714184Sgabeblack@google.com *
2814184Sgabeblack@google.com * Authors: Nathan Binkert
2914184Sgabeblack@google.com */
3014184Sgabeblack@google.com
3114184Sgabeblack@google.com#ifndef __DEV_SINIC_HH__
3214184Sgabeblack@google.com#define __DEV_SINIC_HH__
3314184Sgabeblack@google.com
3414184Sgabeblack@google.com#include "base/inet.hh"
3514184Sgabeblack@google.com#include "base/statistics.hh"
3614184Sgabeblack@google.com#include "dev/etherint.hh"
3714184Sgabeblack@google.com#include "dev/etherpkt.hh"
3814184Sgabeblack@google.com#include "dev/io_device.hh"
3914184Sgabeblack@google.com#include "dev/pcidev.hh"
4014184Sgabeblack@google.com#include "dev/pktfifo.hh"
4114184Sgabeblack@google.com#include "dev/sinicreg.hh"
4214184Sgabeblack@google.com#include "params/Sinic.hh"
4314184Sgabeblack@google.com#include "params/SinicInt.hh"
4414184Sgabeblack@google.com#include "sim/eventq.hh"
4514184Sgabeblack@google.com
4614184Sgabeblack@google.comnamespace Sinic {
4714184Sgabeblack@google.com
4814184Sgabeblack@google.comclass Interface;
4914184Sgabeblack@google.comclass Base : public PciDev
5014184Sgabeblack@google.com{
5114184Sgabeblack@google.com  protected:
5214184Sgabeblack@google.com    bool rxEnable;
5314184Sgabeblack@google.com    bool txEnable;
5414184Sgabeblack@google.com    Tick clock;
5514184Sgabeblack@google.com    inline Tick cycles(int numCycles) const { return numCycles * clock; }
5614184Sgabeblack@google.com
5714184Sgabeblack@google.com  protected:
5814184Sgabeblack@google.com    Tick intrDelay;
5914184Sgabeblack@google.com    Tick intrTick;
6014184Sgabeblack@google.com    bool cpuIntrEnable;
6114184Sgabeblack@google.com    bool cpuPendingIntr;
6214184Sgabeblack@google.com    void cpuIntrPost(Tick when);
6314184Sgabeblack@google.com    void cpuInterrupt();
6414184Sgabeblack@google.com    void cpuIntrClear();
6514184Sgabeblack@google.com
6614184Sgabeblack@google.com    typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent;
6714184Sgabeblack@google.com    friend void IntrEvent::process();
6814184Sgabeblack@google.com    IntrEvent *intrEvent;
6914184Sgabeblack@google.com    Interface *interface;
7014184Sgabeblack@google.com
7114184Sgabeblack@google.com    bool cpuIntrPending() const;
7214184Sgabeblack@google.com    void cpuIntrAck() { cpuIntrClear(); }
7314184Sgabeblack@google.com
7414184Sgabeblack@google.com/**
7514184Sgabeblack@google.com * Serialization stuff
7614184Sgabeblack@google.com */
7714184Sgabeblack@google.com  public:
7814184Sgabeblack@google.com    virtual void serialize(std::ostream &os);
7914184Sgabeblack@google.com    virtual void unserialize(Checkpoint *cp, const std::string &section);
8014184Sgabeblack@google.com
8114184Sgabeblack@google.com/**
8214184Sgabeblack@google.com * Construction/Destruction/Parameters
8314184Sgabeblack@google.com */
8414184Sgabeblack@google.com  public:
8514184Sgabeblack@google.com    typedef SinicParams Params;
8614184Sgabeblack@google.com    const Params *params() const { return (const Params *)_params; }
8714184Sgabeblack@google.com    Base(Params *p);
8814184Sgabeblack@google.com};
8914184Sgabeblack@google.com
9014184Sgabeblack@google.comclass Device : public Base
9114184Sgabeblack@google.com{
9214184Sgabeblack@google.com  protected:
9314184Sgabeblack@google.com    /** Receive State Machine States */
9414184Sgabeblack@google.com    enum RxState {
9514184Sgabeblack@google.com        rxIdle,
9614184Sgabeblack@google.com        rxFifoBlock,
9714184Sgabeblack@google.com        rxBeginCopy,
9814184Sgabeblack@google.com        rxCopy,
9914184Sgabeblack@google.com        rxCopyDone
10014184Sgabeblack@google.com    };
10114184Sgabeblack@google.com
10214184Sgabeblack@google.com    /** Transmit State Machine states */
10314184Sgabeblack@google.com    enum TxState {
10414184Sgabeblack@google.com        txIdle,
10514184Sgabeblack@google.com        txFifoBlock,
10614184Sgabeblack@google.com        txBeginCopy,
10714184Sgabeblack@google.com        txCopy,
10814184Sgabeblack@google.com        txCopyDone
10914184Sgabeblack@google.com    };
11014184Sgabeblack@google.com
11114184Sgabeblack@google.com    /** device register file */
11214184Sgabeblack@google.com    struct {
11314184Sgabeblack@google.com        uint32_t Config;       // 0x00
11414184Sgabeblack@google.com        uint32_t Command;      // 0x04
11514184Sgabeblack@google.com        uint32_t IntrStatus;   // 0x08
11614184Sgabeblack@google.com        uint32_t IntrMask;     // 0x0c
11714184Sgabeblack@google.com        uint32_t RxMaxCopy;    // 0x10
11814184Sgabeblack@google.com        uint32_t TxMaxCopy;    // 0x14
11914184Sgabeblack@google.com        uint32_t RxMaxIntr;    // 0x18
12014184Sgabeblack@google.com        uint32_t VirtualCount; // 0x1c
12114184Sgabeblack@google.com        uint32_t RxFifoSize;   // 0x20
12214184Sgabeblack@google.com        uint32_t TxFifoSize;   // 0x24
12314184Sgabeblack@google.com        uint32_t RxFifoMark;   // 0x28
12414184Sgabeblack@google.com        uint32_t TxFifoMark;   // 0x2c
12514184Sgabeblack@google.com        uint64_t RxData;       // 0x30
12614184Sgabeblack@google.com        uint64_t RxDone;       // 0x38
12714184Sgabeblack@google.com        uint64_t RxWait;       // 0x40
12814184Sgabeblack@google.com        uint64_t TxData;       // 0x48
12914184Sgabeblack@google.com        uint64_t TxDone;       // 0x50
13014184Sgabeblack@google.com        uint64_t TxWait;       // 0x58
13114184Sgabeblack@google.com        uint64_t HwAddr;       // 0x60
13214184Sgabeblack@google.com    } regs;
13314184Sgabeblack@google.com
13414184Sgabeblack@google.com    struct VirtualReg {
13514184Sgabeblack@google.com        uint64_t RxData;
13614184Sgabeblack@google.com        uint64_t RxDone;
13714184Sgabeblack@google.com        uint64_t TxData;
13814184Sgabeblack@google.com        uint64_t TxDone;
13914184Sgabeblack@google.com
14014184Sgabeblack@google.com        PacketFifo::iterator rxPacket;
14114184Sgabeblack@google.com        int rxPacketOffset;
14214184Sgabeblack@google.com        int rxPacketBytes;
14314184Sgabeblack@google.com        uint64_t rxDoneData;
14414184Sgabeblack@google.com
14514184Sgabeblack@google.com        Counter rxUnique;
14614184Sgabeblack@google.com        Counter txUnique;
14714184Sgabeblack@google.com
14814184Sgabeblack@google.com        VirtualReg()
14914184Sgabeblack@google.com            : RxData(0), RxDone(0), TxData(0), TxDone(0),
15014184Sgabeblack@google.com              rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0)
15114184Sgabeblack@google.com        { }
15214184Sgabeblack@google.com    };
15314184Sgabeblack@google.com    typedef std::vector<VirtualReg> VirtualRegs;
15414184Sgabeblack@google.com    typedef std::list<int> VirtualList;
15514184Sgabeblack@google.com    Counter rxUnique;
15614184Sgabeblack@google.com    Counter txUnique;
15714184Sgabeblack@google.com    VirtualRegs virtualRegs;
15814184Sgabeblack@google.com    VirtualList rxList;
15914184Sgabeblack@google.com    VirtualList rxBusy;
16014184Sgabeblack@google.com    int rxActive;
16114184Sgabeblack@google.com    VirtualList txList;
16214184Sgabeblack@google.com
16314184Sgabeblack@google.com    uint8_t  &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
16414184Sgabeblack@google.com    uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
16514184Sgabeblack@google.com    uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }
16614184Sgabeblack@google.com
16714184Sgabeblack@google.com  protected:
16814184Sgabeblack@google.com    RxState rxState;
16914184Sgabeblack@google.com    PacketFifo rxFifo;
17014184Sgabeblack@google.com    PacketFifo::iterator rxFifoPtr;
17114184Sgabeblack@google.com    bool rxEmpty;
17214184Sgabeblack@google.com    bool rxLow;
17314184Sgabeblack@google.com    Addr rxDmaAddr;
17414184Sgabeblack@google.com    uint8_t *rxDmaData;
17514184Sgabeblack@google.com    int rxDmaLen;
17614184Sgabeblack@google.com
17714184Sgabeblack@google.com    TxState txState;
17814184Sgabeblack@google.com    PacketFifo txFifo;
17914184Sgabeblack@google.com    bool txFull;
18014184Sgabeblack@google.com    EthPacketPtr txPacket;
18114184Sgabeblack@google.com    int txPacketOffset;
18214184Sgabeblack@google.com    int txPacketBytes;
18314184Sgabeblack@google.com    Addr txDmaAddr;
18414184Sgabeblack@google.com    uint8_t *txDmaData;
18514184Sgabeblack@google.com    int txDmaLen;
18614184Sgabeblack@google.com
18714184Sgabeblack@google.com  protected:
18814184Sgabeblack@google.com    void reset();
18914184Sgabeblack@google.com
19014184Sgabeblack@google.com    void rxKick();
19114184Sgabeblack@google.com    Tick rxKickTick;
19214184Sgabeblack@google.com    typedef EventWrapper<Device, &Device::rxKick> RxKickEvent;
19314184Sgabeblack@google.com    friend void RxKickEvent::process();
19414184Sgabeblack@google.com
19514184Sgabeblack@google.com    void txKick();
19614184Sgabeblack@google.com    Tick txKickTick;
19714184Sgabeblack@google.com    typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
19814184Sgabeblack@google.com    friend void TxKickEvent::process();
19914184Sgabeblack@google.com
20014184Sgabeblack@google.com    /**
20114184Sgabeblack@google.com     * Retransmit event
20214184Sgabeblack@google.com     */
20314184Sgabeblack@google.com    void transmit();
20414184Sgabeblack@google.com    void txEventTransmit()
20514184Sgabeblack@google.com    {
20614184Sgabeblack@google.com        transmit();
20714184Sgabeblack@google.com        if (txState == txFifoBlock)
20814184Sgabeblack@google.com            txKick();
20914184Sgabeblack@google.com    }
21014184Sgabeblack@google.com    typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent;
21114184Sgabeblack@google.com    friend void TxEvent::process();
21214184Sgabeblack@google.com    TxEvent txEvent;
21314184Sgabeblack@google.com
21414184Sgabeblack@google.com    void txDump() const;
21514184Sgabeblack@google.com    void rxDump() const;
21614184Sgabeblack@google.com
21714184Sgabeblack@google.com    /**
21814184Sgabeblack@google.com     * receive address filter
21914184Sgabeblack@google.com     */
22014184Sgabeblack@google.com    bool rxFilter(const EthPacketPtr &packet);
22114184Sgabeblack@google.com
22214184Sgabeblack@google.com/**
22314184Sgabeblack@google.com * device configuration
22414184Sgabeblack@google.com */
22514184Sgabeblack@google.com    void changeConfig(uint32_t newconfig);
22614184Sgabeblack@google.com    void command(uint32_t command);
22714184Sgabeblack@google.com
22814184Sgabeblack@google.com/**
22914184Sgabeblack@google.com * device ethernet interface
23014184Sgabeblack@google.com */
23114184Sgabeblack@google.com  public:
23214184Sgabeblack@google.com    bool recvPacket(EthPacketPtr packet);
23314184Sgabeblack@google.com    void transferDone();
23414184Sgabeblack@google.com    void setInterface(Interface *i) { assert(!interface); interface = i; }
23514184Sgabeblack@google.com
23614184Sgabeblack@google.com/**
23714184Sgabeblack@google.com * DMA parameters
23814184Sgabeblack@google.com */
23914184Sgabeblack@google.com  protected:
24014184Sgabeblack@google.com    void rxDmaDone();
24114184Sgabeblack@google.com    friend class EventWrapper<Device, &Device::rxDmaDone>;
24214184Sgabeblack@google.com    EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
24314184Sgabeblack@google.com
24414184Sgabeblack@google.com    void txDmaDone();
24514184Sgabeblack@google.com    friend class EventWrapper<Device, &Device::txDmaDone>;
24614184Sgabeblack@google.com    EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
24714184Sgabeblack@google.com
24814184Sgabeblack@google.com    Tick dmaReadDelay;
24914184Sgabeblack@google.com    Tick dmaReadFactor;
25014184Sgabeblack@google.com    Tick dmaWriteDelay;
25114184Sgabeblack@google.com    Tick dmaWriteFactor;
25214184Sgabeblack@google.com
25314184Sgabeblack@google.com/**
25414184Sgabeblack@google.com * Interrupt management
25514184Sgabeblack@google.com */
25614184Sgabeblack@google.com  protected:
25714184Sgabeblack@google.com    void devIntrPost(uint32_t interrupts);
25814184Sgabeblack@google.com    void devIntrClear(uint32_t interrupts = Regs::Intr_All);
25914184Sgabeblack@google.com    void devIntrChangeMask(uint32_t newmask);
26014184Sgabeblack@google.com
26114184Sgabeblack@google.com/**
26214184Sgabeblack@google.com * Memory Interface
26314184Sgabeblack@google.com */
26414184Sgabeblack@google.com  public:
26514184Sgabeblack@google.com    virtual Tick read(PacketPtr pkt);
26614184Sgabeblack@google.com    virtual Tick write(PacketPtr pkt);
26714184Sgabeblack@google.com    virtual void resume();
26814184Sgabeblack@google.com
26914184Sgabeblack@google.com    void prepareIO(int cpu, int index);
27014184Sgabeblack@google.com    void prepareRead(int cpu, int index);
27114184Sgabeblack@google.com    void prepareWrite(int cpu, int index);
27214184Sgabeblack@google.com //   Fault iprRead(Addr daddr, int cpu, uint64_t &result);
27314184Sgabeblack@google.com
27414184Sgabeblack@google.com/**
27514184Sgabeblack@google.com * Statistics
27614184Sgabeblack@google.com */
27714184Sgabeblack@google.com  private:
27814184Sgabeblack@google.com    Stats::Scalar<> rxBytes;
27914184Sgabeblack@google.com    Stats::Formula  rxBandwidth;
28014184Sgabeblack@google.com    Stats::Scalar<> rxPackets;
28114184Sgabeblack@google.com    Stats::Formula  rxPacketRate;
28214184Sgabeblack@google.com    Stats::Scalar<> rxIpPackets;
28314184Sgabeblack@google.com    Stats::Scalar<> rxTcpPackets;
28414184Sgabeblack@google.com    Stats::Scalar<> rxUdpPackets;
28514184Sgabeblack@google.com    Stats::Scalar<> rxIpChecksums;
28614184Sgabeblack@google.com    Stats::Scalar<> rxTcpChecksums;
28714184Sgabeblack@google.com    Stats::Scalar<> rxUdpChecksums;
28814184Sgabeblack@google.com
28914184Sgabeblack@google.com    Stats::Scalar<> txBytes;
29014184Sgabeblack@google.com    Stats::Formula  txBandwidth;
29114184Sgabeblack@google.com    Stats::Formula totBandwidth;
29214184Sgabeblack@google.com    Stats::Formula totPackets;
29314184Sgabeblack@google.com    Stats::Formula totBytes;
29414184Sgabeblack@google.com    Stats::Formula totPacketRate;
29514184Sgabeblack@google.com    Stats::Scalar<> txPackets;
29614184Sgabeblack@google.com    Stats::Formula  txPacketRate;
29714184Sgabeblack@google.com    Stats::Scalar<> txIpPackets;
29814184Sgabeblack@google.com    Stats::Scalar<> txTcpPackets;
29914184Sgabeblack@google.com    Stats::Scalar<> txUdpPackets;
30014184Sgabeblack@google.com    Stats::Scalar<> txIpChecksums;
30114184Sgabeblack@google.com    Stats::Scalar<> txTcpChecksums;
30214184Sgabeblack@google.com    Stats::Scalar<> txUdpChecksums;
30314184Sgabeblack@google.com
30414184Sgabeblack@google.com  public:
30514184Sgabeblack@google.com    virtual void regStats();
30614184Sgabeblack@google.com
30714184Sgabeblack@google.com/**
30814184Sgabeblack@google.com * Serialization stuff
30914184Sgabeblack@google.com */
31014184Sgabeblack@google.com  public:
31114184Sgabeblack@google.com    virtual void serialize(std::ostream &os);
31214184Sgabeblack@google.com    virtual void unserialize(Checkpoint *cp, const std::string &section);
31314184Sgabeblack@google.com
31414184Sgabeblack@google.com  public:
31514184Sgabeblack@google.com    Device(Params *p);
31614184Sgabeblack@google.com    ~Device();
31714184Sgabeblack@google.com};
31814184Sgabeblack@google.com
31914184Sgabeblack@google.com/*
32014184Sgabeblack@google.com * Ethernet Interface for an Ethernet Device
32114184Sgabeblack@google.com */
32214184Sgabeblack@google.comclass Interface : public EtherInt
323{
324  private:
325    Device *dev;
326
327  public:
328    Interface(const std::string &name, Device *d)
329        : EtherInt(name), dev(d) { dev->setInterface(this); }
330
331    virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
332    virtual void sendDone() { dev->transferDone(); }
333};
334
335/* namespace Sinic */ }
336
337#endif // __DEV_SINIC_HH__
338