sinic.hh revision 1993
12SN/A/*
21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
282665Ssaidi@eecs.umich.edu
292SN/A#ifndef __DEV_SINIC_HH__
302SN/A#define __DEV_SINIC_HH__
315584Snate@binkert.org
322SN/A#include "base/inet.hh"
3356SN/A#include "base/statistics.hh"
3456SN/A#include "dev/etherint.hh"
352SN/A#include "dev/etherpkt.hh"
365584Snate@binkert.org#include "dev/io_device.hh"
372SN/A#include "dev/pcidev.hh"
382SN/A#include "dev/pktfifo.hh"
392SN/A#include "dev/sinicreg.hh"
402SN/A#include "mem/bus/bus.hh"
412SN/A#include "sim/eventq.hh"
422SN/A
432SN/Anamespace Sinic {
442SN/A
452SN/Aclass Interface;
462SN/Aclass Base : public PciDev
472SN/A{
482SN/A  protected:
492SN/A    bool rxEnable;
502SN/A    bool txEnable;
512SN/A    Tick clock;
522SN/A    inline Tick cycles(int numCycles) const { return numCycles * clock; }
532SN/A
542SN/A  protected:
552SN/A    Tick intrDelay;
562SN/A    Tick intrTick;
572SN/A    bool cpuIntrEnable;
582SN/A    bool cpuPendingIntr;
592SN/A    void cpuIntrPost(Tick when);
602SN/A    void cpuInterrupt();
612SN/A    void cpuIntrClear();
622SN/A
632SN/A    typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent;
642SN/A    friend void IntrEvent::process();
652SN/A    IntrEvent *intrEvent;
662SN/A    Interface *interface;
672SN/A
682SN/A    bool cpuIntrPending() const;
692SN/A    void cpuIntrAck() { cpuIntrClear(); }
702SN/A
712SN/A/**
722SN/A * Serialization stuff
732SN/A */
742SN/A  public:
752SN/A    virtual void serialize(std::ostream &os);
762SN/A    virtual void unserialize(Checkpoint *cp, const std::string &section);
772SN/A
782SN/A/**
792SN/A * 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    uint8_t  &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
140    uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
141    uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }
142
143  private:
144    Addr addr;
145    static const Addr size = Regs::Size;
146
147  protected:
148    RxState rxState;
149    PacketFifo rxFifo;
150    bool rxEmpty;
151    PacketPtr rxPacket;
152    uint8_t *rxPacketBufPtr;
153    int rxPktBytes;
154    uint64_t rxDoneData;
155    Addr rxDmaAddr;
156    uint8_t *rxDmaData;
157    int rxDmaLen;
158
159    TxState txState;
160    PacketFifo txFifo;
161    bool txFull;
162    PacketPtr txPacket;
163    uint8_t *txPacketBufPtr;
164    int txPktBytes;
165    Addr txDmaAddr;
166    uint8_t *txDmaData;
167    int txDmaLen;
168
169  protected:
170    void reset();
171
172    void rxKick();
173    Tick rxKickTick;
174    typedef EventWrapper<Device, &Device::rxKick> RxKickEvent;
175    friend void RxKickEvent::process();
176
177    void txKick();
178    Tick txKickTick;
179    typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
180    friend void TxKickEvent::process();
181
182    /**
183     * Retransmit event
184     */
185    void transmit();
186    void txEventTransmit()
187    {
188        transmit();
189        if (txState == txFifoBlock)
190            txKick();
191    }
192    typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent;
193    friend void TxEvent::process();
194    TxEvent txEvent;
195
196    void txDump() const;
197    void rxDump() const;
198
199    /**
200     * receive address filter
201     */
202    bool rxFilter(const PacketPtr &packet);
203
204/**
205 * device configuration
206 */
207    void changeConfig(uint32_t newconfig);
208    void command(uint32_t command);
209
210/**
211 * device ethernet interface
212 */
213  public:
214    bool recvPacket(PacketPtr packet);
215    void transferDone();
216    void setInterface(Interface *i) { assert(!interface); interface = i; }
217
218/**
219 * DMA parameters
220 */
221  protected:
222    void rxDmaCopy();
223    void rxDmaDone();
224    friend class EventWrapper<Device, &Device::rxDmaDone>;
225    EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
226
227    void txDmaCopy();
228    void txDmaDone();
229    friend class EventWrapper<Device, &Device::txDmaDone>;
230    EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
231
232    Tick dmaReadDelay;
233    Tick dmaReadFactor;
234    Tick dmaWriteDelay;
235    Tick dmaWriteFactor;
236
237/**
238 * PIO parameters
239 */
240  protected:
241    MemReqPtr rxPioRequest;
242    MemReqPtr txPioRequest;
243
244/**
245 * Interrupt management
246 */
247  protected:
248    void devIntrPost(uint32_t interrupts);
249    void devIntrClear(uint32_t interrupts = Regs::Intr_All);
250    void devIntrChangeMask(uint32_t newmask);
251
252/**
253 * PCI Configuration interface
254 */
255  public:
256    virtual void writeConfig(int offset, int size, const uint8_t *data);
257
258/**
259 * Memory Interface
260 */
261  public:
262    virtual Fault read(MemReqPtr &req, uint8_t *data);
263    virtual Fault write(MemReqPtr &req, const uint8_t *data);
264
265    void prepareRead();
266    Fault iprRead(Addr daddr, uint64_t &result);
267    Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data);
268    Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data);
269    Tick cacheAccess(MemReqPtr &req);
270
271/**
272 * Statistics
273 */
274  private:
275    Stats::Scalar<> rxBytes;
276    Stats::Formula  rxBandwidth;
277    Stats::Scalar<> rxPackets;
278    Stats::Formula  rxPacketRate;
279    Stats::Scalar<> rxIpPackets;
280    Stats::Scalar<> rxTcpPackets;
281    Stats::Scalar<> rxUdpPackets;
282    Stats::Scalar<> rxIpChecksums;
283    Stats::Scalar<> rxTcpChecksums;
284    Stats::Scalar<> rxUdpChecksums;
285
286    Stats::Scalar<> txBytes;
287    Stats::Formula  txBandwidth;
288    Stats::Formula totBandwidth;
289    Stats::Formula totPackets;
290    Stats::Formula totBytes;
291    Stats::Formula totPacketRate;
292    Stats::Scalar<> txPackets;
293    Stats::Formula  txPacketRate;
294    Stats::Scalar<> txIpPackets;
295    Stats::Scalar<> txTcpPackets;
296    Stats::Scalar<> txUdpPackets;
297    Stats::Scalar<> txIpChecksums;
298    Stats::Scalar<> txTcpChecksums;
299    Stats::Scalar<> txUdpChecksums;
300
301  public:
302    virtual void regStats();
303
304/**
305 * Serialization stuff
306 */
307  public:
308    virtual void serialize(std::ostream &os);
309    virtual void unserialize(Checkpoint *cp, const std::string &section);
310
311/**
312 * Construction/Destruction/Parameters
313 */
314  public:
315    struct Params : public Base::Params
316    {
317        IntrControl *i;
318        PhysicalMemory *pmem;
319        Tick tx_delay;
320        Tick rx_delay;
321        HierParams *hier;
322        Bus *pio_bus;
323        Bus *header_bus;
324        Bus *payload_bus;
325        Tick pio_latency;
326        PhysicalMemory *physmem;
327        IntrControl *intctrl;
328        bool rx_filter;
329        Net::EthAddr eaddr;
330        uint32_t rx_max_copy;
331        uint32_t tx_max_copy;
332        uint32_t rx_max_intr;
333        uint32_t rx_fifo_size;
334        uint32_t tx_fifo_size;
335        uint32_t rx_fifo_threshold;
336        uint32_t tx_fifo_threshold;
337        Tick dma_read_delay;
338        Tick dma_read_factor;
339        Tick dma_write_delay;
340        Tick dma_write_factor;
341        bool dma_no_allocate;
342        bool dedicated;
343    };
344
345  protected:
346    const Params *params() const { return (const Params *)_params; }
347
348  public:
349    Device(Params *params);
350    ~Device();
351};
352
353/*
354 * Ethernet Interface for an Ethernet Device
355 */
356class Interface : public EtherInt
357{
358  private:
359    Device *dev;
360
361  public:
362    Interface(const std::string &name, Device *d)
363        : EtherInt(name), dev(d) { dev->setInterface(this); }
364
365    virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); }
366    virtual void sendDone() { dev->transferDone(); }
367};
368
369/* namespace Sinic */ }
370
371#endif // __DEV_SINIC_HH__
372