sinic.hh revision 1762
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 cycleTime;
52    inline Tick cycles(int numCycles) const { return numCycles * cycleTime; }
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 cycle_time;
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;
119        uint32_t RxMaxCopy;
120        uint32_t TxMaxCopy;
121        uint32_t RxThreshold;
122        uint32_t TxThreshold;
123        uint32_t IntrStatus;
124        uint32_t IntrMask;
125        uint64_t RxData;
126        uint64_t RxDone;
127        uint64_t TxData;
128        uint64_t TxDone;
129    } regs;
130
131  private:
132    Addr addr;
133    static const Addr size = Regs::Size;
134
135  protected:
136    RxState rxState;
137    PacketFifo rxFifo;
138    PacketPtr rxPacket;
139    uint8_t *rxPacketBufPtr;
140    int rxPktBytes;
141    uint64_t rxDoneData;
142    Addr rxDmaAddr;
143    uint8_t *rxDmaData;
144    int rxDmaLen;
145
146    TxState txState;
147    PacketFifo txFifo;
148    PacketPtr txPacket;
149    uint8_t *txPacketBufPtr;
150    int txPktBytes;
151    Addr txDmaAddr;
152    uint8_t *txDmaData;
153    int txDmaLen;
154
155  protected:
156    void reset();
157
158    void rxKick();
159    Tick rxKickTick;
160    typedef EventWrapper<Device, &Device::rxKick> RxKickEvent;
161    friend void RxKickEvent::process();
162
163    void txKick();
164    Tick txKickTick;
165    typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
166    friend void TxKickEvent::process();
167
168    /**
169     * Retransmit event
170     */
171    void transmit();
172    void txEventTransmit()
173    {
174        transmit();
175        if (txState == txFifoBlock)
176            txKick();
177    }
178    typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent;
179    friend void TxEvent::process();
180    TxEvent txEvent;
181
182    void txDump() const;
183    void rxDump() const;
184
185    /**
186     * receive address filter
187     */
188    bool rxFilter(const PacketPtr &packet);
189
190/**
191 * device configuration
192 */
193    void changeConfig(uint32_t newconfig);
194
195/**
196 * device ethernet interface
197 */
198  public:
199    bool recvPacket(PacketPtr packet);
200    void transferDone();
201    void setInterface(Interface *i) { assert(!interface); interface = i; }
202
203/**
204 * DMA parameters
205 */
206  protected:
207    void rxDmaCopy();
208    void rxDmaDone();
209    friend class EventWrapper<Device, &Device::rxDmaDone>;
210    EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
211
212    void txDmaCopy();
213    void txDmaDone();
214    friend class EventWrapper<Device, &Device::txDmaDone>;
215    EventWrapper<Device, &Device::rxDmaDone> txDmaEvent;
216
217    Tick dmaReadDelay;
218    Tick dmaReadFactor;
219    Tick dmaWriteDelay;
220    Tick dmaWriteFactor;
221
222/**
223 * PIO parameters
224 */
225  protected:
226    MemReqPtr rxPioRequest;
227    MemReqPtr txPioRequest;
228
229/**
230 * Interrupt management
231 */
232  protected:
233    void devIntrPost(uint32_t interrupts);
234    void devIntrClear(uint32_t interrupts = Regs::Intr_All);
235    void devIntrChangeMask(uint32_t newmask);
236
237/**
238 * PCI Configuration interface
239 */
240  public:
241    virtual void WriteConfig(int offset, int size, uint32_t data);
242
243/**
244 * Memory Interface
245 */
246  public:
247    virtual Fault read(MemReqPtr &req, uint8_t *data);
248    virtual Fault write(MemReqPtr &req, const uint8_t *data);
249    Tick cacheAccess(MemReqPtr &req);
250
251/**
252 * Statistics
253 */
254  private:
255    Stats::Scalar<> rxBytes;
256    Stats::Formula  rxBandwidth;
257    Stats::Scalar<> rxPackets;
258    Stats::Formula  rxPacketRate;
259    Stats::Scalar<> rxIpPackets;
260    Stats::Scalar<> rxTcpPackets;
261    Stats::Scalar<> rxUdpPackets;
262    Stats::Scalar<> rxIpChecksums;
263    Stats::Scalar<> rxTcpChecksums;
264    Stats::Scalar<> rxUdpChecksums;
265
266    Stats::Scalar<> txBytes;
267    Stats::Formula  txBandwidth;
268    Stats::Formula totBandwidth;
269    Stats::Formula totPackets;
270    Stats::Formula totBytes;
271    Stats::Formula totPacketRate;
272    Stats::Scalar<> txPackets;
273    Stats::Formula  txPacketRate;
274    Stats::Scalar<> txIpPackets;
275    Stats::Scalar<> txTcpPackets;
276    Stats::Scalar<> txUdpPackets;
277    Stats::Scalar<> txIpChecksums;
278    Stats::Scalar<> txTcpChecksums;
279    Stats::Scalar<> txUdpChecksums;
280
281  public:
282    virtual void regStats();
283
284/**
285 * Serialization stuff
286 */
287  public:
288    virtual void serialize(std::ostream &os);
289    virtual void unserialize(Checkpoint *cp, const std::string &section);
290
291/**
292 * Construction/Destruction/Parameters
293 */
294  public:
295    struct Params : public Base::Params
296    {
297        IntrControl *i;
298        PhysicalMemory *pmem;
299        Tick tx_delay;
300        Tick rx_delay;
301        HierParams *hier;
302        Bus *io_bus;
303        Bus *payload_bus;
304        Tick pio_latency;
305        PhysicalMemory *physmem;
306        IntrControl *intctrl;
307        bool rx_filter;
308        Net::EthAddr eaddr;
309        uint32_t rx_max_copy;
310        uint32_t tx_max_copy;
311        uint32_t rx_fifo_size;
312        uint32_t tx_fifo_size;
313        uint32_t rx_fifo_threshold;
314        uint32_t tx_fifo_threshold;
315        Tick dma_read_delay;
316        Tick dma_read_factor;
317        Tick dma_write_delay;
318        Tick dma_write_factor;
319        bool dma_no_allocate;
320    };
321
322  protected:
323    const Params *params() const { return (const Params *)_params; }
324
325  public:
326    Device(Params *params);
327    ~Device();
328};
329
330/*
331 * Ethernet Interface for an Ethernet Device
332 */
333class Interface : public EtherInt
334{
335  private:
336    Device *dev;
337
338  public:
339    Interface(const std::string &name, Device *d)
340        : EtherInt(name), dev(d) { dev->setInterface(this); }
341
342    virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); }
343    virtual void sendDone() { dev->transferDone(); }
344};
345
346/* namespace Sinic */ }
347
348#endif // __DEV_SINIC_HH__
349