sinic.hh revision 2282
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 "mem/bus/bus.hh"
41#include "sim/eventq.hh"
42
43namespace Sinic {
44
45class Interface;
46class Base : public PciDev
47{
48  protected:
49    bool rxEnable;
50    bool txEnable;
51    Tick clock;
52    inline Tick cycles(int numCycles) const { return numCycles * clock; }
53
54  protected:
55    Tick intrDelay;
56    Tick intrTick;
57    bool cpuIntrEnable;
58    bool cpuPendingIntr;
59    void cpuIntrPost(Tick when);
60    void cpuInterrupt();
61    void cpuIntrClear();
62
63    typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent;
64    friend void IntrEvent::process();
65    IntrEvent *intrEvent;
66    Interface *interface;
67
68    bool cpuIntrPending() const;
69    void cpuIntrAck() { cpuIntrClear(); }
70
71/**
72 * Serialization stuff
73 */
74  public:
75    virtual void serialize(std::ostream &os);
76    virtual void unserialize(Checkpoint *cp, const std::string &section);
77
78/**
79 * Construction/Destruction/Parameters
80 */
81  public:
82    struct Params : public PciDev::Params
83    {
84        Tick clock;
85        Tick intr_delay;
86    };
87
88    Base(Params *p);
89};
90
91class Device : public Base
92{
93  protected:
94    Platform *plat;
95    PhysicalMemory *physmem;
96
97  protected:
98    /** Receive State Machine States */
99    enum RxState {
100        rxIdle,
101        rxFifoBlock,
102        rxBeginCopy,
103        rxCopy,
104        rxCopyDone
105    };
106
107    /** Transmit State Machine states */
108    enum TxState {
109        txIdle,
110        txFifoBlock,
111        txBeginCopy,
112        txCopy,
113        txCopyDone
114    };
115
116    /** device register file */
117    struct {
118        uint32_t Config;       // 0x00
119        uint32_t Command;      // 0x04
120        uint32_t IntrStatus;   // 0x08
121        uint32_t IntrMask;     // 0x0c
122        uint32_t RxMaxCopy;    // 0x10
123        uint32_t TxMaxCopy;    // 0x14
124        uint32_t RxMaxIntr;    // 0x18
125        uint32_t VirtualCount; // 0x1c
126        uint32_t RxFifoSize;   // 0x20
127        uint32_t TxFifoSize;   // 0x24
128        uint32_t RxFifoMark;   // 0x28
129        uint32_t TxFifoMark;   // 0x2c
130        uint64_t RxData;       // 0x30
131        uint64_t RxDone;       // 0x38
132        uint64_t RxWait;       // 0x40
133        uint64_t TxData;       // 0x48
134        uint64_t TxDone;       // 0x50
135        uint64_t TxWait;       // 0x58
136        uint64_t HwAddr;       // 0x60
137    } regs;
138
139    struct VirtualReg {
140        uint64_t RxData;
141        uint64_t RxDone;
142        uint64_t TxData;
143        uint64_t TxDone;
144
145        PacketFifo::iterator rxPacket;
146        int rxPacketOffset;
147        int rxPacketBytes;
148        uint64_t rxDoneData;
149
150        Counter rxUnique;
151        Counter txUnique;
152
153        VirtualReg()
154            : RxData(0), RxDone(0), TxData(0), TxDone(0),
155              rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0)
156        { }
157    };
158    typedef std::vector<VirtualReg> VirtualRegs;
159    typedef std::list<int> VirtualList;
160    Counter rxUnique;
161    Counter txUnique;
162    VirtualRegs virtualRegs;
163    VirtualList rxList;
164    VirtualList rxBusy;
165    int rxActive;
166    VirtualList txList;
167
168    uint8_t  &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
169    uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
170    uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }
171
172  private:
173    Addr addr;
174    static const Addr size = Regs::Size;
175
176  protected:
177    RxState rxState;
178    PacketFifo rxFifo;
179    PacketFifo::iterator rxFifoPtr;
180    bool rxEmpty;
181    bool rxLow;
182    Addr rxDmaAddr;
183    uint8_t *rxDmaData;
184    int rxDmaLen;
185
186    TxState txState;
187    PacketFifo txFifo;
188    bool txFull;
189    PacketPtr txPacket;
190    int txPacketOffset;
191    int txPacketBytes;
192    Addr txDmaAddr;
193    uint8_t *txDmaData;
194    int txDmaLen;
195
196  protected:
197    void reset();
198
199    void rxKick();
200    Tick rxKickTick;
201    typedef EventWrapper<Device, &Device::rxKick> RxKickEvent;
202    friend void RxKickEvent::process();
203
204    void txKick();
205    Tick txKickTick;
206    typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
207    friend void TxKickEvent::process();
208
209    /**
210     * Retransmit event
211     */
212    void transmit();
213    void txEventTransmit()
214    {
215        transmit();
216        if (txState == txFifoBlock)
217            txKick();
218    }
219    typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent;
220    friend void TxEvent::process();
221    TxEvent txEvent;
222
223    void txDump() const;
224    void rxDump() const;
225
226    /**
227     * receive address filter
228     */
229    bool rxFilter(const PacketPtr &packet);
230
231/**
232 * device configuration
233 */
234    void changeConfig(uint32_t newconfig);
235    void command(uint32_t command);
236
237/**
238 * device ethernet interface
239 */
240  public:
241    bool recvPacket(PacketPtr packet);
242    void transferDone();
243    void setInterface(Interface *i) { assert(!interface); interface = i; }
244
245/**
246 * DMA parameters
247 */
248  protected:
249    void rxDmaCopy();
250    void rxDmaDone();
251    friend class EventWrapper<Device, &Device::rxDmaDone>;
252    EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
253
254    void txDmaCopy();
255    void txDmaDone();
256    friend class EventWrapper<Device, &Device::txDmaDone>;
257    EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
258
259    Tick dmaReadDelay;
260    Tick dmaReadFactor;
261    Tick dmaWriteDelay;
262    Tick dmaWriteFactor;
263
264/**
265 * Interrupt management
266 */
267  protected:
268    void devIntrPost(uint32_t interrupts);
269    void devIntrClear(uint32_t interrupts = Regs::Intr_All);
270    void devIntrChangeMask(uint32_t newmask);
271
272/**
273 * PCI Configuration interface
274 */
275  public:
276    virtual void writeConfig(int offset, int size, const uint8_t *data);
277
278/**
279 * Memory Interface
280 */
281  public:
282    virtual Fault read(MemReqPtr &req, uint8_t *data);
283    virtual Fault write(MemReqPtr &req, const uint8_t *data);
284
285    void prepareIO(int cpu, int index);
286    void prepareRead(int cpu, int index);
287    void prepareWrite(int cpu, int index);
288    Fault iprRead(Addr daddr, int cpu, uint64_t &result);
289    Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data);
290    Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data);
291    Tick cacheAccess(MemReqPtr &req);
292
293/**
294 * Statistics
295 */
296  private:
297    Stats::Scalar<> rxBytes;
298    Stats::Formula  rxBandwidth;
299    Stats::Scalar<> rxPackets;
300    Stats::Formula  rxPacketRate;
301    Stats::Scalar<> rxIpPackets;
302    Stats::Scalar<> rxTcpPackets;
303    Stats::Scalar<> rxUdpPackets;
304    Stats::Scalar<> rxIpChecksums;
305    Stats::Scalar<> rxTcpChecksums;
306    Stats::Scalar<> rxUdpChecksums;
307
308    Stats::Scalar<> txBytes;
309    Stats::Formula  txBandwidth;
310    Stats::Formula totBandwidth;
311    Stats::Formula totPackets;
312    Stats::Formula totBytes;
313    Stats::Formula totPacketRate;
314    Stats::Scalar<> txPackets;
315    Stats::Formula  txPacketRate;
316    Stats::Scalar<> txIpPackets;
317    Stats::Scalar<> txTcpPackets;
318    Stats::Scalar<> txUdpPackets;
319    Stats::Scalar<> txIpChecksums;
320    Stats::Scalar<> txTcpChecksums;
321    Stats::Scalar<> txUdpChecksums;
322
323  public:
324    virtual void regStats();
325
326/**
327 * Serialization stuff
328 */
329  public:
330    virtual void serialize(std::ostream &os);
331    virtual void unserialize(Checkpoint *cp, const std::string &section);
332
333/**
334 * Construction/Destruction/Parameters
335 */
336  public:
337    struct Params : public Base::Params
338    {
339        IntrControl *i;
340        PhysicalMemory *pmem;
341        Tick tx_delay;
342        Tick rx_delay;
343        HierParams *hier;
344        Bus *pio_bus;
345        Bus *header_bus;
346        Bus *payload_bus;
347        Tick pio_latency;
348        PhysicalMemory *physmem;
349        IntrControl *intctrl;
350        bool rx_filter;
351        Net::EthAddr eaddr;
352        uint32_t rx_max_copy;
353        uint32_t tx_max_copy;
354        uint32_t rx_max_intr;
355        uint32_t rx_fifo_size;
356        uint32_t tx_fifo_size;
357        uint32_t rx_fifo_threshold;
358        uint32_t rx_fifo_low_mark;
359        uint32_t tx_fifo_high_mark;
360        uint32_t tx_fifo_threshold;
361        Tick dma_read_delay;
362        Tick dma_read_factor;
363        Tick dma_write_delay;
364        Tick dma_write_factor;
365        bool dma_no_allocate;
366        bool rx_thread;
367        bool tx_thread;
368        bool rss;
369        uint32_t virtual_count;
370        bool zero_copy;
371        bool delay_copy;
372        bool virtual_addr;
373    };
374
375  protected:
376    const Params *params() const { return (const Params *)_params; }
377
378  public:
379    Device(Params *params);
380    ~Device();
381};
382
383/*
384 * Ethernet Interface for an Ethernet Device
385 */
386class Interface : public EtherInt
387{
388  private:
389    Device *dev;
390
391  public:
392    Interface(const std::string &name, Device *d)
393        : EtherInt(name), dev(d) { dev->setInterface(this); }
394
395    virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); }
396    virtual void sendDone() { dev->transferDone(); }
397};
398
399/* namespace Sinic */ }
400
401#endif // __DEV_SINIC_HH__
402