sinic.hh revision 4762
17927SN/A/* 27927SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 38673SN/A * All rights reserved. 48673SN/A * 58721SN/A * Redistribution and use in source and binary forms, with or without 67927SN/A * modification, are permitted provided that the following conditions are 78983Snate@binkert.org * met: redistributions of source code must retain the above copyright 88983Snate@binkert.org * notice, this list of conditions and the following disclaimer; 98983Snate@binkert.org * redistributions in binary form must reproduce the above copyright 108983Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 118983Snate@binkert.org * documentation and/or other materials provided with the distribution; 128835SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its 138835SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from 148721SN/A * this software without specific prior written permission. 158721SN/A * 168721SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 178721SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 188721SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 198721SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 208721SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 218721SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 228721SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 238721SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 248673SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 258673SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 268673SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 278673SN/A * 288673SN/A * Authors: Nathan Binkert 298613SN/A */ 308835SAli.Saidi@ARM.com 318835SAli.Saidi@ARM.com#ifndef __DEV_SINIC_HH__ 328835SAli.Saidi@ARM.com#define __DEV_SINIC_HH__ 338835SAli.Saidi@ARM.com 348835SAli.Saidi@ARM.com#include "base/inet.hh" 358835SAli.Saidi@ARM.com#include "base/statistics.hh" 368835SAli.Saidi@ARM.com#include "dev/etherint.hh" 378835SAli.Saidi@ARM.com#include "dev/etherpkt.hh" 388835SAli.Saidi@ARM.com#include "dev/io_device.hh" 398835SAli.Saidi@ARM.com#include "dev/pcidev.hh" 408835SAli.Saidi@ARM.com#include "dev/pktfifo.hh" 418835SAli.Saidi@ARM.com#include "dev/sinicreg.hh" 428835SAli.Saidi@ARM.com#include "params/Sinic.hh" 438835SAli.Saidi@ARM.com#include "params/SinicInt.hh" 448835SAli.Saidi@ARM.com#include "sim/eventq.hh" 458673SN/A 468835SAli.Saidi@ARM.comnamespace Sinic { 478673SN/A 488835SAli.Saidi@ARM.comclass Interface; 498673SN/Aclass Base : public PciDev 508835SAli.Saidi@ARM.com{ 518673SN/A protected: 528835SAli.Saidi@ARM.com bool rxEnable; 538835SAli.Saidi@ARM.com bool txEnable; 548835SAli.Saidi@ARM.com Tick clock; 558835SAli.Saidi@ARM.com inline Tick cycles(int numCycles) const { return numCycles * clock; } 568673SN/A 578835SAli.Saidi@ARM.com protected: 588835SAli.Saidi@ARM.com Tick intrDelay; 598835SAli.Saidi@ARM.com Tick intrTick; 608835SAli.Saidi@ARM.com bool cpuIntrEnable; 618673SN/A bool cpuPendingIntr; 628835SAli.Saidi@ARM.com void cpuIntrPost(Tick when); 638835SAli.Saidi@ARM.com void cpuInterrupt(); 648835SAli.Saidi@ARM.com void cpuIntrClear(); 658835SAli.Saidi@ARM.com 668673SN/A typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent; 678835SAli.Saidi@ARM.com friend void IntrEvent::process(); 688673SN/A IntrEvent *intrEvent; 698835SAli.Saidi@ARM.com Interface *interface; 708673SN/A 718835SAli.Saidi@ARM.com bool cpuIntrPending() const; 728835SAli.Saidi@ARM.com void cpuIntrAck() { cpuIntrClear(); } 738835SAli.Saidi@ARM.com 748835SAli.Saidi@ARM.com/** 758673SN/A * Serialization stuff 768835SAli.Saidi@ARM.com */ 778835SAli.Saidi@ARM.com public: 788835SAli.Saidi@ARM.com virtual void serialize(std::ostream &os); 798835SAli.Saidi@ARM.com virtual void unserialize(Checkpoint *cp, const std::string §ion); 808673SN/A 818835SAli.Saidi@ARM.com/** 828835SAli.Saidi@ARM.com * Construction/Destruction/Parameters 838835SAli.Saidi@ARM.com */ 848835SAli.Saidi@ARM.com public: 858673SN/A typedef SinicParams Params; 868835SAli.Saidi@ARM.com const Params *params() const { return (const Params *)_params; } 878673SN/A Base(Params *p); 888835SAli.Saidi@ARM.com}; 898673SN/A 908835SAli.Saidi@ARM.comclass Device : public Base 918673SN/A{ 928835SAli.Saidi@ARM.com protected: 938835SAli.Saidi@ARM.com /** Receive State Machine States */ 948835SAli.Saidi@ARM.com enum RxState { 958835SAli.Saidi@ARM.com rxIdle, 968673SN/A rxFifoBlock, 978835SAli.Saidi@ARM.com rxBeginCopy, 988835SAli.Saidi@ARM.com rxCopy, 998835SAli.Saidi@ARM.com rxCopyDone 1008835SAli.Saidi@ARM.com }; 1018673SN/A 1028835SAli.Saidi@ARM.com /** Transmit State Machine states */ 1038835SAli.Saidi@ARM.com enum TxState { 1048835SAli.Saidi@ARM.com txIdle, 1058835SAli.Saidi@ARM.com txFifoBlock, 1068835SAli.Saidi@ARM.com txBeginCopy, 1078835SAli.Saidi@ARM.com txCopy, 1088835SAli.Saidi@ARM.com txCopyDone 1098835SAli.Saidi@ARM.com }; 1108835SAli.Saidi@ARM.com 1118835SAli.Saidi@ARM.com /** device register file */ 1128835SAli.Saidi@ARM.com struct { 1138835SAli.Saidi@ARM.com uint32_t Config; // 0x00 1148835SAli.Saidi@ARM.com uint32_t Command; // 0x04 1158835SAli.Saidi@ARM.com uint32_t IntrStatus; // 0x08 1168613SN/A uint32_t IntrMask; // 0x0c 1178613SN/A uint32_t RxMaxCopy; // 0x10 1188613SN/A uint32_t TxMaxCopy; // 0x14 1198613SN/A uint32_t RxMaxIntr; // 0x18 1208983Snate@binkert.org uint32_t VirtualCount; // 0x1c 1218983Snate@binkert.org uint32_t RxFifoSize; // 0x20 1228613SN/A uint32_t TxFifoSize; // 0x24 1238613SN/A uint32_t RxFifoMark; // 0x28 1248835SAli.Saidi@ARM.com uint32_t TxFifoMark; // 0x2c 1258835SAli.Saidi@ARM.com uint64_t RxData; // 0x30 1268613SN/A uint64_t RxDone; // 0x38 1278673SN/A uint64_t RxWait; // 0x40 1288673SN/A uint64_t TxData; // 0x48 1298613SN/A uint64_t TxDone; // 0x50 1308673SN/A uint64_t TxWait; // 0x58 1318613SN/A uint64_t HwAddr; // 0x60 1328673SN/A } regs; 1338835SAli.Saidi@ARM.com 1348835SAli.Saidi@ARM.com struct VirtualReg { 1358835SAli.Saidi@ARM.com uint64_t RxData; 1368835SAli.Saidi@ARM.com uint64_t RxDone; 1378673SN/A uint64_t TxData; 1388835SAli.Saidi@ARM.com uint64_t TxDone; 1398613SN/A 1408835SAli.Saidi@ARM.com PacketFifo::iterator rxPacket; 1418673SN/A int rxPacketOffset; 1428835SAli.Saidi@ARM.com int rxPacketBytes; 1438673SN/A uint64_t rxDoneData; 1448835SAli.Saidi@ARM.com 1458673SN/A Counter rxUnique; 1468835SAli.Saidi@ARM.com Counter txUnique; 1478613SN/A 1488835SAli.Saidi@ARM.com VirtualReg() 1498673SN/A : RxData(0), RxDone(0), TxData(0), TxDone(0), 1508835SAli.Saidi@ARM.com rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0) 1518673SN/A { } 1528835SAli.Saidi@ARM.com }; 1538835SAli.Saidi@ARM.com typedef std::vector<VirtualReg> VirtualRegs; 1548835SAli.Saidi@ARM.com typedef std::list<int> VirtualList; 1558835SAli.Saidi@ARM.com Counter rxUnique; 1568613SN/A Counter txUnique; 1578613SN/A VirtualRegs virtualRegs; 1588613SN/A VirtualList rxList; 1598613SN/A VirtualList rxBusy; 1608983Snate@binkert.org int rxActive; 1618983Snate@binkert.org VirtualList txList; 1628613SN/A 1638613SN/A uint8_t ®Data8(Addr daddr) { return *((uint8_t *)®s + daddr); } 1648835SAli.Saidi@ARM.com uint32_t ®Data32(Addr daddr) { return *(uint32_t *)®Data8(daddr); } 1658835SAli.Saidi@ARM.com uint64_t ®Data64(Addr daddr) { return *(uint64_t *)®Data8(daddr); } 1668613SN/A 1678613SN/A protected: 1688613SN/A RxState rxState; 1698613SN/A PacketFifo rxFifo; 1708613SN/A PacketFifo::iterator rxFifoPtr; 1718613SN/A bool rxEmpty; 1728613SN/A bool rxLow; 1738613SN/A Addr rxDmaAddr; 1748613SN/A uint8_t *rxDmaData; 1758613SN/A int rxDmaLen; 1768613SN/A 1778613SN/A TxState txState; 1788613SN/A PacketFifo txFifo; 1798673SN/A bool txFull; 1808613SN/A EthPacketPtr txPacket; 1818613SN/A int txPacketOffset; 1828835SAli.Saidi@ARM.com int txPacketBytes; 1838835SAli.Saidi@ARM.com Addr txDmaAddr; 1848673SN/A uint8_t *txDmaData; 1858613SN/A int txDmaLen; 1868613SN/A 1878673SN/A protected: 1888673SN/A void reset(); 1898613SN/A 1908673SN/A void rxKick(); 1918673SN/A Tick rxKickTick; 1928613SN/A typedef EventWrapper<Device, &Device::rxKick> RxKickEvent; 1938613SN/A friend void RxKickEvent::process(); 1948673SN/A 1958673SN/A void txKick(); 1968673SN/A Tick txKickTick; 1978673SN/A typedef EventWrapper<Device, &Device::txKick> TxKickEvent; 1988673SN/A friend void TxKickEvent::process(); 1998673SN/A 2008673SN/A /** 2018613SN/A * Retransmit event 2028613SN/A */ 2038673SN/A void transmit(); 2048673SN/A void txEventTransmit() 2058673SN/A { 2068673SN/A transmit(); 2078673SN/A if (txState == txFifoBlock) 2088673SN/A txKick(); 2098835SAli.Saidi@ARM.com } 2108835SAli.Saidi@ARM.com typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent; 2118835SAli.Saidi@ARM.com friend void TxEvent::process(); 2128835SAli.Saidi@ARM.com TxEvent txEvent; 2138673SN/A 2148835SAli.Saidi@ARM.com void txDump() const; 2158673SN/A void rxDump() const; 2168835SAli.Saidi@ARM.com 2178673SN/A /** 2188835SAli.Saidi@ARM.com * receive address filter 2198673SN/A */ 2208835SAli.Saidi@ARM.com bool rxFilter(const EthPacketPtr &packet); 2218673SN/A 2228835SAli.Saidi@ARM.com/** 2238673SN/A * device configuration 2248835SAli.Saidi@ARM.com */ 2258673SN/A void changeConfig(uint32_t newconfig); 2268835SAli.Saidi@ARM.com void command(uint32_t command); 2278673SN/A 2288835SAli.Saidi@ARM.com/** 2298673SN/A * device ethernet interface 2308835SAli.Saidi@ARM.com */ 2318835SAli.Saidi@ARM.com public: 2328835SAli.Saidi@ARM.com bool recvPacket(EthPacketPtr packet); 2338613SN/A void transferDone(); 2348613SN/A void setInterface(Interface *i) { assert(!interface); interface = i; } 2358613SN/A 2368613SN/A/** 2378983Snate@binkert.org * DMA parameters 2388983Snate@binkert.org */ 2398613SN/A protected: 2408613SN/A void rxDmaDone(); 2418835SAli.Saidi@ARM.com friend class EventWrapper<Device, &Device::rxDmaDone>; 2428835SAli.Saidi@ARM.com EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent; 2438613SN/A 2448673SN/A void txDmaDone(); 2458673SN/A friend class EventWrapper<Device, &Device::txDmaDone>; 2468673SN/A EventWrapper<Device, &Device::txDmaDone> txDmaEvent; 2478673SN/A 2488673SN/A Tick dmaReadDelay; 2498673SN/A Tick dmaReadFactor; 2508835SAli.Saidi@ARM.com Tick dmaWriteDelay; 2518835SAli.Saidi@ARM.com Tick dmaWriteFactor; 2528835SAli.Saidi@ARM.com 2538835SAli.Saidi@ARM.com/** 2548673SN/A * Interrupt management 2558835SAli.Saidi@ARM.com */ 2568613SN/A protected: 2578835SAli.Saidi@ARM.com void devIntrPost(uint32_t interrupts); 2588673SN/A void devIntrClear(uint32_t interrupts = Regs::Intr_All); 2598835SAli.Saidi@ARM.com void devIntrChangeMask(uint32_t newmask); 2608673SN/A 2618835SAli.Saidi@ARM.com/** 2628673SN/A * Memory Interface 2638835SAli.Saidi@ARM.com */ 2648673SN/A public: 2658835SAli.Saidi@ARM.com virtual Tick read(PacketPtr pkt); 2668673SN/A virtual Tick write(PacketPtr pkt); 2678835SAli.Saidi@ARM.com virtual void resume(); 2688673SN/A 2698835SAli.Saidi@ARM.com void prepareIO(int cpu, int index); 2708613SN/A void prepareRead(int cpu, int index); 2718835SAli.Saidi@ARM.com void prepareWrite(int cpu, int index); 2728673SN/A // Fault iprRead(Addr daddr, int cpu, uint64_t &result); 2738835SAli.Saidi@ARM.com 2748673SN/A/** 2758835SAli.Saidi@ARM.com * Statistics 2768835SAli.Saidi@ARM.com */ 2778835SAli.Saidi@ARM.com private: 2788613SN/A Stats::Scalar<> rxBytes; 2798613SN/A Stats::Formula rxBandwidth; 2808613SN/A Stats::Scalar<> rxPackets; 2818613SN/A Stats::Formula rxPacketRate; 2828983Snate@binkert.org Stats::Scalar<> rxIpPackets; 2838983Snate@binkert.org Stats::Scalar<> rxTcpPackets; 2848613SN/A Stats::Scalar<> rxUdpPackets; 2858613SN/A Stats::Scalar<> rxIpChecksums; 2868835SAli.Saidi@ARM.com Stats::Scalar<> rxTcpChecksums; 2878835SAli.Saidi@ARM.com Stats::Scalar<> rxUdpChecksums; 2888613SN/A 2898673SN/A Stats::Scalar<> txBytes; 2908673SN/A Stats::Formula txBandwidth; 2918673SN/A Stats::Formula totBandwidth; 2928673SN/A Stats::Formula totPackets; 2938673SN/A Stats::Formula totBytes; 2948673SN/A Stats::Formula totPacketRate; 2958835SAli.Saidi@ARM.com Stats::Scalar<> txPackets; 2968835SAli.Saidi@ARM.com Stats::Formula txPacketRate; 2978835SAli.Saidi@ARM.com Stats::Scalar<> txIpPackets; 2988835SAli.Saidi@ARM.com Stats::Scalar<> txTcpPackets; 2998673SN/A Stats::Scalar<> txUdpPackets; 3008835SAli.Saidi@ARM.com Stats::Scalar<> txIpChecksums; 3018673SN/A Stats::Scalar<> txTcpChecksums; 3028835SAli.Saidi@ARM.com Stats::Scalar<> txUdpChecksums; 3038673SN/A 3048835SAli.Saidi@ARM.com public: 3058673SN/A virtual void regStats(); 3068835SAli.Saidi@ARM.com 3078673SN/A/** 3088835SAli.Saidi@ARM.com * Serialization stuff 3098673SN/A */ 3108835SAli.Saidi@ARM.com public: 3118673SN/A virtual void serialize(std::ostream &os); 3128835SAli.Saidi@ARM.com virtual void unserialize(Checkpoint *cp, const std::string §ion); 3138673SN/A 3148835SAli.Saidi@ARM.com public: 3158673SN/A Device(Params *p); 3168835SAli.Saidi@ARM.com ~Device(); 3178835SAli.Saidi@ARM.com}; 3188835SAli.Saidi@ARM.com 3198613SN/A/* 3208613SN/A * Ethernet Interface for an Ethernet Device 3218613SN/A */ 3228613SN/Aclass Interface : public EtherInt 3238983Snate@binkert.org{ 3248983Snate@binkert.org private: 3258613SN/A Device *dev; 3268613SN/A 3278835SAli.Saidi@ARM.com public: 3288835SAli.Saidi@ARM.com Interface(const std::string &name, Device *d) 3298613SN/A : EtherInt(name), dev(d) { dev->setInterface(this); } 3308673SN/A 3318613SN/A virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); } 3328673SN/A virtual void sendDone() { dev->transferDone(); } 3338673SN/A}; 3348673SN/A 3358613SN/A/* namespace Sinic */ } 3368835SAli.Saidi@ARM.com 3378835SAli.Saidi@ARM.com#endif // __DEV_SINIC_HH__ 3388835SAli.Saidi@ARM.com