sinic.hh revision 11260
15081Sgblack@eecs.umich.edu/*
25081Sgblack@eecs.umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan
35081Sgblack@eecs.umich.edu * All rights reserved.
47087Snate@binkert.org *
57087Snate@binkert.org * Redistribution and use in source and binary forms, with or without
67087Snate@binkert.org * modification, are permitted provided that the following conditions are
77087Snate@binkert.org * met: redistributions of source code must retain the above copyright
87087Snate@binkert.org * notice, this list of conditions and the following disclaimer;
97087Snate@binkert.org * redistributions in binary form must reproduce the above copyright
107087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
117087Snate@binkert.org * documentation and/or other materials provided with the distribution;
125081Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
137087Snate@binkert.org * contributors may be used to endorse or promote products derived from
147087Snate@binkert.org * this software without specific prior written permission.
157087Snate@binkert.org *
167087Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
177087Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
187087Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
197087Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
207087Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215081Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
227087Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235081Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245081Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255081Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265081Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275081Sgblack@eecs.umich.edu *
285081Sgblack@eecs.umich.edu * Authors: Nathan Binkert
295081Sgblack@eecs.umich.edu */
305081Sgblack@eecs.umich.edu
315081Sgblack@eecs.umich.edu#ifndef __DEV_SINIC_HH__
325081Sgblack@eecs.umich.edu#define __DEV_SINIC_HH__
335081Sgblack@eecs.umich.edu
345081Sgblack@eecs.umich.edu#include "base/inet.hh"
355081Sgblack@eecs.umich.edu#include "base/statistics.hh"
365081Sgblack@eecs.umich.edu#include "dev/etherdevice.hh"
375081Sgblack@eecs.umich.edu#include "dev/etherint.hh"
385081Sgblack@eecs.umich.edu#include "dev/etherpkt.hh"
396559Sgblack@eecs.umich.edu#include "dev/io_device.hh"
406799Sgblack@eecs.umich.edu#include "dev/pci/device.hh"
416559Sgblack@eecs.umich.edu#include "dev/pktfifo.hh"
426559Sgblack@eecs.umich.edu#include "dev/sinicreg.hh"
436559Sgblack@eecs.umich.edu#include "params/Sinic.hh"
446559Sgblack@eecs.umich.edu#include "sim/eventq.hh"
456799Sgblack@eecs.umich.edu
466559Sgblack@eecs.umich.edunamespace Sinic {
476559Sgblack@eecs.umich.edu
486559Sgblack@eecs.umich.educlass Interface;
496559Sgblack@eecs.umich.educlass Base : public EtherDevBase
506559Sgblack@eecs.umich.edu{
516799Sgblack@eecs.umich.edu  protected:
526559Sgblack@eecs.umich.edu    bool rxEnable;
535081Sgblack@eecs.umich.edu    bool txEnable;
546518Sgblack@eecs.umich.edu
556799Sgblack@eecs.umich.edu  protected:
565081Sgblack@eecs.umich.edu    Tick intrDelay;
575081Sgblack@eecs.umich.edu    Tick intrTick;
586518Sgblack@eecs.umich.edu    bool cpuIntrEnable;
596519Sgblack@eecs.umich.edu    bool cpuPendingIntr;
606799Sgblack@eecs.umich.edu    void cpuIntrPost(Tick when);
615081Sgblack@eecs.umich.edu    void cpuInterrupt();
625081Sgblack@eecs.umich.edu    void cpuIntrClear();
636518Sgblack@eecs.umich.edu
645081Sgblack@eecs.umich.edu    typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent;
656519Sgblack@eecs.umich.edu    friend void IntrEvent::process();
666799Sgblack@eecs.umich.edu    IntrEvent *intrEvent;
676559Sgblack@eecs.umich.edu    Interface *interface;
686559Sgblack@eecs.umich.edu
696559Sgblack@eecs.umich.edu    bool cpuIntrPending() const;
706559Sgblack@eecs.umich.edu    void cpuIntrAck() { cpuIntrClear(); }
716559Sgblack@eecs.umich.edu
726559Sgblack@eecs.umich.edu/**
736559Sgblack@eecs.umich.edu * Serialization stuff
746559Sgblack@eecs.umich.edu */
756559Sgblack@eecs.umich.edu  public:
766559Sgblack@eecs.umich.edu    void serialize(CheckpointOut &cp) const override;
776559Sgblack@eecs.umich.edu    void unserialize(CheckpointIn &cp) override;
786559Sgblack@eecs.umich.edu
796559Sgblack@eecs.umich.edu/**
806559Sgblack@eecs.umich.edu * Construction/Destruction/Parameters
816559Sgblack@eecs.umich.edu */
826559Sgblack@eecs.umich.edu  public:
836559Sgblack@eecs.umich.edu    typedef SinicParams Params;
846559Sgblack@eecs.umich.edu    const Params *params() const { return (const Params *)_params; }
856559Sgblack@eecs.umich.edu    Base(const Params *p);
866559Sgblack@eecs.umich.edu};
876559Sgblack@eecs.umich.edu
886559Sgblack@eecs.umich.educlass Device : public Base
896559Sgblack@eecs.umich.edu{
906559Sgblack@eecs.umich.edu  protected:
916559Sgblack@eecs.umich.edu    /** Receive State Machine States */
926559Sgblack@eecs.umich.edu    enum RxState {
936559Sgblack@eecs.umich.edu        rxIdle,
946559Sgblack@eecs.umich.edu        rxFifoBlock,
956559Sgblack@eecs.umich.edu        rxBeginCopy,
966559Sgblack@eecs.umich.edu        rxCopy,
976559Sgblack@eecs.umich.edu        rxCopyDone
986559Sgblack@eecs.umich.edu    };
996559Sgblack@eecs.umich.edu
1006559Sgblack@eecs.umich.edu    /** Transmit State Machine states */
1016559Sgblack@eecs.umich.edu    enum TxState {
1026559Sgblack@eecs.umich.edu        txIdle,
1036559Sgblack@eecs.umich.edu        txFifoBlock,
1046559Sgblack@eecs.umich.edu        txBeginCopy,
1056559Sgblack@eecs.umich.edu        txCopy,
1066559Sgblack@eecs.umich.edu        txCopyDone
1075081Sgblack@eecs.umich.edu    };
1085081Sgblack@eecs.umich.edu
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    EtherInt *getEthPort(const std::string &if_name, int idx) override;
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    Tick read(PacketPtr pkt) override;
273    Tick write(PacketPtr pkt) override;
274    virtual void drainResume() override;
275
276    void prepareIO(ContextID cpu, int index);
277    void prepareRead(ContextID cpu, int index);
278    void prepareWrite(ContextID cpu, int index);
279 //   Fault iprRead(Addr daddr, ContextID 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    void regStats() override;
294    void resetStats() override;
295
296/**
297 * Serialization stuff
298 */
299  public:
300    void serialize(CheckpointOut &cp) const override;
301    void unserialize(CheckpointIn &cp) override;
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