sinic.hh revision 2665
112855Sgabeblack@google.com/*
212855Sgabeblack@google.com * Copyright (c) 2004-2005 The Regents of The University of Michigan
312855Sgabeblack@google.com * All rights reserved.
412855Sgabeblack@google.com *
512855Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
612855Sgabeblack@google.com * modification, are permitted provided that the following conditions are
712855Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
812855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
912855Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1012855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1112855Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1212855Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1312855Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1412855Sgabeblack@google.com * this software without specific prior written permission.
1512855Sgabeblack@google.com *
1612855Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712855Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812855Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912855Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012855Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112855Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212855Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312855Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412855Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512855Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612855Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712855Sgabeblack@google.com *
2812855Sgabeblack@google.com * Authors: Nathan Binkert
2912855Sgabeblack@google.com */
3012855Sgabeblack@google.com
3112855Sgabeblack@google.com#ifndef __DEV_SINIC_HH__
3212855Sgabeblack@google.com#define __DEV_SINIC_HH__
3312855Sgabeblack@google.com
3412855Sgabeblack@google.com#include "base/inet.hh"
3512855Sgabeblack@google.com#include "base/statistics.hh"
3612855Sgabeblack@google.com#include "dev/etherint.hh"
3712855Sgabeblack@google.com#include "dev/etherpkt.hh"
3812855Sgabeblack@google.com#include "dev/io_device.hh"
3912855Sgabeblack@google.com#include "dev/pcidev.hh"
4012855Sgabeblack@google.com#include "dev/pktfifo.hh"
4112855Sgabeblack@google.com#include "dev/sinicreg.hh"
4212855Sgabeblack@google.com#include "sim/eventq.hh"
4312855Sgabeblack@google.com
4412855Sgabeblack@google.comnamespace Sinic {
4512855Sgabeblack@google.com
4612855Sgabeblack@google.comclass Interface;
4712855Sgabeblack@google.comclass Base : public PciDev
4812855Sgabeblack@google.com{
4912855Sgabeblack@google.com  protected:
5012855Sgabeblack@google.com    bool rxEnable;
5112855Sgabeblack@google.com    bool txEnable;
5212855Sgabeblack@google.com    Tick clock;
5312855Sgabeblack@google.com    inline Tick cycles(int numCycles) const { return numCycles * clock; }
5412855Sgabeblack@google.com
5512855Sgabeblack@google.com  protected:
5612855Sgabeblack@google.com    Tick intrDelay;
5712855Sgabeblack@google.com    Tick intrTick;
5812855Sgabeblack@google.com    bool cpuIntrEnable;
5912855Sgabeblack@google.com    bool cpuPendingIntr;
6012855Sgabeblack@google.com    void cpuIntrPost(Tick when);
6112855Sgabeblack@google.com    void cpuInterrupt();
6212855Sgabeblack@google.com    void cpuIntrClear();
6312855Sgabeblack@google.com
6412855Sgabeblack@google.com    typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent;
6512855Sgabeblack@google.com    friend void IntrEvent::process();
6612855Sgabeblack@google.com    IntrEvent *intrEvent;
6712855Sgabeblack@google.com    Interface *interface;
6812855Sgabeblack@google.com
6912855Sgabeblack@google.com    bool cpuIntrPending() const;
7012855Sgabeblack@google.com    void cpuIntrAck() { cpuIntrClear(); }
7112855Sgabeblack@google.com
7212855Sgabeblack@google.com/**
7312855Sgabeblack@google.com * Serialization stuff
7412855Sgabeblack@google.com */
7512855Sgabeblack@google.com  public:
7612855Sgabeblack@google.com    virtual void serialize(std::ostream &os);
7712855Sgabeblack@google.com    virtual void unserialize(Checkpoint *cp, const std::string &section);
7812855Sgabeblack@google.com
7912855Sgabeblack@google.com/**
8012855Sgabeblack@google.com * Construction/Destruction/Parameters
8112855Sgabeblack@google.com */
8212855Sgabeblack@google.com  public:
8312855Sgabeblack@google.com    struct Params : public PciDev::Params
8412855Sgabeblack@google.com    {
8512855Sgabeblack@google.com        Tick clock;
8612855Sgabeblack@google.com        Tick intr_delay;
8712855Sgabeblack@google.com    };
8812855Sgabeblack@google.com
8912855Sgabeblack@google.com    Base(Params *p);
9012855Sgabeblack@google.com};
9112855Sgabeblack@google.com
9212855Sgabeblack@google.comclass Device : public Base
9312855Sgabeblack@google.com{
9412855Sgabeblack@google.com  protected:
9512855Sgabeblack@google.com    /** Receive State Machine States */
9612855Sgabeblack@google.com    enum RxState {
9712855Sgabeblack@google.com        rxIdle,
9812855Sgabeblack@google.com        rxFifoBlock,
9912855Sgabeblack@google.com        rxBeginCopy,
10012855Sgabeblack@google.com        rxCopy,
10112855Sgabeblack@google.com        rxCopyDone
10212855Sgabeblack@google.com    };
10312855Sgabeblack@google.com
10412855Sgabeblack@google.com    /** Transmit State Machine states */
10512855Sgabeblack@google.com    enum TxState {
10612855Sgabeblack@google.com        txIdle,
10712855Sgabeblack@google.com        txFifoBlock,
10812855Sgabeblack@google.com        txBeginCopy,
10912855Sgabeblack@google.com        txCopy,
11012855Sgabeblack@google.com        txCopyDone
11112855Sgabeblack@google.com    };
11212855Sgabeblack@google.com
11312855Sgabeblack@google.com    /** device register file */
11412855Sgabeblack@google.com    struct {
11512855Sgabeblack@google.com        uint32_t Config;       // 0x00
11612855Sgabeblack@google.com        uint32_t Command;      // 0x04
11712855Sgabeblack@google.com        uint32_t IntrStatus;   // 0x08
11812855Sgabeblack@google.com        uint32_t IntrMask;     // 0x0c
11912855Sgabeblack@google.com        uint32_t RxMaxCopy;    // 0x10
12012855Sgabeblack@google.com        uint32_t TxMaxCopy;    // 0x14
12112855Sgabeblack@google.com        uint32_t RxMaxIntr;    // 0x18
12212855Sgabeblack@google.com        uint32_t VirtualCount; // 0x1c
12312855Sgabeblack@google.com        uint32_t RxFifoSize;   // 0x20
12412855Sgabeblack@google.com        uint32_t TxFifoSize;   // 0x24
12512855Sgabeblack@google.com        uint32_t RxFifoMark;   // 0x28
12612855Sgabeblack@google.com        uint32_t TxFifoMark;   // 0x2c
12712855Sgabeblack@google.com        uint64_t RxData;       // 0x30
12812855Sgabeblack@google.com        uint64_t RxDone;       // 0x38
12912855Sgabeblack@google.com        uint64_t RxWait;       // 0x40
130        uint64_t TxData;       // 0x48
131        uint64_t TxDone;       // 0x50
132        uint64_t TxWait;       // 0x58
133        uint64_t HwAddr;       // 0x60
134    } regs;
135
136    struct VirtualReg {
137        uint64_t RxData;
138        uint64_t RxDone;
139        uint64_t TxData;
140        uint64_t TxDone;
141
142        PacketFifo::iterator rxPacket;
143        int rxPacketOffset;
144        int rxPacketBytes;
145        uint64_t rxDoneData;
146
147        Counter rxUnique;
148        Counter txUnique;
149
150        VirtualReg()
151            : RxData(0), RxDone(0), TxData(0), TxDone(0),
152              rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0)
153        { }
154    };
155    typedef std::vector<VirtualReg> VirtualRegs;
156    typedef std::list<int> VirtualList;
157    Counter rxUnique;
158    Counter txUnique;
159    VirtualRegs virtualRegs;
160    VirtualList rxList;
161    VirtualList rxBusy;
162    int rxActive;
163    VirtualList txList;
164
165    uint8_t  &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
166    uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
167    uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }
168
169  protected:
170    RxState rxState;
171    PacketFifo rxFifo;
172    PacketFifo::iterator rxFifoPtr;
173    bool rxEmpty;
174    bool rxLow;
175    Addr rxDmaAddr;
176    uint8_t *rxDmaData;
177    int rxDmaLen;
178
179    TxState txState;
180    PacketFifo txFifo;
181    bool txFull;
182    EthPacketPtr txPacket;
183    int txPacketOffset;
184    int txPacketBytes;
185    Addr txDmaAddr;
186    uint8_t *txDmaData;
187    int txDmaLen;
188
189  protected:
190    void reset();
191
192    void rxKick();
193    Tick rxKickTick;
194    typedef EventWrapper<Device, &Device::rxKick> RxKickEvent;
195    friend void RxKickEvent::process();
196
197    void txKick();
198    Tick txKickTick;
199    typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
200    friend void TxKickEvent::process();
201
202    /**
203     * Retransmit event
204     */
205    void transmit();
206    void txEventTransmit()
207    {
208        transmit();
209        if (txState == txFifoBlock)
210            txKick();
211    }
212    typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent;
213    friend void TxEvent::process();
214    TxEvent txEvent;
215
216    void txDump() const;
217    void rxDump() const;
218
219    /**
220     * receive address filter
221     */
222    bool rxFilter(const EthPacketPtr &packet);
223
224/**
225 * device configuration
226 */
227    void changeConfig(uint32_t newconfig);
228    void command(uint32_t command);
229
230/**
231 * device ethernet interface
232 */
233  public:
234    bool recvPacket(EthPacketPtr packet);
235    void transferDone();
236    void setInterface(Interface *i) { assert(!interface); interface = i; }
237
238/**
239 * DMA parameters
240 */
241  protected:
242    void rxDmaDone();
243    friend class EventWrapper<Device, &Device::rxDmaDone>;
244    EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
245
246    void txDmaDone();
247    friend class EventWrapper<Device, &Device::txDmaDone>;
248    EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
249
250    Tick dmaReadDelay;
251    Tick dmaReadFactor;
252    Tick dmaWriteDelay;
253    Tick dmaWriteFactor;
254
255/**
256 * Interrupt management
257 */
258  protected:
259    void devIntrPost(uint32_t interrupts);
260    void devIntrClear(uint32_t interrupts = Regs::Intr_All);
261    void devIntrChangeMask(uint32_t newmask);
262
263/**
264 * Memory Interface
265 */
266  public:
267    virtual Tick read(Packet *pkt);
268    virtual Tick write(Packet *pkt);
269
270    void prepareIO(int cpu, int index);
271    void prepareRead(int cpu, int index);
272    void prepareWrite(int cpu, int index);
273 //   Fault iprRead(Addr daddr, int cpu, uint64_t &result);
274
275/**
276 * Statistics
277 */
278  private:
279    Stats::Scalar<> rxBytes;
280    Stats::Formula  rxBandwidth;
281    Stats::Scalar<> rxPackets;
282    Stats::Formula  rxPacketRate;
283    Stats::Scalar<> rxIpPackets;
284    Stats::Scalar<> rxTcpPackets;
285    Stats::Scalar<> rxUdpPackets;
286    Stats::Scalar<> rxIpChecksums;
287    Stats::Scalar<> rxTcpChecksums;
288    Stats::Scalar<> rxUdpChecksums;
289
290    Stats::Scalar<> txBytes;
291    Stats::Formula  txBandwidth;
292    Stats::Formula totBandwidth;
293    Stats::Formula totPackets;
294    Stats::Formula totBytes;
295    Stats::Formula totPacketRate;
296    Stats::Scalar<> txPackets;
297    Stats::Formula  txPacketRate;
298    Stats::Scalar<> txIpPackets;
299    Stats::Scalar<> txTcpPackets;
300    Stats::Scalar<> txUdpPackets;
301    Stats::Scalar<> txIpChecksums;
302    Stats::Scalar<> txTcpChecksums;
303    Stats::Scalar<> txUdpChecksums;
304
305  public:
306    virtual void regStats();
307
308/**
309 * Serialization stuff
310 */
311  public:
312    virtual void serialize(std::ostream &os);
313    virtual void unserialize(Checkpoint *cp, const std::string &section);
314
315/**
316 * Construction/Destruction/Parameters
317 */
318  public:
319    struct Params : public Base::Params
320    {
321        Tick tx_delay;
322        Tick rx_delay;
323        bool rx_filter;
324        Net::EthAddr eaddr;
325        uint32_t rx_max_copy;
326        uint32_t tx_max_copy;
327        uint32_t rx_max_intr;
328        uint32_t rx_fifo_size;
329        uint32_t tx_fifo_size;
330        uint32_t rx_fifo_threshold;
331        uint32_t rx_fifo_low_mark;
332        uint32_t tx_fifo_high_mark;
333        uint32_t tx_fifo_threshold;
334        Tick dma_read_delay;
335        Tick dma_read_factor;
336        Tick dma_write_delay;
337        Tick dma_write_factor;
338        bool rx_thread;
339        bool tx_thread;
340        bool rss;
341        uint32_t virtual_count;
342        bool zero_copy;
343        bool delay_copy;
344        bool virtual_addr;
345    };
346
347  protected:
348    const Params *params() const { return (const Params *)_params; }
349
350  public:
351    Device(Params *params);
352    ~Device();
353};
354
355/*
356 * Ethernet Interface for an Ethernet Device
357 */
358class Interface : public EtherInt
359{
360  private:
361    Device *dev;
362
363  public:
364    Interface(const std::string &name, Device *d)
365        : EtherInt(name), dev(d) { dev->setInterface(this); }
366
367    virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
368    virtual void sendDone() { dev->transferDone(); }
369};
370
371/* namespace Sinic */ }
372
373#endif // __DEV_SINIC_HH__
374