sinic.hh revision 2566
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef __DEV_SINIC_HH__
30#define __DEV_SINIC_HH__
31
32#include "base/inet.hh"
33#include "base/statistics.hh"
34#include "dev/etherint.hh"
35#include "dev/etherpkt.hh"
36#include "dev/io_device.hh"
37#include "dev/pcidev.hh"
38#include "dev/pktfifo.hh"
39#include "dev/sinicreg.hh"
40#include "sim/eventq.hh"
41
42namespace Sinic {
43
44class Interface;
45class Base : public PciDev
46{
47  protected:
48    bool rxEnable;
49    bool txEnable;
50    Tick clock;
51    inline Tick cycles(int numCycles) const { return numCycles * clock; }
52
53  protected:
54    Tick intrDelay;
55    Tick intrTick;
56    bool cpuIntrEnable;
57    bool cpuPendingIntr;
58    void cpuIntrPost(Tick when);
59    void cpuInterrupt();
60    void cpuIntrClear();
61
62    typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent;
63    friend void IntrEvent::process();
64    IntrEvent *intrEvent;
65    Interface *interface;
66
67    bool cpuIntrPending() const;
68    void cpuIntrAck() { cpuIntrClear(); }
69
70/**
71 * Serialization stuff
72 */
73  public:
74    virtual void serialize(std::ostream &os);
75    virtual void unserialize(Checkpoint *cp, const std::string &section);
76
77/**
78 * Construction/Destruction/Parameters
79 */
80  public:
81    struct Params : public PciDev::Params
82    {
83        Tick clock;
84        Tick intr_delay;
85    };
86
87    Base(Params *p);
88};
89
90class Device : public Base
91{
92  protected:
93    /** Receive State Machine States */
94    enum RxState {
95        rxIdle,
96        rxFifoBlock,
97        rxBeginCopy,
98        rxCopy,
99        rxCopyDone
100    };
101
102    /** Transmit State Machine states */
103    enum TxState {
104        txIdle,
105        txFifoBlock,
106        txBeginCopy,
107        txCopy,
108        txCopyDone
109    };
110
111    /** device register file */
112    struct {
113        uint32_t Config;       // 0x00
114        uint32_t Command;      // 0x04
115        uint32_t IntrStatus;   // 0x08
116        uint32_t IntrMask;     // 0x0c
117        uint32_t RxMaxCopy;    // 0x10
118        uint32_t TxMaxCopy;    // 0x14
119        uint32_t RxMaxIntr;    // 0x18
120        uint32_t Reserved0;    // 0x1c
121        uint32_t RxFifoSize;   // 0x20
122        uint32_t TxFifoSize;   // 0x24
123        uint32_t RxFifoMark;   // 0x28
124        uint32_t TxFifoMark;   // 0x2c
125        uint64_t RxData;       // 0x30
126        uint64_t RxDone;       // 0x38
127        uint64_t RxWait;       // 0x40
128        uint64_t TxData;       // 0x48
129        uint64_t TxDone;       // 0x50
130        uint64_t TxWait;       // 0x58
131        uint64_t HwAddr;       // 0x60
132    } regs;
133
134    struct VirtualReg {
135        uint64_t RxData;
136        uint64_t RxDone;
137        uint64_t TxData;
138        uint64_t TxDone;
139
140        PacketFifo::iterator rxPacket;
141        int rxPacketOffset;
142        int rxPacketBytes;
143        uint64_t rxDoneData;
144
145        VirtualReg()
146            : RxData(0), RxDone(0), TxData(0), TxDone(0),
147              rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0)
148        { }
149    };
150    typedef std::vector<VirtualReg> VirtualRegs;
151    typedef std::list<int> VirtualList;
152    VirtualRegs virtualRegs;
153    VirtualList rxList;
154    VirtualList txList;
155
156    uint8_t  &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
157    uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
158    uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }
159
160  protected:
161    RxState rxState;
162    PacketFifo rxFifo;
163    PacketFifo::iterator rxFifoPtr;
164    bool rxEmpty;
165    Addr rxDmaAddr;
166    uint8_t *rxDmaData;
167    int rxDmaLen;
168
169    TxState txState;
170    PacketFifo txFifo;
171    bool txFull;
172    EthPacketPtr txPacket;
173    int txPacketOffset;
174    int txPacketBytes;
175    Addr txDmaAddr;
176    uint8_t *txDmaData;
177    int txDmaLen;
178
179  protected:
180    void reset();
181
182    void rxKick();
183    Tick rxKickTick;
184    typedef EventWrapper<Device, &Device::rxKick> RxKickEvent;
185    friend void RxKickEvent::process();
186
187    void txKick();
188    Tick txKickTick;
189    typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
190    friend void TxKickEvent::process();
191
192    /**
193     * Retransmit event
194     */
195    void transmit();
196    void txEventTransmit()
197    {
198        transmit();
199        if (txState == txFifoBlock)
200            txKick();
201    }
202    typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent;
203    friend void TxEvent::process();
204    TxEvent txEvent;
205
206    void txDump() const;
207    void rxDump() const;
208
209    /**
210     * receive address filter
211     */
212    bool rxFilter(const EthPacketPtr &packet);
213
214/**
215 * device configuration
216 */
217    void changeConfig(uint32_t newconfig);
218    void command(uint32_t command);
219
220/**
221 * device ethernet interface
222 */
223  public:
224    bool recvPacket(EthPacketPtr packet);
225    void transferDone();
226    void setInterface(Interface *i) { assert(!interface); interface = i; }
227
228/**
229 * DMA parameters
230 */
231  protected:
232    void rxDmaDone();
233    friend class EventWrapper<Device, &Device::rxDmaDone>;
234    EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
235
236    void txDmaDone();
237    friend class EventWrapper<Device, &Device::txDmaDone>;
238    EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
239
240    Tick dmaReadDelay;
241    Tick dmaReadFactor;
242    Tick dmaWriteDelay;
243    Tick dmaWriteFactor;
244
245/**
246 * Interrupt management
247 */
248  protected:
249    void devIntrPost(uint32_t interrupts);
250    void devIntrClear(uint32_t interrupts = Regs::Intr_All);
251    void devIntrChangeMask(uint32_t newmask);
252
253/**
254 * Memory Interface
255 */
256  public:
257    virtual Tick read(Packet &pkt);
258    virtual Tick write(Packet &pkt);
259
260    void prepareIO(int cpu, int index);
261    void prepareRead(int cpu, int index);
262    void prepareWrite(int cpu, int index);
263 //   Fault iprRead(Addr daddr, int cpu, uint64_t &result);
264
265/**
266 * Statistics
267 */
268  private:
269    Stats::Scalar<> rxBytes;
270    Stats::Formula  rxBandwidth;
271    Stats::Scalar<> rxPackets;
272    Stats::Formula  rxPacketRate;
273    Stats::Scalar<> rxIpPackets;
274    Stats::Scalar<> rxTcpPackets;
275    Stats::Scalar<> rxUdpPackets;
276    Stats::Scalar<> rxIpChecksums;
277    Stats::Scalar<> rxTcpChecksums;
278    Stats::Scalar<> rxUdpChecksums;
279
280    Stats::Scalar<> txBytes;
281    Stats::Formula  txBandwidth;
282    Stats::Formula totBandwidth;
283    Stats::Formula totPackets;
284    Stats::Formula totBytes;
285    Stats::Formula totPacketRate;
286    Stats::Scalar<> txPackets;
287    Stats::Formula  txPacketRate;
288    Stats::Scalar<> txIpPackets;
289    Stats::Scalar<> txTcpPackets;
290    Stats::Scalar<> txUdpPackets;
291    Stats::Scalar<> txIpChecksums;
292    Stats::Scalar<> txTcpChecksums;
293    Stats::Scalar<> txUdpChecksums;
294
295  public:
296    virtual void regStats();
297
298/**
299 * Serialization stuff
300 */
301  public:
302    virtual void serialize(std::ostream &os);
303    virtual void unserialize(Checkpoint *cp, const std::string &section);
304
305/**
306 * Construction/Destruction/Parameters
307 */
308  public:
309    struct Params : public Base::Params
310    {
311        Tick tx_delay;
312        Tick rx_delay;
313        bool rx_filter;
314        Net::EthAddr eaddr;
315        uint32_t rx_max_copy;
316        uint32_t tx_max_copy;
317        uint32_t rx_max_intr;
318        uint32_t rx_fifo_size;
319        uint32_t tx_fifo_size;
320        uint32_t rx_fifo_threshold;
321        uint32_t tx_fifo_threshold;
322        Tick dma_read_delay;
323        Tick dma_read_factor;
324        Tick dma_write_delay;
325        Tick dma_write_factor;
326        bool rx_thread;
327        bool tx_thread;
328        bool rss;
329    };
330
331  protected:
332    const Params *params() const { return (const Params *)_params; }
333
334  public:
335    Device(Params *params);
336    ~Device();
337};
338
339/*
340 * Ethernet Interface for an Ethernet Device
341 */
342class Interface : public EtherInt
343{
344  private:
345    Device *dev;
346
347  public:
348    Interface(const std::string &name, Device *d)
349        : EtherInt(name), dev(d) { dev->setInterface(this); }
350
351    virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
352    virtual void sendDone() { dev->transferDone(); }
353};
354
355/* namespace Sinic */ }
356
357#endif // __DEV_SINIC_HH__
358