sinic.hh revision 4981
16019SN/A/*
26019SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
36019SN/A * All rights reserved.
46019SN/A *
56019SN/A * Redistribution and use in source and binary forms, with or without
66019SN/A * modification, are permitted provided that the following conditions are
76019SN/A * met: redistributions of source code must retain the above copyright
86019SN/A * notice, this list of conditions and the following disclaimer;
96019SN/A * redistributions in binary form must reproduce the above copyright
106019SN/A * notice, this list of conditions and the following disclaimer in the
116019SN/A * documentation and/or other materials provided with the distribution;
126019SN/A * neither the name of the copyright holders nor the names of its
136019SN/A * contributors may be used to endorse or promote products derived from
146019SN/A * this software without specific prior written permission.
156019SN/A *
166019SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176019SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186019SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196019SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206019SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216019SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226019SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236019SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246019SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256019SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266019SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276019SN/A *
286019SN/A * Authors: Nathan Binkert
296019SN/A */
306019SN/A
316019SN/A#ifndef __DEV_SINIC_HH__
326019SN/A#define __DEV_SINIC_HH__
338105Sgblack@eecs.umich.edu
348105Sgblack@eecs.umich.edu#include "base/inet.hh"
356019SN/A#include "base/statistics.hh"
366019SN/A#include "dev/etherint.hh"
376019SN/A#include "dev/etherpkt.hh"
386019SN/A#include "dev/io_device.hh"
396019SN/A#include "dev/pcidev.hh"
406019SN/A#include "dev/pktfifo.hh"
416019SN/A#include "dev/sinicreg.hh"
429897Sandreas@sandberg.pp.se#include "params/Sinic.hh"
436019SN/A#include "sim/eventq.hh"
446019SN/A
456019SN/Anamespace Sinic {
466019SN/A
476019SN/Aclass Interface;
489897Sandreas@sandberg.pp.seclass Base : public PciDev
499897Sandreas@sandberg.pp.se{
506019SN/A  protected:
516019SN/A    bool rxEnable;
526019SN/A    bool txEnable;
53    Tick clock;
54    inline Tick cycles(int numCycles) const { return numCycles * clock; }
55
56  protected:
57    Tick intrDelay;
58    Tick intrTick;
59    bool cpuIntrEnable;
60    bool cpuPendingIntr;
61    void cpuIntrPost(Tick when);
62    void cpuInterrupt();
63    void cpuIntrClear();
64
65    typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent;
66    friend void IntrEvent::process();
67    IntrEvent *intrEvent;
68    Interface *interface;
69
70    bool cpuIntrPending() const;
71    void cpuIntrAck() { cpuIntrClear(); }
72
73/**
74 * Serialization stuff
75 */
76  public:
77    virtual void serialize(std::ostream &os);
78    virtual void unserialize(Checkpoint *cp, const std::string &section);
79
80/**
81 * Construction/Destruction/Parameters
82 */
83  public:
84    typedef SinicParams Params;
85    const Params *params() const { return (const Params *)_params; }
86    Base(const Params *p);
87};
88
89class Device : public Base
90{
91  protected:
92    /** Receive State Machine States */
93    enum RxState {
94        rxIdle,
95        rxFifoBlock,
96        rxBeginCopy,
97        rxCopy,
98        rxCopyDone
99    };
100
101    /** Transmit State Machine states */
102    enum TxState {
103        txIdle,
104        txFifoBlock,
105        txBeginCopy,
106        txCopy,
107        txCopyDone
108    };
109
110    /** device register file */
111    struct {
112        uint32_t Config;       // 0x00
113        uint32_t Command;      // 0x04
114        uint32_t IntrStatus;   // 0x08
115        uint32_t IntrMask;     // 0x0c
116        uint32_t RxMaxCopy;    // 0x10
117        uint32_t TxMaxCopy;    // 0x14
118        uint32_t RxMaxIntr;    // 0x18
119        uint32_t VirtualCount; // 0x1c
120        uint32_t RxFifoSize;   // 0x20
121        uint32_t TxFifoSize;   // 0x24
122        uint32_t RxFifoMark;   // 0x28
123        uint32_t TxFifoMark;   // 0x2c
124        uint64_t RxData;       // 0x30
125        uint64_t RxDone;       // 0x38
126        uint64_t RxWait;       // 0x40
127        uint64_t TxData;       // 0x48
128        uint64_t TxDone;       // 0x50
129        uint64_t TxWait;       // 0x58
130        uint64_t HwAddr;       // 0x60
131    } regs;
132
133    struct VirtualReg {
134        uint64_t RxData;
135        uint64_t RxDone;
136        uint64_t TxData;
137        uint64_t TxDone;
138
139        PacketFifo::iterator rxPacket;
140        int rxPacketOffset;
141        int rxPacketBytes;
142        uint64_t rxDoneData;
143
144        Counter rxUnique;
145        Counter txUnique;
146
147        VirtualReg()
148            : RxData(0), RxDone(0), TxData(0), TxDone(0),
149              rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0)
150        { }
151    };
152    typedef std::vector<VirtualReg> VirtualRegs;
153    typedef std::list<int> VirtualList;
154    Counter rxUnique;
155    Counter txUnique;
156    VirtualRegs virtualRegs;
157    VirtualList rxList;
158    VirtualList rxBusy;
159    int rxActive;
160    VirtualList txList;
161
162    uint8_t  &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
163    uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
164    uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }
165
166  protected:
167    RxState rxState;
168    PacketFifo rxFifo;
169    PacketFifo::iterator rxFifoPtr;
170    bool rxEmpty;
171    bool rxLow;
172    Addr rxDmaAddr;
173    uint8_t *rxDmaData;
174    int rxDmaLen;
175
176    TxState txState;
177    PacketFifo txFifo;
178    bool txFull;
179    EthPacketPtr txPacket;
180    int txPacketOffset;
181    int txPacketBytes;
182    Addr txDmaAddr;
183    uint8_t *txDmaData;
184    int txDmaLen;
185
186  protected:
187    void reset();
188
189    void rxKick();
190    Tick rxKickTick;
191    typedef EventWrapper<Device, &Device::rxKick> RxKickEvent;
192    friend void RxKickEvent::process();
193
194    void txKick();
195    Tick txKickTick;
196    typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
197    friend void TxKickEvent::process();
198
199    /**
200     * Retransmit event
201     */
202    void transmit();
203    void txEventTransmit()
204    {
205        transmit();
206        if (txState == txFifoBlock)
207            txKick();
208    }
209    typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent;
210    friend void TxEvent::process();
211    TxEvent txEvent;
212
213    void txDump() const;
214    void rxDump() const;
215
216    /**
217     * receive address filter
218     */
219    bool rxFilter(const EthPacketPtr &packet);
220
221/**
222 * device configuration
223 */
224    void changeConfig(uint32_t newconfig);
225    void command(uint32_t command);
226
227/**
228 * device ethernet interface
229 */
230  public:
231    bool recvPacket(EthPacketPtr packet);
232    void transferDone();
233    virtual EtherInt *getEthPort(const std::string &if_name, int idx);
234
235/**
236 * DMA parameters
237 */
238  protected:
239    void rxDmaDone();
240    friend class EventWrapper<Device, &Device::rxDmaDone>;
241    EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
242
243    void txDmaDone();
244    friend class EventWrapper<Device, &Device::txDmaDone>;
245    EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
246
247    Tick dmaReadDelay;
248    Tick dmaReadFactor;
249    Tick dmaWriteDelay;
250    Tick dmaWriteFactor;
251
252/**
253 * Interrupt management
254 */
255  protected:
256    void devIntrPost(uint32_t interrupts);
257    void devIntrClear(uint32_t interrupts = Regs::Intr_All);
258    void devIntrChangeMask(uint32_t newmask);
259
260/**
261 * Memory Interface
262 */
263  public:
264    virtual Tick read(PacketPtr pkt);
265    virtual Tick write(PacketPtr pkt);
266    virtual void resume();
267
268    void prepareIO(int cpu, int index);
269    void prepareRead(int cpu, int index);
270    void prepareWrite(int cpu, int index);
271 //   Fault iprRead(Addr daddr, int cpu, uint64_t &result);
272
273/**
274 * Statistics
275 */
276  private:
277    Stats::Scalar<> rxBytes;
278    Stats::Formula  rxBandwidth;
279    Stats::Scalar<> rxPackets;
280    Stats::Formula  rxPacketRate;
281    Stats::Scalar<> rxIpPackets;
282    Stats::Scalar<> rxTcpPackets;
283    Stats::Scalar<> rxUdpPackets;
284    Stats::Scalar<> rxIpChecksums;
285    Stats::Scalar<> rxTcpChecksums;
286    Stats::Scalar<> rxUdpChecksums;
287
288    Stats::Scalar<> txBytes;
289    Stats::Formula  txBandwidth;
290    Stats::Formula totBandwidth;
291    Stats::Formula totPackets;
292    Stats::Formula totBytes;
293    Stats::Formula totPacketRate;
294    Stats::Scalar<> txPackets;
295    Stats::Formula  txPacketRate;
296    Stats::Scalar<> txIpPackets;
297    Stats::Scalar<> txTcpPackets;
298    Stats::Scalar<> txUdpPackets;
299    Stats::Scalar<> txIpChecksums;
300    Stats::Scalar<> txTcpChecksums;
301    Stats::Scalar<> txUdpChecksums;
302
303  public:
304    virtual void regStats();
305
306/**
307 * Serialization stuff
308 */
309  public:
310    virtual void serialize(std::ostream &os);
311    virtual void unserialize(Checkpoint *cp, const std::string &section);
312
313  public:
314    Device(const Params *p);
315    ~Device();
316};
317
318/*
319 * Ethernet Interface for an Ethernet Device
320 */
321class Interface : public EtherInt
322{
323  private:
324    Device *dev;
325
326  public:
327    Interface(const std::string &name, Device *d)
328        : EtherInt(name), dev(d)
329    { }
330
331    virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
332    virtual void sendDone() { dev->transferDone(); }
333};
334
335/* namespace Sinic */ }
336
337#endif // __DEV_SINIC_HH__
338