sinic.hh revision 4762
112653Sandreas.sandberg@arm.com/*
212653Sandreas.sandberg@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan
312653Sandreas.sandberg@arm.com * All rights reserved.
412653Sandreas.sandberg@arm.com *
512653Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
612653Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
712653Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
812653Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
912653Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
1012653Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
1112653Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
1212653Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
1312653Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
1412653Sandreas.sandberg@arm.com * this software without specific prior written permission.
1512653Sandreas.sandberg@arm.com *
1612653Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712653Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812653Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912653Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012653Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112653Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212653Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312653Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412653Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512653Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612653Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712653Sandreas.sandberg@arm.com *
2812653Sandreas.sandberg@arm.com * Authors: Nathan Binkert
2912653Sandreas.sandberg@arm.com */
3012653Sandreas.sandberg@arm.com
3112653Sandreas.sandberg@arm.com#ifndef __DEV_SINIC_HH__
3212653Sandreas.sandberg@arm.com#define __DEV_SINIC_HH__
3312653Sandreas.sandberg@arm.com
3412653Sandreas.sandberg@arm.com#include "base/inet.hh"
3512653Sandreas.sandberg@arm.com#include "base/statistics.hh"
3612653Sandreas.sandberg@arm.com#include "dev/etherint.hh"
3712653Sandreas.sandberg@arm.com#include "dev/etherpkt.hh"
3812653Sandreas.sandberg@arm.com#include "dev/io_device.hh"
3912653Sandreas.sandberg@arm.com#include "dev/pcidev.hh"
4012653Sandreas.sandberg@arm.com#include "dev/pktfifo.hh"
4112653Sandreas.sandberg@arm.com#include "dev/sinicreg.hh"
4212653Sandreas.sandberg@arm.com#include "params/Sinic.hh"
4312653Sandreas.sandberg@arm.com#include "params/SinicInt.hh"
4412653Sandreas.sandberg@arm.com#include "sim/eventq.hh"
4512653Sandreas.sandberg@arm.com
4612653Sandreas.sandberg@arm.comnamespace Sinic {
4712653Sandreas.sandberg@arm.com
4812660Sandreas.sandberg@arm.comclass Interface;
4912653Sandreas.sandberg@arm.comclass Base : public PciDev
5012653Sandreas.sandberg@arm.com{
5112653Sandreas.sandberg@arm.com  protected:
5212653Sandreas.sandberg@arm.com    bool rxEnable;
5312654Sandreas.sandberg@arm.com    bool txEnable;
5412654Sandreas.sandberg@arm.com    Tick clock;
5512653Sandreas.sandberg@arm.com    inline Tick cycles(int numCycles) const { return numCycles * clock; }
5612654Sandreas.sandberg@arm.com
5712654Sandreas.sandberg@arm.com  protected:
5812653Sandreas.sandberg@arm.com    Tick intrDelay;
5912653Sandreas.sandberg@arm.com    Tick intrTick;
6012653Sandreas.sandberg@arm.com    bool cpuIntrEnable;
6112653Sandreas.sandberg@arm.com    bool cpuPendingIntr;
6212653Sandreas.sandberg@arm.com    void cpuIntrPost(Tick when);
6312653Sandreas.sandberg@arm.com    void cpuInterrupt();
6412654Sandreas.sandberg@arm.com    void cpuIntrClear();
6512654Sandreas.sandberg@arm.com
6612653Sandreas.sandberg@arm.com    typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent;
6712653Sandreas.sandberg@arm.com    friend void IntrEvent::process();
6812653Sandreas.sandberg@arm.com    IntrEvent *intrEvent;
6912653Sandreas.sandberg@arm.com    Interface *interface;
7012653Sandreas.sandberg@arm.com
7112653Sandreas.sandberg@arm.com    bool cpuIntrPending() const;
7212654Sandreas.sandberg@arm.com    void cpuIntrAck() { cpuIntrClear(); }
7312654Sandreas.sandberg@arm.com
7412653Sandreas.sandberg@arm.com/**
7512653Sandreas.sandberg@arm.com * Serialization stuff
7612656Sandreas.sandberg@arm.com */
7712656Sandreas.sandberg@arm.com  public:
7812653Sandreas.sandberg@arm.com    virtual void serialize(std::ostream &os);
7912656Sandreas.sandberg@arm.com    virtual void unserialize(Checkpoint *cp, const std::string &section);
8012660Sandreas.sandberg@arm.com
8112660Sandreas.sandberg@arm.com/**
8212660Sandreas.sandberg@arm.com * Construction/Destruction/Parameters
8312660Sandreas.sandberg@arm.com */
8412660Sandreas.sandberg@arm.com  public:
8512660Sandreas.sandberg@arm.com    typedef SinicParams Params;
8612660Sandreas.sandberg@arm.com    const Params *params() const { return (const Params *)_params; }
8712660Sandreas.sandberg@arm.com    Base(Params *p);
8812660Sandreas.sandberg@arm.com};
8912660Sandreas.sandberg@arm.com
9012660Sandreas.sandberg@arm.comclass Device : public Base
9112660Sandreas.sandberg@arm.com{
9212660Sandreas.sandberg@arm.com  protected:
9312660Sandreas.sandberg@arm.com    /** Receive State Machine States */
9412660Sandreas.sandberg@arm.com    enum RxState {
9512660Sandreas.sandberg@arm.com        rxIdle,
9612660Sandreas.sandberg@arm.com        rxFifoBlock,
9712660Sandreas.sandberg@arm.com        rxBeginCopy,
9812660Sandreas.sandberg@arm.com        rxCopy,
9912660Sandreas.sandberg@arm.com        rxCopyDone
10012660Sandreas.sandberg@arm.com    };
10112660Sandreas.sandberg@arm.com
10212660Sandreas.sandberg@arm.com    /** Transmit State Machine states */
10312660Sandreas.sandberg@arm.com    enum TxState {
10412660Sandreas.sandberg@arm.com        txIdle,
10512660Sandreas.sandberg@arm.com        txFifoBlock,
10612660Sandreas.sandberg@arm.com        txBeginCopy,
10712660Sandreas.sandberg@arm.com        txCopy,
10812660Sandreas.sandberg@arm.com        txCopyDone
10912660Sandreas.sandberg@arm.com    };
11012656Sandreas.sandberg@arm.com
11112656Sandreas.sandberg@arm.com    /** device register file */
11212656Sandreas.sandberg@arm.com    struct {
11312656Sandreas.sandberg@arm.com        uint32_t Config;       // 0x00
11412656Sandreas.sandberg@arm.com        uint32_t Command;      // 0x04
11512653Sandreas.sandberg@arm.com        uint32_t IntrStatus;   // 0x08
11612653Sandreas.sandberg@arm.com        uint32_t IntrMask;     // 0x0c
11712656Sandreas.sandberg@arm.com        uint32_t RxMaxCopy;    // 0x10
11812656Sandreas.sandberg@arm.com        uint32_t TxMaxCopy;    // 0x14
11912656Sandreas.sandberg@arm.com        uint32_t RxMaxIntr;    // 0x18
12012653Sandreas.sandberg@arm.com        uint32_t VirtualCount; // 0x1c
12112656Sandreas.sandberg@arm.com        uint32_t RxFifoSize;   // 0x20
12212653Sandreas.sandberg@arm.com        uint32_t TxFifoSize;   // 0x24
12312660Sandreas.sandberg@arm.com        uint32_t RxFifoMark;   // 0x28
12412653Sandreas.sandberg@arm.com        uint32_t TxFifoMark;   // 0x2c
12512660Sandreas.sandberg@arm.com        uint64_t RxData;       // 0x30
12612653Sandreas.sandberg@arm.com        uint64_t RxDone;       // 0x38
12712660Sandreas.sandberg@arm.com        uint64_t RxWait;       // 0x40
12812656Sandreas.sandberg@arm.com        uint64_t TxData;       // 0x48
12912656Sandreas.sandberg@arm.com        uint64_t TxDone;       // 0x50
13012656Sandreas.sandberg@arm.com        uint64_t TxWait;       // 0x58
13112656Sandreas.sandberg@arm.com        uint64_t HwAddr;       // 0x60
13212656Sandreas.sandberg@arm.com    } regs;
13312656Sandreas.sandberg@arm.com
13412656Sandreas.sandberg@arm.com    struct VirtualReg {
13512656Sandreas.sandberg@arm.com        uint64_t RxData;
13612656Sandreas.sandberg@arm.com        uint64_t RxDone;
13712660Sandreas.sandberg@arm.com        uint64_t TxData;
13812653Sandreas.sandberg@arm.com        uint64_t TxDone;
13912660Sandreas.sandberg@arm.com
14012653Sandreas.sandberg@arm.com        PacketFifo::iterator rxPacket;
14112660Sandreas.sandberg@arm.com        int rxPacketOffset;
14212653Sandreas.sandberg@arm.com        int rxPacketBytes;
14312660Sandreas.sandberg@arm.com        uint64_t rxDoneData;
14412653Sandreas.sandberg@arm.com
14512653Sandreas.sandberg@arm.com        Counter rxUnique;
14612660Sandreas.sandberg@arm.com        Counter txUnique;
14712653Sandreas.sandberg@arm.com
14812660Sandreas.sandberg@arm.com        VirtualReg()
14912653Sandreas.sandberg@arm.com            : RxData(0), RxDone(0), TxData(0), TxDone(0),
15012660Sandreas.sandberg@arm.com              rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0)
15112653Sandreas.sandberg@arm.com        { }
15212653Sandreas.sandberg@arm.com    };
15312656Sandreas.sandberg@arm.com    typedef std::vector<VirtualReg> VirtualRegs;
15412653Sandreas.sandberg@arm.com    typedef std::list<int> VirtualList;
15512653Sandreas.sandberg@arm.com    Counter rxUnique;
15612653Sandreas.sandberg@arm.com    Counter txUnique;
15712654Sandreas.sandberg@arm.com    VirtualRegs virtualRegs;
15812654Sandreas.sandberg@arm.com    VirtualList rxList;
15912654Sandreas.sandberg@arm.com    VirtualList rxBusy;
16012654Sandreas.sandberg@arm.com    int rxActive;
16112654Sandreas.sandberg@arm.com    VirtualList txList;
16212654Sandreas.sandberg@arm.com
16312654Sandreas.sandberg@arm.com    uint8_t  &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
16412654Sandreas.sandberg@arm.com    uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
16512654Sandreas.sandberg@arm.com    uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }
16612654Sandreas.sandberg@arm.com
16712654Sandreas.sandberg@arm.com  protected:
16812654Sandreas.sandberg@arm.com    RxState rxState;
16912654Sandreas.sandberg@arm.com    PacketFifo rxFifo;
17012654Sandreas.sandberg@arm.com    PacketFifo::iterator rxFifoPtr;
17112654Sandreas.sandberg@arm.com    bool rxEmpty;
17212654Sandreas.sandberg@arm.com    bool rxLow;
17312654Sandreas.sandberg@arm.com    Addr rxDmaAddr;
17412654Sandreas.sandberg@arm.com    uint8_t *rxDmaData;
17512654Sandreas.sandberg@arm.com    int rxDmaLen;
17612654Sandreas.sandberg@arm.com
17712654Sandreas.sandberg@arm.com    TxState txState;
17812653Sandreas.sandberg@arm.com    PacketFifo txFifo;
17912653Sandreas.sandberg@arm.com    bool txFull;
18012653Sandreas.sandberg@arm.com    EthPacketPtr txPacket;
18112653Sandreas.sandberg@arm.com    int txPacketOffset;
18212653Sandreas.sandberg@arm.com    int txPacketBytes;
183    Addr txDmaAddr;
184    uint8_t *txDmaData;
185    int txDmaLen;
186
187  protected:
188    void reset();
189
190    void rxKick();
191    Tick rxKickTick;
192    typedef EventWrapper<Device, &Device::rxKick> RxKickEvent;
193    friend void RxKickEvent::process();
194
195    void txKick();
196    Tick txKickTick;
197    typedef EventWrapper<Device, &Device::txKick> TxKickEvent;
198    friend void TxKickEvent::process();
199
200    /**
201     * Retransmit event
202     */
203    void transmit();
204    void txEventTransmit()
205    {
206        transmit();
207        if (txState == txFifoBlock)
208            txKick();
209    }
210    typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent;
211    friend void TxEvent::process();
212    TxEvent txEvent;
213
214    void txDump() const;
215    void rxDump() const;
216
217    /**
218     * receive address filter
219     */
220    bool rxFilter(const EthPacketPtr &packet);
221
222/**
223 * device configuration
224 */
225    void changeConfig(uint32_t newconfig);
226    void command(uint32_t command);
227
228/**
229 * device ethernet interface
230 */
231  public:
232    bool recvPacket(EthPacketPtr packet);
233    void transferDone();
234    void setInterface(Interface *i) { assert(!interface); interface = i; }
235
236/**
237 * DMA parameters
238 */
239  protected:
240    void rxDmaDone();
241    friend class EventWrapper<Device, &Device::rxDmaDone>;
242    EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent;
243
244    void txDmaDone();
245    friend class EventWrapper<Device, &Device::txDmaDone>;
246    EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
247
248    Tick dmaReadDelay;
249    Tick dmaReadFactor;
250    Tick dmaWriteDelay;
251    Tick dmaWriteFactor;
252
253/**
254 * Interrupt management
255 */
256  protected:
257    void devIntrPost(uint32_t interrupts);
258    void devIntrClear(uint32_t interrupts = Regs::Intr_All);
259    void devIntrChangeMask(uint32_t newmask);
260
261/**
262 * Memory Interface
263 */
264  public:
265    virtual Tick read(PacketPtr pkt);
266    virtual Tick write(PacketPtr pkt);
267    virtual void resume();
268
269    void prepareIO(int cpu, int index);
270    void prepareRead(int cpu, int index);
271    void prepareWrite(int cpu, int index);
272 //   Fault iprRead(Addr daddr, int cpu, uint64_t &result);
273
274/**
275 * Statistics
276 */
277  private:
278    Stats::Scalar<> rxBytes;
279    Stats::Formula  rxBandwidth;
280    Stats::Scalar<> rxPackets;
281    Stats::Formula  rxPacketRate;
282    Stats::Scalar<> rxIpPackets;
283    Stats::Scalar<> rxTcpPackets;
284    Stats::Scalar<> rxUdpPackets;
285    Stats::Scalar<> rxIpChecksums;
286    Stats::Scalar<> rxTcpChecksums;
287    Stats::Scalar<> rxUdpChecksums;
288
289    Stats::Scalar<> txBytes;
290    Stats::Formula  txBandwidth;
291    Stats::Formula totBandwidth;
292    Stats::Formula totPackets;
293    Stats::Formula totBytes;
294    Stats::Formula totPacketRate;
295    Stats::Scalar<> txPackets;
296    Stats::Formula  txPacketRate;
297    Stats::Scalar<> txIpPackets;
298    Stats::Scalar<> txTcpPackets;
299    Stats::Scalar<> txUdpPackets;
300    Stats::Scalar<> txIpChecksums;
301    Stats::Scalar<> txTcpChecksums;
302    Stats::Scalar<> txUdpChecksums;
303
304  public:
305    virtual void regStats();
306
307/**
308 * Serialization stuff
309 */
310  public:
311    virtual void serialize(std::ostream &os);
312    virtual void unserialize(Checkpoint *cp, const std::string &section);
313
314  public:
315    Device(Params *p);
316    ~Device();
317};
318
319/*
320 * Ethernet Interface for an Ethernet Device
321 */
322class Interface : public EtherInt
323{
324  private:
325    Device *dev;
326
327  public:
328    Interface(const std::string &name, Device *d)
329        : EtherInt(name), dev(d) { dev->setInterface(this); }
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