sinic.hh revision 7811
112077Sgedare@rtems.org/*
212077Sgedare@rtems.org * Copyright (c) 2004-2005 The Regents of The University of Michigan
312077Sgedare@rtems.org * All rights reserved.
412077Sgedare@rtems.org *
512077Sgedare@rtems.org * Redistribution and use in source and binary forms, with or without
612077Sgedare@rtems.org * modification, are permitted provided that the following conditions are
712077Sgedare@rtems.org * met: redistributions of source code must retain the above copyright
812077Sgedare@rtems.org * notice, this list of conditions and the following disclaimer;
912077Sgedare@rtems.org * redistributions in binary form must reproduce the above copyright
1012077Sgedare@rtems.org * notice, this list of conditions and the following disclaimer in the
1112077Sgedare@rtems.org * documentation and/or other materials provided with the distribution;
1212077Sgedare@rtems.org * neither the name of the copyright holders nor the names of its
1312077Sgedare@rtems.org * contributors may be used to endorse or promote products derived from
1412077Sgedare@rtems.org * this software without specific prior written permission.
1512077Sgedare@rtems.org *
1612077Sgedare@rtems.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712077Sgedare@rtems.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812077Sgedare@rtems.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912077Sgedare@rtems.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012077Sgedare@rtems.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112077Sgedare@rtems.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212077Sgedare@rtems.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312077Sgedare@rtems.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412077Sgedare@rtems.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512077Sgedare@rtems.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612077Sgedare@rtems.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712077Sgedare@rtems.org *
2812077Sgedare@rtems.org * Authors: Nathan Binkert
2912077Sgedare@rtems.org */
3012077Sgedare@rtems.org
3112077Sgedare@rtems.org#ifndef __DEV_SINIC_HH__
3212077Sgedare@rtems.org#define __DEV_SINIC_HH__
3312077Sgedare@rtems.org
3412077Sgedare@rtems.org#include "base/inet.hh"
3512077Sgedare@rtems.org#include "base/statistics.hh"
3612077Sgedare@rtems.org#include "dev/etherint.hh"
3712077Sgedare@rtems.org#include "dev/etherpkt.hh"
3812077Sgedare@rtems.org#include "dev/io_device.hh"
3912077Sgedare@rtems.org#include "dev/pcidev.hh"
4012077Sgedare@rtems.org#include "dev/pktfifo.hh"
4112077Sgedare@rtems.org#include "dev/sinicreg.hh"
4212077Sgedare@rtems.org#include "params/Sinic.hh"
4312077Sgedare@rtems.org#include "sim/eventq.hh"
4412077Sgedare@rtems.org
4512077Sgedare@rtems.orgnamespace Sinic {
4612077Sgedare@rtems.org
4712077Sgedare@rtems.orgclass Interface;
4812077Sgedare@rtems.orgclass Base : public PciDev
4912077Sgedare@rtems.org{
5012077Sgedare@rtems.org  protected:
5112077Sgedare@rtems.org    bool rxEnable;
5212077Sgedare@rtems.org    bool txEnable;
5312077Sgedare@rtems.org    Tick clock;
5412077Sgedare@rtems.org    inline Tick ticks(int numCycles) const { return numCycles * clock; }
5512077Sgedare@rtems.org
5612077Sgedare@rtems.org  protected:
5712077Sgedare@rtems.org    Tick intrDelay;
5812077Sgedare@rtems.org    Tick intrTick;
5912077Sgedare@rtems.org    bool cpuIntrEnable;
6012077Sgedare@rtems.org    bool cpuPendingIntr;
6112077Sgedare@rtems.org    void cpuIntrPost(Tick when);
6212077Sgedare@rtems.org    void cpuInterrupt();
6312077Sgedare@rtems.org    void cpuIntrClear();
6412077Sgedare@rtems.org
6512077Sgedare@rtems.org    typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent;
6612077Sgedare@rtems.org    friend void IntrEvent::process();
6712077Sgedare@rtems.org    IntrEvent *intrEvent;
6812077Sgedare@rtems.org    Interface *interface;
6912077Sgedare@rtems.org
7012077Sgedare@rtems.org    bool cpuIntrPending() const;
7112077Sgedare@rtems.org    void cpuIntrAck() { cpuIntrClear(); }
7212077Sgedare@rtems.org
7312077Sgedare@rtems.org/**
7412077Sgedare@rtems.org * Serialization stuff
7512077Sgedare@rtems.org */
7612077Sgedare@rtems.org  public:
7712077Sgedare@rtems.org    virtual void serialize(std::ostream &os);
7812077Sgedare@rtems.org    virtual void unserialize(Checkpoint *cp, const std::string &section);
7912077Sgedare@rtems.org
8012077Sgedare@rtems.org/**
8112077Sgedare@rtems.org * Construction/Destruction/Parameters
8212077Sgedare@rtems.org */
8312077Sgedare@rtems.org  public:
8412077Sgedare@rtems.org    typedef SinicParams Params;
8512077Sgedare@rtems.org    const Params *params() const { return (const Params *)_params; }
8612077Sgedare@rtems.org    Base(const Params *p);
8712077Sgedare@rtems.org};
8812077Sgedare@rtems.org
8912077Sgedare@rtems.orgclass Device : public Base
9012077Sgedare@rtems.org{
9112077Sgedare@rtems.org  protected:
9212077Sgedare@rtems.org    /** Receive State Machine States */
9312077Sgedare@rtems.org    enum RxState {
9412077Sgedare@rtems.org        rxIdle,
9512077Sgedare@rtems.org        rxFifoBlock,
9612077Sgedare@rtems.org        rxBeginCopy,
9712077Sgedare@rtems.org        rxCopy,
9812077Sgedare@rtems.org        rxCopyDone
9912077Sgedare@rtems.org    };
10012077Sgedare@rtems.org
10112077Sgedare@rtems.org    /** Transmit State Machine states */
10212077Sgedare@rtems.org    enum TxState {
10312077Sgedare@rtems.org        txIdle,
10412077Sgedare@rtems.org        txFifoBlock,
10512077Sgedare@rtems.org        txBeginCopy,
10612077Sgedare@rtems.org        txCopy,
10712077Sgedare@rtems.org        txCopyDone
10812077Sgedare@rtems.org    };
10912077Sgedare@rtems.org
11012077Sgedare@rtems.org    /** device register file */
11112077Sgedare@rtems.org    struct {
11212077Sgedare@rtems.org        uint32_t Config;       // 0x00
11312077Sgedare@rtems.org        uint32_t Command;      // 0x04
11412077Sgedare@rtems.org        uint32_t IntrStatus;   // 0x08
11512077Sgedare@rtems.org        uint32_t IntrMask;     // 0x0c
11612077Sgedare@rtems.org        uint32_t RxMaxCopy;    // 0x10
11712077Sgedare@rtems.org        uint32_t TxMaxCopy;    // 0x14
11812077Sgedare@rtems.org        uint32_t ZeroCopySize; // 0x18
11912077Sgedare@rtems.org        uint32_t ZeroCopyMark; // 0x1c
12012077Sgedare@rtems.org        uint32_t VirtualCount; // 0x20
12112077Sgedare@rtems.org        uint32_t RxMaxIntr;    // 0x24
12212077Sgedare@rtems.org        uint32_t RxFifoSize;   // 0x28
12312077Sgedare@rtems.org        uint32_t TxFifoSize;   // 0x2c
12412077Sgedare@rtems.org        uint32_t RxFifoLow;    // 0x30
12512077Sgedare@rtems.org        uint32_t TxFifoLow;    // 0x34
12612077Sgedare@rtems.org        uint32_t RxFifoHigh;   // 0x38
12712077Sgedare@rtems.org        uint32_t TxFifoHigh;   // 0x3c
12812077Sgedare@rtems.org        uint64_t RxData;       // 0x40
12912077Sgedare@rtems.org        uint64_t RxDone;       // 0x48
13012077Sgedare@rtems.org        uint64_t RxWait;       // 0x50
13112077Sgedare@rtems.org        uint64_t TxData;       // 0x58
13212077Sgedare@rtems.org        uint64_t TxDone;       // 0x60
13312077Sgedare@rtems.org        uint64_t TxWait;       // 0x68
13412077Sgedare@rtems.org        uint64_t HwAddr;       // 0x70
13512077Sgedare@rtems.org        uint64_t RxStatus;     // 0x78
13612077Sgedare@rtems.org    } regs;
13712077Sgedare@rtems.org
13812077Sgedare@rtems.org    struct VirtualReg {
13912077Sgedare@rtems.org        uint64_t RxData;
14012077Sgedare@rtems.org        uint64_t RxDone;
14112077Sgedare@rtems.org        uint64_t TxData;
14212077Sgedare@rtems.org        uint64_t TxDone;
14312077Sgedare@rtems.org
14412077Sgedare@rtems.org        PacketFifo::iterator rxIndex;
14512077Sgedare@rtems.org        unsigned rxPacketOffset;
14612077Sgedare@rtems.org        unsigned rxPacketBytes;
14712077Sgedare@rtems.org        uint64_t rxDoneData;
14812077Sgedare@rtems.org
14912077Sgedare@rtems.org        Counter rxUnique;
15012077Sgedare@rtems.org        Counter txUnique;
15112077Sgedare@rtems.org
15212077Sgedare@rtems.org        VirtualReg()
15312077Sgedare@rtems.org            : RxData(0), RxDone(0), TxData(0), TxDone(0),
15412077Sgedare@rtems.org              rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0)
15512077Sgedare@rtems.org        { }
15612077Sgedare@rtems.org    };
15712077Sgedare@rtems.org    typedef std::vector<VirtualReg> VirtualRegs;
15812077Sgedare@rtems.org    typedef std::list<unsigned> VirtualList;
15912077Sgedare@rtems.org    Counter rxUnique;
16012077Sgedare@rtems.org    Counter txUnique;
16112077Sgedare@rtems.org    VirtualRegs virtualRegs;
16212077Sgedare@rtems.org    VirtualList rxList;
16312077Sgedare@rtems.org    VirtualList rxBusy;
16412077Sgedare@rtems.org    int rxActive;
16512077Sgedare@rtems.org    VirtualList txList;
16612077Sgedare@rtems.org
16712077Sgedare@rtems.org    int rxBusyCount;
16812077Sgedare@rtems.org    int rxMappedCount;
16912077Sgedare@rtems.org    int rxDirtyCount;
17012077Sgedare@rtems.org
17112077Sgedare@rtems.org    uint8_t  &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
17212077Sgedare@rtems.org    uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
17312077Sgedare@rtems.org    uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }
17412077Sgedare@rtems.org
17512077Sgedare@rtems.org  protected:
17612077Sgedare@rtems.org    RxState rxState;
17712077Sgedare@rtems.org    PacketFifo rxFifo;
17812077Sgedare@rtems.org    PacketFifo::iterator rxFifoPtr;
179    bool rxEmpty;
180    bool rxLow;
181    Addr rxDmaAddr;
182    uint8_t *rxDmaData;
183    unsigned rxDmaLen;
184
185    TxState txState;
186    PacketFifo txFifo;
187    bool txFull;
188    EthPacketPtr txPacket;
189    int txPacketOffset;
190    int txPacketBytes;
191    Addr txDmaAddr;
192    uint8_t *txDmaData;
193    int txDmaLen;
194
195  protected:
196    void reset();
197
198    void rxKick();
199    Tick rxKickTick;
200    typedef EventWrapper<Device, &Device::rxKick> RxKickEvent;
201    friend void RxKickEvent::process();
202
203    void txKick();
204    Tick txKickTick;
205    typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
206    friend void TxKickEvent::process();
207
208    /**
209     * Retransmit event
210     */
211    void transmit();
212    void txEventTransmit()
213    {
214        transmit();
215        if (txState == txFifoBlock)
216            txKick();
217    }
218    typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent;
219    friend void TxEvent::process();
220    TxEvent txEvent;
221
222    void txDump() const;
223    void rxDump() const;
224
225    /**
226     * receive address filter
227     */
228    bool rxFilter(const EthPacketPtr &packet);
229
230/**
231 * device configuration
232 */
233    void changeConfig(uint32_t newconfig);
234    void command(uint32_t command);
235
236/**
237 * device ethernet interface
238 */
239  public:
240    bool recvPacket(EthPacketPtr packet);
241    void transferDone();
242    virtual EtherInt *getEthPort(const std::string &if_name, int idx);
243
244/**
245 * DMA parameters
246 */
247  protected:
248    void rxDmaDone();
249    friend class EventWrapper<Device, &Device::rxDmaDone>;
250    EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
251
252    void txDmaDone();
253    friend class EventWrapper<Device, &Device::txDmaDone>;
254    EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
255
256    Tick dmaReadDelay;
257    Tick dmaReadFactor;
258    Tick dmaWriteDelay;
259    Tick dmaWriteFactor;
260
261/**
262 * Interrupt management
263 */
264  protected:
265    void devIntrPost(uint32_t interrupts);
266    void devIntrClear(uint32_t interrupts = Regs::Intr_All);
267    void devIntrChangeMask(uint32_t newmask);
268
269/**
270 * Memory Interface
271 */
272  public:
273    virtual Tick read(PacketPtr pkt);
274    virtual Tick write(PacketPtr pkt);
275    virtual void resume();
276
277    void prepareIO(int cpu, int index);
278    void prepareRead(int cpu, int index);
279    void prepareWrite(int cpu, int index);
280 //   Fault iprRead(Addr daddr, int cpu, uint64_t &result);
281
282/**
283 * Statistics
284 */
285  private:
286    Stats::Scalar rxBytes;
287    Stats::Formula  rxBandwidth;
288    Stats::Scalar rxPackets;
289    Stats::Formula  rxPacketRate;
290    Stats::Scalar rxIpPackets;
291    Stats::Scalar rxTcpPackets;
292    Stats::Scalar rxUdpPackets;
293    Stats::Scalar rxIpChecksums;
294    Stats::Scalar rxTcpChecksums;
295    Stats::Scalar rxUdpChecksums;
296
297    Stats::Scalar txBytes;
298    Stats::Formula  txBandwidth;
299    Stats::Formula totBandwidth;
300    Stats::Formula totPackets;
301    Stats::Formula totBytes;
302    Stats::Formula totPacketRate;
303    Stats::Scalar txPackets;
304    Stats::Formula  txPacketRate;
305    Stats::Scalar txIpPackets;
306    Stats::Scalar txTcpPackets;
307    Stats::Scalar txUdpPackets;
308    Stats::Scalar txIpChecksums;
309    Stats::Scalar txTcpChecksums;
310    Stats::Scalar txUdpChecksums;
311
312    Stats::Scalar totalVnicDistance;
313    Stats::Scalar numVnicDistance;
314    Stats::Scalar maxVnicDistance;
315    Stats::Formula avgVnicDistance;
316
317    int _maxVnicDistance;
318
319  public:
320    virtual void regStats();
321    virtual void resetStats();
322
323/**
324 * Serialization stuff
325 */
326  public:
327    virtual void serialize(std::ostream &os);
328    virtual void unserialize(Checkpoint *cp, const std::string &section);
329
330  public:
331    Device(const Params *p);
332    ~Device();
333};
334
335/*
336 * Ethernet Interface for an Ethernet Device
337 */
338class Interface : public EtherInt
339{
340  private:
341    Device *dev;
342
343  public:
344    Interface(const std::string &name, Device *d)
345        : EtherInt(name), dev(d)
346    { }
347
348    virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
349    virtual void sendDone() { dev->transferDone(); }
350};
351
352} // namespace Sinic
353
354#endif // __DEV_SINIC_HH__
355