11156SN/A/* 21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 31156SN/A * All rights reserved. 41156SN/A * 51156SN/A * Redistribution and use in source and binary forms, with or without 61156SN/A * modification, are permitted provided that the following conditions are 71156SN/A * met: redistributions of source code must retain the above copyright 81156SN/A * notice, this list of conditions and the following disclaimer; 91156SN/A * redistributions in binary form must reproduce the above copyright 101156SN/A * notice, this list of conditions and the following disclaimer in the 111156SN/A * documentation and/or other materials provided with the distribution; 121156SN/A * neither the name of the copyright holders nor the names of its 131156SN/A * contributors may be used to endorse or promote products derived from 141156SN/A * this software without specific prior written permission. 151156SN/A * 161156SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171156SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181156SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191156SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201156SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211156SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221156SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231156SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241156SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251156SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261156SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665SN/A * 282665SN/A * Authors: Nathan Binkert 291156SN/A */ 301156SN/A 3111263Sandreas.sandberg@arm.com#ifndef __DEV_NET_SINIC_HH__ 3211263Sandreas.sandberg@arm.com#define __DEV_NET_SINIC_HH__ 331156SN/A 341156SN/A#include "base/inet.hh" 351156SN/A#include "base/statistics.hh" 361156SN/A#include "dev/io_device.hh" 3711263Sandreas.sandberg@arm.com#include "dev/net/etherdevice.hh" 3811263Sandreas.sandberg@arm.com#include "dev/net/etherint.hh" 3911263Sandreas.sandberg@arm.com#include "dev/net/etherpkt.hh" 4011263Sandreas.sandberg@arm.com#include "dev/net/pktfifo.hh" 4111263Sandreas.sandberg@arm.com#include "dev/net/sinicreg.hh" 4211260SN/A#include "dev/pci/device.hh" 434762SN/A#include "params/Sinic.hh" 441156SN/A#include "sim/eventq.hh" 451156SN/A 461156SN/Anamespace Sinic { 471156SN/A 481156SN/Aclass Interface; 499339SN/Aclass Base : public EtherDevBase 501156SN/A{ 511156SN/A protected: 521156SN/A bool rxEnable; 531156SN/A bool txEnable; 541156SN/A 551156SN/A protected: 561156SN/A Tick intrDelay; 571156SN/A Tick intrTick; 581156SN/A bool cpuIntrEnable; 591156SN/A bool cpuPendingIntr; 601156SN/A void cpuIntrPost(Tick when); 611156SN/A void cpuInterrupt(); 621156SN/A void cpuIntrClear(); 631156SN/A 6412087Sspwilson2@wisc.edu EventFunctionWrapper *intrEvent; 651156SN/A Interface *interface; 661156SN/A 671156SN/A bool cpuIntrPending() const; 681156SN/A void cpuIntrAck() { cpuIntrClear(); } 691156SN/A 701156SN/A/** 711156SN/A * Serialization stuff 721156SN/A */ 731156SN/A public: 7411168SN/A void serialize(CheckpointOut &cp) const override; 7511168SN/A void unserialize(CheckpointIn &cp) override; 761156SN/A 771156SN/A/** 781156SN/A * Construction/Destruction/Parameters 791156SN/A */ 801156SN/A public: 814762SN/A typedef SinicParams Params; 824762SN/A const Params *params() const { return (const Params *)_params; } 834981SN/A Base(const Params *p); 841156SN/A}; 851156SN/A 861156SN/Aclass Device : public Base 871156SN/A{ 881156SN/A protected: 891156SN/A /** Receive State Machine States */ 901156SN/A enum RxState { 911156SN/A rxIdle, 921156SN/A rxFifoBlock, 931156SN/A rxBeginCopy, 941156SN/A rxCopy, 951156SN/A rxCopyDone 961156SN/A }; 971156SN/A 981156SN/A /** Transmit State Machine states */ 991156SN/A enum TxState { 1001156SN/A txIdle, 1011156SN/A txFifoBlock, 1021156SN/A txBeginCopy, 1031156SN/A txCopy, 1041156SN/A txCopyDone 1051156SN/A }; 1061156SN/A 1071156SN/A /** device register file */ 1081156SN/A struct { 1091939SN/A uint32_t Config; // 0x00 1101939SN/A uint32_t Command; // 0x04 1111939SN/A uint32_t IntrStatus; // 0x08 1121939SN/A uint32_t IntrMask; // 0x0c 1131939SN/A uint32_t RxMaxCopy; // 0x10 1141939SN/A uint32_t TxMaxCopy; // 0x14 1155603SN/A uint32_t ZeroCopySize; // 0x18 1165603SN/A uint32_t ZeroCopyMark; // 0x1c 1175603SN/A uint32_t VirtualCount; // 0x20 1185603SN/A uint32_t RxMaxIntr; // 0x24 1195603SN/A uint32_t RxFifoSize; // 0x28 1205603SN/A uint32_t TxFifoSize; // 0x2c 1215603SN/A uint32_t RxFifoLow; // 0x30 1225603SN/A uint32_t TxFifoLow; // 0x34 1235603SN/A uint32_t RxFifoHigh; // 0x38 1245603SN/A uint32_t TxFifoHigh; // 0x3c 1255603SN/A uint64_t RxData; // 0x40 1265603SN/A uint64_t RxDone; // 0x48 1275603SN/A uint64_t RxWait; // 0x50 1285603SN/A uint64_t TxData; // 0x58 1295603SN/A uint64_t TxDone; // 0x60 1305603SN/A uint64_t TxWait; // 0x68 1315603SN/A uint64_t HwAddr; // 0x70 1325603SN/A uint64_t RxStatus; // 0x78 1331156SN/A } regs; 1341156SN/A 1352008SN/A struct VirtualReg { 1362008SN/A uint64_t RxData; 1372008SN/A uint64_t RxDone; 1382008SN/A uint64_t TxData; 1392008SN/A uint64_t TxDone; 1402008SN/A 1415603SN/A PacketFifo::iterator rxIndex; 1426227SN/A unsigned rxPacketOffset; 1436227SN/A unsigned rxPacketBytes; 1442008SN/A uint64_t rxDoneData; 1452008SN/A 1462282SN/A Counter rxUnique; 1472282SN/A Counter txUnique; 1482282SN/A 1492008SN/A VirtualReg() 1502008SN/A : RxData(0), RxDone(0), TxData(0), TxDone(0), 1512008SN/A rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0) 1522008SN/A { } 1532008SN/A }; 1542008SN/A typedef std::vector<VirtualReg> VirtualRegs; 1556227SN/A typedef std::list<unsigned> VirtualList; 1562282SN/A Counter rxUnique; 1572282SN/A Counter txUnique; 1582008SN/A VirtualRegs virtualRegs; 1592008SN/A VirtualList rxList; 1602282SN/A VirtualList rxBusy; 1612282SN/A int rxActive; 1622008SN/A VirtualList txList; 1632008SN/A 1645603SN/A int rxBusyCount; 1655603SN/A int rxMappedCount; 1665603SN/A int rxDirtyCount; 1675603SN/A 1681939SN/A uint8_t ®Data8(Addr daddr) { return *((uint8_t *)®s + daddr); } 1691939SN/A uint32_t ®Data32(Addr daddr) { return *(uint32_t *)®Data8(daddr); } 1701939SN/A uint64_t ®Data64(Addr daddr) { return *(uint64_t *)®Data8(daddr); } 1711939SN/A 1721156SN/A protected: 1731156SN/A RxState rxState; 1741156SN/A PacketFifo rxFifo; 1752008SN/A PacketFifo::iterator rxFifoPtr; 1761939SN/A bool rxEmpty; 1772282SN/A bool rxLow; 1781156SN/A Addr rxDmaAddr; 1791156SN/A uint8_t *rxDmaData; 1806227SN/A unsigned rxDmaLen; 1811156SN/A 1821156SN/A TxState txState; 1831156SN/A PacketFifo txFifo; 1841939SN/A bool txFull; 1852566SN/A EthPacketPtr txPacket; 1862008SN/A int txPacketOffset; 1872008SN/A int txPacketBytes; 1881156SN/A Addr txDmaAddr; 1891156SN/A uint8_t *txDmaData; 1901156SN/A int txDmaLen; 1911156SN/A 1921156SN/A protected: 1931156SN/A void reset(); 1941156SN/A 1951156SN/A void rxKick(); 1961156SN/A Tick rxKickTick; 1971156SN/A 1981156SN/A void txKick(); 1991156SN/A Tick txKickTick; 2001156SN/A 2011156SN/A /** 2021156SN/A * Retransmit event 2031156SN/A */ 2041156SN/A void transmit(); 2051156SN/A void txEventTransmit() 2061156SN/A { 2071156SN/A transmit(); 2081156SN/A if (txState == txFifoBlock) 2091156SN/A txKick(); 2101156SN/A } 21112087Sspwilson2@wisc.edu EventFunctionWrapper txEvent; 2121156SN/A 2131156SN/A void txDump() const; 2141156SN/A void rxDump() const; 2151156SN/A 2161156SN/A /** 2171156SN/A * receive address filter 2181156SN/A */ 2192566SN/A bool rxFilter(const EthPacketPtr &packet); 2201156SN/A 2211156SN/A/** 2221156SN/A * device configuration 2231156SN/A */ 2241156SN/A void changeConfig(uint32_t newconfig); 2251939SN/A void command(uint32_t command); 2261156SN/A 2271156SN/A/** 2281156SN/A * device ethernet interface 2291156SN/A */ 2301156SN/A public: 2312566SN/A bool recvPacket(EthPacketPtr packet); 2321156SN/A void transferDone(); 23313784Sgabeblack@google.com Port &getPort(const std::string &if_name, 23413784Sgabeblack@google.com PortID idx=InvalidPortID) override; 2351156SN/A 2361156SN/A/** 2371156SN/A * DMA parameters 2381156SN/A */ 2391156SN/A protected: 2401156SN/A void rxDmaDone(); 24112087Sspwilson2@wisc.edu EventFunctionWrapper rxDmaEvent; 2421156SN/A 2431156SN/A void txDmaDone(); 24412087Sspwilson2@wisc.edu EventFunctionWrapper txDmaEvent; 2451156SN/A 2461156SN/A Tick dmaReadDelay; 2471156SN/A Tick dmaReadFactor; 2481156SN/A Tick dmaWriteDelay; 2491156SN/A Tick dmaWriteFactor; 2501156SN/A 2511156SN/A/** 2521156SN/A * Interrupt management 2531156SN/A */ 2541156SN/A protected: 2551156SN/A void devIntrPost(uint32_t interrupts); 2561156SN/A void devIntrClear(uint32_t interrupts = Regs::Intr_All); 2571156SN/A void devIntrChangeMask(uint32_t newmask); 2581156SN/A 2591156SN/A/** 2601156SN/A * Memory Interface 2611156SN/A */ 2621156SN/A public: 26311169SN/A Tick read(PacketPtr pkt) override; 26411169SN/A Tick write(PacketPtr pkt) override; 26511168SN/A virtual void drainResume() override; 2661993SN/A 26711005SN/A void prepareIO(ContextID cpu, int index); 26811005SN/A void prepareRead(ContextID cpu, int index); 26911005SN/A void prepareWrite(ContextID cpu, int index); 27011005SN/A // Fault iprRead(Addr daddr, ContextID cpu, uint64_t &result); 2711156SN/A 2721156SN/A/** 2731156SN/A * Statistics 2741156SN/A */ 2751156SN/A private: 2765999SN/A Stats::Scalar totalVnicDistance; 2775999SN/A Stats::Scalar numVnicDistance; 2785999SN/A Stats::Scalar maxVnicDistance; 2795603SN/A Stats::Formula avgVnicDistance; 2805603SN/A 2815603SN/A int _maxVnicDistance; 2825603SN/A 2831156SN/A public: 28411169SN/A void regStats() override; 28511169SN/A void resetStats() override; 2861156SN/A 2871156SN/A/** 2881156SN/A * Serialization stuff 2891156SN/A */ 2901156SN/A public: 29111168SN/A void serialize(CheckpointOut &cp) const override; 29211168SN/A void unserialize(CheckpointIn &cp) override; 2931156SN/A 2941156SN/A public: 2954981SN/A Device(const Params *p); 2961156SN/A ~Device(); 2971156SN/A}; 2981156SN/A 2991156SN/A/* 3001156SN/A * Ethernet Interface for an Ethernet Device 3011156SN/A */ 3021156SN/Aclass Interface : public EtherInt 3031156SN/A{ 3041156SN/A private: 3051156SN/A Device *dev; 3061156SN/A 3071156SN/A public: 3081156SN/A Interface(const std::string &name, Device *d) 3094981SN/A : EtherInt(name), dev(d) 3104981SN/A { } 3111156SN/A 3122566SN/A virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); } 3131156SN/A virtual void sendDone() { dev->transferDone(); } 3141156SN/A}; 3151156SN/A 3167811SN/A} // namespace Sinic 3171156SN/A 31811263Sandreas.sandberg@arm.com#endif // __DEV_NET_SINIC_HH__ 319