sinic.hh revision 9339
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 * Authors: Nathan Binkert
29 */
30
31#ifndef __DEV_SINIC_HH__
32#define __DEV_SINIC_HH__
33
34#include "base/inet.hh"
35#include "base/statistics.hh"
36#include "dev/etherdevice.hh"
37#include "dev/etherint.hh"
38#include "dev/etherpkt.hh"
39#include "dev/io_device.hh"
40#include "dev/pcidev.hh"
41#include "dev/pktfifo.hh"
42#include "dev/sinicreg.hh"
43#include "params/Sinic.hh"
44#include "sim/eventq.hh"
45
46namespace Sinic {
47
48class Interface;
49class Base : public EtherDevBase
50{
51  protected:
52    bool rxEnable;
53    bool txEnable;
54
55  protected:
56    Tick intrDelay;
57    Tick intrTick;
58    bool cpuIntrEnable;
59    bool cpuPendingIntr;
60    void cpuIntrPost(Tick when);
61    void cpuInterrupt();
62    void cpuIntrClear();
63
64    typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent;
65    friend void IntrEvent::process();
66    IntrEvent *intrEvent;
67    Interface *interface;
68
69    bool cpuIntrPending() const;
70    void cpuIntrAck() { cpuIntrClear(); }
71
72/**
73 * Serialization stuff
74 */
75  public:
76    virtual void serialize(std::ostream &os);
77    virtual void unserialize(Checkpoint *cp, const std::string &section);
78
79/**
80 * Construction/Destruction/Parameters
81 */
82  public:
83    typedef SinicParams Params;
84    const Params *params() const { return (const Params *)_params; }
85    Base(const Params *p);
86};
87
88class Device : public Base
89{
90  protected:
91    /** Receive State Machine States */
92    enum RxState {
93        rxIdle,
94        rxFifoBlock,
95        rxBeginCopy,
96        rxCopy,
97        rxCopyDone
98    };
99
100    /** Transmit State Machine states */
101    enum TxState {
102        txIdle,
103        txFifoBlock,
104        txBeginCopy,
105        txCopy,
106        txCopyDone
107    };
108
109    /** device register file */
110    struct {
111        uint32_t Config;       // 0x00
112        uint32_t Command;      // 0x04
113        uint32_t IntrStatus;   // 0x08
114        uint32_t IntrMask;     // 0x0c
115        uint32_t RxMaxCopy;    // 0x10
116        uint32_t TxMaxCopy;    // 0x14
117        uint32_t ZeroCopySize; // 0x18
118        uint32_t ZeroCopyMark; // 0x1c
119        uint32_t VirtualCount; // 0x20
120        uint32_t RxMaxIntr;    // 0x24
121        uint32_t RxFifoSize;   // 0x28
122        uint32_t TxFifoSize;   // 0x2c
123        uint32_t RxFifoLow;    // 0x30
124        uint32_t TxFifoLow;    // 0x34
125        uint32_t RxFifoHigh;   // 0x38
126        uint32_t TxFifoHigh;   // 0x3c
127        uint64_t RxData;       // 0x40
128        uint64_t RxDone;       // 0x48
129        uint64_t RxWait;       // 0x50
130        uint64_t TxData;       // 0x58
131        uint64_t TxDone;       // 0x60
132        uint64_t TxWait;       // 0x68
133        uint64_t HwAddr;       // 0x70
134        uint64_t RxStatus;     // 0x78
135    } regs;
136
137    struct VirtualReg {
138        uint64_t RxData;
139        uint64_t RxDone;
140        uint64_t TxData;
141        uint64_t TxDone;
142
143        PacketFifo::iterator rxIndex;
144        unsigned rxPacketOffset;
145        unsigned rxPacketBytes;
146        uint64_t rxDoneData;
147
148        Counter rxUnique;
149        Counter txUnique;
150
151        VirtualReg()
152            : RxData(0), RxDone(0), TxData(0), TxDone(0),
153              rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0)
154        { }
155    };
156    typedef std::vector<VirtualReg> VirtualRegs;
157    typedef std::list<unsigned> VirtualList;
158    Counter rxUnique;
159    Counter txUnique;
160    VirtualRegs virtualRegs;
161    VirtualList rxList;
162    VirtualList rxBusy;
163    int rxActive;
164    VirtualList txList;
165
166    int rxBusyCount;
167    int rxMappedCount;
168    int rxDirtyCount;
169
170    uint8_t  &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
171    uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
172    uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }
173
174  protected:
175    RxState rxState;
176    PacketFifo rxFifo;
177    PacketFifo::iterator rxFifoPtr;
178    bool rxEmpty;
179    bool rxLow;
180    Addr rxDmaAddr;
181    uint8_t *rxDmaData;
182    unsigned rxDmaLen;
183
184    TxState txState;
185    PacketFifo txFifo;
186    bool txFull;
187    EthPacketPtr txPacket;
188    int txPacketOffset;
189    int txPacketBytes;
190    Addr txDmaAddr;
191    uint8_t *txDmaData;
192    int txDmaLen;
193
194  protected:
195    void reset();
196
197    void rxKick();
198    Tick rxKickTick;
199    typedef EventWrapper<Device, &Device::rxKick> RxKickEvent;
200    friend void RxKickEvent::process();
201
202    void txKick();
203    Tick txKickTick;
204    typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
205    friend void TxKickEvent::process();
206
207    /**
208     * Retransmit event
209     */
210    void transmit();
211    void txEventTransmit()
212    {
213        transmit();
214        if (txState == txFifoBlock)
215            txKick();
216    }
217    typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent;
218    friend void TxEvent::process();
219    TxEvent txEvent;
220
221    void txDump() const;
222    void rxDump() const;
223
224    /**
225     * receive address filter
226     */
227    bool rxFilter(const EthPacketPtr &packet);
228
229/**
230 * device configuration
231 */
232    void changeConfig(uint32_t newconfig);
233    void command(uint32_t command);
234
235/**
236 * device ethernet interface
237 */
238  public:
239    bool recvPacket(EthPacketPtr packet);
240    void transferDone();
241    virtual EtherInt *getEthPort(const std::string &if_name, int idx);
242
243/**
244 * DMA parameters
245 */
246  protected:
247    void rxDmaDone();
248    friend class EventWrapper<Device, &Device::rxDmaDone>;
249    EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
250
251    void txDmaDone();
252    friend class EventWrapper<Device, &Device::txDmaDone>;
253    EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
254
255    Tick dmaReadDelay;
256    Tick dmaReadFactor;
257    Tick dmaWriteDelay;
258    Tick dmaWriteFactor;
259
260/**
261 * Interrupt management
262 */
263  protected:
264    void devIntrPost(uint32_t interrupts);
265    void devIntrClear(uint32_t interrupts = Regs::Intr_All);
266    void devIntrChangeMask(uint32_t newmask);
267
268/**
269 * Memory Interface
270 */
271  public:
272    virtual Tick read(PacketPtr pkt);
273    virtual Tick write(PacketPtr pkt);
274    virtual void resume();
275
276    void prepareIO(int cpu, int index);
277    void prepareRead(int cpu, int index);
278    void prepareWrite(int cpu, int index);
279 //   Fault iprRead(Addr daddr, int cpu, uint64_t &result);
280
281/**
282 * Statistics
283 */
284  private:
285    Stats::Scalar totalVnicDistance;
286    Stats::Scalar numVnicDistance;
287    Stats::Scalar maxVnicDistance;
288    Stats::Formula avgVnicDistance;
289
290    int _maxVnicDistance;
291
292  public:
293    virtual void regStats();
294    virtual void resetStats();
295
296/**
297 * Serialization stuff
298 */
299  public:
300    virtual void serialize(std::ostream &os);
301    virtual void unserialize(Checkpoint *cp, const std::string &section);
302
303  public:
304    Device(const Params *p);
305    ~Device();
306};
307
308/*
309 * Ethernet Interface for an Ethernet Device
310 */
311class Interface : public EtherInt
312{
313  private:
314    Device *dev;
315
316  public:
317    Interface(const std::string &name, Device *d)
318        : EtherInt(name), dev(d)
319    { }
320
321    virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); }
322    virtual void sendDone() { dev->transferDone(); }
323};
324
325} // namespace Sinic
326
327#endif // __DEV_SINIC_HH__
328