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