sinic.hh revision 2008
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 Reserved0;    // 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        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    VirtualRegs virtualRegs;
158    VirtualList rxList;
159    VirtualList txList;
160
161    uint8_t  &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
162    uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
163    uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }
164
165  private:
166    Addr addr;
167    static const Addr size = Regs::Size;
168
169  protected:
170    RxState rxState;
171    PacketFifo rxFifo;
172    PacketFifo::iterator rxFifoPtr;
173    bool rxEmpty;
174    Addr rxDmaAddr;
175    uint8_t *rxDmaData;
176    int rxDmaLen;
177
178    TxState txState;
179    PacketFifo txFifo;
180    bool txFull;
181    PacketPtr txPacket;
182    int txPacketOffset;
183    int txPacketBytes;
184    Addr txDmaAddr;
185    uint8_t *txDmaData;
186    int txDmaLen;
187
188  protected:
189    void reset();
190
191    void rxKick();
192    Tick rxKickTick;
193    typedef EventWrapper<Device, &Device::rxKick> RxKickEvent;
194    friend void RxKickEvent::process();
195
196    void txKick();
197    Tick txKickTick;
198    typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
199    friend void TxKickEvent::process();
200
201    /**
202     * Retransmit event
203     */
204    void transmit();
205    void txEventTransmit()
206    {
207        transmit();
208        if (txState == txFifoBlock)
209            txKick();
210    }
211    typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent;
212    friend void TxEvent::process();
213    TxEvent txEvent;
214
215    void txDump() const;
216    void rxDump() const;
217
218    /**
219     * receive address filter
220     */
221    bool rxFilter(const PacketPtr &packet);
222
223/**
224 * device configuration
225 */
226    void changeConfig(uint32_t newconfig);
227    void command(uint32_t command);
228
229/**
230 * device ethernet interface
231 */
232  public:
233    bool recvPacket(PacketPtr packet);
234    void transferDone();
235    void setInterface(Interface *i) { assert(!interface); interface = i; }
236
237/**
238 * DMA parameters
239 */
240  protected:
241    void rxDmaCopy();
242    void rxDmaDone();
243    friend class EventWrapper<Device, &Device::rxDmaDone>;
244    EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
245
246    void txDmaCopy();
247    void txDmaDone();
248    friend class EventWrapper<Device, &Device::txDmaDone>;
249    EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
250
251    Tick dmaReadDelay;
252    Tick dmaReadFactor;
253    Tick dmaWriteDelay;
254    Tick dmaWriteFactor;
255
256/**
257 * Interrupt management
258 */
259  protected:
260    void devIntrPost(uint32_t interrupts);
261    void devIntrClear(uint32_t interrupts = Regs::Intr_All);
262    void devIntrChangeMask(uint32_t newmask);
263
264/**
265 * PCI Configuration interface
266 */
267  public:
268    virtual void writeConfig(int offset, int size, const uint8_t *data);
269
270/**
271 * Memory Interface
272 */
273  public:
274    virtual Fault read(MemReqPtr &req, uint8_t *data);
275    virtual Fault write(MemReqPtr &req, const uint8_t *data);
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    Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data);
282    Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data);
283    void regWrite(Addr daddr, int cpu, const uint8_t *data);
284    Tick cacheAccess(MemReqPtr &req);
285
286  protected:
287    struct RegWriteData {
288        Addr daddr;
289        uint64_t value;
290        RegWriteData(Addr da, uint64_t val) : daddr(da), value(val) {}
291    };
292
293    std::vector<std::list<RegWriteData> > writeQueue;
294
295    bool pioDelayWrite;
296
297/**
298 * Statistics
299 */
300  private:
301    Stats::Scalar<> rxBytes;
302    Stats::Formula  rxBandwidth;
303    Stats::Scalar<> rxPackets;
304    Stats::Formula  rxPacketRate;
305    Stats::Scalar<> rxIpPackets;
306    Stats::Scalar<> rxTcpPackets;
307    Stats::Scalar<> rxUdpPackets;
308    Stats::Scalar<> rxIpChecksums;
309    Stats::Scalar<> rxTcpChecksums;
310    Stats::Scalar<> rxUdpChecksums;
311
312    Stats::Scalar<> txBytes;
313    Stats::Formula  txBandwidth;
314    Stats::Formula totBandwidth;
315    Stats::Formula totPackets;
316    Stats::Formula totBytes;
317    Stats::Formula totPacketRate;
318    Stats::Scalar<> txPackets;
319    Stats::Formula  txPacketRate;
320    Stats::Scalar<> txIpPackets;
321    Stats::Scalar<> txTcpPackets;
322    Stats::Scalar<> txUdpPackets;
323    Stats::Scalar<> txIpChecksums;
324    Stats::Scalar<> txTcpChecksums;
325    Stats::Scalar<> txUdpChecksums;
326
327  public:
328    virtual void regStats();
329
330/**
331 * Serialization stuff
332 */
333  public:
334    virtual void serialize(std::ostream &os);
335    virtual void unserialize(Checkpoint *cp, const std::string &section);
336
337/**
338 * Construction/Destruction/Parameters
339 */
340  public:
341    struct Params : public Base::Params
342    {
343        IntrControl *i;
344        PhysicalMemory *pmem;
345        Tick tx_delay;
346        Tick rx_delay;
347        HierParams *hier;
348        Bus *pio_bus;
349        Bus *header_bus;
350        Bus *payload_bus;
351        Tick pio_latency;
352        bool pio_delay_write;
353        PhysicalMemory *physmem;
354        IntrControl *intctrl;
355        bool rx_filter;
356        Net::EthAddr eaddr;
357        uint32_t rx_max_copy;
358        uint32_t tx_max_copy;
359        uint32_t rx_max_intr;
360        uint32_t rx_fifo_size;
361        uint32_t tx_fifo_size;
362        uint32_t rx_fifo_threshold;
363        uint32_t tx_fifo_threshold;
364        Tick dma_read_delay;
365        Tick dma_read_factor;
366        Tick dma_write_delay;
367        Tick dma_write_factor;
368        bool dma_no_allocate;
369        bool rx_thread;
370        bool tx_thread;
371    };
372
373  protected:
374    const Params *params() const { return (const Params *)_params; }
375
376  public:
377    Device(Params *params);
378    ~Device();
379};
380
381/*
382 * Ethernet Interface for an Ethernet Device
383 */
384class Interface : public EtherInt
385{
386  private:
387    Device *dev;
388
389  public:
390    Interface(const std::string &name, Device *d)
391        : EtherInt(name), dev(d) { dev->setInterface(this); }
392
393    virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); }
394    virtual void sendDone() { dev->transferDone(); }
395};
396
397/* namespace Sinic */ }
398
399#endif // __DEV_SINIC_HH__
400