sinic.hh revision 2008
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 291156SN/A#ifndef __DEV_SINIC_HH__ 301156SN/A#define __DEV_SINIC_HH__ 3111263Sandreas.sandberg@arm.com 3211263Sandreas.sandberg@arm.com#include "base/inet.hh" 331156SN/A#include "base/statistics.hh" 341156SN/A#include "dev/etherint.hh" 351156SN/A#include "dev/etherpkt.hh" 361156SN/A#include "dev/io_device.hh" 3711263Sandreas.sandberg@arm.com#include "dev/pcidev.hh" 3811263Sandreas.sandberg@arm.com#include "dev/pktfifo.hh" 3911263Sandreas.sandberg@arm.com#include "dev/sinicreg.hh" 4011263Sandreas.sandberg@arm.com#include "mem/bus/bus.hh" 4111263Sandreas.sandberg@arm.com#include "sim/eventq.hh" 4211260SN/A 434762SN/Anamespace Sinic { 441156SN/A 451156SN/Aclass Interface; 461156SN/Aclass Base : public PciDev 471156SN/A{ 481156SN/A protected: 499339SN/A bool rxEnable; 501156SN/A bool txEnable; 511156SN/A Tick clock; 521156SN/A inline Tick cycles(int numCycles) const { return numCycles * clock; } 531156SN/A 541156SN/A protected: 551156SN/A Tick intrDelay; 561156SN/A Tick intrTick; 571156SN/A bool cpuIntrEnable; 581156SN/A bool cpuPendingIntr; 591156SN/A void cpuIntrPost(Tick when); 601156SN/A void cpuInterrupt(); 611156SN/A void cpuIntrClear(); 621156SN/A 631156SN/A typedef EventWrapper<Base, &Base::cpuInterrupt> IntrEvent; 6412087Sspwilson2@wisc.edu friend void IntrEvent::process(); 651156SN/A IntrEvent *intrEvent; 661156SN/A Interface *interface; 671156SN/A 681156SN/A bool cpuIntrPending() const; 691156SN/A void cpuIntrAck() { cpuIntrClear(); } 701156SN/A 711156SN/A/** 721156SN/A * Serialization stuff 731156SN/A */ 7411168SN/A public: 7511168SN/A virtual void serialize(std::ostream &os); 761156SN/A virtual void unserialize(Checkpoint *cp, const std::string §ion); 771156SN/A 781156SN/A/** 791156SN/A * Construction/Destruction/Parameters 801156SN/A */ 814762SN/A public: 824762SN/A struct Params : public PciDev::Params 834981SN/A { 841156SN/A Tick clock; 851156SN/A Tick intr_delay; 861156SN/A }; 871156SN/A 881156SN/A Base(Params *p); 891156SN/A}; 901156SN/A 911156SN/Aclass Device : public Base 921156SN/A{ 931156SN/A protected: 941156SN/A Platform *plat; 951156SN/A PhysicalMemory *physmem; 961156SN/A 971156SN/A protected: 981156SN/A /** Receive State Machine States */ 991156SN/A enum RxState { 1001156SN/A rxIdle, 1011156SN/A rxFifoBlock, 1021156SN/A rxBeginCopy, 1031156SN/A rxCopy, 1041156SN/A rxCopyDone 1051156SN/A }; 1061156SN/A 1071156SN/A /** Transmit State Machine states */ 1081156SN/A enum TxState { 1091939SN/A txIdle, 1101939SN/A txFifoBlock, 1111939SN/A txBeginCopy, 1121939SN/A txCopy, 1131939SN/A txCopyDone 1141939SN/A }; 1155603SN/A 1165603SN/A /** device register file */ 1175603SN/A struct { 1185603SN/A uint32_t Config; // 0x00 1195603SN/A uint32_t Command; // 0x04 1205603SN/A uint32_t IntrStatus; // 0x08 1215603SN/A uint32_t IntrMask; // 0x0c 1225603SN/A uint32_t RxMaxCopy; // 0x10 1235603SN/A uint32_t TxMaxCopy; // 0x14 1245603SN/A uint32_t RxMaxIntr; // 0x18 1255603SN/A uint32_t Reserved0; // 0x1c 1265603SN/A uint32_t RxFifoSize; // 0x20 1275603SN/A uint32_t TxFifoSize; // 0x24 1285603SN/A uint32_t RxFifoMark; // 0x28 1295603SN/A uint32_t TxFifoMark; // 0x2c 1305603SN/A uint64_t RxData; // 0x30 1315603SN/A uint64_t RxDone; // 0x38 1325603SN/A uint64_t RxWait; // 0x40 1331156SN/A uint64_t TxData; // 0x48 1341156SN/A uint64_t TxDone; // 0x50 1352008SN/A uint64_t TxWait; // 0x58 1362008SN/A uint64_t HwAddr; // 0x60 1372008SN/A } regs; 1382008SN/A 1392008SN/A struct VirtualReg { 1402008SN/A uint64_t RxData; 1415603SN/A uint64_t RxDone; 1426227SN/A uint64_t TxData; 1436227SN/A uint64_t TxDone; 1442008SN/A 1452008SN/A PacketFifo::iterator rxPacket; 1462282SN/A int rxPacketOffset; 1472282SN/A int rxPacketBytes; 1482282SN/A uint64_t rxDoneData; 1492008SN/A 1502008SN/A VirtualReg() 1512008SN/A : RxData(0), RxDone(0), TxData(0), TxDone(0), 1522008SN/A rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0) 1532008SN/A { } 1542008SN/A }; 1556227SN/A typedef std::vector<VirtualReg> VirtualRegs; 1562282SN/A typedef std::list<int> VirtualList; 1572282SN/A VirtualRegs virtualRegs; 1582008SN/A VirtualList rxList; 1592008SN/A VirtualList txList; 1602282SN/A 1612282SN/A uint8_t ®Data8(Addr daddr) { return *((uint8_t *)®s + daddr); } 1622008SN/A uint32_t ®Data32(Addr daddr) { return *(uint32_t *)®Data8(daddr); } 1632008SN/A uint64_t ®Data64(Addr daddr) { return *(uint64_t *)®Data8(daddr); } 1645603SN/A 1655603SN/A private: 1665603SN/A Addr addr; 1675603SN/A static const Addr size = Regs::Size; 1681939SN/A 1691939SN/A protected: 1701939SN/A RxState rxState; 1711939SN/A PacketFifo rxFifo; 1721156SN/A PacketFifo::iterator rxFifoPtr; 1731156SN/A bool rxEmpty; 1741156SN/A Addr rxDmaAddr; 1752008SN/A uint8_t *rxDmaData; 1761939SN/A int rxDmaLen; 1772282SN/A 1781156SN/A TxState txState; 1791156SN/A PacketFifo txFifo; 1806227SN/A bool txFull; 1811156SN/A PacketPtr txPacket; 1821156SN/A int txPacketOffset; 1831156SN/A int txPacketBytes; 1841939SN/A Addr txDmaAddr; 1852566SN/A uint8_t *txDmaData; 1862008SN/A int txDmaLen; 1872008SN/A 1881156SN/A protected: 1891156SN/A void reset(); 1901156SN/A 1911156SN/A void rxKick(); 1921156SN/A Tick rxKickTick; 1931156SN/A typedef EventWrapper<Device, &Device::rxKick> RxKickEvent; 1941156SN/A friend void RxKickEvent::process(); 1951156SN/A 1961156SN/A void txKick(); 1971156SN/A Tick txKickTick; 1981156SN/A typedef EventWrapper<Device, &Device::txKick> TxKickEvent; 1991156SN/A friend void TxKickEvent::process(); 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 typedef EventWrapper<Device, &Device::txEventTransmit> TxEvent; 2121156SN/A friend void TxEvent::process(); 2131156SN/A TxEvent txEvent; 2141156SN/A 2151156SN/A void txDump() const; 2161156SN/A void rxDump() const; 2171156SN/A 2181156SN/A /** 2192566SN/A * receive address filter 2201156SN/A */ 2211156SN/A bool rxFilter(const PacketPtr &packet); 2221156SN/A 2231156SN/A/** 2241156SN/A * device configuration 2251939SN/A */ 2261156SN/A void changeConfig(uint32_t newconfig); 2271156SN/A void command(uint32_t command); 2281156SN/A 2291156SN/A/** 2301156SN/A * device ethernet interface 2312566SN/A */ 2321156SN/A public: 23313784Sgabeblack@google.com bool recvPacket(PacketPtr packet); 23413784Sgabeblack@google.com void transferDone(); 2351156SN/A void setInterface(Interface *i) { assert(!interface); interface = i; } 2361156SN/A 2371156SN/A/** 2381156SN/A * DMA parameters 2391156SN/A */ 2401156SN/A protected: 24112087Sspwilson2@wisc.edu void rxDmaCopy(); 2421156SN/A void rxDmaDone(); 2431156SN/A friend class EventWrapper<Device, &Device::rxDmaDone>; 24412087Sspwilson2@wisc.edu EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent; 2451156SN/A 2461156SN/A void txDmaCopy(); 2471156SN/A void txDmaDone(); 2481156SN/A friend class EventWrapper<Device, &Device::txDmaDone>; 2491156SN/A EventWrapper<Device, &Device::txDmaDone> txDmaEvent; 2501156SN/A 2511156SN/A Tick dmaReadDelay; 2521156SN/A Tick dmaReadFactor; 2531156SN/A Tick dmaWriteDelay; 2541156SN/A Tick dmaWriteFactor; 2551156SN/A 2561156SN/A/** 2571156SN/A * Interrupt management 2581156SN/A */ 2591156SN/A protected: 2601156SN/A void devIntrPost(uint32_t interrupts); 2611156SN/A void devIntrClear(uint32_t interrupts = Regs::Intr_All); 2621156SN/A void devIntrChangeMask(uint32_t newmask); 26311169SN/A 26411169SN/A/** 26511168SN/A * PCI Configuration interface 2661993SN/A */ 26711005SN/A public: 26811005SN/A virtual void writeConfig(int offset, int size, const uint8_t *data); 26911005SN/A 27011005SN/A/** 2711156SN/A * Memory Interface 2721156SN/A */ 2731156SN/A public: 2741156SN/A virtual Fault read(MemReqPtr &req, uint8_t *data); 2751156SN/A virtual Fault write(MemReqPtr &req, const uint8_t *data); 2765999SN/A 2775999SN/A void prepareIO(int cpu, int index); 2785999SN/A void prepareRead(int cpu, int index); 2795603SN/A void prepareWrite(int cpu, int index); 2805603SN/A Fault iprRead(Addr daddr, int cpu, uint64_t &result); 2815603SN/A Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data); 2825603SN/A Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data); 2831156SN/A void regWrite(Addr daddr, int cpu, const uint8_t *data); 28411169SN/A Tick cacheAccess(MemReqPtr &req); 28511169SN/A 2861156SN/A protected: 2871156SN/A struct RegWriteData { 2881156SN/A Addr daddr; 2891156SN/A uint64_t value; 2901156SN/A RegWriteData(Addr da, uint64_t val) : daddr(da), value(val) {} 29111168SN/A }; 29211168SN/A 2931156SN/A std::vector<std::list<RegWriteData> > writeQueue; 2941156SN/A 2954981SN/A bool pioDelayWrite; 2961156SN/A 2971156SN/A/** 2981156SN/A * Statistics 2991156SN/A */ 3001156SN/A private: 3011156SN/A Stats::Scalar<> rxBytes; 3021156SN/A Stats::Formula rxBandwidth; 3031156SN/A Stats::Scalar<> rxPackets; 3041156SN/A Stats::Formula rxPacketRate; 3051156SN/A Stats::Scalar<> rxIpPackets; 3061156SN/A Stats::Scalar<> rxTcpPackets; 3071156SN/A Stats::Scalar<> rxUdpPackets; 3081156SN/A Stats::Scalar<> rxIpChecksums; 3094981SN/A Stats::Scalar<> rxTcpChecksums; 3104981SN/A Stats::Scalar<> rxUdpChecksums; 3111156SN/A 3122566SN/A Stats::Scalar<> txBytes; 3131156SN/A Stats::Formula txBandwidth; 3141156SN/A Stats::Formula totBandwidth; 3151156SN/A Stats::Formula totPackets; 3167811SN/A Stats::Formula totBytes; 3171156SN/A Stats::Formula totPacketRate; 31811263Sandreas.sandberg@arm.com Stats::Scalar<> txPackets; 319 Stats::Formula txPacketRate; 320 Stats::Scalar<> txIpPackets; 321 Stats::Scalar<> txTcpPackets; 322 Stats::Scalar<> txUdpPackets; 323 Stats::Scalar<> txIpChecksums; 324 Stats::Scalar<> txTcpChecksums; 325 Stats::Scalar<> txUdpChecksums; 326 327 public: 328 virtual void regStats(); 329 330/** 331 * Serialization stuff 332 */ 333 public: 334 virtual void serialize(std::ostream &os); 335 virtual void unserialize(Checkpoint *cp, const std::string §ion); 336 337/** 338 * Construction/Destruction/Parameters 339 */ 340 public: 341 struct Params : public Base::Params 342 { 343 IntrControl *i; 344 PhysicalMemory *pmem; 345 Tick tx_delay; 346 Tick rx_delay; 347 HierParams *hier; 348 Bus *pio_bus; 349 Bus *header_bus; 350 Bus *payload_bus; 351 Tick pio_latency; 352 bool pio_delay_write; 353 PhysicalMemory *physmem; 354 IntrControl *intctrl; 355 bool rx_filter; 356 Net::EthAddr eaddr; 357 uint32_t rx_max_copy; 358 uint32_t tx_max_copy; 359 uint32_t rx_max_intr; 360 uint32_t rx_fifo_size; 361 uint32_t tx_fifo_size; 362 uint32_t rx_fifo_threshold; 363 uint32_t tx_fifo_threshold; 364 Tick dma_read_delay; 365 Tick dma_read_factor; 366 Tick dma_write_delay; 367 Tick dma_write_factor; 368 bool dma_no_allocate; 369 bool rx_thread; 370 bool tx_thread; 371 }; 372 373 protected: 374 const Params *params() const { return (const Params *)_params; } 375 376 public: 377 Device(Params *params); 378 ~Device(); 379}; 380 381/* 382 * Ethernet Interface for an Ethernet Device 383 */ 384class Interface : public EtherInt 385{ 386 private: 387 Device *dev; 388 389 public: 390 Interface(const std::string &name, Device *d) 391 : EtherInt(name), dev(d) { dev->setInterface(this); } 392 393 virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); } 394 virtual void sendDone() { dev->transferDone(); } 395}; 396 397/* namespace Sinic */ } 398 399#endif // __DEV_SINIC_HH__ 400